(prefer-coding-system 'utf-8)
(set-charset-priority 'unicode)
(setq default-process-coding-system '(utf-8-unix . utf-8-unix))
+(when (display-graphic-p)
+ (setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)))
#+END_SRC
*** Hilight matching parentheses
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package aggressive-indent
:ensure aggressive-indent
+ :commands (aggressive-indent-mode global-aggressive-indent-mode)
:config
(progn
(global-aggressive-indent-mode 0)
(use-package anzu
:ensure anzu
:diminish anzu-mode
- :init
+ :defer t
+ :idle
(progn
(global-anzu-mode 1))
:config
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package auto-complete-config
:ensure auto-complete
- :init
- (progn
- (use-package pos-tip
- :ensure t)
- (ac-config-default)
- )
+ :idle
+ (ac-config-default)
:config
(progn
;; hook AC into completion-at-point
(defun sanityinc/dabbrev-friend-buffer (other-buffer)
(< (buffer-size other-buffer) (* 1 1024 1024)))
+ (use-package pos-tip
+ :ensure t)
+
;; custom keybindings to use tab, enter and up and down arrows
(bind-key "\t" 'ac-expand ac-complete-mode-map)
(bind-key "\r" 'ac-complete ac-complete-mode-map)
(use-package autorevert
:commands auto-revert-mode
:diminish auto-revert-mode
- :init
+ :idle
(progn
(setq global-auto-revert-mode t)
(setq global-auto-revert-non-file-buffers t)
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package cal
:commands (cal/insert)
- :bind ("C-c c" . cal/insert))
-#+END_SRC
-
-Weeks start on Monday, not sunday.
-#+BEGIN_SRC emacs-lisp :tangle yes
-(setq calendar-week-start-day 1)
-#+END_SRC
+ :bind ("C-c c" . cal/insert)
+ :config
+ (progn
+ ; Weeks start on Monday, not sunday.
+ (setq calendar-week-start-day 1)
+
+ ; Display ISO week numbers in Calendar Mode
+ (copy-face font-lock-constant-face 'calendar-iso-week-face)
+ (set-face-attribute 'calendar-iso-week-face nil :height 0.7)
+ (setq calendar-intermonth-text
+ '(propertize
+ (format "%2d"
+ (car
+ (calendar-iso-from-absolute
+ (calendar-absolute-from-gregorian (list month day year)))))
+ 'font-lock-face 'calendar-iso-week-face))
+ (copy-face 'default 'calendar-iso-week-header-face)
+ (set-face-attribute 'calendar-iso-week-header-face nil :height 0.7)
+ (setq calendar-intermonth-header
+ (propertize "Wk" ; or e.g. "KW" in Germany
+ 'font-lock-face 'calendar-iso-week-header-face))))
-Display ISO week numbers in Calendar Mode
-#+BEGIN_SRC emacs-lisp :tangle yes
-(copy-face font-lock-constant-face 'calendar-iso-week-face)
-(set-face-attribute 'calendar-iso-week-face nil
- :height 0.7)
-(setq calendar-intermonth-text
- '(propertize
- (format "%2d"
- (car
- (calendar-iso-from-absolute
- (calendar-absolute-from-gregorian (list month day year)))))
- 'font-lock-face 'calendar-iso-week-face))
-(copy-face 'default 'calendar-iso-week-header-face)
-(set-face-attribute 'calendar-iso-week-header-face nil
- :height 0.7)
-(setq calendar-intermonth-header
- (propertize "Wk" ; or e.g. "KW" in Germany
- 'font-lock-face 'calendar-iso-week-header-face))
#+END_SRC
** crontab-mode
(use-package dired
:commands (dired dired-other-window dired-other-frame dired-noselect
dired-mode dired-jump)
+ :defines (dired-omit-regexp-orig)
:init
(progn
(setq diredp-hide-details-initially-flag nil))
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package discover-my-major
:ensure discover-my-major
+ :commands discover-my-major
:bind ("C-h C-m" . discover-my-major))
#+END_SRC
** easypg
:config (progn
(setq ediff-window-setup-function 'ediff-setup-windows-plain)
(setq ediff-split-window-function 'split-window-horizontally)
- (bind-key "j" 'ediff-next-difference ediff-mode-map)
- (bind-key "k" 'ediff-previous-difference ediff-mode-map))
+ )
)
#+END_SRC
** emms
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package expand-region
:ensure expand-region
- :bind ("C-M-+" . er/expand-region))
+ :bind ("C-M-+" . er/expand-region)
+ :commands er/expand-region)
#+END_SRC
** filladapt
[2013-05-02 Thu 00:04]
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package filladapt
:diminish filladapt-mode
- :init
+ :idle
(setq-default filladapt-mode t))
#+END_SRC
** flycheck
:diminish flycheck-mode
:bind (("M-n" . next-error)
("M-p" . previous-error))
- :init
+ :idle
(progn
(add-hook 'find-file-hook
(lambda ()
("C-x s" . git-gutter+-stage-hunks)
("C-x c" . git-gutter+-commit)
)
- :init
+ :idle
(progn
(setq git-gutter+-disabled-modes '(org-mode))
(global-git-gutter+-mode 1))
Browse historic versions of a file with p (previous) and n (next).
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package git-timemachine
- :ensure git-timemachine)
+ :ensure git-timemachine
+ :commands git-timemachine)
#+END_SRC
** gnus
Most of my gnus config is in an own file, [[file:gnus.org][gnus.org]], here I only have
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package hippie-exp
:bind ("M-/" . hippie-expand)
+ :commands hippie-expand
:config
(progn
(setq hippie-expand-try-functions-list '(try-expand-dabbrev
("<XF86WebCam>" . ibuffer)
)
:commands (ibuffer)
- :init
+ :defines (ibuffer-filtering-alist
+ ibuffer-filter-groups ibuffer-compile-formats ibuffer-git-column-length
+ ibuffer-show-empty-filter-groups ibuffer-saved-filter-groups)
+ :config
(progn
+ (defvar my-ibufffer-separator " • ")
+ (setq ibuffer-filter-group-name-face 'variable-pitch
+ ibuffer-use-header-line t
+ ibuffer-old-time 12)
+ (unbind-key "M-o" ibuffer-mode-map)
+ (bind-key "s" 'isearch-forward-regexp ibuffer-mode-map)
+ (bind-key "." 'ibuffer-invert-sorting ibuffer-mode-map)
+
(use-package ibuffer-vc
:ensure t
:commands
ad-do-it
(ibuffer-update nil t)
(unless (string= recent-buffer-name "*Ibuffer*")
- (ibuffer-jump-to-buffer recent-buffer-name)))))
- :config
- (progn
- (defvar my-ibufffer-separator " • ")
- (setq ibuffer-filter-group-name-face 'variable-pitch
- ibuffer-use-header-line t
- ibuffer-old-time 12)
- (unbind-key "M-o" ibuffer-mode-map)
- (bind-key "s" 'isearch-forward-regexp ibuffer-mode-map)
- (bind-key "." 'ibuffer-invert-sorting ibuffer-mode-map)
+ (ibuffer-jump-to-buffer recent-buffer-name))))
(defun ibuffer-magit-status ()
(interactive)
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package info
:bind ("C-h C-i" . info-lookup-symbol)
-
+ :commands info-lookup-symbol
:config
(progn
;; (defadvice info-setup (after load-info+ activate)
ad-do-it))
(ad-activate 'linum-on)
+
(use-package linum-relative
- :ensure linum-relative)
- )
+ :ensure linum-relative
+ :init
+ (progn
+ (setq linum-format 'dynamic)
+ )))
:init
(global-linum-mode 1))
#+END_SRC
** lisp editing stuff
+
[2013-04-21 So 21:00]
I'm not doing much of it, except for my emacs and gnus configs, but
then I like it nice too...
(after "eldoc"
'(diminish 'eldoc-mode))
#+END_SRC
-
** magit
[2013-04-21 So 20:48]
magit is a mode for interacting with git.
)
magit-repo-dirs-depth 4
magit-log-auto-more t)
+
(use-package magit-blame
- :commands magit-blame-mode)
+ :commands magit-blame-mode
+ :defer t)
(use-package magit-svn
:ensure magit-svn
:commands (magit-svn-mode
- turn-on-magit-svn))
+ turn-on-magit-svn)
+ :defer t)
(add-hook 'magit-mode-hook 'hl-line-mode)
(defun magit-status-with-prefix ()
#+END_SRC
** message
#+BEGIN_SRC emacs-lisp :tangle yes
-(require 'message)
-(setq message-kill-buffer-on-exit t)
+(use-package message
+ :idle
+ (progn
+ (setq message-kill-buffer-on-exit t)))
#+END_SRC
** mingus
[[https://github.com/pft/mingus][Mingus]] is a nice interface to mpd, the Music Player Daemon.
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package miniedit
:ensure miniedit
+ :commands miniedit
:config
(progn
(bind-key "M-C-e" 'miniedit minibuffer-local-map)
[2013-05-21 Tue 23:39]
MMM Mode is a minor mode for Emacs that allows Multiple Major Modes to
coexist in one buffer.
-#+BEGIN_SRC emacs-lisp :tangle yes
+#+BEGIN_SRC emacs-lisp :tangle no
(use-package mmm-auto
:ensure mmm-mode
:init
** mo-git-blame
This is [[https://github.com/mbunkus/mo-git-blame][mo-git-blame -- An interactive, iterative 'git blame' mode for
Emacs]].
-
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package mo-git-blame
:ensure mo-git-blame
mc/create-fake-cursor-at-point
mc/pop-state-from-overlay
mc/maybe-multiple-cursors-mode)
+ :defines (multiple-cursors-mode
+ mc--read-char
+ mc--read-quoted-char
+ rectangular-region-mode)
:bind (("C-S-c C-S-c" . mc/edit-lines)
("C->" . mc/mark-next-like-this)
("C-<" . mc/mark-previous-like-this)
:commands (neotree-find
neotree-toggle
neotree)
- :init
+ :idle
(progn
(setq neo-smart-open t))
:config
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package cperl-mode
:commands cperl-mode
- :init
+ :idle
(progn
(defalias 'perl-mode 'cperl-mode)
(add-auto-mode 'cperl-mode "\\.\\([pP][Llm]\\|al\\)\\'")
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package puppet-mode
:mode ("\\.pp\\'" . puppet-mode)
- :config
- (use-package puppet-ext
- :init
+ :commands puppet-mode
+ :idle
(progn
- (bind-key "C-x ?" 'puppet-set-anchor puppet-mode-map)
- (bind-key "C-c C-r" 'puppet-create-require puppet-mode-map)
(defun my-puppet-mode-hook ()
(setq require-final-newline nil))
- (add-hook 'puppet-mode-hook 'my-puppet-mode-hook))))
+ (add-hook 'puppet-mode-hook 'my-puppet-mode-hook))
+ :config
+ (progn
+ (use-package puppet-ext
+ :init
+ (progn
+ (bind-key "C-x ?" 'puppet-set-anchor puppet-mode-map)
+ (bind-key "C-c C-r" 'puppet-create-require puppet-mode-map)))))
#+END_SRC
** python
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package rainbow-delimiters
:ensure rainbow-delimiters
+ :commands rainbow-delimiters-mode
:init
(add-hook 'prog-mode-hook #'rainbow-delimiters-mode))
#+END_SRC
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package rainbow-mode
:ensure rainbow-mode
+ :defer t
:diminish rainbow-mode)
#+END_SRC
Saner regex syntax
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package re-builder
- :command re-builder
+ :commands re-builder
:defer t
:config
(setq reb-re-syntax 'string))
(use-package sh-toggle
:bind ("C-. C-z" . shell-toggle))
#+END_SRC
+** smartscan
+[2015-02-24 Tue 23:35]
+Make =M-n= and =M-p= go forward/backword to the symbol at point.
+#+BEGIN_SRC emacs-lisp :tangle yes
+(use-package smartscan
+ :ensure smartscan
+ :defer t
+ :idle (global-smartscan-mode t))
+#+END_SRC
** timestamp
By default, Emacs can update the time stamp for the following two
formats if one exists in the first 8 lines of the file.
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package time-stamp
:commands time-stamp
- :init
+ :idle
(progn
(add-hook 'write-file-hooks 'time-stamp)
(setq time-stamp-active t))
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package undo-tree
:ensure undo-tree
+ :diminish undo-tree-mode
:init
- (global-undo-tree-mode)
- :diminish undo-tree-mode)
-#+END_SRC
-
-Additionally I would like to keep the region active should I undo
-while I have one.
-
-#+BEGIN_SRC emacs-lisp :tangle yes
-;; Keep region when undoing in region
-(defadvice undo-tree-undo (around keep-region activate)
- (if (use-region-p)
- (let ((m (set-marker (make-marker) (mark)))
- (p (set-marker (make-marker) (point))))
- ad-do-it
- (goto-char p)
- (set-mark m)
- (set-marker p nil)
- (set-marker m nil))
- ad-do-it))
+ (progn
+ (global-undo-tree-mode)
+ (setq undo-tree-visualizer-timestamps t)
+ (setq undo-tree-visualizer-diff t)
+ ;; Keep region when undoing in region
+ (defadvice undo-tree-undo (around keep-region activate)
+ (if (use-region-p)
+ (let ((m (set-marker (make-marker) (mark)))
+ (p (set-marker (make-marker) (point))))
+ ad-do-it
+ (goto-char p)
+ (set-mark m)
+ (set-marker p nil)
+ (set-marker m nil))
+ ad-do-it))))
#+END_SRC
** uniquify
Always have unique buffernames. See [[http://www.gnu.org/software/emacs/manual/html_node/emacs/Uniquify.html][Uniquify - GNU Emacs Manual]]
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package volatile-highlights
:ensure volatile-highlights
- :init
+ :idle
(volatile-highlights-mode t)
:diminish volatile-highlights-mode)
#+END_SRC
+** winner mode - undo and redo window configuration
+[2015-02-24 Tue 23:11]
+=winner-mode= lets you use =C-c <left>= and =C-c <right>= to switch between
+window configurations. This is handy when something has popped up a
+buffer that you want to look at briefly before returning to whatever
+you were working on. When you're done, press =C-c <left>=.
+#+BEGIN_SRC emacs-lisp :tangle yes
+(use-package winner
+ :ensure t
+ :defer t
+ :idle (winner-mode 1))
+#+END_SRC
** writegood
This highlights some /weaselwords/, a mode to /aid in finding common
writing problems/...
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package web-mode
:ensure web-mode
+ :defer t
:mode (("\\.phtml\\'" . web-mode)
("\\.tpl\\.php\\'" . web-mode)
("\\.jsp\\'" . web-mode)
(setq web-mode-enable-current-element-highlight t))))
:config
(progn
+ (setq web-mode-enable-current-element-highlight t)
+ (setq web-mode-ac-sources-alist
+ '(("css" . (ac-source-css-property))
+ ("html" . (ac-source-words-in-buffer ac-source-abbrev))))
(use-package impatient-mode
- :ensure impatient-mode))
+ :ensure impatient-mode
+ :defer t
+ :commands impatient-mode))
)
#+END_SRC
#+BEGIN_SRC emacs-lisp :tangle yes
(use-package yaml-mode
:ensure yaml-mode
-
:mode ("\\.ya?ml\\'" . yaml-mode)
:config
(bind-key "C-m" 'newline-and-indent yaml-mode-map ))
(setq yas-snippet-dirs (expand-file-name "yasnippet/snippets" jj-elisp-dir))
(use-package yasnippet
:ensure yasnippet
- :init
+ :defer t
+ :diminish yas-minor-mode
+ :commands yas-global-mode
+ :idle
(progn
- (yas-global-mode 1)
;; Integrate hippie-expand with ya-snippet
(add-to-list 'hippie-expand-try-functions-list
'yas-hippie-try-expand)
+ (yas-global-mode 1)
+ (setq yas-expand-only-for-last-commands '(self-insert-command))
+ (bind-key "\t" 'hippie-expand yas-minor-mode-map)
))
#+END_SRC
* Thats it
-;;; bind-key --- A simple way to manage personal keybindings
+;;; bind-key.el --- A simple way to manage personal keybindings
;; Copyright (C) 2012 John Wiegley
;; Created: 16 Jun 2012
;; Version: 1.0
;; Keywords: keys keybinding config dotemacs
-;; X-URL: https://github.com/jwiegley/bind-key
+;; URL: https://github.com/jwiegley/use-package
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;;
;; (bind-key* "<C-return>" 'other-window)
;;
-;; If you want to rebind a key only in a particular key, use:
+;; If you want to rebind a key only in a particular keymap, use:
;;
;; (bind-key "C-c x" 'my-ctrl-c-x-command some-other-mode-map)
;;
;;
;; (unbind-key "C-c x" some-other-mode-map)
;;
+;; To bind multiple keys at once, or set up a prefix map, a
+;; `bind-keys' macro is provided. It accepts keyword arguments, see
+;; its documentation for detailed description.
+;;
+;; To add keys into a specific map, use :map argument
+;;
+;; (bind-keys :map dired-mode-map
+;; ("o" . dired-omit-mode)
+;; ("a" . some-custom-dired-function))
+;;
+;; To set up a prefix map, use :prefix-map and :prefix
+;; arguments (both are required)
+;;
+;; (bind-keys :prefix-map my-customize-prefix-map
+;; :prefix "C-c c"
+;; ("f" . customize-face)
+;; ("v" . customize-variable))
+;;
+;; You can combine all the keywords together.
+;; Additionally, :prefix-docstring can be specified to set
+;; documentation of created :prefix-map variable.
+;;
+;; To bind multiple keys in a `bind-key*' way (to be sure that your bindings
+;; will not be overridden by other modes), you may use `bind-keys*' macro:
+;;
+;; (bind-keys*
+;; ("C-o" . other-window)
+;; ("C-M-n" . forward-page)
+;; ("C-M-p" . backward-page))
+;;
;; After Emacs loads, you can see a summary of all your personal keybindings
;; currently in effect with this command:
;;
"A simple way to manage personal keybindings"
:group 'emacs)
+(defcustom bind-key-column-widths '(18 . 40)
+ "Width of columns in `describe-personal-keybindings'."
+ :type '(cons integer integer)
+ :group 'bind-key)
+
(defcustom bind-key-segregation-regexp
"\\`\\(\\(C-[chx] \\|M-[gso] \\)\\([CM]-\\)?\\|.+-\\)"
"Regular expression used to divide key sets in the output from
:type 'regexp
:group 'bind-key)
+(defcustom bind-key-describe-special-forms nil
+ "If non-nil, extract docstrings from lambdas, closures and keymaps if possible."
+ :type 'boolean
+ :group 'bind-key)
+
;; Create override-global-mode to force key remappings
(defvar override-global-map (make-keymap)
(add-to-list 'emulation-mode-map-alists
`((override-global-mode . ,override-global-map)))
-(add-hook 'after-init-hook
- (function
- (lambda ()
- (override-global-mode 1))))
+(defvar personal-keybindings nil
+ "List of bindings performed by `bind-key'.
-(defvar personal-keybindings nil)
+Elements have the form ((KEY . [MAP]) CMD ORIGINAL-CMD)")
(defmacro bind-key (key-name command &optional keymap)
+ "Bind KEY-NAME to COMMAND in KEYMAP (`global-map' if not passed).
+
+KEY-NAME may be a vector, in which case it is passed straight to
+`define-key'. Or it may be a string to be interpreted as
+spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of
+`edmacro-mode' for details."
(let ((namevar (make-symbol "name"))
(keyvar (make-symbol "key"))
+ (kdescvar (make-symbol "kdesc"))
(bindingvar (make-symbol "binding"))
(entryvar (make-symbol "entry")))
- `(let* ((,namevar ,(eval key-name))
- (,keyvar (read-kbd-macro ,namevar))
+ `(let* ((,namevar ,key-name)
+ (,keyvar (if (vectorp ,namevar) ,namevar
+ (read-kbd-macro ,namevar)))
+ (,kdescvar (cons (if (stringp ,namevar) ,namevar
+ (key-description ,namevar))
+ (quote ,keymap)))
(,bindingvar (lookup-key (or ,keymap global-map)
- ,keyvar)))
- (let ((,entryvar (assoc (cons ,namevar (quote ,keymap))
- personal-keybindings)))
- (if ,entryvar
- (setq personal-keybindings
- (delq ,entryvar personal-keybindings))))
- (setq personal-keybindings
- (cons (list (cons ,namevar (quote ,keymap))
- ,command
- (unless (numberp ,bindingvar) ,bindingvar))
- personal-keybindings))
+ ,keyvar))
+ (,entryvar (assoc ,kdescvar personal-keybindings)))
+ (when ,entryvar
+ (setq personal-keybindings
+ (delq ,entryvar personal-keybindings)))
+ (push (list ,kdescvar ,command
+ (unless (numberp ,bindingvar) ,bindingvar))
+ personal-keybindings)
(define-key (or ,keymap global-map) ,keyvar ,command))))
(defmacro unbind-key (key-name &optional keymap)
(bind-key ,key-name ,command)
(define-key override-global-map ,(read-kbd-macro key-name) ,command)))
+(defmacro bind-keys (&rest args)
+ "Bind multiple keys at once.
+
+Accepts keyword arguments:
+:map - a keymap into which the keybindings should be added
+:prefix-map - name of the prefix map that should be created for
+ these bindings
+:prefix - prefix key for these bindings
+:prefix-docstring - docstring for the prefix-map variable
+:menu-name - optional menu string for prefix map
+
+The rest of the arguments are conses of keybinding string and a
+function symbol (unquoted)."
+ (let ((map (plist-get args :map))
+ (doc (plist-get args :prefix-docstring))
+ (prefix-map (plist-get args :prefix-map))
+ (prefix (plist-get args :prefix))
+ (menu-name (plist-get args :menu-name))
+ (key-bindings (progn
+ (while (keywordp (car args))
+ (pop args)
+ (pop args))
+ args)))
+ (when (or (and prefix-map
+ (not prefix))
+ (and prefix
+ (not prefix-map)))
+ (error "Both :prefix-map and :prefix must be supplied"))
+ (when (and menu-name (not prefix))
+ (error "If :menu-name is supplied, :prefix must be too"))
+ `(progn
+ ,@(when prefix-map
+ `((defvar ,prefix-map)
+ ,@(when doc `((put ',prefix-map 'variable-documentation ,doc)))
+ ,@(if menu-name
+ `((define-prefix-command ',prefix-map nil ,menu-name))
+ `((define-prefix-command ',prefix-map)))
+ (bind-key ,prefix ',prefix-map ,map)))
+ ,@(mapcar (lambda (form)
+ `(bind-key ,(car form) ',(cdr form)
+ ,(or prefix-map map)))
+ key-bindings))))
+
+(defmacro bind-keys* (&rest args)
+ `(bind-keys :map override-global-map
+ ,@args))
+
(defun get-binding-description (elem)
(cond
((listp elem)
(cond
((eq 'lambda (car elem))
- "#<lambda>")
+ (if (and bind-key-describe-special-forms
+ (stringp (nth 2 elem)))
+ (nth 2 elem)
+ "#<lambda>"))
((eq 'closure (car elem))
- "#<closure>")
+ (if (and bind-key-describe-special-forms
+ (stringp (nth 3 elem)))
+ (nth 3 elem)
+ "#<closure>"))
((eq 'keymap (car elem))
"#<keymap>")
(t
elem)))
((keymapp elem)
- "#<keymap>")
+ (if (and bind-key-describe-special-forms
+ (symbolp elem)
+ (get elem 'variable-documentation))
+ (format "%s" (get elem 'variable-documentation))
+ "#<keymap>"))
((symbolp elem)
elem)
(t
(cons (string< (caar l) (caar r)) nil)))))
(defun describe-personal-keybindings ()
+ "Display all the personal keybindings defined by `bind-key'."
(interactive)
- (with-current-buffer (get-buffer-create "*Personal Keybindings*")
- (delete-region (point-min) (point-max))
- (insert "Key name Command Comments
------------------ --------------------------------------- ---------------------
-")
+ (with-output-to-temp-buffer "*Personal Keybindings*"
+ (princ (format "Key name%s Command%s Comments\n%s %s ---------------------\n"
+ (make-string (- (car bind-key-column-widths) 9) ? )
+ (make-string (- (cdr bind-key-column-widths) 8) ? )
+ (make-string (1- (car bind-key-column-widths)) ?-)
+ (make-string (1- (cdr bind-key-column-widths)) ?-)))
(let (last-binding)
(dolist (binding
(setq personal-keybindings
(sort personal-keybindings
- #'(lambda (l r)
- (car (compare-keybindings l r))))))
-
+ (lambda (l r)
+ (car (compare-keybindings l r))))))
+
(if (not (eq (cdar last-binding) (cdar binding)))
- (insert ?\n (format "\n%s\n%s\n\n"
- (cdar binding)
- (make-string 79 ?-)))
+ (princ (format "\n\n%s\n%s\n\n"
+ (cdar binding)
+ (make-string (+ 21 (car bind-key-column-widths) (cdr bind-key-column-widths)) ?-)))
(if (and last-binding
(cdr (compare-keybindings last-binding binding)))
- (insert ?\n)))
-
+ (princ "\n")))
+
(let* ((key-name (caar binding))
(at-present (lookup-key (or (symbol-value (cdar binding))
(current-global-map))
(get-binding-description was-command)))
(at-present-desc (get-binding-description at-present))
)
- (insert
- (format
- "%-18s%-40s%s\n"
- key-name command-desc
- (if (string= command-desc at-present-desc)
- (if (or (null was-command)
- (string= command-desc was-command-desc))
- ""
- (format "(%s)" was-command-desc))
- (format "[now: %s]" at-present)))))
-
- (setq last-binding binding)))
-
- (goto-char (point-min))
- (display-buffer (current-buffer))))
+ (let ((line
+ (format
+ (format "%%-%ds%%-%ds%%s\n" (car bind-key-column-widths) (cdr bind-key-column-widths))
+ key-name (format "`%s\'" command-desc)
+ (if (string= command-desc at-present-desc)
+ (if (or (null was-command)
+ (string= command-desc was-command-desc))
+ ""
+ (format "was `%s\'" was-command-desc))
+ (format "[now: `%s\']" at-present)))))
+ (princ (if (string-match "[ \t]+\n" line)
+ (replace-match "\n" t t line)
+ line))))
+
+ (setq last-binding binding)))))
(provide 'bind-key)
;; Local Variables:
-;;; use-package --- A use-package declaration for simplifying your .emacs
+;;; use-package.el --- A use-package declaration for simplifying your .emacs
;; Copyright (C) 2012 John Wiegley
;; utility my total load time is just under 1 second, with no loss of
;; functionality!
;;
-;; Here is the simplest `use-package' declaration:
-;;
-;; (use-package foo)
-;;
-;; This loads in the package foo, but only if foo is available on your system.
-;; If not, a warning is logged to your `*Messages*' buffer. If it succeeds a
-;; message about "Loading foo" is logged, along with the time it took to load,
-;; if that time is over 0.01s.
-;;
-;; Use the :init keywoard to do some stuff to initialize foo, but only if foo
-;; actually gets loaded:
-;;
-;; (use-package foo
-;; :init
-;; (progn
-;; (setq foo-variable t)
-;; (foo-mode 1)))
-;;
-;; A very common thing to do when loading a module is to bind a key to primary
-;; commands within that module:
-;;
-;; (use-package ace-jump-mode
-;; :bind ("C-." . ace-jump-mode))
-;;
-;; This does two things: first, it creates autoload for the `ace-jump-mode'
-;; command, and defers loading of `ace-jump-mode' until you actually use it.
-;; Second, it binds the key `C-.' to that command. After loading, you can use
-;; `M-x describe-personal-keybindings' to see all such bindings you've set
-;; throughout your Emacs.
-;;
-;; A more literal way to do the exact same thing is:
-;;
-;; (use-package ace-jump-mode
-;; :commands ace-jump-mode
-;; :init
-;; (bind-key "C-." 'ace-jump-mode))
-;;
-;; When you use the `:commands' keyword, it creates autoloads for those
-;; commands and defers loading of the module until they are used. In this
-;; case, the `:init' form is always run -- even if ace-jump-mode might not be
-;; on your system. So remember to keep `:init' activities to only those that
-;; would succeed either way.
-;;
-;; Similar to `:bind', you can use `:mode' and `:interpreter' to establish a
-;; deferred binding within `auto-mode-alist' and `interpreter-mode-alist'.
-;; The specifier to either keyword can be a single cons or a list:
-;;
-;; (use-package python-mode
-;; :mode ("\\.py$" . python-mode)
-;; :interpreter ("python" . python-mode))
-;;
-;; If you aren't using `:commands', `:bind', `:mode', or `:interpreter' (all
-;; of which imply `:commands'), you can still defer loading with the `:defer'
-;; keyword:
-;;
-;; (use-package ace-jump-mode
-;; :defer t
-;; :init
-;; (progn
-;; (autoload 'ace-jump-mode "ace-jump-mode" nil t)
-;; (bind-key "C-." 'ace-jump-mode)))
-;;
-;; This does exactly the same thing as the other two commands above.
-;;
-;; A companion to the `:init' keyword is `:config'. Although `:init' always
-;; happens in the case of deferred modules (which are likely to be the most
-;; common kind), `:config' form only run after the module has been loaded by
-;; Emacs:
-;;
-;; (use-package ace-jump-mode
-;; :bind ("C-." . ace-jump-mode)
-;; :config
-;; (message "Yay, ace-jump-mode was actually loaded!"))
-;;
-;; You will see a "Configured..." message in your `*Messages*' log when a
-;; package is configured, and a timing if the configuration time was longer
-;; than 0.01s. You should keep `:init' forms as simple as possible, and put
-;; as much as you can get away with on the `:config' side.
-;;
-;; You can have both `:init' and `:config':
-;;
-;; (use-package haskell-mode
-;; :commands haskell-mode
-;; :init
-;; (add-to-list 'auto-mode-alist '("\\.l?hs$" . haskell-mode))
-;; :config
-;; (progn
-;; (use-package inf-haskell)
-;; (use-package hs-lint)))
-;;
-;; In this case, I want to autoload the command `haskell-mode' from
-;; "haskell-mode.el", add it to `auto-mode-alist' at the time ".emacs" is
-;; loaded, but wait until after I've opened a Haskell file before loading
-;; "inf-haskell.el" and "hs-lint.el".
-;;
-;; Another similar option to `:init' is `:idle'. Like `:init' this always run,
-;; however, it does so when Emacs is idle at some time in the future after
-;; load. This is particularly useful for convienience minor modes which can be
-;; slow to load. For instance, in this case, I want Emacs to always use
-;; `global-pabbrev-mode'. `:commands' creates an appropriate autoload; `:idle'
-;; will run this command at some point in the future. If you start Emacs and
-;; beginning typing straight-away, loading will happen eventually.
-;;
-;; (use-package pabbrev
-;; :commands global-pabbrev-mode
-;; :idle (global-pabbrev-mode))
-;;
-;; Idle functions are run in the order in which they are evaluated. If you
-;; have many, it may take sometime for all to run. `use-package' will always
-;; tell you if there is an error in the form which can otherwise be difficult
-;; to debug. It may tell you about functions being eval'd, depending on the
-;; value of `use-package-verbose'. Other good candidates for `:idle' are
-;; `yasnippet', `auto-complete' and `autopair'.
-;;
-;; The `:bind' keyword takes either a cons or a list of conses:
-;;
-;; (use-package hi-lock
-;; :bind (("M-o l" . highlight-lines-matching-regexp)
-;; ("M-o r" . highlight-regexp)
-;; ("M-o w" . highlight-phrase)))
-;;
-;; The `:commands' keyword likewise takes either a symbol or a list of
-;; symbols.
-;;
-;; You can use the `:if' keyword to predicate the loading and initialization
-;; of a module. For example, I only want an `edit-server' running for my
-;; main, graphical Emacs, not for Emacsen I may start at the command line:
-;;
-;; (use-package edit-server
-;; :if window-system
-;; :init
-;; (progn
-;; (add-hook 'after-init-hook 'server-start t)
-;; (add-hook 'after-init-hook 'edit-server-start t)))
-;;
-;; The `:disabled' keyword can be used to turn off a module that you're having
-;; difficulties with, or to stop loading something you're not really using at
-;; the present time:
-;;
-;; (use-package ess-site
-;; :disabled t
-;; :commands R)
-;;
-;; Another feature of `use-package' is that it always loads every file that it
-;; can when your ".emacs" is being byte-compiled (if you do that, which I
-;; recommend). This helps to silence spurious warnings about unknown
-;; variables and functions.
-;;
-;; However, there are times when this is just not enough. For those times,
-;; use the `:defines' keyword to introduce empty variable definitions solely
-;; for the sake of the byte-compiler:
-;;
-;; (use-package texinfo
-;; :defines texinfo-section-list
-;; :commands texinfo-mode
-;; :init
-;; (add-to-list 'auto-mode-alist '("\\.texi$" . texinfo-mode)))
-;;
-;; If you need to silence a missing function warning, do it with an autoload
-;; stub in your `:init' block:
-;;
-;; (use-package w3m
-;; :commands (w3m-browse-url w3m-session-crash-recovery-remove)
-;; :init
-;; (eval-when-compile
-;; (autoload 'w3m-search-escape-query-string "w3m-search")))
-;;
-;; If your package needs a directory added to the `load-path' in order load,
-;; use `:load-path'. It takes a string or a list of strings. If the path is
-;; relative, it will be expanded within `user-emacs-directory':
-;;
-;; (use-package ess-site
-;; :disabled t
-;; :load-path "site-lisp/ess/lisp/"
-;; :commands R)
-;;
-;; Lastly, `use-package' provides built-in support for the diminish utility,
-;; if you have that installed. It's purpose is to remove strings from your
-;; mode-line that would otherwise always be there and provide no useful
-;; information. It is invoked with the `:diminish' keyword, which is passed
-;; either the minor mode symbol, a cons of the symbol and a replacement string,
-;; or just a replacement string in which case the minor mode symbol is guessed
-;; to be the package name with "-mode" at the end:
-;;
-;; (use-package abbrev
-;; :diminish abbrev-mode
-;; :init
-;; (if (file-exists-p abbrev-file-name)
-;; (quietly-read-abbrev-file))
-;;
-;; :config
-;; (add-hook 'expand-load-hook
-;; (lambda ()
-;; (add-hook 'expand-expand-hook 'indent-according-to-mode)
-;; (add-hook 'expand-jump-hook 'indent-according-to-mode))))
-;;
-;; If you noticed that this declaration has neither a `:bind', `:commands' or
-;; `:defer' keyword: congratulations, you're an A student! What it means is
-;; that both the `:init' and `:config' forms will be executed when ".emacs" is
-;; loaded, with no delays until later. Is this useful? Not really. I just
-;; happen to like separating my configuration into things that must happen at
-;; startup time, and things that could potentioally wait until after the
-;; actual load. In this case, everything could be put inside `:init' and
-;; there would be no difference.
-;;
-;; * For el-get users
-;;
-;; You can use `use-package' as a way to create source definitions for el-get.
-;; All that's needed is to add a `:type' keyword to your declaration. When
-;; this is present, certain keywords get translated to what el-get expects in
-;; the `el-get-sources' list:
-;;
-;; :config -> :after
-;; :requires -> :depends
-;;
-;; A `:name' will be added also, if one is not provided explicitly, which will
-;; be the same as the name of the package.
-;;
-;; But why would you want to use `use-package' when you have el-get? My
-;; answer is that I'd like to use el-get to install and update some packages,
-;; but I don't want it managing configuration. Just loading el-get -- without
-;; call (el-get 'sync) -- takes a quarter second on my machine. That's 25% of
-;; my load time! `use-package' is designed for performance, so I only want to
-;; load el-get when it's time to install or update on of my used packages.
-;;
-;; Here is the `use-package' declaration I use for setting up el-get, but only
-;; when I want to install or update:
-;;
-;; (defvar el-get-sources nil)
-;;
-;; (use-package el-get
-;; :commands (el-get
-;; el-get-install
-;; el-get-update
-;; el-get-list-packages)
-;; :config
-;; (defun el-get-read-status-file ()
-;; (mapcar #'(lambda (entry)
-;; (cons (plist-get entry :symbol)
-;; `(status "installed" recipe ,entry)))
-;; el-get-sources)))
+;; Please see README.md from the same repository for documentation.
\f
;;; Code:
(require 'bytecomp)
(require 'diminish nil t)
-(eval-when-compile
- (require 'cl))
-
(declare-function package-installed-p 'package)
-(declare-function el-get-read-recipe 'el-get)
(defgroup use-package nil
"A use-package declaration for simplifying your `.emacs'."
:group 'startup)
-(defcustom use-package-verbose t
- "Whether to report about loading and configuration details."
- :type 'boolean
- :group 'use-package)
+(defcustom use-package-verbose nil
+ "Whether to report about loading and configuration details.
-(defcustom use-package-debug nil
- "Whether to report more information, mostly regarding el-get."
+If you customize this, then you should require the `use-package'
+feature in files that use one of the macros `use-package' or
+`use-package-with-elapsed-timer', even if these files only
+contain compiled expansions of the macros. If you don't do so,
+then the expanded macros do their job silently."
:type 'boolean
:group 'use-package)
(defcustom use-package-minimum-reported-time 0.01
- "Minimal load time that will be reported"
+ "Minimal load time that will be reported.
+
+Note that `use-package-verbose' has to be set to t, for anything
+to be reported at all.
+
+If you customize this, then you should require the `use-package'
+feature in files that use one of the macros `use-package' or
+`use-package-with-elapsed-timer', even if these files only
+contain compiled expansions of the macros. If you don't do so,
+then the expanded macros do their job silently."
+ :type 'number
+ :group 'use-package)
+
+(defcustom use-package-idle-interval 3
+ "Time to wait when using :idle in a `use-package' specification."
:type 'number
:group 'use-package)
-(defmacro with-elapsed-timer (text &rest forms)
- `(let ((now ,(if use-package-verbose
- '(current-time))))
- ,(if use-package-verbose
- `(message "%s..." ,text))
- (prog1
- ,@forms
- ,(when use-package-verbose
- `(let ((elapsed
- (float-time (time-subtract (current-time) now))))
- (if (> elapsed ,use-package-minimum-reported-time)
- (message "%s...done (%.3fs)" ,text elapsed)
- (message "%s...done" ,text)))))))
-
-(put 'with-elapsed-timer 'lisp-indent-function 1)
-
-(defun use-package-discover-el-get-type (args)
- (let* ((pkg-name (plist-get args :name))
- (git-config (expand-file-name
- (concat pkg-name "/.git/config")
- (if (boundp 'user-site-lisp-directory)
- user-site-lisp-directory
- user-emacs-directory))))
-
- (catch 'found
- ;; Look for a readable .git/config with at least one defined remote.
- (if (file-readable-p git-config)
- (with-temp-buffer
- (insert-file-contents-literally git-config)
- (while (re-search-forward "\\[remote" nil t)
- (if (re-search-forward "url = \\(.+\\)"
- (save-excursion
- (re-search-forward "\\[remote" nil t)
- (point)) t)
- (nconc args (list :type 'git
- :url (match-string 1))))))))
- args))
+(defmacro use-package-with-elapsed-timer (text &rest body)
+ (declare (indent 1))
+ (let ((nowvar (make-symbol "now")))
+ `(if (bound-and-true-p use-package-verbose)
+ (let ((,nowvar (current-time)))
+ (message "%s..." ,text)
+ (prog1 (progn ,@body)
+ (let ((elapsed
+ (float-time (time-subtract (current-time) ,nowvar))))
+ (if (> elapsed
+ (or (bound-and-true-p use-package-minimum-reported-time)
+ "0.01"))
+ (message "%s...done (%.3fs)" ,text elapsed)
+ (message "%s...done" ,text)))))
+ ,@body)))
+
+(put 'use-package-with-elapsed-timer 'lisp-indent-function 1)
(defvar use-package-idle-timer nil)
-(defvar use-package-idle-forms nil)
+(defvar use-package-idle-forms (make-hash-table))
(defun use-package-start-idle-timer ()
"Ensure that the idle timer is running."
(unless use-package-idle-timer
(setq use-package-idle-timer
(run-with-idle-timer
- 3 t
+ use-package-idle-interval t
'use-package-idle-eval))))
-(defun use-package-init-on-idle (form)
+(defun use-package-init-on-idle (form priority)
"Add a new form to the idle queue."
(use-package-start-idle-timer)
- (if use-package-idle-forms
- (add-to-list 'use-package-idle-forms
- form t)
- (setq use-package-idle-forms (list form))))
+ (puthash priority
+ (append (gethash priority use-package-idle-forms)
+ (list form))
+ use-package-idle-forms))
+
+(defun use-package-idle-priorities ()
+ "Get a list of all priorities in the idle queue.
+The list is sorted in the order forms should be run."
+ (let ((priorities nil))
+ (maphash (lambda (priority forms)
+ (setq priorities (cons priority priorities)))
+ use-package-idle-forms)
+ (sort priorities '<)))
+
+(defun use-package-idle-pop ()
+ "Pop the top-priority task from the idle queue.
+Return nil when the queue is empty."
+ (let* ((priority (car (use-package-idle-priorities)))
+ (forms (gethash priority use-package-idle-forms))
+ (first-form (car forms))
+ (forms-remaining (cdr forms)))
+ (if forms-remaining
+ (puthash priority forms-remaining use-package-idle-forms)
+ (remhash priority use-package-idle-forms))
+ first-form))
(defun use-package-idle-eval()
"Start to eval idle-commands from the idle queue."
- (let ((next (pop use-package-idle-forms)))
+ (let ((next (use-package-idle-pop)))
(if next
(progn
(when use-package-verbose
"Failure on use-package idle. Form: %s, Error: %s"
next e)))
;; recurse after a bit
- (when (sit-for 3)
+ (when (sit-for use-package-idle-interval)
(use-package-idle-eval)))
;; finished (so far!)
(cancel-timer use-package-idle-timer)
(setq use-package-idle-timer nil))))
+(defun use-package-pin-package (package archive)
+ "Pin PACKAGE to ARCHIVE."
+ (unless (boundp 'package-pinned-packages)
+ (setq package-pinned-packages ()))
+ (let ((archive-symbol (if (symbolp archive) archive (intern archive)))
+ (archive-name (if (stringp archive) archive (symbol-name archive))))
+ (if (use-package--archive-exists-p archive-symbol)
+ (add-to-list 'package-pinned-packages (cons package archive-name))
+ (error (message "Archive '%s' requested for package '%s' is not available." archive-name package)))
+ (package-initialize t)))
+
+(defun use-package--archive-exists-p (archive)
+ "Check if a given ARCHIVE is enabled.
+
+ARCHIVE can be a string or a symbol or 'manual to indicate a manually updated package."
+ (if (member archive '(manual "manual"))
+ 't
+ (let ((valid nil))
+ (dolist (pa package-archives)
+ (when (member archive (list (car pa) (intern (car pa))))
+ (setq valid 't)))
+ valid)))
+
(defun use-package-ensure-elpa (package)
(when (not (package-installed-p package))
(package-install package)))
+(defvar use-package-keywords
+ '(
+ :bind
+ :bind*
+ :commands
+ :config
+ :defer
+ :defines
+ :demand
+ :diminish
+ :disabled
+ :ensure
+ :idle
+ :idle-priority
+ :if
+ :init
+ :interpreter
+ :load-path
+ :mode
+ :pin
+ :pre-init
+ :pre-load
+ :requires
+ :bind-keymap
+ :bind-keymap*
+ )
+ "Keywords recognized by `use-package'.")
+
+(defun use-package-mplist-get (plist prop)
+ "Get the values associated to PROP in PLIST, a modified plist.
+
+A modified plist is one where keys are keywords and values are
+all non-keywords elements that follow it.
+
+As a special case : if the first occurrence of the keyword PROP
+is followed by another keyword or is the last element in the
+list, the function returns t.
+
+Currently this function infloops when the list is circular."
+ (let ((tail plist)
+ found
+ result)
+ (while (and
+ (consp tail)
+ (not
+ (eq prop (car tail))))
+ (pop tail))
+ (when (eq prop (pop tail))
+ (setq found t))
+ (while (and (consp tail)
+ (not (keywordp (car tail))))
+ (push (pop tail) result))
+ (or (nreverse result) found)))
+
+(defun use-package-plist-get (plist prop &optional eval-backquote no-progn)
+ "Compatibility layer between classical and modified plists.
+
+If `use-package-mplist-get' returns exactly one value, that is
+returned ; otherwise the list is returned wrapped in a `progn'
+unless NO-PROGN is non-nil.
+
+When EVAL-BACKQUOTE is non-nil, the value is first evaluated as
+if it were backquoted."
+ (let ((values (use-package-mplist-get plist prop)))
+ (when eval-backquote
+ (setq values (eval (list 'backquote values))))
+ (when values
+ (cond ((not (listp values))
+ values)
+ ((eq 1 (length values))
+ (car values))
+ (t (if no-progn
+ values
+ (cons 'progn values)))))))
+
+(defun use-package-mplist-keys (plist)
+ "Get the keys in PLIST, a modified plist.
+
+A modified plist is one where properties are keywords and values
+are all non-keywords elements that follow it."
+ (let ((result))
+ (mapc (lambda (elt)
+ (when (keywordp elt)
+ (push elt result)))
+ plist)
+ (nreverse result)))
+
+(defun use-package-validate-keywords (args)
+ "Error if any keyword given in ARGS is not recognized.
+Return the list of recognized keywords."
+ (mapc
+ (function
+ (lambda (keyword)
+ (unless (memq keyword use-package-keywords)
+ (error "Unrecognized keyword: %s" keyword))))
+ (use-package-mplist-keys args)))
(defmacro use-package (name &rest args)
-"Use a package with configuration options.
+ "Use a package with configuration options.
For full documentation. please see commentary.
:init Code to run when `use-package' form evals.
:bind Perform key bindings, and define autoload for bound
commands.
+:bind* Perform key bindings, and define autoload for bound
+ commands, overriding all minor mode bindings.
+:bind-keymap Bind key prefix to an auto-loaded keymap that
+ is defined in the package. Like bind but for keymaps
+ instead of commands.
+:bind-keymap* like bind-keymap, but overrides all minor mode bindings
:commands Define autoloads for given commands.
+:pre-load Code to run when `use-package' form evals and before
+ anything else. Unlike :init this form runs before the
+ package is required or autoloads added.
:mode Form to be added to `auto-mode-alist'.
:interpreter Form to be added to `interpreter-mode-alist'.
:defer Defer loading of package -- automatic
- if :commands, :bind, :mode or :interpreter are used.
+ if :commands, :bind, :bind*, :mode or :interpreter are used.
+:demand Prevent deferred loading in all cases.
:config Runs if and when package loads.
:if Conditional loading.
:disabled Ignore everything.
:defines Define vars to silence byte-compiler.
:load-path Add to `load-path' before loading.
:diminish Support for diminish package (if it's installed).
-:idle adds a form to run on an idle timer"
- (let* ((commands (plist-get args :commands))
- (pre-init-body (plist-get args :pre-init))
- (init-body (plist-get args :init))
- (config-body (plist-get args :config))
- (diminish-var (plist-get args :diminish))
- (defines (plist-get args :defines))
- (idle-body (plist-get args :idle))
- (keybindings )
- (mode-alist )
- (interpreter-alist )
- (predicate (plist-get args :if))
- (pkg-load-path (plist-get args :load-path))
+:idle adds a form to run on an idle timer
+:idle-priority schedules the :idle form to run with the given
+ priority (lower priorities run first). Default priority
+ is 5; forms with the same priority are run in the order in
+ which they are evaluated.
+:ensure loads package using package.el if necessary.
+:pin pin package to archive."
+ (use-package-validate-keywords args) ; error if any bad keyword, ignore result
+ (let* ((commands (use-package-plist-get args :commands t t))
+ (pre-init-body (use-package-plist-get args :pre-init))
+ (pre-load-body (use-package-plist-get args :pre-load))
+ (init-body (use-package-plist-get args :init))
+ (config-body (use-package-plist-get args :config))
+ (diminish-var (use-package-plist-get args :diminish t))
+ (defines (use-package-plist-get args :defines t t))
+ (idle-body (use-package-plist-get args :idle))
+ (idle-priority (use-package-plist-get args :idle-priority))
+ (keybindings-alist (use-package-plist-get args :bind t t))
+ (overriding-keybindings-alist (use-package-plist-get args :bind* t t))
+ (keymap-alist (use-package-plist-get args :bind-keymap t t))
+ (overriding-keymap-alist (use-package-plist-get args :bind-keymap* t t))
+ (mode (use-package-plist-get args :mode t t))
+ (mode-alist
+ (if (stringp mode) (cons mode name) mode))
+ (interpreter (use-package-plist-get args :interpreter t t))
+ (interpreter-alist
+ (if (stringp interpreter) (cons interpreter name) interpreter))
+ (predicate (use-package-plist-get args :if))
+ (pkg-load-path (use-package-plist-get args :load-path t t))
+ (archive-name (use-package-plist-get args :pin))
(defines-eval (if (null defines)
nil
(if (listp defines)
(mapcar (lambda (var) `(defvar ,var)) defines)
`((defvar ,defines)))))
- (requires (plist-get args :requires))
+ (requires (use-package-plist-get args :requires t))
(requires-test (if (null requires)
t
(if (listp requires)
(name-symbol (if (stringp name) (intern name) name)))
;; force this immediately -- one off cost
- (unless (plist-get args :disabled)
- (let* ((ensure (plist-get args :ensure))
+ (unless (use-package-plist-get args :disabled)
+
+ (when archive-name
+ (use-package-pin-package name archive-name))
+
+ (let* ((ensure (use-package-plist-get args :ensure))
(package-name
(or (and (eq ensure t)
name)
`((diminish (quote ,diminish-var))))
((and (consp diminish-var) (stringp (cdr diminish-var)))
`((diminish (quote ,(car diminish-var)) ,(cdr diminish-var))))
- (t ; list of symbols or (symbol . "string") pairs
+ (t ; list of symbols or (symbol . "string") pairs
(mapcar (lambda (var)
(if (listp var)
`(diminish (quote ,(car var)) ,(cdr var))
(when idle-body
+ (when (null idle-priority)
+ (setq idle-priority 5))
(setq init-body
`(progn
- (use-package-init-on-idle (lambda () ,idle-body))
- ,init-body)))
-
+ (require 'use-package)
+ (use-package-init-on-idle (lambda () ,idle-body) ,idle-priority)
+ ,init-body)))
- (let ((init-for-commands
- (lambda (func sym-or-list)
+ (let ((init-for-commands-or-keymaps
+ (lambda (func sym-or-list &optional keymap)
(let ((cons-list (if (and (consp sym-or-list)
(stringp (car sym-or-list)))
(list sym-or-list)
(setq init-body
`(progn
,init-body
- ,@(mapcar #'(lambda (elem)
- (push (cdr elem) commands)
- (funcall func elem))
+ ,@(mapcar (lambda (elem)
+ (when (not keymap)
+ (push (cdr elem) commands))
+ (funcall func elem))
cons-list))))))))
- (funcall init-for-commands
- #'(lambda (binding)
- `(bind-key ,(car binding)
- (quote ,(cdr binding))))
- (plist-get args :bind))
-
- (funcall init-for-commands
- #'(lambda (mode)
- `(add-to-list 'auto-mode-alist
- (quote ,mode)))
- (plist-get args :mode))
-
- (funcall init-for-commands
- #'(lambda (interpreter)
- `(add-to-list 'interpreter-mode-alist
- (quote ,interpreter)))
- (plist-get args :interpreter)))
+ (funcall init-for-commands-or-keymaps
+ (lambda (binding)
+ `(bind-key ,(car binding)
+ (lambda () (interactive)
+ (use-package-autoload-keymap
+ (quote ,(cdr binding))
+ ,(if (stringp name) name `',name)
+ nil))))
+ keymap-alist
+ t)
+
+ (funcall init-for-commands-or-keymaps
+ (lambda (binding)
+ `(bind-key ,(car binding)
+ (lambda () (interactive)
+ (use-package-autoload-keymap
+ (quote ,(cdr binding))
+ ,(if (stringp name) name `',name)
+ t))))
+ overriding-keymap-alist
+ t)
+
+ (funcall init-for-commands-or-keymaps
+ (lambda (binding)
+ `(bind-key ,(car binding)
+ (quote ,(cdr binding))))
+ keybindings-alist)
+
+ (funcall init-for-commands-or-keymaps
+ (lambda (binding)
+ `(bind-key* ,(car binding)
+ (quote ,(cdr binding))))
+ overriding-keybindings-alist)
+
+ (funcall init-for-commands-or-keymaps
+ (lambda (mode)
+ `(add-to-list 'auto-mode-alist
+ (quote ,mode)))
+ mode-alist)
+
+ (funcall init-for-commands-or-keymaps
+ (lambda (interpreter)
+ `(add-to-list 'interpreter-mode-alist
+ (quote ,interpreter)))
+ interpreter-alist))
`(progn
+ ,pre-load-body
,@(mapcar
- #'(lambda (path)
- `(add-to-list 'load-path
- ,(if (file-name-absolute-p path)
- path
- (expand-file-name path user-emacs-directory))))
+ (lambda (path)
+ `(add-to-list 'load-path
+ ,(if (file-name-absolute-p path)
+ path
+ (expand-file-name path user-emacs-directory))))
(cond ((stringp pkg-load-path)
(list pkg-load-path))
((functionp pkg-load-path)
(t
pkg-load-path)))
- (when byte-compile-current-file
- ,@defines-eval
- ,(if (stringp name)
- `(load ,name t)
- `(require ',name nil t)))
-
- ,(when (boundp 'el-get-sources)
- (require 'el-get)
-
- (let ((recipe (ignore-errors
- (el-get-read-recipe name-symbol))))
- (if (null recipe)
- (if use-package-debug
- (message "No el-get recipe found for package `%s'"
- name-symbol))
- (setq args
- (mapcar #'(lambda (arg)
- (cond
- ((eq arg :config)
- :after)
- ((eq arg :requires)
- :depends)
- (t
- arg)))
- args))
-
- (nconc args (list :symbol (intern name-string)))
-
- (let ((elem args))
- (while elem
- (unless (plist-get recipe (car elem))
- (plist-put recipe (car elem) (cadr elem)))
- (setq elem (cddr elem))))
-
- (unless (plist-get recipe :name)
- (nconc recipe (list :name name-string)))
-
- (unless (plist-get recipe :type)
- (setq recipe (use-package-discover-el-get-type recipe)))
-
- (ignore
- (setq el-get-sources (cons recipe el-get-sources))))))
-
- ,(if (or commands (plist-get args :defer))
+ (eval-when-compile
+ (when (bound-and-true-p byte-compile-current-file)
+ ,@defines-eval
+ (condition-case err
+ ,(if (stringp name)
+ `(load ,name t)
+ `(require ',name nil t))
+ (error (message "Error requiring %s: %s" ',name err) nil))))
+
+ ,(if (and (or commands (use-package-plist-get args :defer)
+ (use-package-plist-get args :bind-keymap)
+ (use-package-plist-get args :bind-keymap*))
+ (not (use-package-plist-get args :demand)))
(let (form)
- (mapc #'(lambda (command)
- (push `(autoload (function ,command)
- ,name-string nil t) form))
+ (mapc (lambda (command)
+ (push `(unless (fboundp (quote ,command))
+ (autoload (function ,command)
+ ,name-string nil t))
+ form))
commands)
`(when ,(or predicate t)
,@form
,init-body
,(unless (null config-body)
- `(eval-after-load ,name-string
- (quote
- (if ,requires-test
- ,(macroexpand-all
- `(with-elapsed-timer
- ,(format "Configuring package %s" name-string)
- ,config-body))))))
+ `(eval-after-load ,(if (stringp name) name `',name)
+ `(,(lambda ()
+ (if ,requires-test
+ (use-package-with-elapsed-timer
+ ,(format "Configuring package %s" name-string)
+ ,config-body))))))
t))
`(if (and ,(or predicate t)
,requires-test)
- (with-elapsed-timer
+ (use-package-with-elapsed-timer
,(format "Loading package %s" name-string)
(if (not ,(if (stringp name)
`(load ,name t)
,config-body
t))))))))
-(put 'use-package 'lisp-indent-function 1)
+(defun use-package-autoload-keymap (keymap-symbol package override)
+ "Loads PACKAGE and then binds the key sequence used to invoke this function to
+KEYMAP-SYMBOL. It then simulates pressing the same key sequence a again, so
+that the next key pressed is routed to the newly loaded keymap.
+
+This function supports use-package's :bind-keymap keyword. It works
+by binding the given key sequence to an invocation of this function for a
+particular keymap. The keymap is expected to be defined by the package. In
+this way, loading the package is deferred until the prefix key sequence is
+pressed."
+ (if (if (stringp package) (load package t) (require package nil t))
+ (if (and (boundp keymap-symbol) (keymapp (symbol-value keymap-symbol)))
+ (let ((key (key-description (this-command-keys-vector)))
+ (keymap (symbol-value keymap-symbol)))
+ (progn
+ (if override
+ `(eval `(bind-key* ,key ,keymap)) ; eval form is necessary to avoid compiler error
+ (bind-key key keymap))
+ (setq unread-command-events
+ (listify-key-sequence (this-command-keys-vector)))))
+ (error
+ "use-package: package %s failed to define keymap %s"
+ package keymap-symbol))
+ (error "Could not load package %s" package)))
+
+(put 'use-package 'lisp-indent-function 'defun)
(defconst use-package-font-lock-keywords
- '(("(\\(use-package\\)\\> *\\(\\sw+\\)?"
+ '(("(\\(use-package\\(?:-with-elapsed-timer\\)?\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?"
(1 font-lock-keyword-face)
- (2 font-lock-constant-face))))
+ (2 font-lock-constant-face nil t))))
(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords)