summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2015-05-24 17:47:34 +0900
committerSean Whitton <spwhitton@spwhitton.name>2015-05-24 17:47:34 +0900
commit14dd0ea9e47f31563f4b4deebb2596ddad9c5054 (patch)
treee2ad7239546e32b3e2027560a7ecca7a7c1e2e92
parent391ab142d1e7112d7a5e8c6c49efb98cc4b8d875 (diff)
downloaddotfiles-14dd0ea9e47f31563f4b4deebb2596ddad9c5054.tar.gz
upgrade to use-package.el version 2.0
-rw-r--r--.emacs.d/init-haskell.el42
-rw-r--r--.emacs.d/init.el745
-rw-r--r--.emacs.d/site-lisp/bind-key.el199
-rw-r--r--.emacs.d/site-lisp/use-package.el1359
4 files changed, 1513 insertions, 832 deletions
diff --git a/.emacs.d/init-haskell.el b/.emacs.d/init-haskell.el
index 1bc2bf91..abc2aa40 100644
--- a/.emacs.d/init-haskell.el
+++ b/.emacs.d/init-haskell.el
@@ -31,12 +31,15 @@
:mode (("\\.hs\\'" . haskell-mode)
("\\.cabal\\'" . haskell-cabal-mode)
("\\.hcr\\'" . haskell-core-mode))
+
+ :config
+
;; Start up all my usual minor modes and bindings.
- :init (progn
- (add-hook 'haskell-mode-hook 'spw/haskell-mode-hook)
- (add-hook 'after-save-hook 'spw/haskell-cabal-mode-save-hook))
- :config (setq haskell-tags-on-save t
- haskell-process-suggest-remove-import-lines t))
+ (add-hook 'haskell-mode-hook 'spw/haskell-mode-hook)
+ (add-hook 'after-save-hook 'spw/haskell-cabal-mode-save-hook)
+
+ (setq haskell-tags-on-save t
+ haskell-process-suggest-remove-import-lines t))
;; load haskell-flycheck only once haskell-mode is loaded
@@ -135,20 +138,21 @@
(use-package hi2
:ensure
:diminish hi2-mode
- :init (progn (setq hi2-layout-offset 4
- hi2-left-offset 4
- hi2-show-indentations nil)
-
- (defun spw/hi2-pipe ()
- "Newline, pipe char and indent"
- (interactive)
- (hi2-newline-and-indent)
- (insert "|")
- (indent-for-tab-command)
- (insert " "))
-
- (add-hook 'haskell-mode-hook 'turn-on-hi2)
- (bind-key "C-c |" 'spw/hi2-pipe hi2-mode-map)))
+ :config
+ (setq hi2-layout-offset 4
+ hi2-left-offset 4
+ hi2-show-indentations nil)
+
+ (defun spw/hi2-pipe ()
+ "Newline, pipe char and indent"
+ (interactive)
+ (hi2-newline-and-indent)
+ (insert "|")
+ (indent-for-tab-command)
+ (insert " "))
+
+ (add-hook 'haskell-mode-hook 'turn-on-hi2)
+ (bind-key "C-c |" 'spw/hi2-pipe hi2-mode-map))
(use-package shm
:disabled t
diff --git a/.emacs.d/init.el b/.emacs.d/init.el
index 058a1b43..c2a570f9 100644
--- a/.emacs.d/init.el
+++ b/.emacs.d/init.el
@@ -17,9 +17,7 @@
("melpa-stable" . "http://stable.melpa.org/packages/")
;; ("marmalade" . "http://marmalade-repo.org/packages/")
("org" . "http://orgmode.org/elpa/")
- ("gnu" . "http://elpa.gnu.org/packages/"))
- package-pinned-packages
- '((org-plus-contrib . "org")))
+ ("gnu" . "http://elpa.gnu.org/packages/")))
(package-initialize)
(unless package-archive-contents
@@ -127,15 +125,15 @@
(use-package smart-mode-line
:ensure
- :init (progn
- (use-package powerline :ensure)
- (use-package smart-mode-line-powerline-theme :ensure)
- (sml/setup)
- (sml/apply-theme 'powerline)
- (setq sml/shorten-directory nil
- sml/shorten-modes t
- sml/mode-width 'right
- sml/vc-mode-show-backend t)))
+ :init
+ (use-package powerline :ensure)
+ (use-package smart-mode-line-powerline-theme :ensure)
+ (sml/setup)
+ (sml/apply-theme 'powerline)
+ (setq sml/shorten-directory nil
+ sml/shorten-modes t
+ sml/mode-width 'right
+ sml/vc-mode-show-backend t))
;;; I'm in Korea
@@ -165,31 +163,32 @@
(use-package expand-region
:ensure
:bind ("M-i" . er/expand-region)
- :init (progn
- (setq expand-region-contract-fast-key (kbd "o"))
- ;; fill out the region to the beginning and ends of the
- ;; lines at either end of it when we're not using
- ;; expand-region but we've activated the mark (but only do
- ;; this once)
- (defadvice er/expand-region (around fill-out-region activate)
- (if (or (not (region-active-p))
- (eq last-command 'er/expand-region))
- ad-do-it
- (if (< (point) (mark))
- (let ((beg (point)))
- (goto-char (mark))
- (end-of-line)
- (forward-char 1)
- (push-mark)
- (goto-char beg)
- (beginning-of-line))
- (let ((end (point)))
- (goto-char (mark))
- (beginning-of-line)
- (push-mark)
- (goto-char end)
- (end-of-line)
- (forward-char 1)))))))
+ :init
+ (setq expand-region-contract-fast-key (kbd "o"))
+
+ ;; fill out the region to the beginning and ends of the
+ ;; lines at either end of it when we're not using
+ ;; expand-region but we've activated the mark (but only do
+ ;; this once)
+ (defadvice er/expand-region (around fill-out-region activate)
+ (if (or (not (region-active-p))
+ (eq last-command 'er/expand-region))
+ ad-do-it
+ (if (< (point) (mark))
+ (let ((beg (point)))
+ (goto-char (mark))
+ (end-of-line)
+ (forward-char 1)
+ (push-mark)
+ (goto-char beg)
+ (beginning-of-line))
+ (let ((end (point)))
+ (goto-char (mark))
+ (beginning-of-line)
+ (push-mark)
+ (goto-char end)
+ (end-of-line)
+ (forward-char 1))))))
;;; keep parentheses under control: modern replacement for the mighty paredit
@@ -200,123 +199,123 @@
;; for when I use Emacs via PuTTY
("M-<right>" . sp-forward-slurp-sexp)
("M-<left>" . sp-forward-barf-sexp))
- :commands (smartparens-strict-mode smartparens-mode show-smartparens-global-mode)
- :init (dolist (hook '(emacs-lisp-mode-hook
- lisp-mode-hook
- lisp-interaction-mode-hook
- ielm-mode-hook
- scheme-mode-hook
- inferior-scheme-mode-hook
- python-mode-hook
- minibuffer-setup-hook
- haskell-mode-hook))
- (add-hook hook
- (lambda ()
- (smartparens-strict-mode))))
- :idle (progn
- (show-smartparens-global-mode)
-
- ;; non-strict mode the default, and strict mode in some
- ;; programming language major modes
- ;; (smartparens-global-mode)
- )
- :config (progn
- (require 'smartparens-config)
- (setq sp-navigate-consider-symbols t)
-
- ;; global smartparens bindings
- (sp-use-smartparens-bindings)
- (bind-key "C-w" 'sp-backward-kill-word emacs-lisp-mode-map)
- (bind-key "C-k" 'sp-kill-hybrid-sexp emacs-lisp-mode-map)
- (bind-key "M-<up>" 'sp-raise-sexp smartparens-mode-map)
-
- ;; and now undo some of that in particular major modes
- (add-hook 'org-mode-hook (lambda ()
- (crowding/local-set-minor-mode-key
- 'smartparens-mode (kbd "M-<up>") nil)))
-
- ;; override smartparens binding for C-k outside of lisp,
- ;; since sp-kill-hybrid-sexp isn't very smart in comint
- ;; and I like using C-u C-k
- ;; (define-key smartparens-strict-mode-map [remap kill-line] 'kill-line)
- ;; (bind-key "C-k" 'sp-kill-hybrid-sexp
- ;; emacs-lisp-mode-map)
-
- (defadvice sp-backward-kill-word (after sp-backward-kill-word-fix-punctuation activate)
- ;; when killing the first word of a sentence, leave the
- ;; two spaces after the previous sentence's terminal
- ;; period
- (save-excursion
- (backward-char 2)
- (if (and
- (or
- (looking-at "\\. ")
- (looking-at "! ")
- (looking-at "\\? "))
- (not (looking-back "^[1-9]+")))
- (progn
- (forward-char 1)
- (insert " ")))))
-
- ;; fix cursor position after M-d at the beginning of a line
- (defadvice sp-kill-word (after sp-kill-word-beg-of-line-fix activate)
- (if (looking-back "^[[:space:]]")
- (backward-char 1)))
-
- (defadvice sp-backward-delete-char (around sp-backward-delete-char-remove-indentation activate)
- ;; when after whitespace at the beginning of a line or
- ;; an Org bullet or heading, delete it all
- (if (and
- ;; do it if we're not at the beginning of the line,
- ;; and there's whitespace: if we're at the
- ;; beginning of the line we should always delete
- (not (equal (point) (line-beginning-position)))
- (or
- (looking-back "^[[:space:]]+")
- (looking-back "^[[:space:]]*- ")
- (looking-back "^[*]+ ")))
- (kill-line 0)
- ;; if not after whitespace at the beginning of the
- ;; line, just call as usual
- ad-do-it))
-
- (defadvice sp-backward-kill-word (around sp-backward-delete-word-remove-indentation activate)
- ;; when after whitespace at the beginning of a line or
- ;; an Org bullet or heading, delete it all. This is
- ;; more intuitive when C-w is one's main way to delete
- ;; stuff
- (if (and
- ;; do it if we're not at the beginning of the line,
- ;; and there's whitespace: if we're at the
- ;; beginning of the line we should always delete
- (not (equal (point) (line-beginning-position)))
- (or
- (looking-back "^[[:space:]]+")
- (looking-back "^[[:space:]]*- ")
- (looking-back "^[*]+ ")))
- (kill-line 0)
- ;; if not after whitespace at the beginning of the
- ;; line, just call as usual
- ad-do-it))
-
- ;; define some additional pairings for Org-mode
- (sp-local-pair 'org-mode "=" "=") ; verbatim
- ;; (sp-local-pair 'org-mode "*" "*")
- ;; (sp-local-pair 'org-mode "/" "/")
- ;; (sp-local-pair 'org-mode "~" "~") ; code
- ;; (sp-local-pair 'org-mode "+" "+")
- ;; (sp-local-pair 'org-mode "_" "_")
-
- (defadvice sp--cleanup-after-kill (after haskell-sp-unindent activate)
- (when hi2-mode
- (hi2-indent-backwards)))
-
- ))
+ :commands (smartparens-strict-mode
+ smartparens-mode
+ show-smartparens-global-mode)
+ :defer 5
+ :init
+
+ (dolist (hook '(emacs-lisp-mode-hook
+ lisp-mode-hook
+ lisp-interaction-mode-hook
+ ielm-mode-hook
+ scheme-mode-hook
+ inferior-scheme-mode-hook
+ python-mode-hook
+ minibuffer-setup-hook
+ haskell-mode-hook))
+ (add-hook hook
+ (lambda ()
+ (smartparens-strict-mode 1))))
+
+ :config
+
+ (require 'smartparens-config)
+ (setq sp-navigate-consider-symbols t)
+
+ ;; global smartparens bindings
+ (sp-use-smartparens-bindings)
+ (bind-key "C-w" 'sp-backward-kill-word emacs-lisp-mode-map)
+ (bind-key "C-k" 'sp-kill-hybrid-sexp emacs-lisp-mode-map)
+ (bind-key "M-<up>" 'sp-raise-sexp smartparens-mode-map)
+
+ ;; and now undo some of that in particular major modes
+ (add-hook 'org-mode-hook (lambda ()
+ (crowding/local-set-minor-mode-key
+ 'smartparens-mode (kbd "M-<up>") nil)))
+
+ ;; override smartparens binding for C-k outside of lisp,
+ ;; since sp-kill-hybrid-sexp isn't very smart in comint
+ ;; and I like using C-u C-k
+ ;; (define-key smartparens-strict-mode-map [remap kill-line] 'kill-line)
+ ;; (bind-key "C-k" 'sp-kill-hybrid-sexp
+ ;; emacs-lisp-mode-map)
+
+ (defadvice sp-backward-kill-word (after sp-backward-kill-word-fix-punctuation activate)
+ ;; when killing the first word of a sentence, leave the
+ ;; two spaces after the previous sentence's terminal
+ ;; period
+ (save-excursion
+ (backward-char 2)
+ (if (and
+ (or
+ (looking-at "\\. ")
+ (looking-at "! ")
+ (looking-at "\\? "))
+ (not (looking-back "^[1-9]+")))
+ (progn
+ (forward-char 1)
+ (insert " ")))))
+
+ ;; fix cursor position after M-d at the beginning of a line
+ (defadvice sp-kill-word (after sp-kill-word-beg-of-line-fix activate)
+ (if (looking-back "^[[:space:]]")
+ (backward-char 1)))
+
+ (defadvice sp-backward-delete-char (around sp-backward-delete-char-remove-indentation activate)
+ ;; when after whitespace at the beginning of a line or
+ ;; an Org bullet or heading, delete it all
+ (if (and
+ ;; do it if we're not at the beginning of the line,
+ ;; and there's whitespace: if we're at the
+ ;; beginning of the line we should always delete
+ (not (equal (point) (line-beginning-position)))
+ (or
+ (looking-back "^[[:space:]]+")
+ (looking-back "^[[:space:]]*- ")
+ (looking-back "^[*]+ ")))
+ (kill-line 0)
+ ;; if not after whitespace at the beginning of the
+ ;; line, just call as usual
+ ad-do-it))
+
+ (defadvice sp-backward-kill-word (around sp-backward-delete-word-remove-indentation activate)
+ ;; when after whitespace at the beginning of a line or
+ ;; an Org bullet or heading, delete it all. This is
+ ;; more intuitive when C-w is one's main way to delete
+ ;; stuff
+ (if (and
+ ;; do it if we're not at the beginning of the line,
+ ;; and there's whitespace: if we're at the
+ ;; beginning of the line we should always delete
+ (not (equal (point) (line-beginning-position)))
+ (or
+ (looking-back "^[[:space:]]+")
+ (looking-back "^[[:space:]]*- ")
+ (looking-back "^[*]+ ")))
+ (kill-line 0)
+ ;; if not after whitespace at the beginning of the
+ ;; line, just call as usual
+ ad-do-it))
+
+ ;; define some additional pairings for Org-mode
+ (sp-local-pair 'org-mode "=" "=") ; verbatim
+ ;; (sp-local-pair 'org-mode "*" "*")
+ ;; (sp-local-pair 'org-mode "/" "/")
+ ;; (sp-local-pair 'org-mode "~" "~") ; code
+ ;; (sp-local-pair 'org-mode "+" "+")
+ ;; (sp-local-pair 'org-mode "_" "_")
+
+ (defadvice sp--cleanup-after-kill (after haskell-sp-unindent activate)
+ (when hi2-mode
+ (hi2-indent-backwards)))
+ (show-smartparens-global-mode 1))
;;; Org
(use-package org
:ensure org-plus-contrib
+ :pin org
:mode (("\\.org" . org-mode)
("\\.org_archive" . org-mode))
:commands (org-capture
@@ -332,7 +331,8 @@
(use-package popwin
:ensure
:commands popwin-mode
- :idle (popwin-mode 1))
+ :defer 5
+ :config (popwin-mode 1))
;;; save my places in buffers; this is all the session management I need
@@ -346,10 +346,11 @@
(use-package saveplace
:init (setq-default save-place t
save-place-file "~/.emacs.d/saveplace")
- :idle (progn
- (add-hook 'find-file-hook 'save-place-find-file-hook t)
- (add-hook 'kill-emacs-hook 'save-place-kill-emacs-hook)
- (add-hook 'kill-buffer-hook 'save-place-to-alist)))
+ :defer 5
+ :config
+ (add-hook 'find-file-hook 'save-place-find-file-hook t)
+ (add-hook 'kill-emacs-hook 'save-place-kill-emacs-hook)
+ (add-hook 'kill-buffer-hook 'save-place-to-alist))
;;; fix up whitespace around kill and yanking (package seems to be
;;; unavailable for download)
@@ -369,7 +370,9 @@
(use-package openwith
:ensure
:commands openwith-mode
- :idle (openwith-mode t))
+
+ :demand
+ :config (openwith-mode 1))
;; thanks to openwith, the warning for large files can be at a much
;; larger threshold as the chances of hitting it are low (this is
@@ -389,23 +392,25 @@
(use-package magit
:ensure
:diminish magit-auto-revert-mode
- :config (progn
+ :demand
+ :config
+
+ (setq magit-completing-read-function 'magit-ido-completing-read)
- (setq magit-completing-read-function 'magit-ido-completing-read)
+ ;; C-c C-a to amend without any prompt
+ (defun magit-just-amend ()
+ (interactive)
+ (save-window-excursion
+ (magit-with-refresh
+ (shell-command "git --no-pager commit --amend --reuse-message=HEAD"))))
- ;; C-c C-a to amend without any prompt
- (defun magit-just-amend ()
- (interactive)
- (save-window-excursion
- (magit-with-refresh
- (shell-command "git --no-pager commit --amend --reuse-message=HEAD"))))
- (bind-key "C-c C-a" 'magit-just-amend magit-status-mode-map)
+ (bind-key "C-c C-a" 'magit-just-amend magit-status-mode-map)
- (use-package magit-annex :ensure)
+ (use-package magit-annex :ensure)
- (use-package magit-wip
- :diminish magit-wip-save-mode
- :config (global-magit-wip-save-mode 1))))
+ (use-package magit-wip
+ :diminish magit-wip-save-mode
+ :config (global-magit-wip-save-mode 1)))
;;; pointback mode: make sure that point is back where I left it when
;;; switching between buffers where at least one buffer is displayed
@@ -414,7 +419,9 @@
(use-package pointback
:ensure
:commands global-pointback-mode
- :idle (global-pointback-mode 1))
+ :defer 5
+ :config
+ (global-pointback-mode 1))
;;; colour those parentheses
@@ -428,9 +435,9 @@
(use-package rainbow-mode
:ensure
:commands rainbow-mode
- :init (progn
- (add-hook 'html-mode-hook 'rainbow-mode)
- (add-hook 'css-mode-hook 'rainbow-mode)))
+ :init
+ (add-hook 'html-mode-hook 'rainbow-mode)
+ (add-hook 'css-mode-hook 'rainbow-mode))
;;; keep reindenting lisp
@@ -448,10 +455,9 @@
inferior-scheme-mode-hook))
(add-hook hook
(lambda ()
- (turn-on-eldoc-mode)
- ;; (diminish 'eldoc-mode)
- (aggressive-indent-mode)
- (rainbow-delimiters-mode t))))
+ (eldoc-mode 1)
+ (aggressive-indent-mode 1)
+ (rainbow-delimiters-mode 1))))
;;; boxquotes
@@ -492,39 +498,40 @@
;; :bind ("<tab>" . company-complete)
;; :idle (global-company-mode)
:diminish company-mode
- :config (progn
- ;;; startup company
-
- (defun spw/company-prog-setup ()
- "Setup company mode carefully when its needed, rather than using the brash global-company-mode"
- (company-mode 1)
- (define-key (current-local-map) (kbd "M-/") 'company-complete)
- )
- (add-hook 'prog-mode-hook 'spw/company-prog-setup)
- ;; alternative approach: https://github.com/company-mode/company-mode/issues/94#issuecomment-40884387
-
- ;; I like my C-w binding so move one of company's bindings
- (define-key company-active-map "\C-w" nil)
- (bind-key "M-o" 'company-show-location company-active-map)
-
- ;;; settings
-
- (setq company-idle-delay nil
- company-minimum-prefix-length 0
- company-echo-delay 0)
-
- (add-to-list 'company-backends 'company-capf)
- (add-to-list 'company-transformers 'company-sort-by-occurrence)
-
- ;;; python code completion
-
- (use-package anaconda-mode
- :disabled t
- :ensure
- :config (progn
- (add-hook 'python-mode-hook 'anaconda-mode)
- (add-to-list 'company-backends 'company-anaconda)
- (add-hook 'python-mode-hook 'anaconda-eldoc)))))
+ :config
+
+ ;; startup company
+
+ (defun spw/company-prog-setup ()
+ "Setup company mode carefully when its needed, rather than using the brash global-company-mode"
+ (company-mode 1)
+ (define-key (current-local-map) (kbd "M-/") 'company-complete)
+ )
+ (add-hook 'prog-mode-hook 'spw/company-prog-setup)
+ ;; alternative approach: https://github.com/company-mode/company-mode/issues/94#issuecomment-40884387
+
+ ;; I like my C-w binding so move one of company's bindings
+ (define-key company-active-map "\C-w" nil)
+ (bind-key "M-o" 'company-show-location company-active-map)
+
+ ;; settings
+
+ (setq company-idle-delay nil
+ company-minimum-prefix-length 0
+ company-echo-delay 0)
+
+ (add-to-list 'company-backends 'company-capf)
+ (add-to-list 'company-transformers 'company-sort-by-occurrence)
+
+ ;; python code completion
+
+ (use-package anaconda-mode
+ :disabled t
+ :ensure
+ :config (progn
+ (add-hook 'python-mode-hook 'anaconda-mode)
+ (add-to-list 'company-backends 'company-anaconda)
+ (add-hook 'python-mode-hook 'anaconda-eldoc))))
;; C-o during company isearch narrows to stuff matching that search;
;; mnemonic 'occur'. C-M-s while outside of search to do the same
;; thing
@@ -538,11 +545,14 @@
(use-package markdown-mode
:ensure
:mode "\\.md"
- :init (progn
- (add-hook 'markdown-mode-hook 'turn-on-orgstruct)
- (add-hook 'markdown-mode-hook 'turn-on-orgstruct++))
+
+ :init
+ (add-hook 'markdown-mode-hook 'turn-on-orgstruct)
+ (add-hook 'markdown-mode-hook 'turn-on-orgstruct++)
+
+ :config
;; This binding replaces a `markdown-export'.
- :config (bind-key "C-c C-c e" 'spw/pandoc-paper-compile markdown-mode-map))
+ (bind-key "C-c C-c e" 'spw/pandoc-paper-compile markdown-mode-map))
;;; PHP mode
@@ -552,6 +562,7 @@
(use-package deft
:ensure
+ :commands deft
:init (setq deft-extension "org"
deft-text-mode 'org-mode
deft-directory "~/doc/org/"
@@ -560,17 +571,16 @@
deft-incremental-search t
;; don't just strip the leading hash but the whole #+TITLE:
deft-strip-title-regexp "\\(?:\\#\\+TITLE\\: \\|\\#\\+FILETAGS\\: \\|^%+\\|^[#* ]+\\|-\\*-[[:alpha:]]+-\\*-\\|#+$\\)")
- :config (progn
- (bind-key "C-w" 'deft-filter-decrement-word deft-mode-map)
- ;; (bind-key "C-h" 'deft-filter-decrement deft-mode-map)
+ :config
+ (bind-key "C-w" 'deft-filter-decrement-word deft-mode-map)
- (defadvice deft (before persp-deft activate)
- (projectile-persp-switch-project "~/doc"))
+ (defadvice deft (before persp-deft activate)
+ (projectile-persp-switch-project "~/doc"))
- (defadvice deft-new-file (after insert-org-TITLE activate)
- (save-excursion
- (goto-char (point-min))
- (insert "#+TITLE: ")))))
+ (defadvice deft-new-file (after insert-org-TITLE activate)
+ (save-excursion
+ (goto-char (point-min))
+ (insert "#+TITLE: "))))
;;; The following two python packages seem to be unavailable for
;;; download. Disable them for now.
@@ -588,33 +598,36 @@
(use-package flycheck
:ensure
- :idle (global-flycheck-mode)
- ;; disable flymake; having both running at the same time is annoying
- :init (setq flymake-allowed-file-name-masks nil))
+ :defer 5
+ :init
+ ;; try to disable flymake; having both running at the same time is annoying
+ (setq flymake-allowed-file-name-masks nil)
+ :config
+ (global-flycheck-mode 1))
;;; TRAMP
(use-package tramp
- :config (progn
- (add-to-list 'tramp-default-user-alist '(nil "sdf" "spw"))
- (add-to-list 'tramp-default-user-alist '("sudo" "localhost" "root"))
- (add-to-list 'tramp-default-user-alist '(nil nil "swhitton") t)
- (add-to-list 'tramp-default-user-alist '(nil "ma" "spw"))
- (add-to-list 'tramp-default-user-alist '(nil "sage" "spwhitton"))
+ :config
+ (add-to-list 'tramp-default-user-alist '(nil "sdf" "spw"))
+ (add-to-list 'tramp-default-user-alist '("sudo" "localhost" "root"))
+ (add-to-list 'tramp-default-user-alist '(nil nil "swhitton") t)
+ (add-to-list 'tramp-default-user-alist '(nil "ma" "spw"))
+ (add-to-list 'tramp-default-user-alist '(nil "sage" "spwhitton"))
- ;; TRAMP and zsh are not friends so might as well switch
- ;; over here
- (setenv "SHELL" "/bin/bash")))
+ ;; TRAMP and zsh are not friends so might as well switch
+ ;; over here
+ (setenv "SHELL" "/bin/bash"))
;;; ebib for editing BiBTeX databases
(use-package ebib
:ensure
:bind ("C-c g e" . ebib)
- :init (progn
- (defadvice ebib (before spw/persp-ebib activate)
- (persp-switch "ebib"))
- (setq ebib-preload-bib-files '("~/doc/spw.bib"))))
+ :init
+ (defadvice ebib (before spw/persp-ebib activate)
+ (persp-switch "ebib"))
+ (setq ebib-preload-bib-files '("~/doc/spw.bib")))
;;; dired enhancements
@@ -637,59 +650,60 @@
(use-package projectile
:ensure
:commands projectile-vc
- :init (projectile-global-mode)
- :diminish 'projectile-mode
- :config (progn
- (setq projectile-switch-project-action 'projectile-dired
- projectile-completion-system 'ido)
- (diminish 'projectile-mode)))
+ :demand
+ :config
+ (projectile-global-mode 1)
+ (setq projectile-switch-project-action 'projectile-dired
+ projectile-completion-system 'ido)
+ (diminish 'projectile-mode))
(use-package persp-projectile :ensure)
(use-package perspective
:ensure
:commands (persp-toggle persp-switch)
- :init (progn
- (setq persp-modestring-dividers '("" "" "|"))
-
- ;; activate persp mode, but don't activate it if it's
- ;; already active cos this removes all existing perspectives
- ;; which is annoying
- (unless persp-mode
- (persp-mode))
-
- (defun persp-toggle (arg)
- (interactive "P")
- (if arg (call-interactively 'persp-switch)
- (persp-switch (persp-find-some))))
-
- ;; save and restore a base window configuration ala
- ;; workgroups.el. Designed to handle the perennial Emacs
- ;; problem of Emacs totally screwing up your windows in the
- ;; middle of your work
- (setq persp-basewcs nil)
- (defun persp-basewc-save ()
- (interactive)
- (let* ((name (persp-name persp-curr))
- (wc (current-window-configuration))
- (pair (cons name wc)))
- (setq persp-basewcs
- (remove* name persp-basewcs
- :test 'equal :key 'car))
- (add-to-list 'persp-basewcs pair)))
- ;; Save when opening a perspective.
- (add-hook 'persp-created-hook 'persp-basewc-save)
- ;; Also do a save of the basewc after
- ;; `projectile-persp-switch-project' (I never use
- ;; `projectile-switch-project' directly) switches to dired
- ;; as this is a more sensible initial basewc to go back to.
- (add-hook 'projectile-switch-project-hook 'persp-basewc-save)
- (defun persp-basewc-restore ()
- (interactive)
- (let* ((name (persp-name persp-curr))
- (pair (assoc name persp-basewcs))
- (wc (cdr pair)))
- (set-window-configuration wc)))))
+ :demand
+ :config
+ (setq persp-modestring-dividers '("" "" "|"))
+
+ ;; activate persp mode, but don't activate it if it's
+ ;; already active cos this removes all existing perspectives
+ ;; which is annoying
+ (unless persp-mode
+ (persp-mode))
+
+ (defun persp-toggle (arg)
+ (interactive "P")
+ (if arg (call-interactively 'persp-switch)
+ (persp-switch (persp-find-some))))
+
+ ;; save and restore a base window configuration ala
+ ;; workgroups.el. Designed to handle the perennial Emacs
+ ;; problem of Emacs totally screwing up your windows in the
+ ;; middle of your work
+ (setq persp-basewcs nil)
+ (defun persp-basewc-save ()
+ (interactive)
+ (let* ((name (persp-name persp-curr))
+ (wc (current-window-configuration))
+ (pair (cons name wc)))
+ (setq persp-basewcs
+ (remove* name persp-basewcs
+ :test 'equal :key 'car))
+ (add-to-list 'persp-basewcs pair)))
+ ;; Save when opening a perspective.
+ (add-hook 'persp-created-hook 'persp-basewc-save)
+ ;; Also do a save of the basewc after
+ ;; `projectile-persp-switch-project' (I never use
+ ;; `projectile-switch-project' directly) switches to dired
+ ;; as this is a more sensible initial basewc to go back to.
+ (add-hook 'projectile-switch-project-hook 'persp-basewc-save)
+ (defun persp-basewc-restore ()
+ (interactive)
+ (let* ((name (persp-name persp-curr))
+ (pair (assoc name persp-basewcs))
+ (wc (cdr pair)))
+ (set-window-configuration wc))))
;; completion with ido
@@ -723,16 +737,17 @@
(use-package flx-ido
:ensure
- :init (progn
- (flx-ido-mode 1)
- (setq ido-enable-flex-matching t
- ido-use-faces nil
- flx-ido-threshhold 7500
- gc-cons-threshold 20000000)))
+ :config
+ (flx-ido-mode 1)
+ (setq ido-enable-flex-matching t
+ ido-use-faces nil
+ flx-ido-threshhold 7500
+ gc-cons-threshold 20000000))
(use-package ido-ubiquitous
:ensure
- :init (ido-ubiquitous-mode 1))
+ :config
+ (ido-ubiquitous-mode 1))
;; (use-package ido-vertical-mode
;; :ensure
@@ -740,7 +755,8 @@
(use-package smex
:ensure
- ;; TODO: get keyboard macro bindings back
+ ;; TODO: get keyboard macro bindings, that vanilla emacs has under
+ ;; the prefix C-x C-m, back
:bind ("C-x C-m" . smex))
;; imenu
@@ -751,20 +767,25 @@
(use-package helm
:ensure
- :init
- (progn
- (use-package helm-mode
- :bind ("M-s o" . helm-occur))
- (use-package helm-descbinds
- :ensure
- :idle (helm-descbinds-mode))))
+ :defer 5
+ :config
+ (use-package helm-mode
+ :bind ("M-s o" . helm-occur))
+ (use-package helm-descbinds
+ :ensure
+ :defer 5
+ :config
+ (helm-descbinds-mode)))
;;; snippets
(use-package yasnippet
:ensure
:diminish yas-minor-mode
- :idle (yas-global-mode))
+
+ :defer 5
+ :config
+ (yas-global-mode 1))
;;; htmlize for Org HTML export/publishing
@@ -779,29 +800,33 @@
(use-package highlight-indentation
:ensure
- :init (progn
- (add-hook 'python-mode-hook 'highlight-indentation-current-column-mode)
- ;; (add-hook 'haskell-mode-hook 'highlight-indentation-current-column-mode)
- ))
+ :init
+ (add-hook 'python-mode-hook 'highlight-indentation-current-column-mode))
;;; jump around what's visible
(use-package ace-jump-mode
:ensure
:bind ("M-o" . ace-jump-mode)
+ :config
+
;; make `ace-jump-mode' respect dired-isearch-filenames
;; from https://www.reddit.com/r/emacs/comments/2x3mke/making_acejump_play_nice_with_dired/
- :config (add-hook 'dired-mode-hook
- (lambda ()
- (setq-local ace-jump-search-filter
- (lambda ()
- (get-text-property (point) 'dired-filename))))))
+ ;; (add-hook 'dired-mode-hook
+ ;; (lambda ()
+ ;; (setq-local ace-jump-search-filter
+ ;; (lambda ()
+ ;; (get-text-property (point) 'dired-filename)))))
+
+ )
;;; use ace-jump-mode to move between links in help file
(use-package ace-link
:ensure
- :idle (ace-link-setup-default))
+ :defer 5
+ :config
+ (ace-link-setup-default))
;;; chat on Jabber
@@ -885,44 +910,46 @@
(use-package whole-line-or-region
:ensure
:diminish whole-line-or-region-mode
- :idle (whole-line-or-region-mode 1))
+ :defer 5
+ :config
+ (whole-line-or-region-mode 1))
(use-package hydra
:ensure
- :init (progn
- (setq hydra-windows-config nil)
- (defun spw/maybe-delete-other-windows ()
- (interactive)
- (if (= (count-windows) 1)
- (set-window-configuration hydra-windows-config)
- (setq hydra-windows-config (current-window-configuration))
- (delete-other-windows)))
- (defhydra hydra-windows (global-map "C-x" :color red)
- "windows"
- ("o" other-window "next" :color red)
- ("O" (lambda () (interactive) (other-window -1)) "previous" :color red)
- ("S" spw/toggle-window-split "toggle" :color red)
- ("0" delete-window "del" :color red)
- ("1" spw/maybe-delete-other-windows "max" :color red)
- ("2" split-window-below "horiz" :color red)
- ("3" split-window-right "vert" :color red))))
+ :config
+ (setq hydra-windows-config nil)
+ (defun spw/maybe-delete-other-windows ()
+ (interactive)
+ (if (= (count-windows) 1)
+ (set-window-configuration hydra-windows-config)
+ (setq hydra-windows-config (current-window-configuration))
+ (delete-other-windows)))
+ (defhydra hydra-windows (global-map "C-x" :color red)
+ "windows"
+ ("o" other-window "next" :color red)
+ ("O" (lambda () (interactive) (other-window -1)) "previous" :color red)
+ ("S" spw/toggle-window-split "toggle" :color red)
+ ("0" delete-window "del" :color red)
+ ("1" spw/maybe-delete-other-windows "max" :color red)
+ ("2" split-window-below "horiz" :color red)
+ ("3" split-window-right "vert" :color red)))
;;; aligning rule for Haskell adapted from Haskell mode wiki
(use-package align
- :init (progn
- (add-to-list 'align-rules-list
- '(haskell-defns
- (regexp . "\\(\\s-+\\)\\(::\\|∷\\|=\\)\\s-+")
- (modes quote (haskell-mode literate-haskell-mode))))
- (add-to-list 'align-rules-list
- '(haskell-arrows
- (regexp . "^[^:\n]+\\(\\s-+\\)\\(->\\)\\s-+")
- (modes quote (haskell-mode literate-haskell-mode))))
- (add-to-list 'align-rules-list
- '(haskell-left-arrows
- (regexp . "\\(\\s-+\\)\\(<-\\|←\\)\\s-+")
- (modes quote (haskell-mode literate-haskell-mode))))))
+ :config
+ (add-to-list 'align-rules-list
+ '(haskell-defns
+ (regexp . "\\(\\s-+\\)\\(::\\|∷\\|=\\)\\s-+")
+ (modes quote (haskell-mode literate-haskell-mode))))
+ (add-to-list 'align-rules-list
+ '(haskell-arrows
+ (regexp . "^[^:\n]+\\(\\s-+\\)\\(->\\)\\s-+")
+ (modes quote (haskell-mode literate-haskell-mode))))
+ (add-to-list 'align-rules-list
+ '(haskell-left-arrows
+ (regexp . "\\(\\s-+\\)\\(<-\\|←\\)\\s-+")
+ (modes quote (haskell-mode literate-haskell-mode)))))
;;; edit .nix files
@@ -942,26 +969,26 @@
(use-package god-mode
:ensure
- :config (progn
- ;; (unless god-global-mode (god-mode))
+ :config
+ ;; (unless god-global-mode (god-mode))
- ;; activate with a key-chord to avoid having to have
- ;; capslock bound to both escape and control
- (key-chord-define-global "hj" 'god-mode-all)
+ ;; activate with a key-chord to avoid having to have
+ ;; capslock bound to both escape and control
+ (key-chord-define-global "hj" 'god-mode-all)
- ;; just a little vi in god-mode
- (define-key god-local-mode-map (kbd ".") 'repeat)
- (define-key god-local-mode-map (kbd "i") 'god-mode-all)
+ ;; just a little vi in god-mode
+ (define-key god-local-mode-map (kbd ".") 'repeat)
+ (define-key god-local-mode-map (kbd "i") 'god-mode-all)
- ;; change a part of the modeline depending on whether in god-mode
- (defun spw/god-mode-update-modeline ()
- (set-face-background 'sml/filename (if god-local-mode
- "red"
- ;; following from smart-mode-line-powerline-theme.el
- (or (face-background 'powerline-active1) "Grey30"))))
+ ;; change a part of the modeline depending on whether in god-mode
+ (defun spw/god-mode-update-modeline ()
+ (set-face-background 'sml/filename (if god-local-mode
+ "red"
+ ;; following from smart-mode-line-powerline-theme.el
+ (or (face-background 'powerline-active1) "Grey30"))))
- (add-hook 'god-mode-enabled-hook 'spw/god-mode-update-modeline)
- (add-hook 'god-mode-disabled-hook 'spw/god-mode-update-modeline)))
+ (add-hook 'god-mode-enabled-hook 'spw/god-mode-update-modeline)
+ (add-hook 'god-mode-disabled-hook 'spw/god-mode-update-modeline))
;; good key chords from
;; <http://www.johndcook.com/blog/2015/02/01/rare-bigrams/> via
@@ -992,7 +1019,7 @@
(use-package elisp-slime-nav
:ensure
- :commands turn-on-elisp-slime-nav-mode
+ :commands (turn-on-elisp-slime-nav-mode elisp-slime-nav-mode)
:init (dolist (hook '(emacs-lisp-mode-hook ielm-mode-hook))
(add-hook hook 'elisp-slime-nav-mode)))
diff --git a/.emacs.d/site-lisp/bind-key.el b/.emacs.d/site-lisp/bind-key.el
index 2ddbae2f..5cace724 100644
--- a/.emacs.d/site-lisp/bind-key.el
+++ b/.emacs.d/site-lisp/bind-key.el
@@ -1,59 +1,60 @@
;;; bind-key.el --- A simple way to manage personal keybindings
-;; Copyright (C) 2012 John Wiegley
+;; Copyright (c) 2012-2015 john wiegley
;; Author: John Wiegley <jwiegley@gmail.com>
+;; Maintainer: John Wiegley <jwiegley@gmail.com>
;; Created: 16 Jun 2012
;; Version: 1.0
;; Keywords: keys keybinding config dotemacs
;; 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
-;; published by the Free Software Foundation; either version 2, or (at
+;; modify it under the terms of the gnu general public license as
+;; published by the free software foundation; either version 2, or (at
;; your option) any later version.
;; This program is distributed in the hope that it will be useful, but
-;; WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-;; General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; without any warranty; without even the implied warranty of
+;; merchantability or fitness for a particular purpose. see the gnu
+;; general public license for more details.
+
+;; You should have received a copy of the gnu general public license
+;; along with gnu emacs; see the file copying. if not, write to the
+;; free software foundation, inc., 59 temple place - suite 330,
+;; boston, ma 02111-1307, usa.
;;; Commentary:
;; If you have lots of keybindings set in your .emacs file, it can be hard to
;; know which ones you haven't set yet, and which may now be overriding some
-;; new default in a new Emacs version. This module aims to solve that
+;; new default in a new emacs version. This module aims to solve that
;; problem.
;;
;; Bind keys as follows in your .emacs:
;;
;; (require 'bind-key)
;;
-;; (bind-key "C-c x" 'my-ctrl-c-x-command)
+;; (bind-key "c-c x" 'my-ctrl-c-x-command)
;;
;; If you want the keybinding to override all minor modes that may also bind
;; the same key, use the `bind-key*' form:
;;
-;; (bind-key* "<C-return>" 'other-window)
+;; (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)
+;; (bind-key "c-c x" 'my-ctrl-c-x-command some-other-mode-map)
;;
;; To unbind a key within a keymap (for example, to stop your favorite major
;; mode from changing a binding that you don't want to override everywhere),
;; use `unbind-key':
;;
-;; (unbind-key "C-c x" 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 bind multiple keys at once, or set up a prefix map, a `bind-keys' macro
+;; is provided. It accepts keyword arguments, please see its documentation
+;; for a detailed description.
;;
;; To add keys into a specific map, use :map argument
;;
@@ -61,17 +62,25 @@
;; ("o" . dired-omit-mode)
;; ("a" . some-custom-dired-function))
;;
-;; To set up a prefix map, use :prefix-map and :prefix
-;; arguments (both are required)
+;; 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.
+;; 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:
@@ -82,6 +91,7 @@
;; what the default was. Also, it will tell you if the key was rebound after
;; your binding it with `bind-key', and what it was rebound it to.
+(require 'cl-lib)
(require 'easy-mmode)
(defgroup bind-key nil
@@ -119,44 +129,55 @@
(add-to-list 'emulation-mode-map-alists
`((override-global-mode . ,override-global-map)))
-(defvar personal-keybindings nil)
+(defvar personal-keybindings nil
+ "List of bindings performed by `bind-key'.
+Elements have the form ((KEY . [MAP]) CMD ORIGINAL-CMD)")
+
+;;;###autoload
(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 passed straight to
+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"))
- (bindingvar (make-symbol "binding"))
- (entryvar (make-symbol "entry")))
+ (kdescvar (make-symbol "kdesc"))
+ (bindingvar (make-symbol "binding")))
`(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))
+ (add-to-list 'personal-keybindings
+ (list ,kdescvar ,command
+ (unless (numberp ,bindingvar) ,bindingvar)))
(define-key (or ,keymap global-map) ,keyvar ,command))))
+;;;###autoload
(defmacro unbind-key (key-name &optional keymap)
- `(bind-key ,key-name nil ,keymap))
+ `(progn
+ (bind-key ,key-name nil ,keymap)
+ (setq personal-keybindings
+ (cl-delete-if #'(lambda (k)
+ ,(if keymap
+ `(and (consp (car k))
+ (string= (caar k) ,key-name)
+ (eq (cdar k) ',keymap))
+ `(and (stringp (car k))
+ (string= (car k) ,key-name))))
+ personal-keybindings))))
+;;;###autoload
(defmacro bind-key* (key-name command)
- `(progn
- (bind-key ,key-name ,command)
- (define-key override-global-map ,(read-kbd-macro key-name) ,command)))
+ `(bind-key ,key-name ,command override-global-map))
+;;;###autoload
(defmacro bind-keys (&rest args)
"Bind multiple keys at once.
@@ -166,33 +187,54 @@ Accepts keyword arguments:
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))
- (key-bindings (progn
- (while (keywordp (car args))
- (pop args)
- (pop args))
- args)))
- (when (or (and prefix-map
- (not prefix))
- (and prefix
- (not prefix-map)))
+ (let* ((map (plist-get args :map))
+ (maps (if (listp map) map (list 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"))
- `(progn
- ,@(when prefix-map
- `((defvar ,prefix-map)
- ,@(when doc `((put ',prefix-map 'variable-documentation ,doc)))
- (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))))
+ (when (and menu-name (not prefix))
+ (error "If :menu-name is supplied, :prefix must be too"))
+ (macroexp-progn
+ (append
+ (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)))
+ ,@(if maps
+ (mapcar
+ #'(lambda (m)
+ `(bind-key ,prefix ',prefix-map ,m)) maps)
+ `((bind-key ,prefix ',prefix-map)))))
+ (apply
+ #'nconc
+ (mapcar (lambda (form)
+ (if prefix-map
+ `((bind-key ,(car form) ',(cdr form) ,prefix-map))
+ (if maps
+ (mapcar
+ #'(lambda (m)
+ `(bind-key ,(car form) ',(cdr form) ,m)) maps)
+ `((bind-key ,(car form) ',(cdr form))))))
+ key-bindings))))))
+
+;;;###autoload
+(defmacro bind-keys* (&rest args)
+ `(bind-keys :map override-global-map ,@args))
(defun get-binding-description (elem)
(cond
@@ -212,12 +254,9 @@ function symbol (unquoted)."
"#<keymap>")
(t
elem)))
- ((keymapp elem)
- (if (and bind-key-describe-special-forms
- (symbolp elem)
- (get elem 'variable-documentation))
- (format "%s" (get elem 'variable-documentation))
- "#<keymap>"))
+ ;; must be a symbol, non-symbol keymap case covered above
+ ((and bind-key-describe-special-forms (keymapp elem))
+ (get elem 'variable-documentation))
((symbolp elem)
elem)
(t
@@ -250,11 +289,13 @@ function symbol (unquoted)."
(t
(cons (string< (caar l) (caar r)) nil)))))
+;;;###autoload
(defun describe-personal-keybindings ()
"Display all the personal keybindings defined by `bind-key'."
(interactive)
(with-output-to-temp-buffer "*Personal Keybindings*"
- (princ (format "Key name%s Command%s Comments\n%s %s ---------------------\n"
+ (princ (format (concat "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)) ?-)
@@ -263,13 +304,14 @@ function symbol (unquoted)."
(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)))
(princ (format "\n\n%s\n%s\n\n"
(cdar binding)
- (make-string (+ 21 (car bind-key-column-widths) (cdr bind-key-column-widths)) ?-)))
+ (make-string (+ 21 (car bind-key-column-widths)
+ (cdr bind-key-column-widths)) ?-)))
(if (and last-binding
(cdr (compare-keybindings last-binding binding)))
(princ "\n")))
@@ -287,7 +329,8 @@ function symbol (unquoted)."
)
(let ((line
(format
- (format "%%-%ds%%-%ds%%s\n" (car bind-key-column-widths) (cdr bind-key-column-widths))
+ (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)
@@ -302,7 +345,9 @@ function symbol (unquoted)."
(setq last-binding binding)))))
(provide 'bind-key)
+
;; Local Variables:
;; indent-tabs-mode: nil
;; End:
+
;;; bind-key.el ends here
diff --git a/.emacs.d/site-lisp/use-package.el b/.emacs.d/site-lisp/use-package.el
index 36e7e0b7..6feb0d84 100644
--- a/.emacs.d/site-lisp/use-package.el
+++ b/.emacs.d/site-lisp/use-package.el
@@ -3,11 +3,12 @@
;; Copyright (C) 2012 John Wiegley
;; Author: John Wiegley <jwiegley@gmail.com>
+;; Maintainer: John Wiegley <jwiegley@gmail.com>
;; Created: 17 Jun 2012
-;; Version: 1.0
+;; Version: 2.0
;; Package-Requires: ((bind-key "1.0") (diminish "0.44"))
;; Keywords: dotemacs startup speed config package
-;; X-URL: https://github.com/jwiegley/use-package
+;; 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
@@ -23,7 +24,7 @@
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
-
+
;;; Commentary:
;; The `use-package' declaration macro allows you to isolate package
@@ -34,418 +35,1022 @@
;; functionality!
;;
;; Please see README.md from the same repository for documentation.
-
+
;;; Code:
(require 'bind-key)
(require 'bytecomp)
(require 'diminish nil t)
+(require 'bytecomp)
+(eval-when-compile (require 'cl))
-(when (fboundp 'declare-function)
- (declare-function package-installed-p 'package))
+(declare-function package-installed-p 'package)
(defgroup use-package nil
"A use-package declaration for simplifying your `.emacs'."
:group 'startup)
(defcustom use-package-verbose nil
- "Whether to report about loading and configuration details."
+ "Whether to report about loading and configuration details.
+
+If you customize this, then you should require the `use-package'
+feature in files that use `use-package', 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"
- :type 'number
+(defcustom use-package-debug nil
+ "Whether to display use-package expansions in a *use-package* buffer."
+ :type 'boolean
:group 'use-package)
-(defcustom use-package-idle-interval 3
- "Time to wait when using :idle in a `use-package' specification."
+(defcustom use-package-always-ensure nil
+ "Treat every package as though it had specified `:ensure SEXP`."
+ :type 'sexp
+ :group 'use-package)
+
+(defcustom use-package-minimum-reported-time 0.1
+ "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 `use-package', 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)
-(defmacro use-package-with-elapsed-timer (text &rest body)
+(defcustom use-package-inject-hooks nil
+ "If non-nil, add hooks to the `:init' and `:config' sections.
+In particular, for a given package `foo', the following hooks
+become available:
+
+ `use-package--foo--pre-init-hook'
+ `use-package--foo--post-init-hook'
+ `use-package--foo--pre-config-hook'
+ `use-package--foo--post-config-hook'
+
+This way, you can add to these hooks before evalaution of a
+`use-package` declaration, and exercise some control over what
+happens.
+
+Note that if either `pre-init' hooks returns a nil value, that
+block's user-supplied configuration is not evaluated, so be
+certain to return `t' if you only wish to add behavior to what
+the user specified."
+ :type 'boolean
+ :group 'use-package)
+
+(defcustom use-package-keywords
+ '(:disabled
+ :pin
+ :ensure
+ :if
+ :when
+ :unless
+ :requires
+ :load-path
+ :preface
+ :no-require
+ :bind
+ :bind*
+ :bind-keymap
+ :bind-keymap*
+ :interpreter
+ :mode
+ :commands
+ :defines
+ :functions
+ :defer
+ :demand
+ :init
+ :config
+ :diminish
+ :delight)
+ "Establish which keywords are valid, and the order they are processed in.
+
+Note that `:disabled' is special, in that it causes nothing at all to happen,
+even if the rest of the use-package declaration is incorrect."
+ :type '(repeat symbol)
+ :group 'use-package)
+
+(defcustom use-package-expand-minimally nil
+ "If non-nil, make the expanded code as minimal as possible.
+This disables:
+ - Printing to the *Messages* buffer of slowly-evaluating forms
+ - Capture of load errors (normally redisplayed as warnings)
+ - Conditional loading of packages (load failures become errors)
+The only advantage is that, if you know your configuration works,
+then your byte-compiled init file is as minimal as possible."
+ :type 'boolean
+ :group 'use-package)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Utility functions
+;;
+
+(defun use-package-expand (name label form)
+ "FORM is a list of forms, so `((foo))' if only `foo' is being called."
(declare (indent 1))
- (let ((nowvar (make-symbol "now")))
- `(if use-package-verbose
- (let ((,nowvar (current-time)))
- (message "%s..." ,text)
- (prog1 (progn ,@body)
- (let ((elapsed
- (float-time (time-subtract (current-time) ,nowvar))))
- (if (> elapsed ,use-package-minimum-reported-time)
- (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 (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
- use-package-idle-interval t
- 'use-package-idle-eval))))
-
-(defun use-package-init-on-idle (form priority)
- "Add a new form to the idle queue."
- (use-package-start-idle-timer)
- (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 (use-package-idle-pop)))
- (if next
- (progn
- (when use-package-verbose
- (message "use-package idle:%s" next))
-
- (condition-case e
- (funcall next)
+ (when form
+ (if use-package-expand-minimally
+ form
+ (let ((err (make-symbol "err")))
+ (list
+ `(condition-case-unless-debug ,err
+ ,(macroexp-progn form)
(error
- (message
- "Failure on use-package idle. Form: %s, Error: %s"
- next e)))
- ;; recurse after a bit
- (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))))
+ (ignore
+ (display-warning 'use-package
+ (format "%s %s: %s"
+ ,name ,label (error-message-string ,err))
+ :error)))))))))
+
+(put 'use-package-expand 'lisp-indent-function 'defun)
+
+(defun use-package-hook-injector (name-string keyword body)
+ "Wrap pre/post hook injections around a given keyword form.
+ARGS is a list of forms, so `((foo))' if only `foo' is being called."
+ (if (not use-package-inject-hooks)
+ (use-package-expand name-string (format "%s" keyword) body)
+ (let ((keyword-name (substring (format "%s" keyword) 1)))
+ (when body
+ `((when ,(macroexp-progn
+ (use-package-expand name-string (format "pre-%s hook" keyword)
+ `(run-hook-with-args-until-failure
+ ',(intern (concat "use-package--" name-string
+ "--pre-" keyword-name "-hook")))))
+ ,(macroexp-progn
+ (use-package-expand name-string (format "%s" keyword) body))
+ ,(macroexp-progn
+ (use-package-expand name-string (format "post-%s hook" keyword)
+ `(run-hooks
+ ',(intern (concat "use-package--" name-string
+ "--post-" keyword-name "-hook")))))))))))
+
+(defun use-package--with-elapsed-timer (text body)
+ "BODY is a list of forms, so `((foo))' if only `foo' is being called."
+ (declare (indent 1))
+ (if use-package-expand-minimally
+ body
+ (let ((nowvar (make-symbol "now")))
+ (if (bound-and-true-p use-package-verbose)
+ `((let ((,nowvar (current-time)))
+ (message "%s..." ,text)
+ (prog1
+ ,(macroexp-progn body)
+ (let ((elapsed
+ (float-time (time-subtract (current-time) ,nowvar))))
+ (if (> elapsed ,use-package-minimum-reported-time)
+ (message "%s...done (%.3fs)" ,text elapsed)
+ (message "%s...done" ,text))))))
+ body))))
+
+(put 'use-package--with-elapsed-timer 'lisp-indent-function 1)
+
+(defsubst use-package-error (msg)
+ "Report MSG as an error, so the user knows it came from this package."
+ (error "use-package: %s" msg))
+
+(defsubst use-package-plist-maybe-put (plist property value)
+ "Add a VALUE for PROPERTY to PLIST, if it does not already exist."
+ (if (plist-member plist property)
+ plist
+ (plist-put plist property value)))
+
+(defsubst use-package-plist-cons (plist property value)
+ "Cons VALUE onto the head of the list at PROPERTY in PLIST."
+ (plist-put plist property (cons value (plist-get plist property))))
+
+(defsubst use-package-plist-append (plist property value)
+ "Append VALUE onto the front of the list at PROPERTY in PLIST."
+ (plist-put plist property (append value (plist-get plist property))))
+
+(defun use-package-plist-delete (plist property)
+ "Delete PROPERTY from PLIST.
+This is in contrast to merely setting it to 0."
+ (let (p)
+ (while plist
+ (if (not (eq property (car plist)))
+ (setq p (plist-put p (car plist) (nth 1 plist))))
+ (setq plist (cddr plist)))
+ p))
+
+(defun use-package-split-list (pred xs)
+ (let ((ys (list nil)) (zs (list nil)) flip)
+ (dolist (x xs)
+ (if flip
+ (nconc zs (list x))
+ (if (funcall pred x)
+ (progn
+ (setq flip t)
+ (nconc zs (list x)))
+ (nconc ys (list x)))))
+ (cons (cdr ys) (cdr zs))))
+
+(defun use-package-keyword-index (keyword)
+ (loop named outer
+ with index = 0
+ for k in use-package-keywords do
+ (if (eq k keyword)
+ (return-from outer index))
+ (incf index)))
+
+(defun use-package-sort-keywords (plist)
+ (let (plist-grouped)
+ (while plist
+ (push (cons (car plist) (cadr plist))
+ plist-grouped)
+ (setq plist (cddr plist)))
+ (let (result)
+ (dolist (x
+ (nreverse
+ (sort plist-grouped
+ #'(lambda (l r) (< (use-package-keyword-index (car l))
+ (use-package-keyword-index (car r)))))))
+ (setq result (cons (car x) (cons (cdr x) result))))
+ result)))
+
+(defsubst use-package-concat (&rest elems)
+ "Delete all empty lists from ELEMS (nil or (list nil)), and append them."
+ (apply #'nconc (delete nil (delete (list nil) elems))))
+
+(defconst use-package-font-lock-keywords
+ '(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?"
+ (1 font-lock-keyword-face)
+ (2 font-lock-constant-face nil t))))
+
+(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Keyword processing
+;;
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Normalization functions
+;;
+
+(defun use-package-normalize-plist (name-symbol input)
+ "Given a pseudo-plist, normalize it to a regular plist."
+ (unless (null input)
+ (let* ((keyword (car input))
+ (xs (use-package-split-list #'keywordp (cdr input)))
+ (args (car xs))
+ (tail (cdr xs))
+ (normalizer (intern (concat "use-package-normalize/"
+ (symbol-name keyword))))
+ (arg
+ (cond
+ ((eq keyword :disabled)
+ (use-package-normalize-plist name-symbol tail))
+ ((functionp normalizer)
+ (funcall normalizer name-symbol keyword args))
+ ((= (length args) 1)
+ (car args))
+ (t
+ args))))
+ (if (memq keyword use-package-keywords)
+ (cons keyword
+ (cons arg (use-package-normalize-plist name-symbol tail)))
+ (use-package-error (format "Unrecognized keyword: %s" keyword))))))
+
+(defun use-package-process-keywords (name-symbol plist &optional state)
+ "Process the next keyword in the free-form property list PLIST.
+The values in the PLIST have each been normalized by the function
+use-package-normalize/KEYWORD (minus the colon).
+
+STATE is a property list that the function may modify and/or
+query. This is useful if a package defines multiple keywords and
+wishes them to have some kind of stateful interaction.
+
+Unless the KEYWORD being processed intends to ignore remaining
+keywords, it must call this function recursively, passing in the
+plist with its keyword and argument removed, and passing in the
+next value for the STATE."
+ (unless (null plist)
+ (let* ((keyword (car plist))
+ (arg (cadr plist))
+ (rest (cddr plist)))
+ (unless (keywordp keyword)
+ (use-package-error (format "%s is not a keyword" keyword)))
+ (let* ((handler (concat "use-package-handler/" (symbol-name keyword)))
+ (handler-sym (intern handler)))
+ (if (functionp handler-sym)
+ (funcall handler-sym name-symbol keyword arg rest state)
+ (use-package-error
+ (format "Keyword handler not defined: %s" handler)))))))
+
+(put 'use-package-process-keywords 'lisp-indent-function 'defun)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :pin
+;;
+
+(defun use-package-only-one (label args f)
+ "Call F on the first member of ARGS if it has exactly one element."
+ (declare (indent 1))
+ (cond
+ ((and (listp args) (listp (cdr args))
+ (= (length args) 1))
+ (funcall f label (car args)))
+ (t
+ (use-package-error
+ (concat label " wants exactly one argument")))))
+
+(put 'use-package-only-one 'lisp-indent-function 'defun)
+
+(defun use-package-normalize/:pin (name-symbol keyword args)
+ (use-package-only-one (symbol-name keyword) args
+ (lambda (label arg)
+ (cond
+ ((stringp arg) arg)
+ ((symbolp arg) (symbol-name arg))
+ (t
+ (use-package-error
+ ":pin wants an archive name (a string)"))))))
+
+(eval-when-compile
+ (defvar package-pinned-packages)
+ (defvar package-archives))
+
+(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-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)
+ (push (cons package archive-name) package-pinned-packages)
+ (error "Archive '%s' requested for package '%s' is not available."
+ archive-name package))
+ (package-initialize t)))
+
+(defun use-package-handler/:pin (name-symbol keyword archive-name rest state)
+ (let ((body (use-package-process-keywords name-symbol rest state)))
+ ;; This happens at macro expansion time, not when the expanded code is
+ ;; compiled or evaluated.
+ (if (null archive-name)
+ body
+ (use-package-pin-package name-symbol archive-name)
+ (use-package-concat
+ body
+ `((push '(,name-symbol . ,archive-name)
+ package-pinned-packages)
+ t)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :ensure
+;;
+
+(defun use-package-normalize/:ensure (name-symbol keyword args)
+ (if (null args)
+ t
+ (use-package-only-one (symbol-name keyword) args
+ (lambda (label arg)
+ (if (symbolp arg)
+ arg
+ (use-package-error
+ (concat ":ensure wants an optional package name "
+ "(an unquoted symbol name)")))))))
(defun use-package-ensure-elpa (package)
(when (not (package-installed-p package))
(package-install package)))
-(defvar use-package-keywords
- '(
- :bind
- :commands
- :config
- :defer
- :defines
- :demand
- :diminish
- :disabled
- :ensure
- :idle
- :idle-priority
- :if
- :init
- :interpreter
- :load-path
- :mode
- :pre-init
- :pre-load
- :requires
- )
- "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)
- "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'."
- (let ((values (use-package-mplist-get plist prop)))
- (when values
- (cond ((not (listp values))
- values)
- ((eq 1 (length values))
- (car values))
- (t (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)))
-
-(defun use-package-plist-get-value (plist prop)
- "Return the value of PROP in PLIST as if it was backquoted."
- (eval (list '\` (use-package-plist-get plist prop))))
+(defun use-package-handler/:ensure (name-symbol keyword ensure rest state)
+ (let ((body (use-package-process-keywords name-symbol rest state)))
+ ;; This happens at macro expansion time, not when the expanded code is
+ ;; compiled or evaluated.
+ (let ((package-name (or (and (eq ensure t) name-symbol) ensure)))
+ (when package-name
+ (require 'package)
+ (use-package-ensure-elpa package-name)))
+ body))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :if, :when and :unless
+;;
+
+(defsubst use-package-normalize-value (label arg)
+ "Normalize a value."
+ (cond ((symbolp arg)
+ `(symbol-value ',arg))
+ ((functionp arg)
+ `(funcall #',arg))
+ (t arg)))
+
+(defun use-package-normalize-test (name-symbol keyword args)
+ (use-package-only-one (symbol-name keyword) args
+ #'use-package-normalize-value))
+
+(defalias 'use-package-normalize/:if 'use-package-normalize-test)
+(defalias 'use-package-normalize/:when 'use-package-normalize-test)
+
+(defun use-package-normalize/:unless (name-symbol keyword args)
+ (not (use-package-only-one (symbol-name keyword) args
+ #'use-package-normalize-value)))
+
+(defun use-package-handler/:if (name-symbol keyword pred rest state)
+ (let ((body (use-package-process-keywords name-symbol rest state)))
+ `((when ,pred ,@body))))
+
+(defalias 'use-package-handler/:when 'use-package-handler/:if)
+
+(defun use-package-handler/:unless (name-symbol keyword pred rest state)
+ (let ((body (use-package-process-keywords name-symbol rest state)))
+ `((unless ,pred ,@body))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :requires
+;;
+
+(defun use-package-as-one (label args f)
+ "Call F on the first element of ARGS if it has one element, or all of ARGS."
+ (declare (indent 1))
+ (if (and (listp args) (listp (cdr args)))
+ (if (= (length args) 1)
+ (funcall f label (car args))
+ (funcall f label args))
+ (use-package-error
+ (concat label " wants a list"))))
+
+(put 'use-package-as-one 'lisp-indent-function 'defun)
+
+(defun use-package-normalize-symbols (label arg &optional recursed)
+ "Normalize a list of symbols."
+ (cond
+ ((symbolp arg)
+ (list arg))
+ ((and (not recursed) (listp arg) (listp (cdr arg)))
+ (mapcar #'(lambda (x) (car (use-package-normalize-symbols label x t))) arg))
+ (t
+ (use-package-error
+ (concat label " wants a symbol, or list of symbols")))))
+
+(defun use-package-normalize-symlist (name-symbol keyword args)
+ (use-package-as-one (symbol-name keyword) args
+ #'use-package-normalize-symbols))
+
+(defalias 'use-package-normalize/:requires 'use-package-normalize-symlist)
+
+(defun use-package-handler/:requires (name-symbol keyword requires rest state)
+ (let ((body (use-package-process-keywords name-symbol rest state)))
+ (if (null requires)
+ body
+ `((when ,(if (listp requires)
+ `(not (member nil (mapcar #'featurep ',requires)))
+ `(featurep ',requires))
+ ,@body)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :load-path
+;;
+
+(defun use-package-normalize-paths (label arg &optional recursed)
+ "Normalize a list of filesystem paths."
+ (cond
+ ((or (symbolp arg) (functionp arg))
+ (let ((value (use-package-normalize-value label arg)))
+ (use-package-normalize-paths label (eval value))))
+ ((stringp arg)
+ (let ((path (if (file-name-absolute-p arg)
+ arg
+ (expand-file-name arg user-emacs-directory))))
+ (list path)))
+ ((and (not recursed) (listp arg) (listp (cdr arg)))
+ (mapcar #'(lambda (x)
+ (car (use-package-normalize-paths label x t))) arg))
+ (t
+ (use-package-error
+ (concat label " wants a directory path, or list of paths")))))
+
+(defun use-package-normalize/:load-path (name-symbol keyword args)
+ (use-package-as-one (symbol-name keyword) args
+ #'use-package-normalize-paths))
+
+(defun use-package-handler/:load-path (name-symbol keyword arg rest state)
+ (let ((body (use-package-process-keywords name-symbol rest state)))
+ (use-package-concat
+ (mapcar #'(lambda (path)
+ `(eval-and-compile (push ,path load-path))) arg)
+ body)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :no-require
+;;
+
+(defun use-package-normalize-predicate (name-symbol keyword args)
+ (if (null args)
+ t
+ (use-package-only-one (symbol-name keyword) args
+ #'use-package-normalize-value)))
+
+(defalias 'use-package-normalize/:no-require 'use-package-normalize-predicate)
+
+(defun use-package-handler/:no-require (name-symbol keyword arg rest state)
+ ;; This keyword has no functional meaning.
+ (use-package-process-keywords name-symbol rest state))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :preface
+;;
+
+(defun use-package-normalize-form (label args)
+ "Given a list of forms, return it wrapped in `progn'."
+ (unless (listp (car args))
+ (use-package-error (concat label " wants a sexp or list of sexps")))
+ (mapcar #'(lambda (form)
+ (if (and (consp form)
+ (eq (car form) 'use-package))
+ (macroexpand form)
+ form)) args))
+
+(defun use-package-normalize-forms (name-symbol keyword args)
+ (use-package-normalize-form (symbol-name keyword) args))
+
+(defalias 'use-package-normalize/:preface 'use-package-normalize-forms)
+
+(defun use-package-handler/:preface (name-symbol keyword arg rest state)
+ (let ((body (use-package-process-keywords name-symbol rest state)))
+ (use-package-concat
+ (unless (null arg)
+ `((eval-and-compile ,@arg)))
+ body)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :bind, :bind*
+;;
+
+(defsubst use-package-is-sympair (x &optional allow-vector)
+ "Return t if X has the type (STRING . SYMBOL)."
+ (and (consp x)
+ (or (stringp (car x))
+ (and allow-vector (vectorp (car x))))
+ (symbolp (cdr x))))
+
+(defun use-package-normalize-pairs
+ (name-symbol label arg &optional recursed allow-vector)
+ "Normalize a list of string/symbol pairs."
+ (cond
+ ((or (stringp arg) (and allow-vector (vectorp arg)))
+ (list (cons arg name-symbol)))
+ ((use-package-is-sympair arg allow-vector)
+ (list arg))
+ ((and (not recursed) (listp arg) (listp (cdr arg)))
+ (mapcar #'(lambda (x) (car (use-package-normalize-pairs
+ name-symbol label x t allow-vector))) arg))
+ (t
+ (use-package-error
+ (concat label " wants a string, (string . symbol) or list of these")))))
+
+(defun use-package-normalize-binder (name-symbol keyword args)
+ (use-package-as-one (symbol-name keyword) args
+ (lambda (label arg)
+ (use-package-normalize-pairs name-symbol label arg nil t))))
+
+(defalias 'use-package-normalize/:bind 'use-package-normalize-binder)
+(defalias 'use-package-normalize/:bind* 'use-package-normalize-binder)
+
+(defun use-package-handler/:bind
+ (name-symbol keyword arg rest state &optional override)
+ (let ((commands (mapcar #'cdr arg)))
+ (use-package-concat
+ (use-package-process-keywords name-symbol
+ (use-package-sort-keywords
+ (use-package-plist-maybe-put rest :defer t))
+ (use-package-plist-append state :commands commands))
+ `((ignore (,(if override 'bind-keys* 'bind-keys) ,@arg))))))
+
+(defun use-package-handler/:bind* (name-symbol keyword arg rest state)
+ (use-package-handler/:bind name-symbol keyword arg rest state t))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :bind-keymap, :bind-keymap*
+;;
+
+(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder)
+(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder)
+
+(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 (not (require package nil t))
+ (use-package-error (format "Could not load package.el: %s" package))
+ (if (and (boundp keymap-symbol)
+ (keymapp (symbol-value keymap-symbol)))
+ (let ((key (key-description (this-command-keys-vector)))
+ (keymap (symbol-value keymap-symbol)))
+ (if override
+ ;; eval form is necessary to avoid compiler error
+ `(eval `(bind-key* ,key ,keymap))
+ (bind-key key keymap))
+ (setq unread-command-events
+ (listify-key-sequence (this-command-keys-vector))))
+ (use-package-error
+ (format "use-package: package.el %s failed to define keymap %s"
+ package keymap-symbol)))))
+
+(defun use-package-handler/:bind-keymap
+ (name-symbol keyword arg rest state &optional override)
+ (let* (commands
+ (form (mapcar
+ #'(lambda (binding)
+ (push (cdr binding) commands)
+ `(,(if override
+ 'bind-key*
+ 'bind-key)
+ ,(car binding)
+ #'(lambda ()
+ (interactive)
+ (use-package-autoload-keymap
+ ',(cdr binding) ',name-symbol nil)))) arg)))
+ (use-package-concat
+ (use-package-process-keywords name-symbol
+ (use-package-sort-keywords
+ (use-package-plist-maybe-put rest :defer t))
+ (use-package-plist-append state :commands commands))
+ `((ignore ,@form)))))
+
+(defun use-package-handler/:bind-keymap* (name-symbol keyword arg rest state)
+ (use-package-handler/:bind-keymap name-symbol keyword arg rest state t))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :interpreter
+;;
+
+(defun use-package-normalize-mode (name-symbol keyword args)
+ (use-package-as-one (symbol-name keyword) args
+ (apply-partially #'use-package-normalize-pairs name-symbol)))
+
+(defalias 'use-package-normalize/:interpreter 'use-package-normalize-mode)
+
+(defun use-package-handler/:interpreter (name-symbol keyword arg rest state)
+ (let* (commands
+ (form (mapcar #'(lambda (interpreter)
+ (push (cdr interpreter) commands)
+ `(push ',interpreter interpreter-mode-alist)) arg)))
+ (use-package-concat
+ (use-package-process-keywords name-symbol
+ (use-package-sort-keywords
+ (use-package-plist-maybe-put rest :defer t))
+ (use-package-plist-append state :commands commands))
+ `((ignore ,@form)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :mode
+;;
+
+(defalias 'use-package-normalize/:mode 'use-package-normalize-mode)
+
+(defun use-package-handler/:mode (name-symbol keyword arg rest state)
+ (let* (commands
+ (form (mapcar #'(lambda (mode)
+ (push (cdr mode) commands)
+ `(push ',mode auto-mode-alist)) arg)))
+ (use-package-concat
+ (use-package-process-keywords name-symbol
+ (use-package-sort-keywords
+ (use-package-plist-maybe-put rest :defer t))
+ (use-package-plist-append state :commands commands))
+ `((ignore ,@form)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :commands
+;;
+
+(defalias 'use-package-normalize/:commands 'use-package-normalize-symlist)
+
+(defun use-package-handler/:commands (name-symbol keyword arg rest state)
+ ;; The actual processing for commands is done in :defer
+ (use-package-process-keywords name-symbol
+ (use-package-sort-keywords
+ (use-package-plist-maybe-put rest :defer t))
+ (use-package-plist-append state :commands arg)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :defines
+;;
+
+(defalias 'use-package-normalize/:defines 'use-package-normalize-symlist)
+
+(defun use-package-handler/:defines (name-symbol keyword arg rest state)
+ (let ((body (use-package-process-keywords name-symbol rest state)))
+ body))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :functions
+;;
+
+(defalias 'use-package-normalize/:functions 'use-package-normalize-symlist)
+
+(defun use-package-handler/:functions (name-symbol keyword arg rest state)
+ (let ((body (use-package-process-keywords name-symbol rest state)))
+ (if (not (bound-and-true-p byte-compile-current-file))
+ body
+ (use-package-concat
+ (unless (null arg)
+ `((eval-when-compile
+ ,@(mapcar
+ #'(lambda (fn)
+ `(declare-function ,fn ,(symbol-name name-symbol))) arg))))
+ body))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :defer
+;;
+
+(defalias 'use-package-normalize/:defer 'use-package-normalize-predicate)
+
+(defun use-package-handler/:defer (name-symbol keyword arg rest state)
+ (let ((body (use-package-process-keywords name-symbol rest
+ (plist-put state :deferred t)))
+ (name-string (symbol-name name-symbol)))
+ (use-package-concat
+ ;; Load the package after a set amount of idle time, if the argument to
+ ;; `:defer' was a number.
+ (when (numberp arg)
+ `((run-with-idle-timer ,arg nil #'require ',name-symbol nil t)))
+
+ ;; Since we deferring load, establish any necessary autoloads, and also
+ ;; keep the byte-compiler happy.
+ (apply
+ #'nconc
+ (mapcar #'(lambda (command)
+ (append
+ `((unless (fboundp ',command)
+ (autoload #',command ,name-string nil t)))
+ (when (bound-and-true-p byte-compile-current-file)
+ `((eval-when-compile
+ (declare-function ,command ,name-string))))))
+ (delete-dups (plist-get state :commands))))
+
+ body)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :demand
+;;
+
+(defalias 'use-package-normalize/:demand 'use-package-normalize-predicate)
+
+(defun use-package-handler/:demand (name-symbol keyword arg rest state)
+ (use-package-process-keywords name-symbol rest
+ (use-package-plist-delete state :deferred)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :init
+;;
+
+(defalias 'use-package-normalize/:init 'use-package-normalize-forms)
+
+(defun use-package-handler/:init (name-symbol keyword arg rest state)
+ (let ((body (use-package-process-keywords name-symbol rest state)))
+ (use-package-concat
+ ;; The user's initializations
+ (use-package-hook-injector (symbol-name name-symbol) :init arg)
+ body)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :config
+;;
+
+(defalias 'use-package-normalize/:config 'use-package-normalize-forms)
+
+(defun use-package-handler/:config (name-symbol keyword arg rest state)
+ (let* ((body (use-package-process-keywords name-symbol rest state))
+ (config-body
+ (if (equal arg '(t))
+ body
+ (use-package--with-elapsed-timer
+ (format "Configuring package %s" name-symbol)
+ (use-package-concat
+ (use-package-hook-injector (symbol-name name-symbol)
+ :config arg)
+ body
+ (list t))))))
+ (if (plist-get state :deferred)
+ (unless (or (null config-body) (equal config-body '(t)))
+ `((eval-after-load ',name-symbol
+ ',(macroexp-progn config-body))))
+ (use-package--with-elapsed-timer
+ (format "Loading package %s" name-symbol)
+ (if use-package-expand-minimally
+ (use-package-concat
+ (list `(require ',name-symbol))
+ config-body)
+ `((if (not (require ',name-symbol nil t))
+ (ignore
+ (message (format "Could not load %s" ',name-symbol)))
+ ,@config-body)))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :diminish
+
+(defun use-package-normalize-diminish (name-symbol label arg &optional recursed)
+ "Normalize the arguments to diminish down to a list of one of two forms:
+ SYMBOL
+ (SYMBOL . STRING)"
+ (cond
+ ((symbolp arg)
+ (list arg))
+ ((stringp arg)
+ (list (cons (intern (concat (symbol-name name-symbol) "-mode")) arg)))
+ ((and (consp arg) (stringp (cdr arg)))
+ (list arg))
+ ((and (not recursed) (listp arg) (listp (cdr arg)))
+ (mapcar #'(lambda (x) (car (use-package-normalize-diminish
+ name-symbol label x t))) arg))
+ (t
+ (use-package-error
+ (concat label " wants a string, symbol, "
+ "(symbol . string) or list of these")))))
+
+(defun use-package-normalize/:diminish (name-symbol keyword args)
+ (use-package-as-one (symbol-name keyword) args
+ (apply-partially #'use-package-normalize-diminish name-symbol)))
+
+(defun use-package-handler/:diminish (name-symbol keyword arg rest state)
+ (let ((body (use-package-process-keywords name-symbol rest state)))
+ (use-package-concat
+ (mapcar #'(lambda (var)
+ `(if (fboundp 'diminish)
+ ,(if (consp var)
+ `(diminish ',(car var) ,(cdr var))
+ `(diminish ',var))))
+ arg)
+ body)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :delight
+;;
+
+(defun use-package-normalize/:delight (name-symbol keyword args)
+ "Normalize arguments to delight."
+ (cond
+ ((and (= (length args) 1)
+ (symbolp (car args)))
+ (list (car args) nil name-symbol))
+ ((and (= (length args) 2)
+ (symbolp (car args)))
+ (list (car args) (cadr args) name-symbol))
+ ((and (= (length args) 3)
+ (symbolp (car args)))
+ args)
+ (t
+ (use-package-error ":delight expects same args as delight function"))))
+
+(defun use-package-handler/:delight (name-symbol keyword args rest state)
+ (let ((body (use-package-process-keywords name-symbol rest state)))
+ (use-package-concat
+ body
+ `((delight (quote ,(nth 0 args)) ,(nth 1 args) (quote ,(nth 2 args))) t))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; The main macro
+;;
(defmacro use-package (name &rest args)
- "Use a package with configuration options.
+ "Declare an Emacs package by specifying a group of configuration options.
-For full documentation. please see commentary.
+For full documentation, please see the README file that came with
+this file. Usage:
(use-package package-name
- :keyword option)
-
-:init Code to run when `use-package' form evals.
-:bind Perform key bindings, and define autoload for bound
- commands.
-: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.
-: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
-: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."
- (use-package-validate-keywords args) ; error if any bad keyword, ignore result
- (let* ((commands (use-package-plist-get args :commands))
- (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-value args :diminish))
- (defines (use-package-plist-get-value args :defines))
- (idle-body (use-package-plist-get args :idle))
- (idle-priority (use-package-plist-get args :idle-priority))
- (keybindings-alist (use-package-plist-get-value args :bind))
- (mode (use-package-plist-get-value args :mode))
- (mode-alist
- (if (stringp mode) (cons mode name) mode))
- (interpreter (use-package-plist-get-value args :interpreter))
- (interpreter-alist
- (if (stringp interpreter) (cons interpreter name) interpreter))
- (predicate (use-package-plist-get args :if))
- (pkg-load-path (use-package-plist-get-value args :load-path))
- (defines-eval (if (null defines)
- nil
- (if (listp defines)
- (mapcar (lambda (var) `(defvar ,var)) defines)
- `((defvar ,defines)))))
- (requires (use-package-plist-get-value args :requires))
- (requires-test (if (null requires)
- t
- (if (listp requires)
- `(not (member nil (mapcar #'featurep
- (quote ,requires))))
- `(featurep (quote ,requires)))))
- (name-string (if (stringp name) name (symbol-name name)))
- (name-symbol (if (stringp name) (intern name) name)))
-
- ;; force this immediately -- one off cost
- (unless (use-package-plist-get args :disabled)
-
- (let* ((ensure (use-package-plist-get args :ensure))
- (package-name
- (or (and (eq ensure t)
- name)
- ensure)))
-
- (when package-name
- (require 'package)
- (use-package-ensure-elpa package-name)))
-
-
- (if diminish-var
- (setq config-body
- `(progn
- ,config-body
- (ignore-errors
- ,@(cond
- ((stringp diminish-var)
- `((diminish (quote ,(intern (concat name-string "-mode")))
- ,diminish-var)))
- ((symbolp diminish-var)
- `((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
- (mapcar (lambda (var)
- (if (listp var)
- `(diminish (quote ,(car var)) ,(cdr var))
- `(diminish (quote ,var))))
- diminish-var)))))))
-
- (if (and commands (symbolp commands))
- (setq commands (list commands)))
-
-
- (when idle-body
- (when (null idle-priority)
- (setq idle-priority 5))
- (setq init-body
- `(progn
- (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 ((cons-list (if (and (consp sym-or-list)
- (stringp (car sym-or-list)))
- (list sym-or-list)
- sym-or-list)))
- (if cons-list
- (setq init-body
- `(progn
- ,init-body
- ,@(mapcar #'(lambda (elem)
- (push (cdr elem) commands)
- (funcall func elem))
- cons-list))))))))
-
- (funcall init-for-commands
- #'(lambda (binding)
- `(bind-key ,(car binding)
- (quote ,(cdr binding))))
- keybindings-alist)
-
- (funcall init-for-commands
- #'(lambda (mode)
- `(add-to-list 'auto-mode-alist
- (quote ,mode)))
- mode-alist)
-
- (funcall init-for-commands
- #'(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))))
- (cond ((stringp pkg-load-path)
- (list pkg-load-path))
- ((functionp pkg-load-path)
- (funcall pkg-load-path))
- (t
- pkg-load-path)))
-
- (eval-when-compile
- (when (bound-and-true-p byte-compile-current-file)
- ,@defines-eval
- ,(if (stringp name)
- `(load ,name t)
- `(require ',name nil t))))
-
- ,(if (and (or commands (use-package-plist-get args :defer))
- (not (use-package-plist-get args :demand)))
- (let (form)
- (mapc #'(lambda (command)
- (push `(autoload (function ,command)
- ,name-string nil t) form))
- commands)
-
- `(when ,(or predicate t)
- ,pre-init-body
- ,@form
- ,init-body
- ,(unless (null 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)
- (use-package-with-elapsed-timer
- ,(format "Loading package %s" name-string)
- (if (not ,(if (stringp name)
- `(load ,name t)
- `(require ',name nil t)))
- (message "Could not load package %s" ,name-string)
- ,pre-init-body
- ,init-body
- ,config-body
- t))))))))
+ [:keyword [option]]...)
-(put 'use-package 'lisp-indent-function 'defun)
+:init Code to run before PACKAGE-NAME has been loaded.
+:config Code to run after PACKAGE-NAME has been loaded. Note that if
+ loading is deferred for any reason, this code does not execute
+ until the lazy load has occurred.
+:preface Code to be run before everything except `:disabled'; this can
+ be used to define functions for use in `:if', or that should be
+ seen by the byte-compiler.
-(defconst use-package-font-lock-keywords
- '(("(\\(use-package\\(?:-with-elapsed-timer\\)?\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?"
- (1 font-lock-keyword-face)
- (2 font-lock-constant-face nil t))))
+:mode Form to be added to `auto-mode-alist'.
+:interpreter Form to be added to `interpreter-mode-alist'.
-(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords)
+:commands Define autoloads for commands that will be defined by the
+ package. This is useful if the package is being lazily loaded,
+ and you wish to conditionally call functions in your `:init'
+ block that are defined in the package.
+
+:bind Bind keys, and define autoloads for the bound commands.
+:bind* Bind keys, and define autoloads for the bound commands,
+ *overriding all minor mode bindings*.
+:bind-keymap Bind a key prefix to an auto-loaded keymap defined in the
+ package. This is like `:bind', but for keymaps.
+:bind-keymap* Like `:bind-keymap', but overrides all minor mode bindings
+
+:defer Defer loading of a package -- this is implied when using
+ `:commands', `:bind', `:bind*', `:mode' or `:interpreter'.
+ This can be an integer, to force loading after N seconds of
+ idle time, if the package has not already been loaded.
+:demand Prevent deferred loading in all cases.
+
+:if EXPR Initialize and load only if EXPR evaluates to a non-nil value.
+:disabled The package is ignored completely if this keyword is present.
+:defines Declare certain variables to silence the byte-compiler.
+:functions Declare certain functions to silence the byte-compiler.
+:load-path Add to the `load-path' before attempting to load the package.
+:diminish Support for diminish.el (if installed).
+:ensure Loads the package using package.el if necessary.
+:pin Pin the package to an archive."
+ (declare (indent 1))
+ (unless (member :disabled args)
+ (let* ((name-symbol (if (stringp name) (intern name) name))
+ (args0 (use-package-plist-maybe-put
+ (use-package-normalize-plist name-symbol args)
+ :config '(t)))
+ (args* (use-package-sort-keywords
+ (if use-package-always-ensure
+ (use-package-plist-maybe-put
+ args0 :ensure use-package-always-ensure)
+ args0))))
+
+ ;; When byte-compiling, pre-load the package so all its symbols are in
+ ;; scope.
+ (if (bound-and-true-p byte-compile-current-file)
+ (setq args*
+ (use-package-plist-cons
+ args* :preface
+ `(eval-when-compile
+ ,@(mapcar #'(lambda (var) `(defvar ,var))
+ (plist-get args* :defines))
+ (with-demoted-errors
+ ,(format "Cannot load %s: %%S" name-symbol)
+ ,(if use-package-verbose
+ `(message "Compiling package %s" ',name-symbol))
+ ,(unless (plist-get args* :no-require)
+ `(require ',name-symbol)))))))
+
+ (let ((body
+ (macroexp-progn
+ (use-package-process-keywords name-symbol args*))))
+ (if use-package-debug
+ (display-buffer
+ (save-current-buffer
+ (let ((buf (get-buffer-create "*use-package*")))
+ (with-current-buffer buf
+ (delete-region (point-min) (point-max))
+ (emacs-lisp-mode)
+ (insert (pp-to-string body)))
+ buf))))
+ body))))
+
+
+(put 'use-package 'lisp-indent-function 'defun)
(provide 'use-package)
+
;; Local Variables:
;; indent-tabs-mode: nil
;; End:
+
;;; use-package.el ends here