summaryrefslogtreecommitdiff
path: root/.emacs.d/initlibs
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2018-04-07 13:05:13 -0700
committerSean Whitton <spwhitton@spwhitton.name>2018-04-07 13:06:15 -0700
commit91fadfaedf04241ff71b512b1bb9b3ebad45b607 (patch)
treed6ef74f28b8bb9e69e5f5d6c008f127dc19dd30a /.emacs.d/initlibs
parent3fe038ceef923df58adaf4e06df7962c078ad03c (diff)
downloaddotfiles-91fadfaedf04241ff71b512b1bb9b3ebad45b607.tar.gz
.emacs.d/{lisp => initlibs}
dirs called 'lisp' has a special meaning in Emacs
Diffstat (limited to '.emacs.d/initlibs')
-rw-r--r--.emacs.d/initlibs/bind-key.el413
-rw-r--r--.emacs.d/initlibs/diminish.el294
-rw-r--r--.emacs.d/initlibs/key-chord.el372
-rw-r--r--.emacs.d/initlibs/let-alist.el170
-rw-r--r--.emacs.d/initlibs/smex.el446
-rw-r--r--.emacs.d/initlibs/use-package.el1194
6 files changed, 2889 insertions, 0 deletions
diff --git a/.emacs.d/initlibs/bind-key.el b/.emacs.d/initlibs/bind-key.el
new file mode 100644
index 00000000..995e4816
--- /dev/null
+++ b/.emacs.d/initlibs/bind-key.el
@@ -0,0 +1,413 @@
+;;; bind-key.el --- A simple way to manage personal keybindings
+
+;; 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
+;; 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.
+
+;;; 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
+;; problem.
+;;
+;; Bind keys as follows in your .emacs:
+;;
+;; (require 'bind-key)
+;;
+;; (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)
+;;
+;; 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)
+;;
+;; 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)
+;;
+;; 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
+;;
+;; (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:
+;;
+;; M-x describe-personal-keybindings
+;;
+;; This display will tell you if you've overriden a default keybinding, and
+;; 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
+ "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
+\\[describe-personal-keybindings]."
+ :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)
+ "override-global-mode keymap")
+
+(define-minor-mode override-global-mode
+ "A minor mode so that keymap settings override other modes."
+ t "")
+
+;; the keymaps in `emulation-mode-map-alists' take precedence over
+;; `minor-mode-map-alist'
+(add-to-list 'emulation-mode-map-alists
+ `((override-global-mode . ,override-global-map)))
+
+(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 predicate)
+ "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.
+
+If PREDICATE is non-nil, it is a form evaluated to determine when
+a key should be bound. It must return non-nil in such cases.
+Emacs can evaluate this form at any time that it does redisplay
+or operates on menu data structures, so you should write it so it
+can safely be called at any time."
+ (let ((namevar (make-symbol "name"))
+ (keyvar (make-symbol "key"))
+ (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)))
+ (add-to-list 'personal-keybindings
+ (list ,kdescvar ,command
+ (unless (numberp ,bindingvar) ,bindingvar)))
+ ,(if predicate
+ `(define-key (or ,keymap global-map) ,keyvar
+ '(menu-item "" nil :filter (lambda (&optional _)
+ (when ,predicate
+ ,command))))
+ `(define-key (or ,keymap global-map) ,keyvar ,command)))))
+
+;;;###autoload
+(defmacro unbind-key (key-name &optional keymap)
+ "Unbind the given KEY-NAME, within the KEYMAP (if specified).
+See `bind-key' for more details."
+ `(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 &optional predicate)
+ "Similar to `bind-key', but overrides any mode-specific bindings."
+ `(bind-key ,key-name ,command override-global-map ,predicate))
+
+(defun bind-keys-form (args)
+ "Bind multiple keys at once.
+
+Accepts keyword arguments:
+:map MAP - a keymap into which the keybindings should be
+ added
+:prefix KEY - prefix key for these bindings
+:prefix-map MAP - name of the prefix map that should be created
+ for these bindings
+:prefix-docstring STR - docstring for the prefix-map variable
+:menu-name NAME - optional menu string for prefix map
+:filter FORM - optional form to determine when bindings apply
+
+The rest of the arguments are conses of keybinding string and a
+function symbol (unquoted)."
+ ;; jww (2016-02-26): This is a hack; this whole function needs to be
+ ;; rewritten to normalize arguments the way that use-package.el does.
+ (if (and (eq (car args) :package)
+ (not (eq (car (cdr (cdr args))) :map)))
+ (setq args (cons :map (cons 'global-map args))))
+ (let* ((map (plist-get args :map))
+ (doc (plist-get args :prefix-docstring))
+ (prefix-map (plist-get args :prefix-map))
+ (prefix (plist-get args :prefix))
+ (filter (plist-get args :filter))
+ (menu-name (plist-get args :menu-name))
+ (pkg (plist-get args :package))
+ (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"))
+ (let ((args key-bindings)
+ saw-map first next)
+ (while args
+ (if (keywordp (car args))
+ (progn
+ (setq next args)
+ (setq args nil))
+ (if first
+ (nconc first (list (car args)))
+ (setq first (list (car args))))
+ (setq args (cdr args))))
+ (cl-flet
+ ((wrap (map bindings)
+ (if (and map pkg (not (eq map 'global-map)))
+ (if (boundp map)
+ bindings
+ `((eval-after-load
+ ,(if (symbolp pkg) `',pkg pkg)
+ '(progn ,@bindings))))
+ bindings)))
+ (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 (and map (not (eq map 'global-map)))
+ (wrap map `((bind-key ,prefix ',prefix-map ,map ,filter)))
+ `((bind-key ,prefix ',prefix-map nil ,filter)))))
+ (wrap map
+ (cl-mapcan
+ (lambda (form)
+ (if prefix-map
+ `((bind-key ,(car form) ',(cdr form) ,prefix-map ,filter))
+ (if (and map (not (eq map 'global-map)))
+ `((bind-key ,(car form) ',(cdr form) ,map ,filter))
+ `((bind-key ,(car form) ',(cdr form) nil ,filter)))))
+ first))
+ (when next
+ (bind-keys-form
+ (if pkg
+ (cons :package (cons pkg next))
+ next))))))))
+
+;;;###autoload
+(defmacro bind-keys (&rest args)
+ "Bind multiple keys at once.
+
+Accepts keyword arguments:
+:map MAP - a keymap into which the keybindings should be
+ added
+:prefix KEY - prefix key for these bindings
+:prefix-map MAP - name of the prefix map that should be created
+ for these bindings
+:prefix-docstring STR - docstring for the prefix-map variable
+:menu-name NAME - optional menu string for prefix map
+:filter FORM - optional form to determine when bindings apply
+
+The rest of the arguments are conses of keybinding string and a
+function symbol (unquoted)."
+ (macroexp-progn (bind-keys-form args)))
+
+;;;###autoload
+(defmacro bind-keys* (&rest args)
+ (macroexp-progn
+ (bind-keys-form `(:map override-global-map ,@args))))
+
+(defun get-binding-description (elem)
+ (cond
+ ((listp elem)
+ (cond
+ ((eq 'lambda (car elem))
+ (if (and bind-key-describe-special-forms
+ (stringp (nth 2 elem)))
+ (nth 2 elem)
+ "#<lambda>"))
+ ((eq 'closure (car elem))
+ (if (and bind-key-describe-special-forms
+ (stringp (nth 3 elem)))
+ (nth 3 elem)
+ "#<closure>"))
+ ((eq 'keymap (car elem))
+ "#<keymap>")
+ (t
+ elem)))
+ ;; must be a symbol, non-symbol keymap case covered above
+ ((and bind-key-describe-special-forms (keymapp elem))
+ (let ((doc (get elem 'variable-documentation)))
+ (if (stringp doc) doc elem)))
+ ((symbolp elem)
+ elem)
+ (t
+ "#<byte-compiled lambda>")))
+
+(defun compare-keybindings (l r)
+ (let* ((regex bind-key-segregation-regexp)
+ (lgroup (and (string-match regex (caar l))
+ (match-string 0 (caar l))))
+ (rgroup (and (string-match regex (caar r))
+ (match-string 0 (caar r))))
+ (lkeymap (cdar l))
+ (rkeymap (cdar r)))
+ (cond
+ ((and (null lkeymap) rkeymap)
+ (cons t t))
+ ((and lkeymap (null rkeymap))
+ (cons nil t))
+ ((and lkeymap rkeymap
+ (not (string= (symbol-name lkeymap) (symbol-name rkeymap))))
+ (cons (string< (symbol-name lkeymap) (symbol-name rkeymap)) t))
+ ((and (null lgroup) rgroup)
+ (cons t t))
+ ((and lgroup (null rgroup))
+ (cons nil t))
+ ((and lgroup rgroup)
+ (if (string= lgroup rgroup)
+ (cons (string< (caar l) (caar r)) nil)
+ (cons (string< lgroup rgroup) t)))
+ (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 (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)) ?-)
+ (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))))))
+
+ (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)) ?-)))
+ (if (and last-binding
+ (cdr (compare-keybindings last-binding binding)))
+ (princ "\n")))
+
+ (let* ((key-name (caar binding))
+ (at-present (lookup-key (or (symbol-value (cdar binding))
+ (current-global-map))
+ (read-kbd-macro key-name)))
+ (command (nth 1 binding))
+ (was-command (nth 2 binding))
+ (command-desc (get-binding-description command))
+ (was-command-desc (and was-command
+ (get-binding-description was-command)))
+ (at-present-desc (get-binding-description at-present))
+ )
+ (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:
+;; indent-tabs-mode: nil
+;; End:
+
+;;; bind-key.el ends here
diff --git a/.emacs.d/initlibs/diminish.el b/.emacs.d/initlibs/diminish.el
new file mode 100644
index 00000000..ae92ea8e
--- /dev/null
+++ b/.emacs.d/initlibs/diminish.el
@@ -0,0 +1,294 @@
+;;; diminish.el --- Diminished modes are minor modes with no modeline display
+
+;; Copyright (C) 1998 Free Software Foundation, Inc.
+
+;; Author: Will Mengarini <seldon@eskimo.com>
+;; URL: <http://www.eskimo.com/~seldon>
+;; Package-Version: 0.44
+;; Created: Th 19 Feb 98
+;; Version: 0.44, Sa 23 Jan 99
+;; Keywords: extensions, diminish, minor, codeprose
+
+;; This file is part of GNU Emacs.
+
+;; 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 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.
+
+;;; Commentary:
+
+;; Minor modes each put a word on the mode line to signify that they're
+;; active. This can cause other displays, such as % of file that point is
+;; at, to run off the right side of the screen. For some minor modes, such
+;; as mouse-avoidance-mode, the display is a waste of space, since users
+;; typically set the mode in their .emacs & never change it. For other
+;; modes, such as my jiggle-mode, it's a waste because there's already a
+;; visual indication of whether the mode is in effect.
+
+;; A diminished mode is a minor mode that has had its mode line
+;; display diminished, usually to nothing, although diminishing to a
+;; shorter word or a single letter is also supported. This package
+;; implements diminished modes.
+
+;; You can use this package either interactively or from your .emacs file.
+;; In either case, first you'll need to copy this file to a directory that
+;; appears in your load-path. `load-path' is the name of a variable that
+;; contains a list of directories Emacs searches for files to load.
+;; To prepend another directory to load-path, put a line like
+;; (add-to-list 'load-path "c:/My_Directory") in your .emacs file.
+
+;; To create diminished modes interactively, type
+;; M-x load-library
+;; to get a prompt like
+;; Load library:
+;; and respond `diminish' (unquoted). Then type
+;; M-x diminish
+;; to get a prompt like
+;; Diminish what minor mode:
+;; and respond with the name of some minor mode, like mouse-avoidance-mode.
+;; You'll then get this prompt:
+;; To what mode-line display:
+;; Respond by just hitting <Enter> if you want the name of the mode
+;; completely removed from the mode line. If you prefer, you can abbreviate
+;; the name. If your abbreviation is 2 characters or more, such as "Av",
+;; it'll be displayed as a separate word on the mode line, just like minor
+;; modes' names. If it's a single character, such as "V", it'll be scrunched
+;; up against the previous word, so for example if the undiminished mode line
+;; display had been "Abbrev Fill Avoid", it would become "Abbrev FillV".
+;; Multiple single-letter diminished modes will all be scrunched together.
+;; The display of undiminished modes will not be affected.
+
+;; To find out what the mode line would look like if all diminished modes
+;; were still minor, type M-x diminished-modes. This displays in the echo
+;; area the complete list of minor or diminished modes now active, but
+;; displays them all as minor. They remain diminished on the mode line.
+
+;; To convert a diminished mode back to a minor mode, type M-x diminish-undo
+;; to get a prompt like
+;; Restore what diminished mode:
+;; Respond with the name of some diminished mode. To convert all
+;; diminished modes back to minor modes, respond to that prompt
+;; with `diminished-modes' (unquoted, & note the hyphen).
+
+;; When you're responding to the prompts for mode names, you can use
+;; completion to avoid extra typing; for example, m o u SPC SPC SPC
+;; is usually enough to specify mouse-avoidance-mode. Mode names
+;; typically end in "-mode", but for historical reasons
+;; auto-fill-mode is named by "auto-fill-function".
+
+;; To create diminished modes noninteractively in your .emacs file, put
+;; code like
+;; (require 'diminish)
+;; (diminish 'abbrev-mode "Abv")
+;; (diminish 'jiggle-mode)
+;; (diminish 'mouse-avoidance-mode "M")
+;; near the end of your .emacs file. It should be near the end so that any
+;; minor modes your .emacs loads will already have been loaded by the time
+;; they're to be converted to diminished modes.
+
+;; To diminish a major mode, (setq mode-name "whatever") in the mode hook.
+
+;;; Epigraph:
+
+;; "The quality of our thoughts is bordered on all sides
+;; by our facility with language."
+;; --J. Michael Straczynski
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+
+(defvar diminish-must-not-copy-minor-mode-alist nil
+ "Non-nil means loading diminish.el won't (copy-alist minor-mode-alist).
+Normally `minor-mode-alist' is setq to that copy on loading diminish because
+at least one of its cons cells, that for abbrev-mode, is read-only (see
+ELisp Info on \"pure storage\"). If you setq this variable to t & then
+try to diminish abbrev-mode under GNU Emacs 19.34, you'll get the error
+message \"Attempt to modify read-only object\".")
+
+(or diminish-must-not-copy-minor-mode-alist
+ (callf copy-alist minor-mode-alist))
+
+(defvar diminished-mode-alist nil
+ "The original `minor-mode-alist' value of all (diminish)ed modes.")
+
+(defvar diminish-history-symbols nil
+ "Command history for symbols of diminished modes.")
+
+(defvar diminish-history-names nil
+ "Command history for names of diminished modes.")
+
+;; When we diminish a mode, we are saying we want it to continue doing its
+;; work for us, but we no longer want to be reminded of it. It becomes a
+;; night worker, like a janitor; it becomes an invisible man; it remains a
+;; component, perhaps an important one, sometimes an indispensable one, of
+;; the mechanism that maintains the day-people's world, but its place in
+;; their thoughts is diminished, usually to nothing. As we grow old we
+;; diminish more and more such thoughts, such people, usually to nothing.
+
+;; "The wise man knows that to keep under is to endure." The diminished
+;; often come to value their invisibility. We speak--speak--of "the strong
+;; silent type", but only as a superficiality; a stereotype in a movie,
+;; perhaps, but even if an acquaintance, necessarily, by hypothesis, a
+;; distant one. The strong silent type is actually a process. It begins
+;; with introspection, continues with judgment, and is shaped by the
+;; discovery that these judgments are impractical to share; there is no
+;; appetite for the wisdom of the self-critical among the creatures of
+;; material appetite who dominate our world. Their dominance's Darwinian
+;; implications reinforce the self-doubt that is the germ of higher wisdom.
+;; The thoughtful contemplate the evolutionary triumph of the predator.
+;; Gnostics deny the cosmos could be so evil; this must all be a prank; the
+;; thoughtful remain silent, invisible, self-diminished, and discover,
+;; perhaps at first in surprise, the freedom they thus gain, and grow strong.
+
+;;;###autoload
+(defun diminish (mode &optional to-what)
+ "Diminish mode-line display of minor mode MODE to TO-WHAT (default \"\").
+
+Interactively, enter (with completion) the name of any minor mode, followed
+on the next line by what you want it diminished to (default empty string).
+The response to neither prompt should be quoted. However, in Lisp code,
+both args must be quoted, the first as a symbol, the second as a string,
+as in (diminish 'jiggle-mode \" Jgl\").
+
+The mode-line displays of minor modes usually begin with a space, so
+the modes' names appear as separate words on the mode line. However, if
+you're having problems with a cramped mode line, you may choose to use single
+letters for some modes, without leading spaces. Capitalizing them works
+best; if you then diminish some mode to \"X\" but have abbrev-mode enabled as
+well, you'll get a display like \"AbbrevX\". This function prepends a space
+to TO-WHAT if it's > 1 char long & doesn't already begin with a space."
+ (interactive (list (read (completing-read
+ "Diminish what minor mode: "
+ (mapcar (lambda (x) (list (symbol-name (car x))))
+ minor-mode-alist)
+ nil t nil 'diminish-history-symbols))
+ (read-from-minibuffer
+ "To what mode-line display: "
+ nil nil nil 'diminish-history-names)))
+ (let ((minor (assq mode minor-mode-alist)))
+ (or minor (error "%S is not currently registered as a minor mode" mode))
+ (callf or to-what "")
+ (when (> (length to-what) 1)
+ (or (= (string-to-char to-what) ?\ )
+ (callf2 concat " " to-what)))
+ (or (assq mode diminished-mode-alist)
+ (push (copy-sequence minor) diminished-mode-alist))
+ (setcdr minor (list to-what))))
+
+;; But an image comes to me, vivid in its unreality, of a loon alone on his
+;; forest lake, shrieking his soul out into a canopy of stars. Alone this
+;; afternoon in my warm city apartment, I can feel the bite of his night air,
+;; and smell his conifers. In him there is no acceptance of diminishment.
+
+;; "I have a benevolent habit of pouring out myself to everybody,
+;; and would even pay for a listener, and I am afraid
+;; that the Athenians may think me too talkative."
+;; --Socrates, in the /Euthyphro/
+
+;; I remember a news story about a retired plumber who had somehow managed to
+;; steal a military tank. He rode it down city streets, rode over a parked
+;; car--no one was hurt--rode onto a freeway, that concrete symbol of the
+;; American spirit, or so we fancy it, shouting "Plumber Bob! Plumber Bob!".
+;; He was shot dead by police.
+
+;;;###autoload
+(defun diminish-undo (mode)
+ "Restore mode-line display of diminished mode MODE to its minor-mode value.
+Do nothing if the arg is a minor mode that hasn't been diminished.
+
+Interactively, enter (with completion) the name of any diminished mode (a
+mode that was formerly a minor mode on which you invoked M-x diminish).
+To restore all diminished modes to minor status, answer `diminished-modes'.
+The response to the prompt shouldn't be quoted. However, in Lisp code,
+the arg must be quoted as a symbol, as in (diminish-undo 'diminished-modes)."
+ (interactive
+ (list (read (completing-read
+ "Restore what diminished mode: "
+ (cons (list "diminished-modes")
+ (mapcar (lambda (x) (list (symbol-name (car x))))
+ diminished-mode-alist))
+ nil t nil 'diminish-history-symbols))))
+ (if (eq mode 'diminished-modes)
+ (let ((diminished-modes diminished-mode-alist))
+ (while diminished-modes
+ (diminish-undo (caar diminished-modes))
+ (callf cdr diminished-modes)))
+ (let ((minor (assq mode minor-mode-alist))
+ (diminished (assq mode diminished-mode-alist)))
+ (or minor
+ (error "%S is not currently registered as a minor mode" mode))
+ (when diminished
+ (setcdr minor (cdr diminished))))))
+
+;; Plumber Bob was not from Seattle, my grey city, for rainy Seattle is a
+;; city of interiors, a city of the self-diminished. When I moved here one
+;; sunny June I was delighted to find that ducks and geese were common in
+;; the streets. But I hoped to find a loon or two, and all I found were
+;; ducks and geese. I wondered about this; I wondered why there were no
+;; loons in Seattle; but my confusion resulted from my ignorance of the
+;; psychology of rain, which is to say my ignorance of diminished modes.
+;; What I needed, and lacked, was a way to discover they were there.
+
+;;;###autoload
+(defun diminished-modes ()
+ "Echo all active diminished or minor modes as if they were minor.
+The display goes in the echo area; if it's too long even for that,
+you can see the whole thing in the *Messages* buffer.
+This doesn't change the status of any modes; it just lets you see
+what diminished modes would be on the mode-line if they were still minor."
+ (interactive)
+ (let ((minor-modes minor-mode-alist)
+ message)
+ (while minor-modes
+ (when (symbol-value (caar minor-modes))
+ ;; This minor mode is active in this buffer
+ (let* ((mode-pair (car minor-modes))
+ (mode (car mode-pair))
+ (minor-pair (or (assq mode diminished-mode-alist) mode-pair))
+ (minor-name (cadr minor-pair)))
+ (when (symbolp minor-name)
+ ;; This minor mode uses symbol indirection in the cdr
+ (let ((symbols-seen (list minor-name)))
+ (while (and (symbolp (callf symbol-value minor-name))
+ (not (memq minor-name symbols-seen)))
+ (push minor-name symbols-seen))))
+ (push minor-name message)))
+ (callf cdr minor-modes))
+ (setq message (mapconcat 'identity (nreverse message) ""))
+ (when (= (string-to-char message) ?\ )
+ (callf substring message 1))
+ (message "%s" message)))
+
+;; A human mind is a Black Forest of diminished modes. Some are dangerous;
+;; most of the mind of an intimate is a secret stranger, and these diminished
+;; modes are rendered more unpredictable by their long isolation from the
+;; corrective influence of interaction with reality. The student of history
+;; learns that this description applies to whole societies as well. In some
+;; ways the self-diminished are better able to discern the night worker.
+;; They are rendered safer by their heightened awareness of others'
+;; diminished modes, and more congenial by the spare blandness of their own
+;; mode lines. To some people rain is truly depressing, but others it just
+;; makes pensive, and, forcing them indoors where they may not have the
+;; luxury of solitude, teaches them to self-diminish. That was what I had
+;; not understood when I was searching for loons among the ducks and geese.
+;; Loons come to Seattle all the time, but the ones that like it learn to be
+;; silent, learn to self-diminish, and take on the colors of ducks and geese.
+;; Now, here a dozen years, I can recognize them everywhere, standing quietly
+;; in line with the ducks and geese at the espresso counter, gazing placidly
+;; out on the world through loon-red eyes, thinking secret thoughts.
+
+(provide 'diminish)
+
+;;; diminish.el ends here
diff --git a/.emacs.d/initlibs/key-chord.el b/.emacs.d/initlibs/key-chord.el
new file mode 100644
index 00000000..b5f65d0e
--- /dev/null
+++ b/.emacs.d/initlibs/key-chord.el
@@ -0,0 +1,372 @@
+;;; key-chord.el --- map pairs of simultaneously pressed keys to commands
+;;-------------------------------------------------------------------
+;;
+;; Copyright (C) 2003,2005,2008,2012 David Andersson
+;;
+;; This file is NOT part of Emacs.
+;;
+;; 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 of
+;; the License, 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 this program; if not, write to the Free
+;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+;; MA 02111-1307 USA
+;;
+;;-------------------------------------------------------------------
+
+;; Author: David Andersson <l.david.andersson(at)sverige.nu>
+;; Created: 27 April 2003
+;; Version: 0.6 (2012-10-23)
+;; Keywords: keyboard chord input
+
+;;; Commentary:
+
+;; ######## Compatibility ########################################
+;;
+;; Works with Emacs-20.3, 20.6, 20.7, 21.2, 21.4, 22.1 and 23.1
+;; Does not work with Emacs-19.31 nor XEmacs-20.4 and 21.4.
+
+;; ######## Quick start ########################################
+;;
+;; Add to your ~/.emacs
+;;
+;; (require 'key-chord)
+;; (key-chord-mode 1)
+;;
+;; and some chords, for example
+;;
+;; (key-chord-define-global "hj" 'undo)
+;; (key-chord-define-global ",." "<>\C-b")
+
+;; ######## Terminology ########################################
+;;
+;; In this package, a "key chord" is two keys pressed simultaneously,
+;; or a single key quickly pressed twice.
+;;
+;; (Sometimes pressing SHIFT and/or META plus another key is call a chord,
+;; but not here. However SHIFT plus two normal keys can be a "key chord".)
+
+;; ######## Description ########################################
+;;
+;; Key chord mode acts like a global minor mode controlled by the function
+;; `key-chord-mode'.
+;;
+;; Key chord definitions are stored in ordinary key-maps.
+;; The function `key-chord-define-global' defines a chord in the global
+;; key-map and `key-chord-define' defines a chord in a specified key-map,
+;; for example for a specific mode.
+;;
+;; A TWO-key chord is two distinct keys pressed simultaneously (within
+;; one tenth of a second, or so).
+;;
+;; Examples:
+;;
+;; (key-chord-define-global ",." "<>\C-b")
+;; (key-chord-define-global "hj" 'undo)
+;; (key-chord-define-global [?h ?j] 'undo) ; the same
+;; (key-chord-define-global "jk" 'dabbrev-expand)
+;; (key-chord-define-global "cv" 'reindent-then-newline-and-indent)
+;; (key-chord-define-global "4r" "$")
+;;
+;; Comma and dot pressed together insert a pair of angle brackets.
+;; `h' and `j' pressed together invoke the undo command.
+;; `j' and `k' pressed together invoke the dabbrev-expand command.
+;; 'c' and 'v' pressed together insert a newline.
+;; `4' and `r' pressed together insert a dollar sign.
+;;
+;; A ONE-key chord is a single key quickly pressed twice (within one third
+;; of a second or so).
+;;
+;; Examples:
+;;
+;; (key-chord-define-global "''" "`'\C-b")
+;; (key-chord-define-global ",," 'indent-for-comment)
+;; (key-chord-define-global "qq" "the ")
+;; (key-chord-define-global "QQ" "The ")
+;;
+;; Tick (') pressed twice inserts a back-tick and a tick (`').
+;; Comma (,) pressed twice indents for and/or inserts a comment.
+;; `q' pressed twice inserts the word "the ".
+;;
+;; Examples: Mode specific chords
+;;
+;; (key-chord-define c++-mode-map ";;" "\C-e;")
+;; (key-chord-define c++-mode-map "{}" "{\n\n}\C-p\t")
+;;
+;; The command `key-chord-describe' lists currently defined key chords.
+;; The standard command `describe-bindings' (C-h b) will also show key chords.
+;;
+;; The standard command `describe-key' (C-h k) will accept a key chord and
+;; show its definition. (Isn't that amazing. There is no explicit code to
+;; carry out this functionality.)
+
+;; ######## Tips ########################################
+;;
+;; Don't chord key combinations that exists in the languages you typically
+;; write. Otherwise, if you are typing fast, two key intended to be separate
+;; letters might instead trig a chord.
+;; E.g. "uu" would be a good chord in spanish but not in finnish, and
+;; "hj" would be a good chord in english but not in swedish.
+;;
+;; Don't rely solely on /usr/dict/words to find unusual combination.
+;; For example "cv" or "fg" can be quite common in certain kinds of
+;; programming. Grep your own texts to verify that a combination is unusual.
+;; And don't forget to check both permutations: "fg" and "gf".
+;;
+;; Choose two keys that are close to each other on the keyboard, so they
+;; can be quickly typed without effort. Chords involving two hands (as
+;; opposed to two fingers on one hand) are harder to type (quickly).
+;; The idea is that key chords are to replace function keys for functions
+;; that are frequently performed while the hands are in writing position.
+;;
+;; Key chords might not work well over a slow network.
+
+;; ######## Limitations ########################################
+;;
+;; When recording keyboard macros, the time between keyboard inputs are not
+;; recorded. Thus, the key-chord-input-method cannot know for sure if two keys
+;; in a macro was a chord or not. The current solution remembers the first key
+;; of the chords typed during macro recording, and keys that match those (and
+;; are defined as chords) are considered key-chords during macro execution.
+;; This knowledge is not saved with `name-last-kbd-macro', so they may
+;; execute wrong if they contain pair of keys that match defined chords.
+;;
+;; Emacs will not call input-method-function for keys that have non numeric
+;; codes or whos code is outside the range 32..126. Thus you cannot define
+;; key chords involving function keys, control keys, or even your non-english
+;; letters (on national keyboards) that otherwise are well positioned for
+;; chording on your keyboard.
+;; (I think chording left and right arrow keys would be useful, but cannot do.
+;; I consider this a bug in Emacs. Input methods could happily return
+;; unmodified *any* key they don't know about.)
+;;
+;; Key chords longer that 2 keys are not supported. It could be done, but I
+;; don't think it is worth the trubbel since most keyboards will not reliably
+;; send all key codes when 3 or more keys are pressed simultaneously.
+;; It might also be a bit trickier to maintain performance.
+;;
+;; Key chord mode uses input-method-function. And so do internationalisation
+;; packages (mule, quail, etc). Do not expect them to work well together.
+;; The last one that gets the input-method-function rules.
+
+;; ######## Implementation ########################################
+;;
+;; Key chords piggy back in ordinary key maps, so they can be defined
+;; per mode without having to add hooks to all modes.
+;;
+;; Key chord key codes are vectors beginning with the atom `key-chord'.
+;; A two key chord, e.g. "hj", will add two entries in the key-map.
+;; E.g. [key-chord ?h ?j] and [key-chord ?j ?h].
+;;
+;; When key-chord-mode is enabled input-method-function is set to
+;; key-chord-input-method.
+
+;; ######## To do ########################################
+;;
+;; * Find a way to save key-chord info in keyboard macros.
+;;
+;; * Save previous value of input-method-function? And call it?
+;;
+;; * input-method-function is reset in *info* buffers! What to do?
+;;
+;; * How to enter interactively command OR string in key-chord-define-global?
+;;
+;; * Customize public vars (defcustom).
+
+;; ######## History ########################################
+;;
+;; 0.6 (2012-10-23) l.david.andersson(at)sverige.nu
+;; Add key-chord-define-local, key-chord-unset-local, key-chord-unset-global
+;; 0.5 (2008-09-15) david(at)symsoft.se
+;; Bugfix sit-for; Improved examples; New E-mail in comment
+;; 0.4 (2005-05-07) david(at)symsoft.se
+;; Slightly better macro heuristics; Added option key-chord-in-macros
+;; 0.3 (2005-04-14) david(at)symsoft.se
+;; Require advice; More examples
+;; 0.2 (2003-09-13) david(at)symsoft.se
+;; Quick and dirty fix for keyboard macros
+;; 0.1 (2003-04-27) david(at)symsoft.se
+;; First release
+
+;;; Code:
+
+(defvar key-chord-two-keys-delay 0.1 ; 0.05 or 0.1
+ "Max time delay between two key press to be considered a key chord.")
+
+(defvar key-chord-one-key-delay 0.2 ; 0.2 or 0.3 to avoid first autorepeat
+ "Max time delay between two press of the same key to be considered a key chord.
+This should normally be a little longer than `key-chord-two-keys-delay'.")
+
+(defvar key-chord-in-macros t
+ "If nil, don't expand key chords when executing keyboard macros.
+If non-nil, expand chord sequenses in macros, but only if a similar chord was
+entered during the last interactive macro recording. (This carries a bit of
+guesswork. We can't know for sure when executing whether two keys were
+typed quickly or slowly when recorded.)")
+
+;; Internal vars
+(defvar key-chord-mode nil)
+
+;; Shortcut for key-chord-input-method: no need to test a key again if it
+;; didn't matched a chord the last time. Improves feedback during autorepeat.
+(defvar key-chord-last-unmatched nil)
+
+;; Macro heuristics: Keep track of which chords was used when the last macro
+;; was defined. Or rather, only the first-char of the chords. Only expand
+;; matching chords during macro execution.
+(defvar key-chord-in-last-kbd-macro nil)
+(defvar key-chord-defining-kbd-macro nil)
+
+;;;###autoload
+(defun key-chord-mode (arg)
+ "Toggle key chord mode.
+With positive ARG enable the mode. With zero or negative arg disable the mode.
+A key chord is two keys that are pressed simultaneously, or one key quickly
+pressed twice.
+\nSee functions `key-chord-define-global', `key-chord-define-local', and
+`key-chord-define' and variables `key-chord-two-keys-delay' and
+`key-chord-one-key-delay'."
+
+ (interactive "P")
+ (setq key-chord-mode (if arg
+ (> (prefix-numeric-value arg) 0)
+ (not key-chord-mode)))
+ (cond (key-chord-mode
+ (setq input-method-function 'key-chord-input-method)
+ (message "Key Chord mode on"))
+ (t
+ (setq input-method-function nil)
+ (message "Key Chord mode off"))))
+
+;;;###autoload
+(defun key-chord-define-global (keys command)
+ "Define a key-chord of the two keys in KEYS starting a COMMAND.
+\nKEYS can be a string or a vector of two elements. Currently only elements
+that corresponds to ascii codes in the range 32 to 126 can be used.
+\nCOMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed.
+\nNote that KEYS defined locally in the current buffer will have precedence."
+ (interactive "sSet key chord globally (2 keys): \nCSet chord \"%s\" to command: ")
+ (key-chord-define (current-global-map) keys command))
+
+;;;###autoload
+(defun key-chord-define-local (keys command)
+ "Locally define a key-chord of the two keys in KEYS starting a COMMAND.
+\nKEYS can be a string or a vector of two elements. Currently only elements
+that corresponds to ascii codes in the range 32 to 126 can be used.
+\nCOMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed.
+\nThe binding goes in the current buffer's local map,
+which in most cases is shared with all other buffers in the same major mode."
+ (interactive "sSet key chord locally (2 keys): \nCSet chord \"%s\" to command: ")
+ (key-chord-define (current-local-map) keys command))
+
+(defun key-chord-unset-global (keys)
+ "Remove global key-chord of the two keys in KEYS."
+ (interactive "sUnset key chord globally (2 keys): ")
+ (key-chord-define (current-local-map) keys nil))
+
+(defun key-chord-unset-local (keys)
+ "Remove local key-chord of the two keys in KEYS."
+ (interactive "sUnset key chord locally (2 keys): ")
+ (key-chord-define (current-local-map) keys nil))
+
+;;;###autoload
+(defun key-chord-define (keymap keys command)
+ "Define in KEYMAP, a key-chord of the two keys in KEYS starting a COMMAND.
+\nKEYS can be a string or a vector of two elements. Currently only elements
+that corresponds to ascii codes in the range 32 to 126 can be used.
+\nCOMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed."
+ (if (/= 2 (length keys))
+ (error "Key-chord keys must have two elements"))
+ ;; Exotic chars in a string are >255 but define-key wants 128..255 for those
+ (let ((key1 (logand 255 (aref keys 0)))
+ (key2 (logand 255 (aref keys 1))))
+ (if (eq key1 key2)
+ (define-key keymap (vector 'key-chord key1 key2) command)
+ ;; else
+ (define-key keymap (vector 'key-chord key1 key2) command)
+ (define-key keymap (vector 'key-chord key2 key1) command))))
+
+(defun key-chord-lookup-key1 (keymap key)
+ "Like lookup-key but no third arg and no numeric return value."
+ (let ((res (lookup-key keymap key)))
+ (if (numberp res)
+ nil
+ ;; else
+ res)))
+
+(defun key-chord-lookup-key (key)
+ "Lookup KEY in all current key maps."
+ (let ((maps (current-minor-mode-maps))
+ res)
+ (while (and maps (not res))
+ (setq res (key-chord-lookup-key1 (car maps) key)
+ maps (cdr maps)))
+ (or res
+ (if (current-local-map)
+ (key-chord-lookup-key1 (current-local-map) key))
+ (key-chord-lookup-key1 (current-global-map) key))))
+
+(defun key-chord-describe ()
+ "List key chord bindings in a help buffer.
+\nTwo key chords will be listed twice and there will be Prefix Commands.
+Please ignore that."
+ (interactive)
+ (describe-bindings [key-chord]))
+
+(defun key-chord-input-method (first-char)
+ "Input method controlled by key bindings with the prefix `key-chord'."
+ (if (and (not (eq first-char key-chord-last-unmatched))
+ (key-chord-lookup-key (vector 'key-chord first-char)))
+ (let ((delay (if (key-chord-lookup-key (vector 'key-chord first-char first-char))
+ key-chord-one-key-delay
+ ;; else
+ key-chord-two-keys-delay)))
+ (if (if executing-kbd-macro
+ (not (memq first-char key-chord-in-last-kbd-macro))
+ (when (bound-and-true-p eldoc-mode)
+ (eldoc-pre-command-refresh-echo-area))
+
+ (sit-for delay 0 'no-redisplay))
+ (progn
+ (setq key-chord-last-unmatched nil)
+ (list first-char))
+ ;; else input-pending-p
+ (let* ((input-method-function nil)
+ (next-char (read-event))
+ (res (vector 'key-chord first-char next-char)))
+ (if (key-chord-lookup-key res)
+ (progn
+ (setq key-chord-defining-kbd-macro
+ (cons first-char key-chord-defining-kbd-macro))
+ (list 'key-chord first-char next-char))
+ ;; else put back next-char and return first-char
+ (setq unread-command-events (cons next-char unread-command-events))
+ (if (eq first-char next-char)
+ (setq key-chord-last-unmatched first-char))
+ (list first-char)))))
+ ;; else no key-chord keymap
+ (setq key-chord-last-unmatched first-char)
+ (list first-char)))
+
+(require 'advice)
+
+(defadvice start-kbd-macro (after key-chord activate)
+ (setq key-chord-defining-kbd-macro nil))
+
+(defadvice end-kbd-macro (after key-chord activate)
+ (setq key-chord-in-last-kbd-macro key-chord-defining-kbd-macro))
+
+(provide 'key-chord)
+
+;;; key-chord.el ends here
diff --git a/.emacs.d/initlibs/let-alist.el b/.emacs.d/initlibs/let-alist.el
new file mode 100644
index 00000000..dbf31e02
--- /dev/null
+++ b/.emacs.d/initlibs/let-alist.el
@@ -0,0 +1,170 @@
+;;; let-alist.el --- Easily let-bind values of an assoc-list by their names -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2014-2015 Free Software Foundation, Inc.
+
+;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
+;; Maintainer: Artur Malabarba <bruce.connor.am@gmail.com>
+;; Version: 1.0.4
+;; Keywords: extensions lisp
+;; Prefix: let-alist
+;; Separator: -
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs 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. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package offers a single macro, `let-alist'. This macro takes a
+;; first argument (whose value must be an alist) and a body.
+;;
+;; The macro expands to a let form containing body, where each dotted
+;; symbol inside body is let-bound to their cdrs in the alist. Dotted
+;; symbol is any symbol starting with a `.'. Only those present in
+;; the body are let-bound and this search is done at compile time.
+;;
+;; For instance, the following code
+;;
+;; (let-alist alist
+;; (if (and .title .body)
+;; .body
+;; .site
+;; .site.contents))
+;;
+;; essentially expands to
+;;
+;; (let ((.title (cdr (assq 'title alist)))
+;; (.body (cdr (assq 'body alist)))
+;; (.site (cdr (assq 'site alist)))
+;; (.site.contents (cdr (assq 'contents (cdr (assq 'site alist))))))
+;; (if (and .title .body)
+;; .body
+;; .site
+;; .site.contents))
+;;
+;; If you nest `let-alist' invocations, the inner one can't access
+;; the variables of the outer one. You can, however, access alists
+;; inside the original alist by using dots inside the symbol, as
+;; displayed in the example above by the `.site.contents'.
+;;
+;;; Code:
+
+
+(defun let-alist--deep-dot-search (data)
+ "Return alist of symbols inside DATA that start with a `.'.
+Perform a deep search and return an alist where each car is the
+symbol, and each cdr is the same symbol without the `.'."
+ (cond
+ ((symbolp data)
+ (let ((name (symbol-name data)))
+ (when (string-match "\\`\\." name)
+ ;; Return the cons cell inside a list, so it can be appended
+ ;; with other results in the clause below.
+ (list (cons data (intern (replace-match "" nil nil name)))))))
+ ((not (consp data)) nil)
+ (t (append (let-alist--deep-dot-search (car data))
+ (let-alist--deep-dot-search (cdr data))))))
+
+(defun let-alist--access-sexp (symbol variable)
+ "Return a sexp used to access SYMBOL inside VARIABLE."
+ (let* ((clean (let-alist--remove-dot symbol))
+ (name (symbol-name clean)))
+ (if (string-match "\\`\\." name)
+ clean
+ (let-alist--list-to-sexp
+ (mapcar #'intern (nreverse (split-string name "\\.")))
+ variable))))
+
+(defun let-alist--list-to-sexp (list var)
+ "Turn symbols LIST into recursive calls to `cdr' `assq' on VAR."
+ `(cdr (assq ',(car list)
+ ,(if (cdr list) (let-alist--list-to-sexp (cdr list) var)
+ var))))
+
+(defun let-alist--remove-dot (symbol)
+ "Return SYMBOL, sans an initial dot."
+ (let ((name (symbol-name symbol)))
+ (if (string-match "\\`\\." name)
+ (intern (replace-match "" nil nil name))
+ symbol)))
+
+
+;;; The actual macro.
+;;;###autoload
+(defmacro let-alist (alist &rest body)
+ "Let-bind dotted symbols to their cdrs in ALIST and execute BODY.
+Dotted symbol is any symbol starting with a `.'. Only those present
+in BODY are let-bound and this search is done at compile time.
+
+For instance, the following code
+
+ (let-alist alist
+ (if (and .title .body)
+ .body
+ .site
+ .site.contents))
+
+essentially expands to
+
+ (let ((.title (cdr (assq 'title alist)))
+ (.body (cdr (assq 'body alist)))
+ (.site (cdr (assq 'site alist)))
+ (.site.contents (cdr (assq 'contents (cdr (assq 'site alist))))))
+ (if (and .title .body)
+ .body
+ .site
+ .site.contents))
+
+If you nest `let-alist' invocations, the inner one can't access
+the variables of the outer one. You can, however, access alists
+inside the original alist by using dots inside the symbol, as
+displayed in the example above."
+ (declare (indent 1) (debug t))
+ (let ((var (make-symbol "alist")))
+ `(let ((,var ,alist))
+ (let ,(mapcar (lambda (x) `(,(car x) ,(let-alist--access-sexp (car x) var)))
+ (delete-dups (let-alist--deep-dot-search body)))
+ ,@body))))
+
+;;;; ChangeLog:
+
+;; 2015-06-11 Artur Malabarba <bruce.connor.am@gmail.com>
+;;
+;; * let-alist (let-alist--deep-dot-search): Fix cons
+;;
+;; 2015-03-07 Artur Malabarba <bruce.connor.am@gmail.com>
+;;
+;; let-alist: Update copyright
+;;
+;; 2014-12-22 Artur Malabarba <bruce.connor.am@gmail.com>
+;;
+;; packages/let-alist: Use `make-symbol' instead of `gensym'.
+;;
+;; 2014-12-20 Artur Malabarba <bruce.connor.am@gmail.com>
+;;
+;; packages/let-alist: Enable access to deeper alists
+;;
+;; 2014-12-14 Artur Malabarba <bruce.connor.am@gmail.com>
+;;
+;; let-alist.el: Add lexical binding. Version bump.
+;;
+;; 2014-12-11 Artur Malabarba <bruce.connor.am@gmail.com>
+;;
+;; let-alist: New package
+;;
+
+
+(provide 'let-alist)
+
+;;; let-alist.el ends here
diff --git a/.emacs.d/initlibs/smex.el b/.emacs.d/initlibs/smex.el
new file mode 100644
index 00000000..36d5b2e4
--- /dev/null
+++ b/.emacs.d/initlibs/smex.el
@@ -0,0 +1,446 @@
+;;; smex.el --- M-x interface with Ido-style fuzzy matching.
+
+;; Copyright (C) 2009-2014 Cornelius Mika and contributors
+;;
+;; Author: Cornelius Mika <cornelius.mika@gmail.com> and contributors
+;; URL: http://github.com/nonsequitur/smex/
+;; Version: 3.0
+;; Keywords: convenience, usability
+
+;; This file is not part of GNU Emacs.
+
+;;; License:
+
+;; Licensed under the same terms as Emacs.
+
+;;; Commentary:
+
+;; Quick start:
+;; run (smex-initialize)
+;;
+;; Bind the following commands:
+;; smex, smex-major-mode-commands
+;;
+;; For a detailed introduction see:
+;; http://github.com/nonsequitur/smex/blob/master/README.markdown
+
+;;; Code:
+
+(require 'ido)
+
+(defgroup smex nil
+ "M-x interface with Ido-style fuzzy matching and ranking heuristics."
+ :group 'extensions
+ :group 'convenience
+ :link '(emacs-library-link :tag "Lisp File" "smex.el"))
+
+(defcustom smex-auto-update t
+ "If non-nil, `Smex' checks for new commands each time it is run.
+Turn it off for minor speed improvements on older systems."
+ :type 'boolean
+ :group 'smex)
+
+(defcustom smex-save-file "~/.smex-items"
+ "File in which the smex state is saved between Emacs sessions.
+Variables stored are: `smex-data', `smex-history'.
+Must be set before initializing Smex."
+ :type 'string
+ :group 'smex)
+
+(defcustom smex-history-length 7
+ "Determines on how many recently executed commands
+Smex should keep a record.
+Must be set before initializing Smex."
+ :type 'integer
+ :group 'smex)
+
+(defcustom smex-prompt-string "M-x "
+ "String to display in the Smex prompt."
+ :type 'string
+ :group 'smex)
+
+(defcustom smex-flex-matching t
+ "Enables Ido flex matching. On by default.
+Set this to nil to disable fuzzy matching."
+ :type 'boolean
+ :group 'smex)
+
+(defvar smex-initialized-p nil)
+(defvar smex-cache)
+(defvar smex-ido-cache)
+(defvar smex-data)
+(defvar smex-history)
+(defvar smex-command-count 0)
+(defvar smex-custom-action nil)
+
+;;--------------------------------------------------------------------------------
+;; Smex Interface
+
+;;;###autoload
+(defun smex ()
+ (interactive)
+ (unless smex-initialized-p
+ (smex-initialize))
+ (if (smex-already-running)
+ (smex-update-and-rerun)
+ (and smex-auto-update
+ (smex-detect-new-commands)
+ (smex-update))
+ (smex-read-and-run smex-ido-cache)))
+
+(defsubst smex-already-running ()
+ (and (boundp 'ido-choice-list) (eql ido-choice-list smex-ido-cache)))
+
+(defsubst smex-update-and-rerun ()
+ (smex-do-with-selected-item
+ (lambda (ignore) (smex-update) (smex-read-and-run smex-ido-cache ido-text))))
+
+(defun smex-read-and-run (commands &optional initial-input)
+ (let* ((chosen-item-name (smex-completing-read commands initial-input))
+ (chosen-item (intern chosen-item-name)))
+ (if smex-custom-action
+ (let ((action smex-custom-action))
+ (setq smex-custom-action nil)
+ (funcall action chosen-item))
+ (unwind-protect
+ (execute-extended-command current-prefix-arg chosen-item-name)
+ (smex-rank chosen-item)))))
+
+(defun smex-major-mode-commands ()
+ "Like `smex', but limited to commands that are relevant to the active major mode."
+ (interactive)
+ (let ((commands (delete-dups (append (smex-extract-commands-from-keymap (current-local-map))
+ (smex-extract-commands-from-features major-mode)))))
+ (setq commands (smex-sort-according-to-cache commands))
+ (setq commands (mapcar #'symbol-name commands))
+ (smex-read-and-run commands)))
+
+(defun smex-completing-read (choices initial-input)
+ (let ((ido-completion-map ido-completion-map)
+ (ido-setup-hook (cons 'smex-prepare-ido-bindings ido-setup-hook))
+ (ido-enable-prefix nil)
+ (ido-enable-flex-matching smex-flex-matching)
+ (ido-max-prospects 10)
+ (minibuffer-completion-table choices))
+ (ido-completing-read (smex-prompt-with-prefix-arg) choices nil nil
+ initial-input 'extended-command-history (car choices))))
+
+(defun smex-prompt-with-prefix-arg ()
+ (if (not current-prefix-arg)
+ smex-prompt-string
+ (concat
+ (if (eq current-prefix-arg '-)
+ "- "
+ (if (integerp current-prefix-arg)
+ (format "%d " current-prefix-arg)
+ (if (= (car current-prefix-arg) 4)
+ "C-u "
+ (format "%d " (car current-prefix-arg)))))
+ smex-prompt-string)))
+
+(defun smex-prepare-ido-bindings ()
+ (define-key ido-completion-map (kbd "TAB") 'minibuffer-complete)
+ (define-key ido-completion-map (kbd "C-h f") 'smex-describe-function)
+ (define-key ido-completion-map (kbd "C-h w") 'smex-where-is)
+ (define-key ido-completion-map (kbd "M-.") 'smex-find-function)
+ (define-key ido-completion-map (kbd "C-a") 'move-beginning-of-line))
+
+;;--------------------------------------------------------------------------------
+;; Cache and Maintenance
+
+(defun smex-rebuild-cache ()
+ (interactive)
+ (setq smex-cache nil)
+
+ ;; Build up list 'new-commands' and later put it at the end of 'smex-cache'.
+ ;; This speeds up sorting.
+ (let (new-commands)
+ (mapatoms (lambda (symbol)
+ (when (commandp symbol)
+ (let ((known-command (assq symbol smex-data)))
+ (if known-command
+ (setq smex-cache (cons known-command smex-cache))
+ (setq new-commands (cons (list symbol) new-commands)))))))
+ (if (eq (length smex-cache) 0)
+ (setq smex-cache new-commands)
+ (setcdr (last smex-cache) new-commands)))
+
+ (setq smex-cache (sort smex-cache 'smex-sorting-rules))
+ (smex-restore-history)
+ (setq smex-ido-cache (smex-convert-for-ido smex-cache)))
+
+(defun smex-convert-for-ido (command-items)
+ (mapcar (lambda (command-item) (symbol-name (car command-item))) command-items))
+
+(defun smex-restore-history ()
+ "Rearranges `smex-cache' according to `smex-history'"
+ (if (> (length smex-history) smex-history-length)
+ (setcdr (nthcdr (- smex-history-length 1) smex-history) nil))
+ (mapc (lambda (command)
+ (unless (eq command (caar smex-cache))
+ (let ((command-cell-position (smex-detect-position smex-cache (lambda (cell)
+ (eq command (caar cell))))))
+ (if command-cell-position
+ (let ((command-cell (smex-remove-nth-cell command-cell-position smex-cache)))
+ (setcdr command-cell smex-cache)
+ (setq smex-cache command-cell))))))
+ (reverse smex-history)))
+
+(defun smex-sort-according-to-cache (list)
+ "Sorts a list of commands by their order in `smex-cache'"
+ (let (sorted)
+ (dolist (command-item smex-cache)
+ (let ((command (car command-item)))
+ (when (memq command list)
+ (setq sorted (cons command sorted))
+ (setq list (delq command list)))))
+ (nreverse (append list sorted))))
+
+(defun smex-update ()
+ (interactive)
+ (smex-save-history)
+ (smex-rebuild-cache))
+
+(defun smex-detect-new-commands ()
+ (let ((i 0))
+ (mapatoms (lambda (symbol) (if (commandp symbol) (setq i (1+ i)))))
+ (unless (= i smex-command-count)
+ (setq smex-command-count i))))
+
+(defun smex-auto-update (&optional idle-time)
+ "Update Smex when Emacs has been idle for IDLE-TIME."
+ (unless idle-time (setq idle-time 60))
+ (run-with-idle-timer idle-time t
+ '(lambda () (if (smex-detect-new-commands) (smex-update)))))
+
+;;;###autoload
+(defun smex-initialize ()
+ (interactive)
+ (unless ido-mode (smex-initialize-ido))
+ (smex-load-save-file)
+ (smex-detect-new-commands)
+ (smex-rebuild-cache)
+ (add-hook 'kill-emacs-hook 'smex-save-to-file)
+ (setq smex-initialized-p t))
+
+(defun smex-initialize-ido ()
+ "Sets up a minimal Ido environment for `ido-completing-read'."
+ (ido-init-completion-maps)
+ (add-hook 'minibuffer-setup-hook 'ido-minibuffer-setup))
+
+(defun smex-load-save-file ()
+ "Loads `smex-history' and `smex-data' from `smex-save-file'"
+ (let ((save-file (expand-file-name smex-save-file)))
+ (if (file-readable-p save-file)
+ (with-temp-buffer
+ (insert-file-contents save-file)
+ (condition-case nil
+ (setq smex-history (read (current-buffer))
+ smex-data (read (current-buffer)))
+ (error (if (smex-save-file-not-empty-p)
+ (error "Invalid data in smex-save-file (%s). Can't restore history."
+ smex-save-file)
+ (if (not (boundp 'smex-history)) (setq smex-history))
+ (if (not (boundp 'smex-data)) (setq smex-data))))))
+ (setq smex-history nil smex-data nil))))
+
+(defsubst smex-save-file-not-empty-p ()
+ (string-match-p "\[^[:space:]\]" (buffer-string)))
+
+(defun smex-save-history ()
+ "Updates `smex-history'"
+ (setq smex-history nil)
+ (let ((cell smex-cache))
+ (dotimes (i smex-history-length)
+ (setq smex-history (cons (caar cell) smex-history))
+ (setq cell (cdr cell))))
+ (setq smex-history (nreverse smex-history)))
+
+(defun smex-save-to-file ()
+ (interactive)
+ (smex-save-history)
+ (with-temp-file (expand-file-name smex-save-file)
+ (ido-pp 'smex-history)
+ (ido-pp 'smex-data)))
+
+;;--------------------------------------------------------------------------------
+;; Ranking
+
+(defun smex-sorting-rules (command-item other-command-item)
+ "Returns true if COMMAND-ITEM should sort before OTHER-COMMAND-ITEM."
+ (let* ((count (or (cdr command-item ) 0))
+ (other-count (or (cdr other-command-item) 0))
+ (name (car command-item))
+ (other-name (car other-command-item))
+ (length (length (symbol-name name)))
+ (other-length (length (symbol-name other-name))))
+ (or (> count other-count) ; 1. Frequency of use
+ (and (= count other-count)
+ (or (< length other-length) ; 2. Command length
+ (and (= length other-length)
+ (string< name other-name))))))) ; 3. Alphabetical order
+
+(defun smex-rank (command)
+ (let ((command-item (or (assq command smex-cache)
+ ;; Update caches and try again if not found.
+ (progn (smex-update)
+ (assq command smex-cache)))))
+ (when command-item
+ (smex-update-counter command-item)
+
+ ;; Don't touch the cache order if the chosen command
+ ;; has just been execucted previously.
+ (unless (eq command-item (car smex-cache))
+ (let (command-cell
+ (pos (smex-detect-position smex-cache (lambda (cell)
+ (eq command-item (car cell))))))
+ ;; Remove the just executed command.
+ (setq command-cell (smex-remove-nth-cell pos smex-cache))
+ ;; And put it on top of the cache.
+ (setcdr command-cell smex-cache)
+ (setq smex-cache command-cell)
+
+ ;; Repeat the same for the ido cache. Should this be DRYed?
+ (setq command-cell (smex-remove-nth-cell pos smex-ido-cache))
+ (setcdr command-cell smex-ido-cache)
+ (setq smex-ido-cache command-cell)
+
+ ;; Now put the last history item back to its normal place.
+ (smex-sort-item-at smex-history-length))))))
+
+(defun smex-update-counter (command-item)
+ (let ((count (cdr command-item)))
+ (setcdr command-item
+ (if count
+ (1+ count)
+ ;; Else: Command has just been executed for the first time.
+ ;; Add it to `smex-data'.
+ (if smex-data
+ (setcdr (last smex-data) (list command-item))
+ (setq smex-data (list command-item)))
+ 1))))
+
+(defun smex-sort-item-at (n)
+ "Sorts item at position N in `smex-cache'."
+ (let* ((command-cell (nthcdr n smex-cache))
+ (command-item (car command-cell))
+ (command-count (cdr command-item)))
+ (let ((insert-at (smex-detect-position command-cell (lambda (cell)
+ (smex-sorting-rules command-item (car cell))))))
+ ;; TODO: Should we handle the case of 'insert-at' being nil?
+ ;; This will never happen in practice.
+ (when (> insert-at 1)
+ (setq command-cell (smex-remove-nth-cell n smex-cache))
+ ;; smex-cache just got shorter by one element, so subtract '1' from insert-at.
+ (setq insert-at (+ n (- insert-at 1)))
+ (smex-insert-cell command-cell insert-at smex-cache)
+
+ ;; Repeat the same for the ido cache. DRY?
+ (setq command-cell (smex-remove-nth-cell n smex-ido-cache))
+ (smex-insert-cell command-cell insert-at smex-ido-cache)))))
+
+(defun smex-detect-position (cell function)
+ "Detects, relatively to CELL, the position of the cell
+on which FUNCTION returns true.
+Only checks cells after CELL, starting with the cell right after CELL.
+Returns nil when reaching the end of the list."
+ (let ((pos 1))
+ (catch 'break
+ (while t
+ (setq cell (cdr cell))
+ (if (not cell)
+ (throw 'break nil)
+ (if (funcall function cell) (throw 'break pos))
+ (setq pos (1+ pos)))))))
+
+(defun smex-remove-nth-cell (n list)
+ "Removes and returns the Nth cell in LIST."
+ (let* ((previous-cell (nthcdr (- n 1) list))
+ (result (cdr previous-cell)))
+ (setcdr previous-cell (cdr result))
+ result))
+
+(defun smex-insert-cell (new-cell n list)
+ "Inserts cell at position N in LIST."
+ (let* ((cell (nthcdr (- n 1) list))
+ (next-cell (cdr cell)))
+ (setcdr (setcdr cell new-cell) next-cell)))
+
+;;--------------------------------------------------------------------------------
+;; Help and Reference
+
+(defun smex-do-with-selected-item (fn)
+ (setq smex-custom-action fn)
+ (ido-exit-minibuffer))
+
+(defun smex-describe-function ()
+ (interactive)
+ (smex-do-with-selected-item (lambda (chosen)
+ (describe-function chosen)
+ (pop-to-buffer "*Help*"))))
+
+(defun smex-where-is ()
+ (interactive)
+ (smex-do-with-selected-item 'where-is))
+
+(defun smex-find-function ()
+ (interactive)
+ (smex-do-with-selected-item 'find-function))
+
+(defun smex-extract-commands-from-keymap (map)
+ (let (commands)
+ (smex-parse-keymap map commands)
+ commands))
+
+(defun smex-parse-keymap (map commands)
+ (map-keymap (lambda (binding element)
+ (if (and (listp element) (eq 'keymap (car element)))
+ (smex-parse-keymap element commands)
+ ; Strings are commands, too. Reject them.
+ (if (and (symbolp element) (commandp element))
+ (push element commands))))
+ map))
+
+(defun smex-extract-commands-from-features (mode)
+ (let ((library-path (symbol-file mode))
+ (mode-name (symbol-name mode))
+ commands)
+
+ (string-match "\\(.+?\\)\\(-mode\\)?$" mode-name)
+ ;; 'lisp-mode' -> 'lisp'
+ (setq mode-name (match-string 1 mode-name))
+ (if (string= mode-name "c") (setq mode-name "cc"))
+ (setq mode-name (regexp-quote mode-name))
+
+ (dolist (feature load-history)
+ (let ((feature-path (car feature)))
+ (when (and feature-path (or (equal feature-path library-path)
+ (string-match mode-name (file-name-nondirectory
+ feature-path))))
+ (dolist (item (cdr feature))
+ (if (and (listp item) (eq 'defun (car item)))
+ (let ((function (cdr item)))
+ (when (commandp function)
+ (setq commands (append commands (list function))))))))))
+ commands))
+
+(defun smex-show-unbound-commands ()
+ "Shows unbound commands in a new buffer,
+sorted by frequency of use."
+ (interactive)
+ (setq smex-data (sort smex-data 'smex-sorting-rules))
+ (let ((unbound-commands (delq nil
+ (mapcar (lambda (command-item)
+ (unless (where-is-internal (car command-item))
+ command-item))
+ smex-data))))
+ (view-buffer-other-window "*Smex: Unbound Commands*")
+ (setq buffer-read-only t)
+ (let ((inhibit-read-only t))
+ (erase-buffer)
+ (ido-pp 'unbound-commands))
+ (set-buffer-modified-p nil)
+ (goto-char (point-min))))
+
+(provide 'smex)
+;;; smex.el ends here
diff --git a/.emacs.d/initlibs/use-package.el b/.emacs.d/initlibs/use-package.el
new file mode 100644
index 00000000..4928ece0
--- /dev/null
+++ b/.emacs.d/initlibs/use-package.el
@@ -0,0 +1,1194 @@
+;;; use-package.el --- A use-package declaration for simplifying your .emacs
+
+;; Copyright (C) 2012 John Wiegley
+
+;; Author: John Wiegley <jwiegley@gmail.com>
+;; Maintainer: John Wiegley <jwiegley@gmail.com>
+;; Created: 17 Jun 2012
+;; Modified: 17 Oct 2016
+;; Version: 2.3
+;; Package-Requires: ((bind-key "1.0") (diminish "0.44"))
+;; Keywords: dotemacs startup speed config 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
+;; 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.
+
+;;; Commentary:
+
+;; The `use-package' declaration macro allows you to isolate package
+;; configuration in your ".emacs" in a way that is performance-oriented and,
+;; well, just tidy. I created it because I have over 80 packages that I use
+;; in Emacs, and things were getting difficult to manage. Yet with this
+;; utility my total load time is just under 1 second, with no loss of
+;; 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))
+(eval-when-compile (require 'regexp-opt))
+
+(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.
+
+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 '(choice (const :tag "Quiet" nil) (const :tag "Verbose" t)
+ (const :tag "Debug" debug))
+ :group 'use-package)
+
+(defcustom use-package-debug nil
+ "Whether to display use-package expansions in a *use-package* buffer."
+ :type 'boolean
+ :group 'use-package)
+
+(defcustom use-package-check-before-init nil
+ "If non-nil, check that package exists before executing its `:init' block.
+The check is performed by looking for the module using `locate-library'."
+ :type 'boolean
+ :group 'use-package)
+
+(defcustom use-package-always-defer nil
+ "If non-nil, assume `:defer t` unless `:demand t` is given."
+ :type 'boolean
+ :group 'use-package)
+
+(defcustom use-package-always-ensure nil
+ "Treat every package as though it had specified `:ensure SEXP`."
+ :type 'sexp
+ :group 'use-package)
+
+(defcustom use-package-always-pin nil
+ "Treat every package as though it had specified `:pin SYM."
+ :type 'symbol
+ :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)
+
+(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
+ :init
+ :after
+ :demand
+ :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)
+
+(defcustom use-package-enable-imenu-support nil
+ "If non-nil, adjust `lisp-imenu-generic-expression' to include
+support for finding `use-package' and `require' forms.
+
+Must be set before loading use-package."
+ :type 'boolean
+ :group 'use-package)
+
+(when use-package-enable-imenu-support
+ ;; Not defined in Emacs 24
+ (defvar lisp-mode-symbol-regexp
+ "\\(?:\\sw\\|\\s_\\|\\\\.\\)+")
+ (add-to-list
+ 'lisp-imenu-generic-expression
+ (list "Package"
+ (purecopy (concat "^\\s-*("
+ (eval-when-compile
+ (regexp-opt
+ '("use-package" "require")
+ t))
+ "\\s-+\\(" lisp-mode-symbol-regexp "\\)"))
+ 2)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Utility functions
+;;
+
+(defun use-package-as-symbol (string-or-symbol)
+ "If STRING-OR-SYMBOL is already a symbol, return it. Otherwise
+convert it to a symbol and return that."
+ (if (symbolp string-or-symbol) string-or-symbol
+ (intern string-or-symbol)))
+
+(defun use-package-as-string (string-or-symbol)
+ "If STRING-OR-SYMBOL is already a string, return it. Otherwise
+convert it to a string and return that."
+ (if (stringp string-or-symbol) string-or-symbol
+ (symbol-name string-or-symbol)))
+
+(defun use-package-load-name (name &optional noerror)
+ "Return a form which will load or require NAME depending on
+whether it's a string or symbol."
+ (if (stringp name)
+ `(load ,name ',noerror)
+ `(require ',name nil ',noerror)))
+
+(defun use-package-expand (name label form)
+ "FORM is a list of forms, so `((foo))' if only `foo' is being called."
+ (declare (indent 1))
+ (when form
+ (if use-package-expand-minimally
+ form
+ (let ((err (make-symbol "err")))
+ (list
+ `(condition-case-unless-debug ,err
+ ,(macroexp-progn form)
+ (error
+ (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 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 tail))
+ ((functionp normalizer)
+ (funcall normalizer name keyword args))
+ ((= (length args) 1)
+ (car args))
+ (t
+ args))))
+ (if (memq keyword use-package-keywords)
+ (cons keyword
+ (cons arg (use-package-normalize-plist name tail)))
+ (use-package-error (format "Unrecognized keyword: %s" keyword))))))
+
+(defun use-package-process-keywords (name 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."
+ (declare (indent 1))
+ (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 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 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)
+ (add-to-list 'package-pinned-packages (cons package archive-name))
+ (error "Archive '%s' requested for package '%s' is not available."
+ archive-name package))
+ (unless (bound-and-true-p package--initialized)
+ (package-initialize t))))
+
+(defun use-package-handler/:pin (name keyword archive-name rest state)
+ (let ((body (use-package-process-keywords name rest state))
+ (pin-form (if archive-name
+ `(use-package-pin-package ',(use-package-as-symbol name)
+ ,archive-name))))
+ ;; Pinning should occur just before ensuring
+ ;; See `use-package-handler/:ensure'.
+ (if (bound-and-true-p byte-compile-current-file)
+ (eval pin-form) ; Eval when byte-compiling,
+ (push pin-form body)) ; or else wait until runtime.
+ body))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :ensure
+;;
+(defvar package-archive-contents)
+(defun use-package-normalize/:ensure (name 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 &optional no-refresh)
+ (if (package-installed-p package)
+ t
+ (if (and (not no-refresh)
+ (assoc package (bound-and-true-p package-pinned-packages)))
+ (package-read-all-archive-contents))
+ (if (or (assoc package package-archive-contents) no-refresh)
+ (package-install package)
+ (progn
+ (package-refresh-contents)
+ (use-package-ensure-elpa package t)))))
+
+(defun use-package-handler/:ensure (name keyword ensure rest state)
+ (let* ((body (use-package-process-keywords name rest state))
+ (package-name (or (and (eq ensure t) (use-package-as-symbol name)) ensure))
+ (ensure-form (if package-name
+ `(progn (require 'package)
+ (use-package-ensure-elpa ',package-name)))))
+ ;; We want to avoid installing packages when the `use-package'
+ ;; macro is being macro-expanded by elisp completion (see
+ ;; `lisp--local-variables'), but still do install packages when
+ ;; byte-compiling to avoid requiring `package' at runtime.
+ (if (bound-and-true-p byte-compile-current-file)
+ (eval ensure-form) ; Eval when byte-compiling,
+ (push ensure-form body)) ; or else wait until runtime.
+ 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 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)
+(defalias 'use-package-normalize/:unless 'use-package-normalize-test)
+
+(defun use-package-handler/:if (name keyword pred rest state)
+ (let ((body (use-package-process-keywords name rest state)))
+ `((when ,pred ,@body))))
+
+(defalias 'use-package-handler/:when 'use-package-handler/:if)
+
+(defun use-package-handler/:unless (name keyword pred rest state)
+ (let ((body (use-package-process-keywords name 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 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 keyword requires rest state)
+ (let ((body (use-package-process-keywords name 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
+ ((and arg (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 keyword args)
+ (use-package-as-one (symbol-name keyword) args
+ #'use-package-normalize-paths))
+
+(defun use-package-handler/:load-path (name keyword arg rest state)
+ (let ((body (use-package-process-keywords name rest state)))
+ (use-package-concat
+ (mapcar #'(lambda (path)
+ `(eval-and-compile (add-to-list 'load-path ,path))) arg)
+ body)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :no-require
+;;
+
+(defun use-package-normalize-predicate (name 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 keyword arg rest state)
+ ;; This keyword has no functional meaning.
+ (use-package-process-keywords name 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 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 keyword arg rest state)
+ (let ((body (use-package-process-keywords name 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))))
+
+(defsubst use-package-is-string-pair (x)
+ "Return t if X has the type (STRING . STRING)."
+ (and (consp x)
+ (stringp (car x))
+ (stringp (cdr x))))
+
+(defun use-package-normalize-pairs
+ (name label arg &optional recursed allow-vector allow-string-cdrs)
+ "Normalize a list of string/symbol pairs.
+If RECURSED is non-nil, recurse into sublists.
+If ALLOW-VECTOR is non-nil, then the key to bind may specify a
+vector of keys, as accepted by `define-key'.
+If ALLOW-STRING-CDRS is non-nil, then the command name to bind to
+may also be a string, as accepted by `define-key'."
+ (cond
+ ((or (stringp arg) (and allow-vector (vectorp arg)))
+ (list (cons arg (use-package-as-symbol name))))
+ ((use-package-is-sympair arg allow-vector)
+ (list arg))
+ ((and (not recursed) (listp arg) (listp (cdr arg)))
+ (mapcar #'(lambda (x)
+ (let ((ret (use-package-normalize-pairs
+ name label x t allow-vector allow-string-cdrs)))
+ (if (listp ret)
+ (car ret)
+ ret))) arg))
+ ((and allow-string-cdrs (use-package-is-string-pair arg))
+ (list arg))
+ (t arg)))
+
+(defun use-package-normalize-binder (name keyword args)
+ (use-package-as-one (symbol-name keyword) args
+ (lambda (label arg)
+ (use-package-normalize-pairs name label arg nil t 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 keyword arg rest state &optional bind-macro)
+ (let ((commands (remq nil (mapcar #'(lambda (arg)
+ (if (listp arg)
+ (cdr arg)
+ nil)) arg))))
+ (use-package-concat
+ (use-package-process-keywords name
+ (use-package-sort-keywords
+ (use-package-plist-maybe-put rest :defer t))
+ (use-package-plist-append state :commands commands))
+ `((ignore
+ ,(macroexpand
+ `(,(if bind-macro bind-macro 'bind-keys)
+ :package ,name ,@arg)))))))
+
+(defun use-package-handler/:bind* (name keyword arg rest state)
+ (use-package-handler/:bind name keyword arg rest state 'bind-keys*))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :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 "Cannot load package.el: %s" package))
+ (if (and (boundp keymap-symbol)
+ (keymapp (symbol-value keymap-symbol)))
+ (let* ((kv (this-command-keys-vector))
+ (key (key-description kv))
+ (keymap (symbol-value keymap-symbol)))
+ (if override
+ (bind-key* key keymap)
+ (bind-key key keymap))
+ (setq unread-command-events
+ (listify-key-sequence kv)))
+ (use-package-error
+ (format "use-package: package.el %s failed to define keymap %s"
+ package keymap-symbol)))))
+
+(defun use-package-handler/:bind-keymap
+ (name keyword arg rest state &optional override)
+ (let ((form (mapcar
+ #'(lambda (binding)
+ `(,(if override
+ 'bind-key*
+ 'bind-key)
+ ,(car binding)
+ #'(lambda ()
+ (interactive)
+ (use-package-autoload-keymap
+ ',(cdr binding) ',(use-package-as-symbol name) ,override)))) arg)))
+ (use-package-concat
+ (use-package-process-keywords name
+ (use-package-sort-keywords
+ (use-package-plist-maybe-put rest :defer t))
+ state)
+ `((ignore ,@form)))))
+
+(defun use-package-handler/:bind-keymap* (name keyword arg rest state)
+ (use-package-handler/:bind-keymap name keyword arg rest state t))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :interpreter
+;;
+
+(defun use-package-normalize-mode (name keyword args)
+ (use-package-as-one (symbol-name keyword) args
+ (apply-partially #'use-package-normalize-pairs name)))
+
+(defalias 'use-package-normalize/:interpreter 'use-package-normalize-mode)
+
+(defun use-package-handler/:interpreter (name keyword arg rest state)
+ (let* (commands
+ (form (mapcar #'(lambda (interpreter)
+ (push (cdr interpreter) commands)
+ `(add-to-list 'interpreter-mode-alist ',interpreter)) arg)))
+ (use-package-concat
+ (use-package-process-keywords name
+ (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 keyword arg rest state)
+ (let* (commands
+ (form (mapcar #'(lambda (mode)
+ (push (cdr mode) commands)
+ `(add-to-list 'auto-mode-alist ',mode)) arg)))
+ (use-package-concat
+ (use-package-process-keywords name
+ (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 keyword arg rest state)
+ ;; The actual processing for commands is done in :defer
+ (use-package-process-keywords name
+ (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 keyword arg rest state)
+ (let ((body (use-package-process-keywords name rest state)))
+ body))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :functions
+;;
+
+(defalias 'use-package-normalize/:functions 'use-package-normalize-symlist)
+
+(defun use-package-handler/:functions (name keyword arg rest state)
+ (let ((body (use-package-process-keywords name 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 ,(use-package-as-string name))) arg))))
+ body))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :defer
+;;
+
+(defalias 'use-package-normalize/:defer 'use-package-normalize-predicate)
+
+(defun use-package-handler/:defer (name keyword arg rest state)
+ (let ((body (use-package-process-keywords name rest
+ (plist-put state :deferred t)))
+ (name-string (use-package-as-string name)))
+ (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 ',(use-package-as-symbol name) nil t)))
+
+ ;; Since we deferring load, establish any necessary autoloads, and also
+ ;; keep the byte-compiler happy.
+ (apply
+ #'nconc
+ (mapcar #'(lambda (command)
+ (when (not (stringp 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)))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :after
+;;
+
+(defalias 'use-package-normalize/:after 'use-package-normalize-symlist)
+
+(defun use-package-require-after-load (features name)
+ "Return form for after any of FEATURES require NAME."
+ `(progn
+ ,@(mapcar
+ (lambda (feat)
+ `(eval-after-load
+ (quote ,feat)
+ (quote (require (quote ,name) nil t))))
+ features)))
+
+(defun use-package-handler/:after (name keyword arg rest state)
+ (let ((body (use-package-process-keywords name rest
+ (plist-put state :deferred t)))
+ (name-string (use-package-as-string name)))
+ (use-package-concat
+ (when arg
+ (list (use-package-require-after-load arg name)))
+ body)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :demand
+;;
+
+(defalias 'use-package-normalize/:demand 'use-package-normalize-predicate)
+
+(defun use-package-handler/:demand (name keyword arg rest state)
+ (use-package-process-keywords name rest
+ (use-package-plist-delete state :deferred)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :init
+;;
+
+(defalias 'use-package-normalize/:init 'use-package-normalize-forms)
+
+(defun use-package-handler/:init (name keyword arg rest state)
+ (let ((body (use-package-process-keywords name rest state)))
+ (use-package-concat
+ ;; The user's initializations
+ (let ((init-body
+ (use-package-hook-injector (use-package-as-string name)
+ :init arg)))
+ (if use-package-check-before-init
+ `((if (locate-library ,(use-package-as-string name))
+ ,(macroexp-progn init-body)))
+ init-body))
+ body)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :config
+;;
+
+(defalias 'use-package-normalize/:config 'use-package-normalize-forms)
+
+(defun use-package-handler/:config (name keyword arg rest state)
+ (let* ((body (use-package-process-keywords name rest state))
+ (name-symbol (use-package-as-symbol name))
+ (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 ,(if (symbolp name) `',name name)
+ ',(macroexp-progn config-body))))
+ (use-package--with-elapsed-timer
+ (format "Loading package %s" name)
+ (if use-package-expand-minimally
+ (use-package-concat
+ (list (use-package-load-name name))
+ config-body)
+ `((if (not ,(use-package-load-name name t))
+ (ignore
+ (message (format "Cannot load %s" ',name)))
+ ,@config-body)))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; :diminish
+
+(defun use-package-normalize-diminish (name 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 (use-package-as-string name) "-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 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 keyword args)
+ (use-package-as-one (symbol-name keyword) args
+ (apply-partially #'use-package-normalize-diminish name)))
+
+(defun use-package-handler/:diminish (name keyword arg rest state)
+ (let ((body (use-package-process-keywords name 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 keyword args)
+ "Normalize arguments to delight."
+ (cond
+ ((and (= (length args) 1)
+ (symbolp (car args)))
+ (list (car args) nil name))
+ ((and (= (length args) 2)
+ (symbolp (car args)))
+ (list (car args) (cadr args) (use-package-as-symbol name)))
+ ((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 keyword args rest state)
+ (let ((body (use-package-process-keywords name rest state)))
+ (use-package-concat
+ body
+ `((delight (quote ,(nth 0 args)) ,(nth 1 args) (quote ,(nth 2 args))) t))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; The main macro
+;;
+
+;;;###autoload
+(defmacro use-package (name &rest args)
+ "Declare an Emacs package by specifying a group of configuration options.
+
+For full documentation, please see the README file that came with
+this file. Usage:
+
+ (use-package package-name
+ [:keyword [option]]...)
+
+: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.
+
+:mode Form to be added to `auto-mode-alist'.
+:interpreter Form to be added to `interpreter-mode-alist'.
+
+: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.
+
+:after Defer loading of a package until after any of the named
+ features are 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 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)))
+ (args* (use-package-sort-keywords
+ (if use-package-always-pin
+ (use-package-plist-maybe-put
+ args* :pin use-package-always-pin)
+ args*))))
+
+ ;; 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)
+ ,(if (eq use-package-verbose 'debug)
+ `(message "Compiling package %s" ',name-symbol))
+ ,(unless (plist-get args* :no-require)
+ (use-package-load-name name)))))))
+
+ (let ((body
+ (macroexp-progn
+ (use-package-process-keywords name args*
+ (and use-package-always-defer (list :deferred t))))))
+ (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