diff options
| author | Astounds <kirito@disroot.org> | 2026-08-07 16:18:49 -0500 |
|---|---|---|
| committer | Astounds <kirito@disroot.org> | 2026-08-07 16:18:49 -0500 |
| commit | 79e04842d239770fbe86bcfa60c693480a6b60cc (patch) | |
| tree | 24006eab643de7333e24ab80f96ac032766ddeb9 | |
| parent | e90e5cfbc6ca58c26a91a6b449b017b1102069be (diff) | |
| download | emacs-personal-79e04842d239770fbe86bcfa60c693480a6b60cc.tar.lz emacs-personal-79e04842d239770fbe86bcfa60c693480a6b60cc.tar.xz emacs-personal-79e04842d239770fbe86bcfa60c693480a6b60cc.zip | |
test
23 files changed, 8844 insertions, 6 deletions
diff --git a/modules/init-elpa.el b/modules/init-elpa.el index 56a4e55..e58ecdd 100644 --- a/modules/init-elpa.el +++ b/modules/init-elpa.el @@ -28,12 +28,13 @@ (setq package-check-signature 'allow-unsigned) (package-initialize) -(unless (package-installed-p 'use-package) - (unless (assoc 'use-package package-archive-contents) - (package-refresh-contents)) - (package-install 'use-package)) - -(require 'use-package) +;; use-package is bundled with Emacs 28+, but on older Emacs it is not. +;; Since MELPA no longer distributes use-package, load the vendored copy +;; from site-lisp/ so the bootstrap does not depend on GNU ELPA. +(unless (require 'use-package nil t) + (add-to-list 'load-path (expand-file-name "site-lisp/bind-key-2.4.1/" user-emacs-directory)) + (add-to-list 'load-path (expand-file-name "site-lisp/use-package-2.4.6/" user-emacs-directory)) + (require 'use-package)) (setq use-package-always-ensure t use-package-always-defer t use-package-compute-statistics t) diff --git a/site-lisp/bind-key-2.4.1/.elpaignore b/site-lisp/bind-key-2.4.1/.elpaignore new file mode 100644 index 0000000..d9ca1c7 --- /dev/null +++ b/site-lisp/bind-key-2.4.1/.elpaignore @@ -0,0 +1,2 @@ +.travis.yml +doc/* diff --git a/site-lisp/bind-key-2.4.1/.github/workflows/test.yml b/site-lisp/bind-key-2.4.1/.github/workflows/test.yml new file mode 100644 index 0000000..51fc206 --- /dev/null +++ b/site-lisp/bind-key-2.4.1/.github/workflows/test.yml @@ -0,0 +1,34 @@ +## test.yml + +name: Main workflow +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + emacs_version: + - '26.1' + - '26.2' + - '26.3' + - '27.1' + - '27.2' + - '28.1' + - 'snapshot' + include: + - emacs_version: 'snapshot' + allow_failure: true + steps: + - uses: actions/checkout@v2 + - uses: purcell/setup-emacs@master + with: + version: ${{ matrix.emacs_version }} + + - name: Run tests + if: matrix.allow_failure != true + run: 'make && make test' + + - name: Run tests (allow failure) + if: matrix.allow_failure == true + run: 'make && make test || true' diff --git a/site-lisp/bind-key-2.4.1/bind-chord.el b/site-lisp/bind-key-2.4.1/bind-chord.el new file mode 100644 index 0000000..bf0f586 --- /dev/null +++ b/site-lisp/bind-key-2.4.1/bind-chord.el @@ -0,0 +1,103 @@ +;;; bind-chord.el --- key-chord binding helper for use-package-chords -*- lexical-binding: t; -*- + +;; Copyright (C) 2015-2022 Free Software Foundation, Inc. + +;; Author: Justin Talbott <justin@waymondo.com> +;; Keywords: convenience, tools, extensions +;; URL: https://github.com/jwiegley/use-package +;; Version: 0.2.1 +;; Package-Requires: ((bind-key "1.0") (key-chord "0.6")) +;; Filename: bind-chord.el +;; License: GNU General Public License version 3, or (at your option) any later version +;; + +;;; Commentary: +;; + +;;; Code: + +(require 'bind-key) +(require 'key-chord nil t) + +;;;###autoload +(defmacro bind-chord (chord command &optional keymap) + "Bind CHORD to COMMAND in KEYMAP (`global-map' if not passed)." + (let ((key1 (logand 255 (aref chord 0))) + (key2 (logand 255 (aref chord 1)))) + (if (eq key1 key2) + `(bind-key (vector 'key-chord ,key1 ,key2) ,command ,keymap) + `(progn + (bind-key (vector 'key-chord ,key1 ,key2) ,command ,keymap) + (bind-key (vector 'key-chord ,key2 ,key1) ,command ,keymap))))) + +(defun bind-chords-form (args keymap) + "Bind multiple chords at once. + +Accepts keyword arguments: +:map MAP - a keymap into which the keybindings should be + added + +The rest of the arguments are conses of keybinding string and a +function symbol (unquoted)." + (let (map pkg) + (let ((cont t)) + (while (and cont args) + (if (cond ((eq :map (car args)) + (setq map (cadr args))) + ((eq :package (car args)) + (setq pkg (cadr args)))) + (setq args (cddr args)) + (setq cont nil)))) + + (unless map (setq map keymap)) + + (let (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 (memq map '(global-map + override-global-map)))) + `((if (boundp ',map) + ,(macroexp-progn bindings) + (eval-after-load + ,(if (symbolp pkg) `',pkg pkg) + ',(macroexp-progn bindings)))) + bindings))) + + (append + (wrap map + (cl-mapcan + (lambda (form) + (let ((fun (and (cdr form) (list 'function (cdr form))))) + (if (and map (not (eq map 'global-map))) + `((bind-chord ,(car form) ,fun ,map)) + `((bind-chord ,(car form) ,fun nil))))) + first)) + (when next + (bind-chords-form (if pkg + (cons :package (cons pkg next)) + next) map))))))) + +;;;###autoload +(defmacro bind-chords (&rest args) + "Bind multiple chords at once. + +Accepts keyword argument: +:map - a keymap into which the keybindings should be added + +The rest of the arguments are conses of keybinding string and a +function symbol (unquoted)." + (macroexp-progn (bind-chords-form args nil))) + +(provide 'bind-chord) + +;;; bind-chord.el ends here diff --git a/site-lisp/bind-key-2.4.1/bind-key-pkg.el b/site-lisp/bind-key-2.4.1/bind-key-pkg.el new file mode 100644 index 0000000..add7f68 --- /dev/null +++ b/site-lisp/bind-key-2.4.1/bind-key-pkg.el @@ -0,0 +1,2 @@ +;; Generated package description from bind-key.el -*- no-byte-compile: t -*- +(define-package "bind-key" "2.4.1" "A simple way to manage personal keybindings" 'nil :commit "4932ed21d40f9e8ad48ad2a1f086fdf9b3847ac9" :authors '(("John Wiegley" . "johnw@newartisans.com")) :maintainer '("John Wiegley" . "johnw@newartisans.com") :keywords '("keys" "keybinding" "config" "dotemacs") :url "https://github.com/jwiegley/use-package") diff --git a/site-lisp/bind-key-2.4.1/bind-key.el b/site-lisp/bind-key-2.4.1/bind-key.el new file mode 100644 index 0000000..cca5ad8 --- /dev/null +++ b/site-lisp/bind-key-2.4.1/bind-key.el @@ -0,0 +1,548 @@ +;;; bind-key.el --- A simple way to manage personal keybindings -*- lexical-binding: t; -*- + +;; Copyright (c) 2012-2022 Free Software Foundation, Inc. + +;; Author: John Wiegley <johnw@newartisans.com> +;; Maintainer: John Wiegley <johnw@newartisans.com> +;; Created: 16 Jun 2012 +;; Modified: 29 Nov 2017 +;; Version: 2.4.1 +;; 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 3, 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 the keybinding argument is a vector, it is passed straight to +;; `define-key', so remapping a key with `[remap COMMAND]' works as +;; expected: +;; +;; (bind-key [remap original-ctrl-c-x-command] '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 overridden 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. + +;;; Code: + +(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." + :init-value t + :lighter "") + +;; 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. + +COMMAND must be an interactive function or lambda form. + +KEYMAP, if present, should be a keymap variable or symbol. +For example: + + (bind-key \"M-h\" #\\='some-interactive-function my-mode-map) + + (bind-key \"M-h\" #\\='some-interactive-function \\='my-mode-map) + +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")) + (kmapvar (make-symbol "kmap")) + (kdescvar (make-symbol "kdesc")) + (bindingvar (make-symbol "binding"))) + `(let* ((,namevar ,key-name) + (,keyvar ,(if (stringp key-name) (read-kbd-macro key-name) + `(if (vectorp ,namevar) ,namevar + (read-kbd-macro ,namevar)))) + (,kmapvar (or (if (and ,keymap (symbolp ,keymap)) + (symbol-value ,keymap) ,keymap) + global-map)) + (,kdescvar (cons (if (stringp ,namevar) ,namevar + (key-description ,namevar)) + (if (symbolp ,keymap) ,keymap (quote ,keymap)))) + (,bindingvar (lookup-key ,kmapvar ,keyvar))) + (let ((entry (assoc ,kdescvar personal-keybindings)) + (details (list ,command + (unless (numberp ,bindingvar) + ,bindingvar)))) + (if entry + (setcdr entry details) + (add-to-list 'personal-keybindings (cons ,kdescvar details)))) + ,(if predicate + `(define-key ,kmapvar ,keyvar + '(menu-item "" nil :filter (lambda (&optional _) + (when ,predicate + ,command)))) + `(define-key ,kmapvar ,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." + (let ((namevar (make-symbol "name")) + (kdescvar (make-symbol "kdesc"))) + `(let* ((,namevar ,key-name) + (,kdescvar (cons (if (stringp ,namevar) ,namevar + (key-description ,namevar)) + (if (symbolp ,keymap) ,keymap (quote ,keymap))))) + (bind-key--remove (if (vectorp ,namevar) ,namevar + (read-kbd-macro ,namevar)) + (or (if (and ,keymap (symbolp ,keymap)) + (symbol-value ,keymap) ,keymap) + global-map)) + (setq personal-keybindings + (cl-delete-if (lambda (k) (equal (car k) ,kdescvar)) + personal-keybindings)) + nil))) + +(defun bind-key--remove (key keymap) + "Remove KEY from KEYMAP. + +In contrast to `define-key', this function removes the binding from the keymap." + (define-key keymap key nil) + ;; Split M-key in ESC key + (setq key (mapcan (lambda (k) + (if (and (integerp k) (/= (logand k ?\M-\0) 0)) + (list ?\e (logxor k ?\M-\0)) + (list k))) + key)) + ;; Delete single keys directly + (if (= (length key) 1) + (delete key keymap) + ;; Lookup submap and delete key from there + (let* ((prefix (vconcat (butlast key))) + (submap (lookup-key keymap prefix))) + (unless (keymapp submap) + (error "Not a keymap for %s" key)) + (when (symbolp submap) + (setq submap (symbol-function submap))) + (delete (last key) submap) + ;; Delete submap if it is empty + (when (= 1 (length submap)) + (bind-key--remove prefix keymap))))) + +;;;###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 keymap) + "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 +:repeat-docstring STR - docstring for the repeat-map variable +:repeat-map MAP - name of the repeat map that should be created + for these bindings. If specified, the + `repeat-map' property of each command bound + (within the scope of the `:repeat-map' keyword) + is set to this map. +:exit BINDINGS - Within the scope of `:repeat-map' will bind the + key in the repeat map, but will not set the + `repeat-map' property of the bound command. +:continue BINDINGS - Within the scope of `:repeat-map' forces the + same behaviour as if no special keyword had + been used (that is, the command is bound, and + it's `repeat-map' property set) +:filter FORM - optional form to determine when bindings apply + +The rest of the arguments are conses of keybinding string and a +function symbol (unquoted)." + (let (map + prefix-doc + prefix-map + prefix + repeat-map + repeat-doc + repeat-type ;; Only used internally + filter + menu-name + pkg) + + ;; Process any initial keyword arguments + (let ((cont t) + (arg-change-func 'cddr)) + (while (and cont args) + (if (cond ((and (eq :map (car args)) + (not prefix-map)) + (setq map (cadr args))) + ((eq :prefix-docstring (car args)) + (setq prefix-doc (cadr args))) + ((and (eq :prefix-map (car args)) + (not (memq map '(global-map + override-global-map)))) + (setq prefix-map (cadr args))) + ((eq :repeat-docstring (car args)) + (setq repeat-doc (cadr args))) + ((and (eq :repeat-map (car args)) + (not (memq map '(global-map + override-global-map)))) + (setq repeat-map (cadr args)) + (setq map repeat-map)) + ((eq :continue (car args)) + (setq repeat-type :continue + arg-change-func 'cdr)) + ((eq :exit (car args)) + (setq repeat-type :exit + arg-change-func 'cdr)) + ((eq :prefix (car args)) + (setq prefix (cadr args))) + ((eq :filter (car args)) + (setq filter (cadr args)) t) + ((eq :menu-name (car args)) + (setq menu-name (cadr args))) + ((eq :package (car args)) + (setq pkg (cadr args)))) + (setq args (funcall arg-change-func args)) + (setq cont nil)))) + + (when (or (and prefix-map (not prefix)) + (and prefix (not prefix-map))) + (error "Both :prefix-map and :prefix must be supplied")) + + (when repeat-type + (unless repeat-map + (error ":continue and :exit require specifying :repeat-map"))) + + (when (and menu-name (not prefix)) + (error "If :menu-name is supplied, :prefix must be too")) + + (unless map (setq map keymap)) + + ;; Process key binding arguments + (let (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 (memq map '(global-map + override-global-map)))) + `((if (boundp ',map) + ,(macroexp-progn bindings) + (eval-after-load + ,(if (symbolp pkg) `',pkg pkg) + ',(macroexp-progn bindings)))) + bindings))) + + (append + (when prefix-map + `((defvar ,prefix-map) + ,@(when prefix-doc `((put ',prefix-map 'variable-documentation ,prefix-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))))) + (when repeat-map + `((defvar ,repeat-map (make-sparse-keymap) + ,@(when repeat-doc `(,repeat-doc))))) + (wrap map + (cl-mapcan + (lambda (form) + (let ((fun (and (cdr form) (list 'function (cdr form))))) + (if prefix-map + `((bind-key ,(car form) ,fun ,prefix-map ,filter)) + (if (and map (not (eq map 'global-map))) + ;; Only needed in this branch, since when + ;; repeat-map is non-nil, map is always + ;; non-nil + `(,@(when (and repeat-map (not (eq repeat-type :exit))) + `((put ,fun 'repeat-map ',repeat-map))) + (bind-key ,(car form) ,fun ,map ,filter)) + `((bind-key ,(car form) ,fun nil ,filter)))))) + first)) + (when next + (bind-keys-form `(,@(when repeat-map `(:repeat-map ,repeat-map)) + ,@(if pkg + (cons :package (cons pkg next)) + next)) map))))))) + +;;;###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 +:repeat-docstring STR - docstring for the repeat-map variable +:repeat-map MAP - name of the repeat map that should be created + for these bindings. If specified, the + `repeat-map' property of each command bound + (within the scope of the `:repeat-map' keyword) + is set to this map. +:exit BINDINGS - Within the scope of `:repeat-map' will bind the + key in the repeat map, but will not set the + `repeat-map' property of the bound command. +:continue BINDINGS - Within the scope of `:repeat-map' forces the + same behaviour as if no special keyword had + been used (that is, the command is bound, and + it's `repeat-map' property set) +: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 nil))) + +;;;###autoload +(defmacro bind-keys* (&rest args) + (macroexp-progn (bind-keys-form args 'override-global-map))) + +(defun get-binding-description (elem) + (cond + ((listp elem) + (cond + ((memq (car elem) '(lambda function)) + (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: %s\n%s\n\n" + (cdar binding) (caar 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: +;; outline-regexp: ";;;\\(;* [^\s\t\n]\\|###autoload\\)\\|(" +;; indent-tabs-mode: nil +;; End: + +;;; bind-key.el ends here diff --git a/site-lisp/bind-key-2.4.1/default.mk b/site-lisp/bind-key-2.4.1/default.mk new file mode 100644 index 0000000..3204881 --- /dev/null +++ b/site-lisp/bind-key-2.4.1/default.mk @@ -0,0 +1,93 @@ +TOP := $(dir $(lastword $(MAKEFILE_LIST))) + +## User options ###################################################### +# +# You can override these settings in "config.mk" or on the command +# line. +# +# You might also want to set LOAD_PATH. If you do, then it must +# contain "-L .". +# +# If you don't do so, then the default is set in the "Load-Path" +# section below. The default assumes that all dependencies are +# installed either at "../<DEPENDENCY>", or when using package.el +# at "ELPA_DIR/<DEPENDENCY>-<HIGHEST-VERSION>". + +PREFIX ?= /usr/local +sharedir ?= $(PREFIX)/share +lispdir ?= $(sharedir)/emacs/site-lisp/use-package +infodir ?= $(sharedir)/info +docdir ?= $(sharedir)/doc/use-package +statsdir ?= $(TOP)/stats + +CP ?= install -p -m 644 +MKDIR ?= install -p -m 755 -d +RMDIR ?= rm -rf +TAR ?= tar +SED ?= sed + +EMACS ?= emacs +EMACSBIN ?= $(EMACS) +BATCH = $(EMACSBIN) -Q --batch $(LOAD_PATH) + +INSTALL_INFO ?= $(shell command -v ginstall-info || printf install-info) +MAKEINFO ?= makeinfo +MANUAL_HTML_ARGS ?= --css-ref /assets/page.css + +## Files ############################################################# + +PKG = use-package +PACKAGES = use-package + +TEXIPAGES = $(addsuffix .texi,$(filter-out git-commit,$(PACKAGES))) +INFOPAGES = $(addsuffix .info,$(filter-out git-commit,$(PACKAGES))) +HTMLFILES = $(addsuffix .html,$(filter-out git-commit,$(PACKAGES))) +HTMLDIRS = $(filter-out git-commit,$(PACKAGES)) +PDFFILES = $(addsuffix .pdf,$(filter-out git-commit,$(PACKAGES))) + +ELS = use-package.el +ELS += bind-key.el +ELS += bind-chord.el +ELS += use-package-bind-key.el +ELS += use-package-core.el +ELS += use-package-delight.el +ELS += use-package-diminish.el +ELS += use-package-ensure.el +ELS += use-package-jump.el +ELS += use-package-tests.el +ELS += use-package-chords.el +ELS += use-package-ensure-system-package.el +ELCS = $(ELS:.el=.elc) +ELMS = use-package.el $(filter-out $(addsuffix .el,$(PACKAGES)),$(ELS)) +ELGS = + +## Versions ########################################################## + +VERSION = 2.4.2 + +USE_PACKAGE_VERSION = 2.4.2 + +EMACS_VERSION = 24.3 + +EMACSOLD := $(shell $(BATCH) --eval \ + "(and (version< emacs-version \"$(EMACS_VERSION)\") (princ \"true\"))") +ifeq "$(EMACSOLD)" "true" + $(error At least version $(EMACS_VERSION) of Emacs is required) +endif + +## Load-Path ######################################################### + +ifndef LOAD_PATH + +ELPA_DIR ?= $(HOME)/.emacs.d/elpa + +SYSTYPE := $(shell $(EMACSBIN) -Q --batch --eval "(princ system-type)") +ifeq ($(SYSTYPE), windows-nt) + CYGPATH := $(shell cygpath --version 2>/dev/null) +endif + +LOAD_PATH = -L $(TOP) + +endif # ifndef LOAD_PATH + +DOC_LOAD_PATH ?= $(LOAD_PATH) -L $(HOME)/emacs/site-lisp diff --git a/site-lisp/use-package-2.4.6/dir b/site-lisp/use-package-2.4.6/dir new file mode 100644 index 0000000..8f047aa --- /dev/null +++ b/site-lisp/use-package-2.4.6/dir @@ -0,0 +1,18 @@ +This is the file .../info/dir, which contains the +topmost node of the Info hierarchy, called (dir)Top. +The first time you invoke Info you start off looking at this node. + +File: dir, Node: Top This is the top of the INFO tree + + This (the Directory node) gives a menu of major topics. + Typing "q" exits, "H" lists all Info commands, "d" returns here, + "h" gives a primer for first-timers, + "mEmacs<Return>" visits the Emacs manual, etc. + + In Emacs, you can click mouse button 2 on a menu item or cross reference + to select it. + +* Menu: + +Emacs misc features +* use-package: (use-package). Declarative package configuration for Emacs. diff --git a/site-lisp/use-package-2.4.6/doclicense.texi b/site-lisp/use-package-2.4.6/doclicense.texi new file mode 100644 index 0000000..eaf3da0 --- /dev/null +++ b/site-lisp/use-package-2.4.6/doclicense.texi @@ -0,0 +1,505 @@ +@c The GNU Free Documentation License. +@center Version 1.3, 3 November 2008 + +@c This file is intended to be included within another document, +@c hence no sectioning command or @node. + +@display +Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. +@uref{https://fsf.org/} + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. +@end display + +@enumerate 0 +@item +PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +functional and useful document @dfn{free} in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of ``copyleft'', which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + +@item +APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The ``Document'', below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as ``you''. You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A ``Modified Version'' of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A ``Secondary Section'' is a named appendix or a front-matter section +of the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall +subject (or to related matters) and contains nothing that could fall +directly within that overall subject. (Thus, if the Document is in +part a textbook of mathematics, a Secondary Section may not explain +any mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The ``Invariant Sections'' are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The ``Cover Texts'' are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A ``Transparent'' copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not ``Transparent'' is called ``Opaque''. + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, La@TeX{} input +format, SGML or XML using a publicly available +DTD, and standard-conforming simple HTML, +PostScript or PDF designed for human modification. Examples +of transparent image formats include PNG, XCF and +JPG@. Opaque formats include proprietary formats that can be +read and edited only by proprietary word processors, SGML or +XML for which the DTD and/or processing tools are +not generally available, and the machine-generated HTML, +PostScript or PDF produced by some word processors for +output purposes only. + +The ``Title Page'' means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, ``Title Page'' means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +The ``publisher'' means any person or entity that distributes copies +of the Document to the public. + +A section ``Entitled XYZ'' means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as ``Acknowledgements'', +``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title'' +of such a section when you modify the Document means that it remains a +section ``Entitled XYZ'' according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + +@item +VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + +@item +COPYING IN QUANTITY + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + +@item +MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +@enumerate A +@item +Use in the Title Page (and on the covers, if any) a title distinct +from that of the Document, and from those of previous versions +(which should, if there were any, be listed in the History section +of the Document). You may use the same title as a previous version +if the original publisher of that version gives permission. + +@item +List on the Title Page, as authors, one or more persons or entities +responsible for authorship of the modifications in the Modified +Version, together with at least five of the principal authors of the +Document (all of its principal authors, if it has fewer than five), +unless they release you from this requirement. + +@item +State on the Title page the name of the publisher of the +Modified Version, as the publisher. + +@item +Preserve all the copyright notices of the Document. + +@item +Add an appropriate copyright notice for your modifications +adjacent to the other copyright notices. + +@item +Include, immediately after the copyright notices, a license notice +giving the public permission to use the Modified Version under the +terms of this License, in the form shown in the Addendum below. + +@item +Preserve in that license notice the full lists of Invariant Sections +and required Cover Texts given in the Document's license notice. + +@item +Include an unaltered copy of this License. + +@item +Preserve the section Entitled ``History'', Preserve its Title, and add +to it an item stating at least the title, year, new authors, and +publisher of the Modified Version as given on the Title Page. If +there is no section Entitled ``History'' in the Document, create one +stating the title, year, authors, and publisher of the Document as +given on its Title Page, then add an item describing the Modified +Version as stated in the previous sentence. + +@item +Preserve the network location, if any, given in the Document for +public access to a Transparent copy of the Document, and likewise +the network locations given in the Document for previous versions +it was based on. These may be placed in the ``History'' section. +You may omit a network location for a work that was published at +least four years before the Document itself, or if the original +publisher of the version it refers to gives permission. + +@item +For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve +the Title of the section, and preserve in the section all the +substance and tone of each of the contributor acknowledgements and/or +dedications given therein. + +@item +Preserve all the Invariant Sections of the Document, +unaltered in their text and in their titles. Section numbers +or the equivalent are not considered part of the section titles. + +@item +Delete any section Entitled ``Endorsements''. Such a section +may not be included in the Modified Version. + +@item +Do not retitle any existing section to be Entitled ``Endorsements'' or +to conflict in title with any Invariant Section. + +@item +Preserve any Warranty Disclaimers. +@end enumerate + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled ``Endorsements'', provided it contains +nothing but endorsements of your Modified Version by various +parties---for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + +@item +COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled ``History'' +in the various original documents, forming one section Entitled +``History''; likewise combine any sections Entitled ``Acknowledgements'', +and any sections Entitled ``Dedications''. You must delete all +sections Entitled ``Endorsements.'' + +@item +COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + +@item +AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an ``aggregate'' if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + +@item +TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled ``Acknowledgements'', +``Dedications'', or ``History'', the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + +@item +TERMINATION + +You may not copy, modify, sublicense, or distribute the Document +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense, or distribute it is void, and +will automatically terminate your rights under this License. + +However, if you cease all violation of this License, then your license +from a particular copyright holder is reinstated (a) provisionally, +unless and until the copyright holder explicitly and finally +terminates your license, and (b) permanently, if the copyright holder +fails to notify you of the violation by some reasonable means prior to +60 days after the cessation. + +Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + +Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, receipt of a copy of some or all of the same material does +not give you any rights to use it. + +@item +FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +@uref{https://www.gnu.org/licenses/}. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License ``or any later version'' applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. If the Document +specifies that a proxy can decide which future versions of this +License can be used, that proxy's public statement of acceptance of a +version permanently authorizes you to choose that version for the +Document. + +@item +RELICENSING + +``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any +World Wide Web server that publishes copyrightable works and also +provides prominent facilities for anybody to edit those works. A +public wiki that anybody can edit is an example of such a server. A +``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the +site means any set of copyrightable works thus published on the MMC +site. + +``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0 +license published by Creative Commons Corporation, a not-for-profit +corporation with a principal place of business in San Francisco, +California, as well as future copyleft versions of that license +published by that same organization. + +``Incorporate'' means to publish or republish a Document, in whole or +in part, as part of another Document. + +An MMC is ``eligible for relicensing'' if it is licensed under this +License, and if all works that were first published under this License +somewhere other than this MMC, and subsequently incorporated in whole +or in part into the MMC, (1) had no cover texts or invariant sections, +and (2) were thus incorporated prior to November 1, 2008. + +The operator of an MMC Site may republish an MMC contained in the site +under CC-BY-SA on the same site at any time before August 1, 2009, +provided the MMC is eligible for relicensing. + +@end enumerate + +@page +@heading ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + +@smallexample +@group + Copyright (C) @var{year} @var{your name}. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. A copy of the license is included in the section entitled ``GNU + Free Documentation License''. +@end group +@end smallexample + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the ``with@dots{}Texts.''@: line with this: + +@smallexample +@group + with the Invariant Sections being @var{list their titles}, with + the Front-Cover Texts being @var{list}, and with the Back-Cover Texts + being @var{list}. +@end group +@end smallexample + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. + +@c Local Variables: +@c ispell-local-pdict: "ispell-dict" +@c End: diff --git a/site-lisp/use-package-2.4.6/docstyle.texi b/site-lisp/use-package-2.4.6/docstyle.texi new file mode 100644 index 0000000..e740439 --- /dev/null +++ b/site-lisp/use-package-2.4.6/docstyle.texi @@ -0,0 +1,19 @@ +@c Emacs documentation style settings +@documentencoding UTF-8 +@c These two require Texinfo 5.0 or later, so we use the older +@c equivalent @set variables supported in 4.11 and hence +@ignore +@codequotebacktick on +@codequoteundirected on +@end ignore +@set txicodequoteundirected +@set txicodequotebacktick +@iftex +@c It turns out TeX sometimes fails to hyphenate, so we help it here +@hyphenation{au-to-mat-i-cal-ly} +@hyphenation{spec-i-fied} +@hyphenation{work-a-round} +@hyphenation{work-a-rounds} +@hyphenation{un-marked} +@hyphenation{dic-tion-ary} +@end iftex diff --git a/site-lisp/use-package-2.4.6/emacsver.texi b/site-lisp/use-package-2.4.6/emacsver.texi new file mode 100644 index 0000000..994b39a --- /dev/null +++ b/site-lisp/use-package-2.4.6/emacsver.texi @@ -0,0 +1,2 @@ +@set USEP_DIST from GNU ELPA +@set EMACSVER diff --git a/site-lisp/use-package-2.4.6/use-package-bind-key.el b/site-lisp/use-package-2.4.6/use-package-bind-key.el new file mode 100644 index 0000000..18c3f29 --- /dev/null +++ b/site-lisp/use-package-2.4.6/use-package-bind-key.el @@ -0,0 +1,176 @@ +;;; use-package-bind-key.el --- Support for the :bind/:bind-keymap keywords -*- lexical-binding: t; -*- + +;; Copyright (C) 2012-2024 Free Software Foundation, Inc. + +;; Author: John Wiegley <johnw@newartisans.com> +;; Maintainer: John Wiegley <johnw@newartisans.com> + +;; 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 <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Provides support for the :bind, :bind*, :bind-keymap and :bind-keymap* +;; keywords. Note that these are currently still baked into +;; `use-package-keywords' and `use-package-deferring-keywords', although this +;; is harmless if they are never used. +;; +;; These keywords are made available by default by requiring `use-package'. +;; +;; See the `use-package' info manual for more information. + +;;; Code: + +(require 'use-package-core) +(require 'bind-key) + +;;;###autoload +(defun use-package-autoload-keymap (keymap-symbol package override) + "Load PACKAGE and bind key sequence invoking this function to KEYMAP-SYMBOL. +Then simulate 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 + (mapcar (lambda (ev) (cons t ev)) + (listify-key-sequence kv)))) + (use-package-error + (format "package.el %s failed to define keymap %s" + package keymap-symbol))))) + +;;;###autoload +(defun use-package-normalize-binder (name keyword args) + (let ((arg args) + args*) + (while arg + (let ((x (car arg))) + (cond + ;; (KEY . COMMAND) + ((and (consp x) + (or (stringp (car x)) + (vectorp (car x))) + (or (use-package-recognize-function (cdr x) t #'stringp))) + (setq args* (nconc args* (list x))) + (setq arg (cdr arg))) + ;; KEYWORD + ;; :map KEYMAP + ;; :prefix-docstring STRING + ;; :prefix-map SYMBOL + ;; :prefix STRING + ;; :repeat-docstring STRING + ;; :repeat-map SYMBOL + ;; :filter SEXP + ;; :menu-name STRING + ;; :package SYMBOL + ;; :continue and :exit are used within :repeat-map + ((or (and (eq x :map) (symbolp (cadr arg))) + (and (eq x :prefix) (stringp (cadr arg))) + (and (eq x :prefix-map) (symbolp (cadr arg))) + (and (eq x :prefix-docstring) (stringp (cadr arg))) + (and (eq x :repeat-map) (symbolp (cadr arg))) + (eq x :continue) + (eq x :exit) + (and (eq x :repeat-docstring) (stringp (cadr arg))) + (eq x :filter) + (and (eq x :menu-name) (stringp (cadr arg))) + (and (eq x :package) (symbolp (cadr arg)))) + (setq args* (nconc args* (list x (cadr arg)))) + (setq arg (cddr arg))) + ((listp x) + (setq args* + (nconc args* (use-package-normalize-binder name keyword x))) + (setq arg (cdr arg))) + (t + ;; Error! + (use-package-error + (concat (symbol-name name) + " wants arguments acceptable to the `bind-keys' macro," + " or a list of such values")))))) + args*)) + +;;;; :bind, :bind* + +;;;###autoload +(defalias 'use-package-normalize/:bind 'use-package-normalize-binder) +;;;###autoload +(defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) + +;; jww (2017-12-07): This is too simplistic. It will fail to determine +;; autoloads in this situation: +;; (use-package foo +;; :bind (:map foo-map (("C-a" . func)))) +;;;###autoload +(defalias 'use-package-autoloads/:bind 'use-package-autoloads-mode) +;;;###autoload +(defalias 'use-package-autoloads/:bind* 'use-package-autoloads-mode) + +;;;###autoload +(defun use-package-handler/:bind + (name _keyword args rest state &optional bind-macro) + (use-package-concat + (use-package-process-keywords name rest state) + `(,@(mapcar + #'(lambda (xs) + `(,(if bind-macro bind-macro 'bind-keys) + :package ,name ,@(use-package-normalize-commands xs))) + (use-package-split-list-at-keys :break args))))) + +(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* + +;;;###autoload +(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder) +;;;###autoload +(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder) + +;;;###autoload +(defun use-package-handler/:bind-keymap + (name _keyword args rest state &optional override) + (use-package-concat + (use-package-process-keywords name rest state) + (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)))) + args))) + +;;;###autoload +(defun use-package-handler/:bind-keymap* (name keyword arg rest state) + (use-package-handler/:bind-keymap name keyword arg rest state t)) + +(provide 'use-package-bind-key) + +;;; use-package-bind-key.el ends here diff --git a/site-lisp/use-package-2.4.6/use-package-core.el b/site-lisp/use-package-2.4.6/use-package-core.el new file mode 100644 index 0000000..8c3241d --- /dev/null +++ b/site-lisp/use-package-2.4.6/use-package-core.el @@ -0,0 +1,1855 @@ +;;; use-package-core.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*- + +;; Copyright (C) 2012-2024 Free Software Foundation, Inc. + +;; Author: John Wiegley <johnw@newartisans.com> +;; Maintainer: John Wiegley <johnw@newartisans.com> + +;; 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 <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This file contains the core implementation of the `use-package' +;; macro. +;; +;; See the `use-package' info manual for more information. + +;;; Code: + +(require 'bytecomp) +(require 'cl-lib) +(require 'tabulated-list) + +(eval-and-compile + ;; Declare a synthetic theme for :custom variables. + ;; Necessary in order to avoid having those variables saved by custom.el. + (deftheme use-package)) + +(enable-theme 'use-package) +;; Remove the synthetic use-package theme from the enabled themes, so +;; iterating over them to "disable all themes" won't disable it. +(setq custom-enabled-themes (remq 'use-package custom-enabled-themes)) + +(eval-when-compile + (if (and (eq emacs-major-version 24) (eq emacs-minor-version 3)) + (progn + (defsubst hash-table-keys (hash-table) + "Return a list of keys in HASH-TABLE." + (cl-loop for k being the hash-keys of hash-table collect k)) + (defsubst string-suffix-p (suffix string &optional ignore-case) + (let ((start-pos (- (length string) (length suffix)))) + (and (>= start-pos 0) + (eq t (compare-strings suffix nil nil + string start-pos nil ignore-case)))))) + (require 'subr-x))) + +(eval-when-compile + (require 'regexp-opt)) + +(defgroup use-package nil + "A `use-package' declaration for simplifying your `.emacs'." + :group 'initialization + :link '(custom-manual "(use-package) Top") + :version "29.1") + +(defconst use-package-version "2.4.5" + "This version of `use-package'.") + +(defcustom use-package-keywords + '(:disabled + :load-path + :requires + :defines + :functions + :preface + :if :when :unless + :vc + :no-require + :catch + :after + :custom + :custom-face + :bind + :bind* + :bind-keymap + :bind-keymap* + :interpreter + :mode + :magic + :magic-fallback + :hook + ;; Any other keyword that also declares commands to be autoloaded (such as + ;; :bind) must appear before this keyword. + :commands + :autoload + :init + :defer + :demand + :load + ;; This must occur almost last; the only forms which should appear after + ;; are those that must happen directly after the config forms. + :config) + "The set of valid keywords, in the order they are processed in. +The order of this list is *very important*, so it is only +advisable to insert new keywords, never to delete or reorder +them. Further, attention should be paid to the NEWS.md if the +default order ever changes, as they may have subtle effects on +the semantics of `use-package' declarations and may necessitate +changing where you had inserted a new keyword earlier. + +Note that `:disabled' is special in this list, as 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-deferring-keywords + '(:bind-keymap + :bind-keymap* + :commands + :autoload) + "Unless `:demand' is used, keywords in this list imply deferred loading. +The reason keywords like `:hook' are not in this list is that +they only imply deferred loading if they reference actual +function symbols that can be autoloaded from the module; whereas +the default keywords provided here always defer loading unless +otherwise requested." + :type '(repeat symbol) + :group 'use-package) + +(defcustom use-package-ignore-unknown-keywords nil + "If non-nil, warn instead of signaling error for unknown keywords. +The unknown keyword and its associated arguments will be ignored +in the `use-package' expansion." + :type 'boolean + :group 'use-package) + +(defcustom use-package-use-theme t + "If non-nil, use a custom theme to avoid saving :custom +variables twice (once in the Custom file, once in the use-package +call)." + :type 'boolean + :group 'use-package) + +(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, without catching errors" errors) + (const :tag "Quiet" nil) + (const :tag "Verbose" t) + (const :tag "Debug" debug)) + :group 'use-package) + +(defcustom use-package-check-before-init nil + "If non-nil, check that package exists before executing its `:init' block. +This check is performed by calling `locate-library'." + :type 'boolean + :group 'use-package) + +(defcustom use-package-always-defer nil + "If non-nil, assume `:defer t' unless `:demand' is used. +See also `use-package-defaults', which uses this value." + :type 'boolean + :group 'use-package) + +(defcustom use-package-always-demand nil + "If non-nil, assume `:demand t' unless `:defer' is used. +See also `use-package-defaults', which uses this value." + :type 'boolean + :group 'use-package) + +(defcustom use-package-defaults + '(;; this '(t) has special meaning; see `use-package-handler/:config' + (:config '(t) t) + (:init nil t) + (:catch t (lambda (name args) + (not use-package-expand-minimally))) + (:defer use-package-always-defer + (lambda (name args) + (and use-package-always-defer + (not (plist-member args :defer)) + (not (plist-member args :demand))))) + (:demand use-package-always-demand + (lambda (name args) + (and use-package-always-demand + (not (plist-member args :defer)) + (not (plist-member args :demand)))))) + "Default values for specified `use-package' keywords. +Each entry in the alist is a list of three elements: +The first element is the `use-package' keyword. + +The second is a form that can be evaluated to get the default +value. It can also be a function that will receive the name of +the `use-package' declaration and the keyword plist given to +`use-package', in normalized form. The value it returns should +also be in normalized form (which is sometimes *not* what one +would normally write in a `use-package' declaration, so use +caution). + +The third element is a form that can be evaluated to determine +whether or not to assign a default value; if it evaluates to nil, +then the default value is not assigned even if the keyword is not +present in the `use-package' form. This third element may also be +a function, in which case it receives the name of the package (as +a symbol) and a list of keywords (in normalized form). It should +return nil or non-nil depending on whether defaulting should be +attempted." + :type `(repeat + (list (symbol :tag "Keyword") + (choice :tag "Default value" sexp function) + (choice :tag "Enable if non-nil" sexp function))) + :group 'use-package) + +(defcustom use-package-merge-key-alist + '((:if . (lambda (new old) `(and ,new ,old))) + (:after . (lambda (new old) `(:all ,new ,old))) + (:defer . (lambda (new old) old)) + (:bind . (lambda (new old) (append new (list :break) old)))) + "Alist of keys and the functions used to merge multiple values. +For example, if the following form is provided: + + (use-package foo :if pred1 :if pred2) + +Then based on the above defaults, the merged result will be: + + (use-package foo :if (and pred1 pred2)) + +This is done so that, at the stage of invoking handlers, each +handler is called only once." + :type `(repeat + (cons (choice :tag "Keyword" + ,@(mapcar #'(lambda (k) (list 'const k)) + use-package-keywords) + (const :tag "Any" t)) + function)) + :group 'use-package) + +(defcustom use-package-hook-name-suffix "-hook" + "Text append to the name of hooks mentioned by :hook. +Set to nil if you don't want this to happen; it's only a +convenience." + :type '(choice string (const :tag "No suffix" nil)) + :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 a non-nil value +for anything to be reported at all." + :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 evaluation of a +`use-package` declaration, and exercise some control over what +happens. + +NOTE: These hooks are run even if the user does not specify an +`:init' or `:config' block, and they will happen at the regular +time when initialization and configuration would have been +performed. + +NOTE: If the `pre-init' hook return 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 had +specified." + :type 'boolean + :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 + - Capturing of load errors (normally redisplayed as warnings) + - Conditional loading of packages (load failures become errors) + +The main advantage to this variable is that, if you know your +configuration works, it will make the byte-compiled file as +minimal as possible. It can also help with reading macro-expanded +definitions, to understand the main intent of what's happening." + :type 'boolean + :group 'use-package) + +(defcustom use-package-form-regexp-eval + `(concat ,(eval-when-compile + (concat "^\\s-*(" + (regexp-opt '("use-package" "require") t) + "\\s-+\\(")) + (or (bound-and-true-p lisp-mode-symbol-regexp) + "\\(?:\\sw\\|\\s_\\|\\\\.\\)+") "\\)") + "Sexp providing regexp for finding `use-package' forms in user files. +This is used by `use-package-jump-to-package-form' and +`use-package-enable-imenu-support'." + :type 'sexp + :group 'use-package) + +(defcustom use-package-enable-imenu-support nil + "If non-nil, cause imenu to see `use-package' declarations. +This is done by adjusting `lisp-imenu-generic-expression' to +include support for finding `use-package' and `require' forms. + +Must be set before loading `use-package'." + :type 'boolean + :set + #'(lambda (sym value) + (eval-after-load 'lisp-mode + (if value + `(add-to-list 'lisp-imenu-generic-expression + (list "Packages" ,use-package-form-regexp-eval 2)) + `(setq lisp-imenu-generic-expression + (remove (list "Packages" ,use-package-form-regexp-eval 2) + lisp-imenu-generic-expression)))) + (set-default sym value)) + :group 'use-package) + +;; Redundant in Emacs 26 or later, which already highlights macro names. +(defconst use-package-font-lock-keywords + '(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" + (1 font-lock-keyword-face) + (2 font-lock-constant-face nil t)))) +(make-obsolete-variable 'use-package-font-lock-keywords + 'lisp-el-font-lock-keywords "30.1") +(when (< emacs-major-version 26) + (font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords)) + +(defcustom use-package-compute-statistics nil + "If non-nil, compute statistics concerned `use-package' declarations. +View the statistical report using `use-package-report'. Note that +if this option is enabled, you must require `use-package' in your +user init file at loadup time, or you will see errors concerning +undefined variables." + :type 'boolean + :group 'use-package) + +(defcustom use-package-vc-prefer-newest nil + "Prefer the newest commit over the latest release. +By default, much like GNU ELPA and NonGNU ELPA, the `:vc' keyword +tracks the latest stable release of a package. If this option is +non-nil, the latest commit is preferred instead. This has the +same effect as specifying `:rev :newest' in every invocation of +`:vc'. + +Note that always tracking a package's latest commit might lead to +stability issues." + :type 'boolean + :version "30.1" + :group 'use-package) + +(defvar use-package-statistics (make-hash-table)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Utility functions +;; + +(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-concat (&rest elems) + "Delete all empty lists from ELEMS (nil or (list nil)), and append them." + (apply #'append (delete nil (delete (list nil) elems)))) + +(defsubst use-package-non-nil-symbolp (sym) + (and sym (symbolp sym))) + +(defsubst 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))) + +(defsubst 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))) + +(defsubst use-package-regex-p (re) + "Return t if RE is some regexp-like thing." + (or (and (listp re) (eq (car re) 'rx)) + (stringp re))) + +(defun use-package-normalize-regex (re) + "Given some regexp-like thing in RE, resolve to a regular expression." + (cond + ((and (listp re) (eq (car re) 'rx)) (eval re)) + ((stringp re) re) + (t (error "Not recognized as regular expression: %s" re)))) + +(defsubst use-package-is-pair (x car-pred cdr-pred) + "Return non-nil if X is a cons satisfying the given predicates. +CAR-PRED and CDR-PRED are applied to X's `car' and `cdr', +respectively." + (and (consp x) + (funcall car-pred (car x)) + (funcall cdr-pred (cdr x)))) + +(defun use-package-as-mode (string-or-symbol) + "If STRING-OR-SYMBOL ends in `-mode' (or its name does), return +it as a symbol. Otherwise, return it as a symbol with `-mode' +appended." + (let ((string (use-package-as-string string-or-symbol))) + (intern (if (string-match "-mode\\'" string) + string + (concat string "-mode"))))) + +(defsubst use-package-load-name (name &optional noerror) + "Return a form which will load or require NAME. +It does the right thing no matter if NAME is a string or symbol. +Argument NOERROR means to indicate load failures as a warning." + (if (stringp name) + `(load ,name ,noerror) + `(require ',name nil ,noerror))) + +(defun use-package-hook-injector (name-string keyword body) + "Wrap pre/post hook injections around the given BODY for KEYWORD. +The BODY is a list of forms, so `((foo))' if only `foo' is being called." + (if (not use-package-inject-hooks) + body + (let ((keyword-name (substring (format "%s" keyword) 1))) + `((when (run-hook-with-args-until-failure + ',(intern (concat "use-package--" name-string + "--pre-" keyword-name "-hook"))) + ,@body + (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) + +(defun use-package-require (name &optional no-require body) + (if use-package-expand-minimally + (use-package-concat + (unless no-require + (list (use-package-load-name name))) + body) + (if no-require + body + (use-package-with-elapsed-timer + (format "Loading package %s" name) + `((if (not ,(use-package-load-name name t)) + (display-warning 'use-package + (format "Cannot load %s" ',name) + :error) + ,@body)))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Property lists +;; + +(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-plist-delete-first (plist property) + "Delete PROPERTY from PLIST. +This is in contrast to merely setting it to 0." + (let (p) + (while plist + (if (eq property (car plist)) + (setq p (nconc p (cddr plist)) + plist nil) + (setq p (nconc p (list (car plist) (cadr plist))) + plist (cddr plist)))) + p)) + +(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-split-list (pred xs) + (let ((ys (list nil)) (zs (list nil)) flip) + (cl-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-split-list-at-keys (key lst) + (and lst + (let ((xs (use-package-split-list (apply-partially #'eq key) lst))) + (cons (car xs) (use-package-split-list-at-keys key (cddr xs)))))) + +(defun use-package-split-when (pred xs) + "Repeatedly split a list according to PRED. +Split XS every time PRED returns t. Keep the delimiters, and +arrange the result in an alist. For example: + + (use-package-split-when #\\='keywordp \\='(:a 1 :b 2 3 4 :c 5)) + ;; => \\='((:a 1) (:b 2 3 4) (:c 5)) + + (use-package-split-when (lambda (x) (> x 2)) \\='(10 1 3 2 4 -1 8 9)) + ;; => \\='((10 1) (3 2) (4 -1) (8) (9))" + (unless (seq-empty-p xs) + (pcase-let* ((`(,first . ,rest) (if (funcall pred (car xs)) + (cons (car xs) (cdr xs)) + (use-package-split-list pred xs))) + (`(,val . ,recur) (use-package-split-list pred rest))) + (cons (cons first val) + (use-package-split-when pred recur))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Keywords +;; + +(defun use-package-keyword-index (keyword) + (cl-loop named outer + with index = 0 + for k in use-package-keywords do + (if (eq k keyword) + (cl-return-from outer index)) + (cl-incf index))) + +(defun use-package-normalize-plist (name input &optional plist merge-function) + "Given a pseudo-plist, normalize it to a regular plist. +The normalized key/value pairs from input are added to PLIST, +extending any keys already present." + (if (null input) + plist + (let* ((keyword (car input)) + (xs (use-package-split-list #'keywordp (cdr input))) + (args (car xs)) + (tail (cdr xs)) + (normalizer + (intern-soft (concat "use-package-normalize/" + (symbol-name keyword)))) + (arg (and (functionp normalizer) + (funcall normalizer name keyword args))) + (error-string (format "Unrecognized keyword: %s" keyword))) + (if (memq keyword use-package-keywords) + (progn + (setq plist (use-package-normalize-plist + name tail plist merge-function)) + (plist-put plist keyword + (if (plist-member plist keyword) + (funcall merge-function keyword arg + (plist-get plist keyword)) + arg))) + (if use-package-ignore-unknown-keywords + (progn + (display-warning 'use-package error-string) + (use-package-normalize-plist + name tail plist merge-function)) + (use-package-error error-string)))))) + +(defun use-package-unalias-keywords (_name args) + (setq args (cl-nsubstitute :if :when args)) + (let (temp) + (while (setq temp (plist-get args :unless)) + (setq args (use-package-plist-delete-first args :unless) + args (append args `(:if (not ,temp)))))) + args) + +(defun use-package-merge-keys (key new old) + (let ((merger (assq key use-package-merge-key-alist))) + (if merger + (funcall (cdr merger) new old) + (append new old)))) + +(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) + (cl-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))) + +(defun use-package-normalize-keywords (name args) + (let* ((name-symbol (if (stringp name) (intern name) name)) + (name-string (symbol-name name-symbol))) + + ;; The function `elisp--local-variables' inserts this unbound variable into + ;; macro forms to determine the locally bound variables for + ;; `elisp-completion-at-point'. It ends up throwing a lot of errors since it + ;; can occupy the position of a keyword (or look like a second argument to a + ;; keyword that takes one). Deleting it when it's at the top level should be + ;; harmless since there should be no locally bound variables to discover + ;; here anyway. + (setq args (delq 'elisp--witness--lisp args)) + + ;; Reduce the set of keywords down to its most fundamental expression. + (setq args (use-package-unalias-keywords name-symbol args)) + + ;; Normalize keyword values, coalescing multiple occurrences. + (setq args (use-package-normalize-plist name-symbol args nil + #'use-package-merge-keys)) + + ;; Add default values for keywords not specified, when applicable. + (cl-dolist (spec use-package-defaults) + (when (let ((func (nth 2 spec))) + (if (and func (functionp func)) + (funcall func name args) + (eval func))) + (setq args (use-package-plist-maybe-put + args (nth 0 spec) + (let ((func (nth 1 spec))) + (if (and func (functionp func)) + (funcall func name args) + (eval func))))))) + + ;; Determine any autoloads implied by the keywords used. + (let ((iargs args) + commands) + (while iargs + (when (keywordp (car iargs)) + (let ((autoloads + (intern-soft (concat "use-package-autoloads/" + (symbol-name (car iargs)))))) + (when (functionp autoloads) + (setq commands + ;; jww (2017-12-07): Right now we just ignored the type of + ;; the autoload being requested, and assume they are all + ;; `command'. + (append (mapcar + #'car + (funcall autoloads name-symbol (car iargs) + (cadr iargs))) + commands))))) + (setq iargs (cddr iargs))) + (when commands + (setq args + ;; Like `use-package-plist-append', but removing duplicates. + (plist-put args :commands + (delete-dups + (append commands (plist-get args :commands))))))) + + ;; If byte-compiling, pre-load the package so all its symbols are in + ;; scope. This is done by prepending statements to the :preface. + (when (bound-and-true-p byte-compile-current-file) + (setq args + (use-package-plist-append + args :preface + (use-package-concat + (mapcar #'(lambda (var) `(defvar ,var)) + (plist-get args :defines)) + (mapcar #'(lambda (fn) `(declare-function ,fn ,name-string)) + (plist-get args :functions)) + `((eval-when-compile + (with-demoted-errors + ,(format "Cannot load %s: %%S" name-string) + ,(when (eq use-package-verbose 'debug) + `(message ,(format "Compiling package %s" name-string))) + ,(unless (plist-get args :no-require) + `(unless (featurep ',name-symbol) + (load ,name-string nil t)))))))))) + + ;; Certain keywords imply :defer, if :demand was not specified. + (when (and (not (plist-member args :demand)) + (not (plist-member args :defer)) + (not (or (equal '(t) (plist-get args :load)) + (equal (list (use-package-as-string name)) + (mapcar #'use-package-as-string + (plist-get args :load))))) + (cl-some #'identity + (mapcar (apply-partially #'plist-member args) + use-package-deferring-keywords))) + (setq args (append args '(:defer t)))) + + ;; The :load keyword overrides :no-require + (when (and (plist-member args :load) + (plist-member args :no-require)) + (setq args (use-package-plist-delete args :no-require))) + + ;; If at this point no :load, :defer or :no-require has been seen, then + ;; :load the package itself. + (when (and (not (plist-get args :load)) + (not (plist-get args :defer)) + (not (plist-get args :no-require))) + (setq args (append args `(:load (,name))))) + + ;; Sort the list of keywords based on the order of `use-package-keywords'. + (use-package-sort-keywords args))) + +(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) + +(defun use-package-list-insert (elem xs &optional anchor after test) + "Insert ELEM into the list XS. +If ANCHOR is also a keyword, place the new KEYWORD before that +one. +If AFTER is non-nil, insert KEYWORD either at the end of the +keywords list, or after the ANCHOR if one has been provided. +If TEST is non-nil, it is the test used to compare ELEM to list +elements. The default is `eq'. +The modified list is returned. The original list is not modified." + (let (result) + (dolist (k xs) + (if (funcall (or test #'eq) k anchor) + (if after + (setq result (cons k result) + result (cons elem result)) + (setq result (cons elem result) + result (cons k result))) + (setq result (cons k result)))) + (if anchor + (nreverse result) + (if after + (nreverse (cons elem result)) + (cons elem (nreverse result)))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Argument Processing +;; + +(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-as-one (label args f &optional allow-empty) + "Call F on the first element of ARGS if it has one element, or all of ARGS. +If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." + (declare (indent 1)) + (if (if args + (and (listp args) (listp (cdr args))) + allow-empty) + (if (= (length args) 1) + (funcall f label (car args)) + (funcall f label args)) + (use-package-error + (concat label " wants a non-empty list")))) + +(put 'use-package-as-one 'lisp-indent-function 'defun) + +(defun use-package-memoize (f arg) + "Ensure the macro-expansion of F applied to ARG evaluates ARG +no more than once." + (let ((loaded (cl-gentemp "use-package--loaded")) + (result (cl-gentemp "use-package--result")) + (next (cl-gentemp "use-package--next"))) + `((defvar ,loaded nil) + (defvar ,result nil) + (defvar ,next #'(lambda () (if ,loaded ,result + (setq ,loaded t ,result ,arg)))) + ,@(funcall f `((funcall ,next)))))) + +(defsubst use-package-normalize-value (_label arg) + "Normalize the Lisp value given by ARG. +The argument LABEL is ignored." + (cond ((null arg) nil) + ((eq t arg) t) + ((use-package-non-nil-symbolp arg) + `(symbol-value ',arg)) + ((functionp arg) + `(funcall #',arg)) + (t arg))) + +(defun use-package-normalize-symbols (label arg &optional recursed) + "Normalize a list of symbols." + (cond + ((use-package-non-nil-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)) + +(defun use-package-normalize-recursive-symbols (label arg) + "Normalize a list of symbols." + (cond + ((use-package-non-nil-symbolp arg) + arg) + ((and (listp arg) (listp (cdr arg))) + (mapcar #'(lambda (x) (use-package-normalize-recursive-symbols label x)) + arg)) + (t + (use-package-error + (concat label " wants a symbol, or nested list of symbols"))))) + +(defun use-package-normalize-recursive-symlist (_name keyword args) + (use-package-as-one (symbol-name keyword) args + #'use-package-normalize-recursive-symbols)) + +(defun use-package-normalize-paths (label arg &optional recursed) + "Normalize a list of filesystem paths." + (cond + ((and arg (or (use-package-non-nil-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-predicate (_name keyword args) + (if (null args) + t + (use-package-only-one (symbol-name keyword) args + #'use-package-normalize-value))) + +(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) + (memq (car form) + '(use-package bind-key bind-key* + unbind-key bind-keys bind-keys*))) + (macroexpand form) + form)) args)) + +(defun use-package-normalize-forms (_name keyword args) + (use-package-normalize-form (symbol-name keyword) args)) + +(defun use-package-normalize-pairs + (key-pred val-pred name label arg &optional recursed) + "Normalize a list of pairs. +KEY-PRED and VAL-PRED are predicates recognizing valid keys and +values, respectively. +If RECURSED is non-nil, recurse into sublists." + (cond + ((funcall key-pred arg) + (list (cons arg (use-package-as-symbol name)))) + ((use-package-is-pair arg key-pred val-pred) + (list arg)) + ((and (not recursed) (listp arg) (listp (cdr arg))) + (let (last-item) + (mapcar + #'(lambda (x) + (prog1 + (let ((ret (use-package-normalize-pairs + key-pred val-pred name label x t))) + (if (and (listp ret) + (not (keywordp last-item))) + (car ret) + ret)) + (setq last-item x))) arg))) + (t arg))) + +(defun use-package-recognize-function (v &optional binding additional-pred) + "A predicate that recognizes functional constructions: + nil + sym + \\='sym + (quote sym) + #\\='sym + (function sym) + (lambda () ...) + \\='(lambda () ...) + (quote (lambda () ...)) + #\\='(lambda () ...) + (function (lambda () ...))" + (or (if binding + (symbolp v) + (use-package-non-nil-symbolp v)) + (and (listp v) + (memq (car v) '(quote function)) + (use-package-non-nil-symbolp (cadr v))) + (if binding (commandp v) (functionp v)) + (and additional-pred + (funcall additional-pred v)))) + +(defun use-package-normalize-function (v) + "Reduce functional constructions to one of two normal forms: + sym + #\\='(lambda () ...)" + (cond ((symbolp v) v) + ((and (listp v) + (memq (car v) '(quote function)) + (use-package-non-nil-symbolp (cadr v))) + (cadr v)) + ((and (consp v) + (eq 'lambda (car v))) + v) + ((and (listp v) + (memq (car v) '(quote function)) + (eq 'lambda (car (cadr v)))) + (cadr v)) + (t v))) + +(defun use-package-normalize-commands (args) + "Map over ARGS of the form ((_ . F) ...), normalizing functional F's." + (mapcar #'(lambda (x) + (if (consp x) + (cons (car x) (use-package-normalize-function (cdr x))) + x)) + args)) + +(defun use-package-normalize-mode (name keyword args) + "Normalize arguments for keywords which add regexp/mode pairs to an alist." + (use-package-as-one (symbol-name keyword) args + (apply-partially #'use-package-normalize-pairs + #'use-package-regex-p + #'use-package-recognize-function + name))) + +(defun use-package-autoloads-mode (_name _keyword args) + (mapcar + #'(lambda (x) (cons (cdr x) 'command)) + (cl-remove-if-not #'(lambda (x) + (and (consp x) + (use-package-non-nil-symbolp (cdr x)))) + args))) + +(defun use-package-handle-mode (name alist args rest state) + "Handle keywords which add regexp/mode pairs to an alist." + (use-package-concat + (use-package-process-keywords name rest state) + (mapcar + #'(lambda (thing) + `(add-to-list + ',alist + ',(cons (use-package-normalize-regex (car thing)) + (cdr thing)))) + (use-package-normalize-commands args)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Statistics +;; + +(defun use-package-reset-statistics () + "Reset statistics for `use-package'. +See also `use-package-statistics'." + (interactive) + (setq use-package-statistics (make-hash-table))) + +(defun use-package-statistics-status (package) + "Return loading configuration status of PACKAGE statistics." + (cond ((gethash :config package) "Configured") + ((gethash :init package) "Initialized") + ((gethash :preface package) "Prefaced") + ((gethash :use-package package) "Declared"))) + +(defun use-package-statistics-last-event (package) + "Return the date when PACKAGE's status last changed. +The date is returned as a string." + (or (gethash :config package) + (gethash :init package) + (gethash :preface package) + (gethash :use-package package))) + +(defun use-package-statistics-time (package) + "Return the time is took for PACKAGE to load." + (+ (float-time (gethash :config-secs package '(0 0 0 0))) + (float-time (gethash :init-secs package '(0 0 0 0))) + (float-time (gethash :preface-secs package '(0 0 0 0))) + (float-time (gethash :use-package-secs package '(0 0 0 0))))) + +(defun use-package-statistics-convert (package) + "Return information about PACKAGE. + +The information is formatted in a way suitable for +`use-package-statistics-mode'." + (let ((statistics (gethash package use-package-statistics))) + (list + package + (vector + (symbol-name package) + (use-package-statistics-status statistics) + (format-time-string + "%H:%M:%S.%6N" + (use-package-statistics-last-event statistics)) + (format "%.2f" (use-package-statistics-time statistics)))))) + +(defun use-package-report () + "Show current statistics gathered about `use-package' declarations. +In the table that's generated, the status field has the following +meaning: + Configured :config has been processed (the package is loaded!) + Initialized :init has been processed (load status unknown) + Prefaced :preface has been processed + Declared the use-package declaration was seen + +Customize the user option `use-package-compute-statistics' to +enable gathering statistics." + (interactive) + (let ((statistics (hash-table-keys use-package-statistics))) + (unless statistics + (if use-package-compute-statistics + (user-error "No use-package statistics available") + (user-error (concat "Customize `use-package-compute-statistics'" + " to enable reporting")))) + (with-current-buffer (get-buffer-create "*use-package statistics*") + (setq tabulated-list-entries + (mapcar #'use-package-statistics-convert statistics)) + (use-package-statistics-mode) + (tabulated-list-print) + (display-buffer (current-buffer))))) + +(defvar use-package-statistics-status-order + '(("Declared" . 0) + ("Prefaced" . 1) + ("Initialized" . 2) + ("Configured" . 3))) + +(define-derived-mode use-package-statistics-mode tabulated-list-mode + "use-package statistics" + "Show current statistics gathered about `use-package' declarations." + :interactive nil + (setq tabulated-list-format + ;; The sum of column width is 80 characters: + [("Package" 25 t) + ("Status" 13 + (lambda (a b) + (< (assoc-default + (use-package-statistics-status + (gethash (car a) use-package-statistics)) + use-package-statistics-status-order) + (assoc-default + (use-package-statistics-status + (gethash (car b) use-package-statistics)) + use-package-statistics-status-order)))) + ("Last Event" 23 + (lambda (a b) + (< (float-time + (use-package-statistics-last-event + (gethash (car a) use-package-statistics))) + (float-time + (use-package-statistics-last-event + (gethash (car b) use-package-statistics)))))) + ("Time" 10 + (lambda (a b) + (< (use-package-statistics-time + (gethash (car a) use-package-statistics)) + (use-package-statistics-time + (gethash (car b) use-package-statistics)))))]) + (setq tabulated-list-sort-key '("Time" . t)) + (tabulated-list-init-header)) + +(defun use-package-statistics-gather (keyword name after) + (let* ((hash (gethash name use-package-statistics + (make-hash-table))) + (before (and after (gethash keyword hash (current-time))))) + (puthash keyword (current-time) hash) + (when after + (puthash (intern (concat (symbol-name keyword) "-secs")) + (time-subtract (current-time) before) hash)) + (puthash name hash use-package-statistics))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Handlers +;; + +;;;; :disabled + +;; Don't alias this to `ignore', as that will cause the resulting +;; function to be interactive. +(defun use-package-normalize/:disabled (_name _keyword _arg) + "Do nothing, return nil.") + +(defun use-package-handler/:disabled (name _keyword _arg rest state) + (use-package-process-keywords name rest state)) + +;;;; :if, :when and :unless + +(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) + +(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-normalize/:when 'use-package-normalize-test) + +(defalias 'use-package-handler/:when 'use-package-handler/:if) + +(defalias 'use-package-normalize/:unless 'use-package-normalize-test) + +(defun use-package-handler/:unless (name _keyword pred rest state) + (let ((body (use-package-process-keywords name rest state))) + `((unless ,pred ,@body)))) + +;;;; :requires + +(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 (> (length requires) 1) + `(not (member nil (mapcar #'featurep ',requires))) + `(featurep ',(car requires))) + ,@body))))) + +;;;; :load-path + +(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 + (plist-put state :load-path arg)))) + (use-package-concat + (mapcar #'(lambda (path) + `(eval-and-compile (add-to-list 'load-path ,path))) + arg) + body))) + +;;;; :no-require + +(defalias 'use-package-normalize/:no-require 'use-package-normalize-predicate) + +(defun use-package-handler/:no-require (name _keyword _arg rest state) + (use-package-process-keywords name rest state)) + +;;;; :defines + +(defalias 'use-package-normalize/:defines 'use-package-normalize-symlist) + +(defun use-package-handler/:defines (name _keyword _arg rest state) + (use-package-process-keywords name rest state)) + +;;;; :functions + +(defalias 'use-package-normalize/:functions 'use-package-normalize-symlist) + +(defun use-package-handler/:functions (name _keyword _arg rest state) + (use-package-process-keywords name rest state)) + +;;;; :preface + +(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 + (when use-package-compute-statistics + `((use-package-statistics-gather :preface ',name nil))) + (when arg + `((eval-and-compile ,@arg))) + body + (when use-package-compute-statistics + `((use-package-statistics-gather :preface ',name t)))))) + +;;;; :catch + +(defvar use-package--form) +(defvar use-package--hush-function #'(lambda (_keyword body) body)) + +(defsubst use-package-hush (context keyword body) + `((condition-case-unless-debug err + ,(macroexp-progn body) + (error (funcall ,context ,keyword err))))) + +(defun use-package-normalize/:catch (_name keyword args) + (if (null args) + t + (use-package-only-one (symbol-name keyword) args + use-package--hush-function))) + +(defun use-package-handler/:catch (name keyword arg rest state) + (let* ((context (cl-gentemp "use-package--warning"))) + (cond + ((not arg) + (use-package-process-keywords name rest state)) + ((eq arg t) + `((defvar ,context + #'(lambda (keyword err) + (let ((msg (format "%s/%s: %s" ',name keyword + (error-message-string err)))) + ,@(when (eq use-package-verbose 'debug) + `((with-current-buffer + (get-buffer-create "*use-package*") + (goto-char (point-max)) + (insert "-----\n" msg ,use-package--form) + (emacs-lisp-mode)) + (setq msg + (concat msg + " (see the *use-package* buffer)")))) + (display-warning 'use-package msg :error)))) + ,@(let ((use-package--hush-function + (apply-partially #'use-package-hush context))) + (funcall use-package--hush-function keyword + (use-package-process-keywords name rest state))))) + ((functionp arg) + `((defvar ,context ,arg) + ,@(let ((use-package--hush-function + (apply-partially #'use-package-hush context))) + (funcall use-package--hush-function keyword + (use-package-process-keywords name rest state))))) + (t + (use-package-error "The :catch keyword expects 't' or a function"))))) + +;;;; :interpreter + +(defalias 'use-package-normalize/:interpreter 'use-package-normalize-mode) +(defalias 'use-package-autoloads/:interpreter 'use-package-autoloads-mode) + +(defun use-package-handler/:interpreter (name _keyword arg rest state) + (use-package-handle-mode name 'interpreter-mode-alist arg rest state)) + +;;;; :mode + +(defalias 'use-package-normalize/:mode 'use-package-normalize-mode) +(defalias 'use-package-autoloads/:mode 'use-package-autoloads-mode) + +(defun use-package-handler/:mode (name _keyword arg rest state) + (use-package-handle-mode name 'auto-mode-alist arg rest state)) + +;;;; :magic + +(defalias 'use-package-normalize/:magic 'use-package-normalize-mode) +(defalias 'use-package-autoloads/:magic 'use-package-autoloads-mode) + +(defun use-package-handler/:magic (name _keyword arg rest state) + (use-package-handle-mode name 'magic-mode-alist arg rest state)) + +;;;; :magic-fallback + +(defalias 'use-package-normalize/:magic-fallback 'use-package-normalize-mode) +(defalias 'use-package-autoloads/:magic-fallback 'use-package-autoloads-mode) + +(defun use-package-handler/:magic-fallback (name _keyword arg rest state) + (use-package-handle-mode name 'magic-fallback-mode-alist arg rest state)) + +;;;; :hook + +(defun use-package-normalize/:hook (name keyword args) + (use-package-as-one (symbol-name keyword) args + #'(lambda (label arg) + (unless (or (use-package-non-nil-symbolp arg) (consp arg)) + (use-package-error + (concat label " a <symbol> or (<symbol or list of symbols> . <symbol or function>)" + " or list of these"))) + (use-package-normalize-pairs + #'(lambda (k) + (or (use-package-non-nil-symbolp k) + (and k (let ((every t)) + (while (and every k) + (if (and (consp k) + (use-package-non-nil-symbolp (car k))) + (setq k (cdr k)) + (setq every nil))) + every)))) + #'use-package-recognize-function + (if (string-suffix-p "-mode" (symbol-name name)) + name + (intern (concat (symbol-name name) "-mode"))) + label arg)))) + +(defalias 'use-package-autoloads/:hook 'use-package-autoloads-mode) + +(defun use-package-handler/:hook (name _keyword args rest state) + "Generate use-package custom keyword code." + (use-package-concat + (use-package-process-keywords name rest state) + (cl-mapcan + #'(lambda (def) + (let ((syms (car def)) + (fun (cdr def))) + (when fun + (mapcar + #'(lambda (sym) + `(add-hook + (quote ,(intern + (concat (symbol-name sym) + use-package-hook-name-suffix))) + (function ,fun))) + (use-package-hook-handler-normalize-mode-symbols syms))))) + (use-package-normalize-commands args)))) + +(defun use-package-hook-handler-normalize-mode-symbols (syms) + "Ensure that `SYMS' turns into a list of modes." + (if (use-package-non-nil-symbolp syms) (list syms) syms)) + +;;;; :commands + +(defalias 'use-package-normalize/:commands 'use-package-normalize-symlist) + +(defun use-package-handler/:commands (name _keyword arg rest state) + (use-package-concat + ;; Since we deferring load, establish any necessary autoloads, and also + ;; keep the byte-compiler happy. + (let ((name-string (use-package-as-string name))) + (cl-mapcan + #'(lambda (command) + (when (symbolp command) + (append + (unless (plist-get state :demand) + `((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 arg))) + (use-package-process-keywords name rest state))) + +;;;; :autoload + +(defalias 'use-package-normalize/:autoload 'use-package-normalize/:commands) + +(defun use-package-handler/:autoload (name _keyword arg rest state) + (use-package-concat + ;; Since we deferring load, establish any necessary autoloads, and also + ;; keep the byte-compiler happy. + (let ((name-string (use-package-as-string name))) + (cl-mapcan + #'(lambda (command) + (when (symbolp command) + (append + (unless (plist-get state :demand) + `((unless (fboundp ',command) + (autoload #',command ,name-string)))) + (when (bound-and-true-p byte-compile-current-file) + `((eval-when-compile + (declare-function ,command ,name-string))))))) + (delete-dups arg))) + (use-package-process-keywords name rest state))) + +;;;; :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 state))) + (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))) + (if (or (not arg) (null body)) + body + `((eval-after-load ',name ',(macroexp-progn body))))))) + +;;;; :after + +(defun use-package-normalize/:after (name keyword args) + (setq args (use-package-normalize-recursive-symlist name keyword args)) + (if (consp args) + args + (list args))) + +(defun use-package-after-count-uses (features*) + "Count the number of time the body would appear in the result." + (cond ((use-package-non-nil-symbolp features*) + 1) + ((and (consp features*) + (memq (car features*) '(:or :any))) + (let ((num 0)) + (cl-dolist (next (cdr features*)) + (setq num (+ num (use-package-after-count-uses next)))) + num)) + ((and (consp features*) + (memq (car features*) '(:and :all))) + (apply #'max (mapcar #'use-package-after-count-uses + (cdr features*)))) + ((listp features*) + (use-package-after-count-uses (cons :all features*))))) + +(defun use-package-require-after-load (features* body) + "Generate `eval-after-load' statements to represents FEATURES*. +FEATURES* is a list containing keywords `:and' and `:all', where +no keyword implies `:all'." + (cond + ((use-package-non-nil-symbolp features*) + `((eval-after-load ',features* ',(macroexp-progn body)))) + ((and (consp features*) + (memq (car features*) '(:or :any))) + (cl-mapcan #'(lambda (x) (use-package-require-after-load x body)) + (cdr features*))) + ((and (consp features*) + (memq (car features*) '(:and :all))) + (cl-dolist (next (cdr features*)) + (setq body (use-package-require-after-load next body))) + body) + ((listp features*) + (use-package-require-after-load (cons :all features*) body)))) + +(defun use-package-handler/:after (name _keyword arg rest state) + (let ((body (use-package-process-keywords name rest state)) + (uses (use-package-after-count-uses arg))) + (if (or (null uses) (null body)) + body + (if (<= uses 1) + (use-package-require-after-load arg body) + (use-package-memoize + (apply-partially #'use-package-require-after-load arg) + (macroexp-progn 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 state)) + +;;;; :custom + +(defun use-package-normalize/:custom (_name keyword args) + "Normalize use-package custom keyword." + (use-package-as-one (symbol-name keyword) args + #'(lambda (label arg) + (unless (listp arg) + (use-package-error + (concat label " a (<symbol> <value> [comment])" + " or list of these"))) + (if (use-package-non-nil-symbolp (car arg)) + (list arg) + arg)))) + +(defun use-package-handler/:custom (name _keyword args rest state) + "Generate use-package custom keyword code." + (use-package-concat + (if (bound-and-true-p use-package-use-theme) + `((let ((custom--inhibit-theme-enable nil)) + ;; Declare the theme here so use-package can be required inside + ;; eval-and-compile without warnings about unknown theme. + (unless (memq 'use-package custom-known-themes) + (deftheme use-package) + (enable-theme 'use-package) + (setq custom-enabled-themes (remq 'use-package custom-enabled-themes))) + (custom-theme-set-variables + 'use-package + ,@(mapcar + #'(lambda (def) + (let ((variable (nth 0 def)) + (value (nth 1 def)) + (comment (nth 2 def))) + (unless (and comment (stringp comment)) + (setq comment (format "Customized with use-package %s" name))) + `'(,variable ,value nil () ,comment))) + args)))) + (mapcar + #'(lambda (def) + (let ((variable (nth 0 def)) + (value (nth 1 def)) + (comment (nth 2 def))) + (unless (and comment (stringp comment)) + (setq comment (format "Customized with use-package %s" name))) + `(customize-set-variable (quote ,variable) ,value ,comment))) + args)) + (use-package-process-keywords name rest state))) + +;;;; :custom-face + +(defun use-package-normalize/:custom-face (name-symbol _keyword arg) + "Normalize use-package custom-face keyword." + (let ((error-msg + (format "%s wants a (<symbol> <face-spec> [spec-type]) or list of these" + name-symbol))) + (unless (listp arg) + (use-package-error error-msg)) + (cl-dolist (def arg arg) + (unless (listp def) + (use-package-error error-msg)) + (let ((face (nth 0 def)) + (spec (nth 1 def))) + (when (or (not face) + (not spec) + (> (length def) 3)) + (use-package-error error-msg)))))) + +(defun use-package-handler/:custom-face (name _keyword args rest state) + "Generate use-package custom-face keyword code." + (use-package-concat + (mapcar #'(lambda (def) `(apply #'face-spec-set (backquote ,def))) args) + (use-package-process-keywords name rest state))) + +;;;; :init + +(defalias 'use-package-normalize/:init 'use-package-normalize-forms) + +(defun use-package-handler/:init (name _keyword arg rest state) + (use-package-concat + (when use-package-compute-statistics + `((use-package-statistics-gather :init ',name nil))) + (let ((init-body + (use-package-hook-injector (use-package-as-string name) + :init arg))) + (when init-body + (funcall use-package--hush-function :init + (if use-package-check-before-init + `((when (locate-library ,(use-package-as-string name)) + ,@init-body)) + init-body)))) + (use-package-process-keywords name rest state) + (when use-package-compute-statistics + `((use-package-statistics-gather :init ',name t))))) + +;;;; :load + +(defun use-package-normalize/:load (name keyword args) + (setq args (use-package-normalize-recursive-symlist name keyword args)) + (if (consp args) + args + (list args))) + +(defun use-package-handler/:load (name _keyword arg rest state) + (let ((body (use-package-process-keywords name rest state))) + (cl-dolist (pkg arg) + (setq body (use-package-require (if (eq t pkg) name pkg) nil 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))) + (use-package-concat + (when use-package-compute-statistics + `((use-package-statistics-gather :config ',name nil))) + (if (and (or (null arg) (equal arg '(t))) (not use-package-inject-hooks)) + body + (use-package-with-elapsed-timer + (format "Configuring package %s" name-symbol) + (funcall use-package--hush-function :config + (use-package-concat + (use-package-hook-injector + (symbol-name name-symbol) :config arg) + body + (list t))))) + (when use-package-compute-statistics + `((use-package-statistics-gather :config ',name t)))))) + +;;;; :vc + +(defun use-package-vc-install (arg &optional local-path) + "Install a package with `package-vc.el'. +ARG is a list of the form (NAME OPTIONS REVISION), as returned by +`use-package-normalize--vc-arg'. If LOCAL-PATH is non-nil, call +`package-vc-install-from-checkout'; otherwise, indicating a +remote host, call `package-vc-install' instead." + (pcase-let* ((`(,name ,opts ,rev) arg) + (spec (if opts (cons name opts) name))) + (unless (package-installed-p name) + (if local-path + (package-vc-install-from-checkout local-path (symbol-name name)) + (package-vc-install spec rev))))) + +(defun use-package-handler/:vc (name _keyword arg rest state) + "Generate code to install package NAME, or do so directly. +When the use-package declaration is part of a byte-compiled file, +install the package during compilation; otherwise, add it to the +macro expansion and wait until runtime. The remaining arguments +are as follows: + +_KEYWORD is ignored. + +ARG is the normalized input to the `:vc' keyword, as returned by +the `use-package-normalize/:vc' function. + +REST is a plist of other (following) keywords and their +arguments, each having already been normalized by the respective +function. + +STATE is a plist of any state that keywords processed before +`:vc' (see `use-package-keywords') may have accumulated. + +Also see the Info node `(use-package) Creating an extension'." + (let ((body (use-package-process-keywords name rest state)) + (local-path (car (plist-get state :load-path)))) + ;; See `use-package-handler/:ensure' for an explanation. + (if (bound-and-true-p byte-compile-current-file) + (funcall #'use-package-vc-install arg local-path) ; compile time + (push `(use-package-vc-install ',arg ,local-path) body)) ; runtime + body)) + +(defconst use-package-vc-valid-keywords + '( :url :branch :lisp-dir :main-file :vc-backend :rev + :shell-command :make :ignored-files) + "Valid keywords for the `:vc' keyword. +See Info node `(emacs)Fetching Package Sources'.") + +(defun use-package-normalize--vc-arg (arg) + "Normalize possible arguments to the `:vc' keyword. +ARG is a cons-cell of approximately the form that +`package-vc-selected-packages' accepts, plus an additional `:rev' +keyword. If `:rev' is not given, it defaults to `:last-release'. + +Returns a list (NAME SPEC REV), where (NAME . SPEC) is compliant +with `package-vc-selected-packages' and REV is a (possibly nil, +indicating the latest commit) revision." + (cl-flet* ((ensure-string (s) + (if (and s (stringp s)) s (symbol-name s))) + (ensure-symbol (s) + (if (and s (stringp s)) (intern s) s)) + (normalize (k v) + (pcase k + (:rev (pcase v + ('nil (if use-package-vc-prefer-newest nil :last-release)) + (:last-release :last-release) + (:newest nil) + (_ (ensure-string v)))) + (:vc-backend (ensure-symbol v)) + (:ignored-files (if (listp v) v (list v))) + (_ (ensure-string v))))) + (pcase-let* ((`(,name . ,opts) arg)) + (if (stringp opts) ; (NAME . VERSION-STRING) ? + (list name opts) + (let ((opts (use-package-split-when + (lambda (el) + (seq-contains-p use-package-vc-valid-keywords el)) + opts))) + ;; Error handling + (cl-loop for (k . _) in opts + if (not (member k use-package-vc-valid-keywords)) + do (use-package-error + (format "Keyword :vc received unknown argument: %s. Supported keywords are: %s" + k use-package-vc-valid-keywords))) + ;; Actual normalization + (list name + (cl-loop for (k . v) in opts + if (not (eq k :rev)) + nconc (list k (normalize k (if (length= v 1) (car v) v)))) + (normalize :rev (car (alist-get :rev opts))))))))) + +(defun use-package-normalize/:vc (name _keyword args) + "Normalize possible arguments to the `:vc' keyword. +NAME is the name of the `use-package' declaration, _KEYWORD is +ignored, and ARGS it a list of arguments given to the `:vc' +keyword, the cdr of which is ignored. + +See `use-package-normalize--vc-arg' for most of the actual +normalization work. Also see the Info +node `(use-package) Creating an extension'." + (let ((arg (car args))) + (pcase arg + ((or 'nil 't) (list name)) ; guess name + ((pred symbolp) (list arg)) ; use this name + ((pred stringp) (list name arg)) ; version string + guess name + (`(,(pred keywordp) . ,(pred listp)) ; list + guess name + (use-package-normalize--vc-arg (cons name arg))) + (`(,(pred symbolp) . ,(or (pred listp) ; list/version string + name + (pred stringp))) + (use-package-normalize--vc-arg arg)) + (_ (use-package-error "Unrecognized argument to :vc.\ + The keyword wants an argument of nil, t, a name of a package,\ + or a cons-cell as accepted by `package-vc-selected-packages', where \ + the accepted plist is augmented by a `:rev' keyword."))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; The main macro +;; + +(defmacro use-package-core (name args) + `(let* ((args* (use-package-normalize-keywords ,name ,args)) + (use-package--form + (if (eq use-package-verbose 'debug) + (concat "\n\n" + (pp-to-string `(use-package ,name ,@,args)) + "\n -->\n\n" + (pp-to-string `(use-package ,name ,@args*)) + "\n ==>\n\n" + (pp-to-string + (macroexp-progn + (let ((use-package-verbose 'errors) + (use-package-expand-minimally t)) + (use-package-process-keywords name args* + (and (plist-get args* :demand) + (list :demand t))))))) + ""))) + (use-package-process-keywords name args* + (and (plist-get args* :demand) + (list :demand t))))) + +;;;###autoload +(defmacro use-package (name &rest args) + "Declare an Emacs package by specifying a group of configuration options. + +For the full documentation, see Info node `(use-package) top'. +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'. +:magic Form to be added to `magic-mode-alist'. +:magic-fallback Form to be added to `magic-fallback-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. +:autoload Similar to :commands, but it for no-interactive one. +:hook Specify hook(s) to attach this package to. + +: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', `:magic', `:hook', + `:magic-fallback', or `:interpreter'. This can be an integer, + to force loading after N seconds of idle time, if the package + has not already been loaded. +:demand Prevent the automatic deferred loading introduced by constructs + such as `:bind' (see `:defer' for the complete list). + +:after Delay the effect of the use-package declaration + until after the named libraries have loaded. + Before they have been loaded, no other keyword + has any effect at all, and once they have been + loaded it is as if `:after' was not specified. + +: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). +:delight Support for delight.el (if installed). +:custom Call `Custom-set' or `set-default' with each variable + definition without modifying the Emacs `custom-file'. + (compare with `custom-set-variables'). +:custom-face Call `custom-set-faces' with each face definition. +:ensure Loads the package using package.el if necessary. +:pin Pin the package to an archive. +:vc Install the package directly from a version control system + (using `package-vc.el')." + (declare (indent defun)) + (unless (memq :disabled args) + (macroexp-progn + (use-package-concat + (when use-package-compute-statistics + `((use-package-statistics-gather :use-package ',name nil))) + (if (eq use-package-verbose 'errors) + (use-package-core name args) + (condition-case-unless-debug err + (use-package-core name args) + (error + (ignore + (display-warning + 'use-package + (format "Failed to parse package %s: %s" + name (error-message-string err)) :error))))) + (when use-package-compute-statistics + `((use-package-statistics-gather :use-package ',name t))))))) + +(provide 'use-package-core) + +;;; use-package-core.el ends here diff --git a/site-lisp/use-package-2.4.6/use-package-delight.el b/site-lisp/use-package-2.4.6/use-package-delight.el new file mode 100644 index 0000000..c458d26 --- /dev/null +++ b/site-lisp/use-package-2.4.6/use-package-delight.el @@ -0,0 +1,88 @@ +;;; use-package-delight.el --- Support for the :delight keyword -*- lexical-binding: t; -*- + +;; Copyright (C) 2012-2024 Free Software Foundation, Inc. + +;; Author: John Wiegley <johnw@newartisans.com> +;; Maintainer: John Wiegley <johnw@newartisans.com> + +;; 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 <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Provides support for the :delight keyword, which is made available +;; by default by requiring `use-package'. Using it requires the +;; `delight' package to be installed (available on GNU ELPA). +;; +;; See the `use-package' info manual for more information. + +;;; Code: + +(require 'use-package-core) + +(defun use-package-normalize-delight (name args) + "Normalize ARGS for a single call to `delight'." + (when (eq :eval (car args)) + ;; Handle likely common mistake. + (use-package-error ":delight mode line constructs must be quoted")) + (cond ((and (= (length args) 1) + (use-package-non-nil-symbolp (car args))) + `(,(nth 0 args) nil ,name)) + ((= (length args) 2) + `(,(nth 0 args) ,(nth 1 args) ,name)) + ((= (length args) 3) + args) + (t + (use-package-error + ":delight expects `delight' arguments or a list of them")))) + +;;;###autoload +(defun use-package-normalize/:delight (name _keyword args) + "Normalize arguments to delight." + (cond ((null args) + `((,(use-package-as-mode name) nil ,name))) + ((and (= (length args) 1) + (use-package-non-nil-symbolp (car args))) + `((,(car args) nil ,name))) + ((and (= (length args) 1) + (stringp (car args))) + `((,(use-package-as-mode name) ,(car args) ,name))) + ((and (= (length args) 1) + (listp (car args)) + (eq 'quote (caar args))) + `((,(use-package-as-mode name) ,@(cdar args) ,name))) + ((and (= (length args) 2) + (listp (nth 1 args)) + (eq 'quote (car (nth 1 args)))) + `((,(car args) ,@(cdr (nth 1 args)) ,name))) + (t (mapcar + (apply-partially #'use-package-normalize-delight name) + (if (use-package-non-nil-symbolp (car args)) + (list args) + args))))) + +;;;###autoload +(defun use-package-handler/:delight (name _keyword args rest state) + (let ((body (use-package-process-keywords name rest state))) + (use-package-concat + body + `((if (fboundp 'delight) + (delight '(,@args))))))) + +(add-to-list 'use-package-keywords :delight t) + +(provide 'use-package-delight) + +;;; use-package-delight.el ends here diff --git a/site-lisp/use-package-2.4.6/use-package-diminish.el b/site-lisp/use-package-2.4.6/use-package-diminish.el new file mode 100644 index 0000000..79421a0 --- /dev/null +++ b/site-lisp/use-package-2.4.6/use-package-diminish.el @@ -0,0 +1,77 @@ +;;; use-package-diminish.el --- Support for the :diminish keyword -*- lexical-binding: t; -*- + +;; Copyright (C) 2012-2024 Free Software Foundation, Inc. + +;; Author: John Wiegley <johnw@newartisans.com> +;; Maintainer: John Wiegley <johnw@newartisans.com> + +;; 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 <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Provides support for the :diminish keyword, which is made available +;; by default by requiring `use-package'. Using it requires the +;; `diminish' package to be installed (available on GNU ELPA). +;; +;; See the `use-package' info manual for more information. + +;;; Code: + +(require 'use-package-core) + +(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 + ((not arg) + (list (use-package-as-mode name))) + ((use-package-non-nil-symbolp arg) + (list arg)) + ((stringp arg) + (list (cons (use-package-as-mode name) 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"))))) + +;;;###autoload +(defun use-package-normalize/:diminish (name keyword args) + (use-package-as-one (symbol-name keyword) args + (apply-partially #'use-package-normalize-diminish name) t)) + +;;;###autoload +(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))) + +(add-to-list 'use-package-keywords :diminish t) + +(provide 'use-package-diminish) + +;;; use-package-diminish.el ends here diff --git a/site-lisp/use-package-2.4.6/use-package-ensure-system-package.el b/site-lisp/use-package-2.4.6/use-package-ensure-system-package.el new file mode 100644 index 0000000..9ad2e19 --- /dev/null +++ b/site-lisp/use-package-2.4.6/use-package-ensure-system-package.el @@ -0,0 +1,104 @@ +;;; use-package-ensure-system-package.el --- auto install system packages -*- lexical-binding: t; -*- + +;; Copyright (C) 2022-2024 Free Software Foundation, Inc. + +;; Author: Justin Talbott <justin@waymondo.com> +;; Keywords: convenience, tools, extensions +;; URL: https://github.com/waymondo/use-package-ensure-system-package +;; Package-Requires: ((use-package "2.1") (system-packages "1.0.4")) + +;; 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 <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; The `:ensure-system-package` keyword allows you to ensure system +;; binaries exist alongside your `use-package` declarations. Using it +;; requires the `system-packages' package to be installed (available +;; on GNU ELPA). +;; +;; See the `use-package' info manual for more information. + +;;; Code: + +(require 'use-package) +(require 'system-packages nil t) + +(eval-when-compile + (declare-function system-packages-get-command "system-packages")) + +(defvar use-package-ensure-system-package--custom-packages '() + "List of commands used to install custom packages.") + +(defun use-package-ensure-system-package-consify (arg) + "Turn ARG into a cons of the form (PACKAGE-NAME . INSTALL-COMMAND')." + (cond + ((stringp arg) + (cons arg `(system-packages-install ,arg))) + ((symbolp arg) + (cons arg `(system-packages-install ,(symbol-name arg)))) + ((consp arg) + (cond + ((not (cdr arg)) + (use-package-ensure-system-package-consify (car arg))) + ((stringp (cdr arg)) + (progn + (push (cdr arg) use-package-ensure-system-package--custom-packages) + (cons (car arg) `(async-shell-command ,(cdr arg))))) + (t + (cons (car arg) + `(system-packages-install ,(symbol-name (cdr arg))))))))) + +(defun use-package-ensure-system-package-update-custom-packages () + "Update custom packages (not installed by system package manager). +Run the same commands used for installing them." + (interactive) + (dolist (cmd use-package-ensure-system-package--custom-packages) + (async-shell-command cmd))) + +;;;###autoload +(defun use-package-normalize/:ensure-system-package (_name-symbol keyword args) + "Turn ARGS into a list of conses of the form (PACKAGE-NAME . INSTALL-COMMAND)." + (use-package-as-one (symbol-name keyword) args + (lambda (_label arg) + (cond + ((and (listp arg) (listp (cdr arg))) + (mapcar #'use-package-ensure-system-package-consify arg)) + (t + (list (use-package-ensure-system-package-consify arg))))))) + +(defun use-package-ensure-system-package-exists? (file-or-exe) + "If FILE-OR-EXE is a string, ensure the file path exists. +If it is a symbol, ensure the binary exist." + (if (stringp file-or-exe) + (file-exists-p file-or-exe) + (executable-find (symbol-name file-or-exe)))) + + +;;;###autoload +(defun use-package-handler/:ensure-system-package (name _keyword arg rest state) + "Execute the handler for `:ensure-system-package' keyword in `use-package'." + (let ((body (use-package-process-keywords name rest state))) + (use-package-concat + (mapcar #'(lambda (cons) + `(unless (use-package-ensure-system-package-exists? ',(car cons)) + ,(cdr cons))) arg) + body))) + +(add-to-list 'use-package-keywords :ensure-system-package t) + +(provide 'use-package-ensure-system-package) + +;;; use-package-ensure-system-package.el ends here diff --git a/site-lisp/use-package-2.4.6/use-package-ensure.el b/site-lisp/use-package-2.4.6/use-package-ensure.el new file mode 100644 index 0000000..5f75b6b --- /dev/null +++ b/site-lisp/use-package-2.4.6/use-package-ensure.el @@ -0,0 +1,213 @@ +;;; use-package-ensure.el --- Support for the :ensure and :pin keywords -*- lexical-binding: t; -*- + +;; Copyright (C) 2012-2024 Free Software Foundation, Inc. + +;; Author: John Wiegley <johnw@newartisans.com> +;; Maintainer: John Wiegley <johnw@newartisans.com> + +;; 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 <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Provides support for the :ensure and :pin keywords, which are made +;; available by default by requiring `use-package'. +;; +;; See the `use-package' info manual for more information. + +;;; Code: + +(require 'cl-lib) +(require 'use-package-core) + +(defgroup use-package-ensure nil + "Support for :ensure and :pin keywords in `use-package' declarations." + :group 'use-package + :link '(custom-manual "(use-package) Installing packages") + :version "29.1") + +(eval-when-compile + (declare-function package-installed-p "package") + (declare-function package-read-all-archive-contents "package" ())) + +(defcustom use-package-always-ensure nil + "Treat every package as though it had specified using `:ensure SEXP'. +See also `use-package-defaults', which uses this value." + :type 'sexp + :group 'use-package-ensure) + +(defcustom use-package-always-pin nil + "Treat every package as though it had specified using `:pin SYM'. +See also `use-package-defaults', which uses this value." + :type 'symbol + :group 'use-package-ensure) + +(defcustom use-package-ensure-function 'use-package-ensure-elpa + "Function that ensures a package is installed. +This function is called with three arguments: the name of the +package declared in the `use-package' form; the arguments passed +to all `:ensure' keywords (always a list, even if only one); and +the current `state' plist created by previous handlers. + +Note that this function is called whenever `:ensure' is provided, +even if it is nil. It is up to the function to decide on the +semantics of the various values for `:ensure'. + +This function should return non-nil if the package is installed. + +The default value uses package.el to install the package." + :type '(choice (const :tag "package.el" use-package-ensure-elpa) + (function :tag "Custom")) + :group 'use-package-ensure) + +;;;; :pin + +(defun use-package-normalize/:pin (_name keyword args) + (use-package-only-one (symbol-name keyword) args + #'(lambda (_label arg) + (cond + ((stringp arg) arg) + ((use-package-non-nil-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) + +;;;###autoload +(defun use-package-normalize/:ensure (_name keyword args) + (if (null args) + (list t) + (use-package-only-one (symbol-name keyword) args + #'(lambda (_label arg) + (cond + ((symbolp arg) + (list arg)) + ((and (listp arg) (= 3 (length arg)) + (symbolp (nth 0 arg)) + (eq :pin (nth 1 arg)) + (or (stringp (nth 2 arg)) + (symbolp (nth 2 arg)))) + (list (cons (nth 0 arg) (nth 2 arg)))) + (t + (use-package-error + (concat ":ensure wants an optional package name " + "(an unquoted symbol name), or (<symbol> :pin <string>)")))))))) + +(defun use-package-ensure-elpa (name args _state &optional _no-refresh) + (dolist (ensure args) + (let ((package + (or (and (eq ensure t) (use-package-as-symbol name)) + ensure))) + (when package + (require 'package) + (when (consp package) + (use-package-pin-package (car package) (cdr package)) + (setq package (car package))) + (unless (package-installed-p package) + (condition-case-unless-debug err + (progn + (when (assoc package (bound-and-true-p + package-pinned-packages)) + (package-read-all-archive-contents)) + (if (assoc package package-archive-contents) + (package-install package) + (package-refresh-contents) + (when (assoc package (bound-and-true-p + package-pinned-packages)) + (package-read-all-archive-contents)) + (package-install package)) + t) + (error + (display-warning 'use-package + (format "Failed to install %s: %s" + name (error-message-string err)) + :error)))))))) + +;;;###autoload +(defun use-package-handler/:ensure (name _keyword ensure rest state) + (let* ((body (use-package-process-keywords name rest state)) + (ensure (and (not (plist-member rest :vc)) ensure))) + ;; We want to avoid installing packages when the `use-package' macro is + ;; being macro-expanded by elisp completion (see `lisp--local-variables'), + ;; but still install packages when byte-compiling, to avoid requiring + ;; `package' at runtime. + (if (bound-and-true-p byte-compile-current-file) + ;; Eval when byte-compiling, + (funcall use-package-ensure-function name ensure state) + ;; or else wait until runtime. + (push `(,use-package-ensure-function ',name ',ensure ',state) + body)) + body)) + +(add-to-list 'use-package-defaults + '(:ensure (list use-package-always-ensure) + (lambda (name args) + (and use-package-always-ensure + (not (plist-member args :load-path))))) t) + +(add-to-list 'use-package-defaults + '(:pin use-package-always-pin use-package-always-pin) t) + +(add-to-list 'use-package-keywords :ensure) +(add-to-list 'use-package-keywords :pin) + +(provide 'use-package-ensure) + +;;; use-package-ensure.el ends here diff --git a/site-lisp/use-package-2.4.6/use-package-jump.el b/site-lisp/use-package-2.4.6/use-package-jump.el new file mode 100644 index 0000000..604b260 --- /dev/null +++ b/site-lisp/use-package-2.4.6/use-package-jump.el @@ -0,0 +1,74 @@ +;;; use-package-jump.el --- Attempt to jump to a use-package declaration -*- lexical-binding: t; -*- + +;; Copyright (C) 2012-2024 Free Software Foundation, Inc. + +;; Author: John Wiegley <johnw@newartisans.com> +;; Maintainer: John Wiegley <johnw@newartisans.com> + +;; 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 <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Provides the command `M-x use-package-jump-to-package-form'. However, it +;; only works if the package being jumped to was required during +;; initialization. If it was autoloaded, it will not work. +;; Improvements are needed. +;; +;; See the `use-package' info manual for more information. + +;;; Code: + +(require 'use-package-core) + +(defun use-package-find-require (package) + "Find file that required PACKAGE by searching `load-history'. +Returns an absolute file path or nil if none is found." + (catch 'suspect + (dolist (filespec load-history) + (dolist (entry (cdr filespec)) + (when (equal entry (cons 'require package)) + (throw 'suspect (car filespec))))))) + +;;;###autoload +(defun use-package-jump-to-package-form (package) + "Attempt to find and jump to the `use-package' form that loaded PACKAGE. +This will only find the form if that form actually required +PACKAGE. If PACKAGE was previously required then this function +will jump to the file that originally required PACKAGE instead." + (interactive (list (completing-read "Package: " features))) + (let* ((package (if (stringp package) (intern package) package)) + (requiring-file (use-package-find-require package)) + file location) + (if (null requiring-file) + (user-error "Can't find file requiring file; may have been autoloaded") + (setq file (if (string= (file-name-extension requiring-file) "elc") + (concat (file-name-sans-extension requiring-file) ".el") + requiring-file)) + (when (file-exists-p file) + (find-file-other-window file) + (save-excursion + (goto-char (point-min)) + (setq location + (re-search-forward + (format (eval use-package-form-regexp-eval) package) nil t))) + (if (null location) + (message "No use-package form found.") + (goto-char location) + (beginning-of-line)))))) + +(provide 'use-package-jump) + +;;; use-package-jump.el ends here diff --git a/site-lisp/use-package-2.4.6/use-package-lint.el b/site-lisp/use-package-2.4.6/use-package-lint.el new file mode 100644 index 0000000..15c5880 --- /dev/null +++ b/site-lisp/use-package-2.4.6/use-package-lint.el @@ -0,0 +1,80 @@ +;;; use-package-lint.el --- Attempt to find errors in use-package declarations -*- lexical-binding: t; -*- + +;; Copyright (C) 2012-2024 Free Software Foundation, Inc. + +;; Author: John Wiegley <johnw@newartisans.com> +;; Maintainer: John Wiegley <johnw@newartisans.com> + +;; 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 <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Provides the command `M-x use-package-lint'. +;; +;; See the `use-package' info manual for more information. + +;;; Code: + +(require 'cl-lib) +(require 'use-package-core) + +(defun use-package-lint-declaration (name plist) + (dolist (path (plist-get plist :load-path)) + (unless (file-exists-p path) + (display-warning + 'use-package + (format "%s :load-path does not exist: %s" + name path) :error))) + + (unless (or (plist-member plist :disabled) + (plist-get plist :no-require) + (locate-library (use-package-as-string name) nil + (plist-get plist :load-path))) + (display-warning + 'use-package + (format "%s module cannot be located" name) :error)) + + ;; (dolist (command (plist-get plist :commands)) + ;; (unless (string= (find-lisp-object-file-name command nil) + ;; (locate-library (use-package-as-string name) nil + ;; (plist-get plist :load-path))) + ;; (display-warning + ;; 'use-package + ;; (format "%s :command is from different path: %s" + ;; name (symbol-name command)) :error))) + ) + +;;;###autoload +(defun use-package-lint () + "Check for errors in `use-package' declarations. +For example, if the module's `:if' condition is met, but even +with the specified `:load-path' the module cannot be found." + (interactive) + (save-excursion + (goto-char (point-min)) + (let ((re (eval use-package-form-regexp-eval))) + (while (re-search-forward re nil t) + (goto-char (match-beginning 0)) + (let ((decl (read (current-buffer)))) + (when (eq (car decl) 'use-package) + (use-package-lint-declaration + (use-package-as-string (cadr decl)) + (use-package-normalize-keywords + (cadr decl) (cddr decl))))))))) + +(provide 'use-package-lint) + +;;; use-package-lint.el ends here diff --git a/site-lisp/use-package-2.4.6/use-package-pkg.el b/site-lisp/use-package-2.4.6/use-package-pkg.el new file mode 100644 index 0000000..f362c86 --- /dev/null +++ b/site-lisp/use-package-2.4.6/use-package-pkg.el @@ -0,0 +1,2 @@ +;; Generated package description from use-package.el -*- no-byte-compile: t -*- +(define-package "use-package" "2.4.6" "A configuration macro for simplifying your .emacs" '((emacs "24.3") (bind-key "2.4")) :commit "d8e9eb73c2b5f93adf3ae29d1349ce2161e23cb4" :authors '(("John Wiegley" . "johnw@newartisans.com")) :maintainer '("John Wiegley" . "johnw@newartisans.com") :keywords '("dotemacs" "startup" "speed" "config" "package" "extensions") :url "https://github.com/jwiegley/use-package") diff --git a/site-lisp/use-package-2.4.6/use-package.el b/site-lisp/use-package-2.4.6/use-package.el new file mode 100644 index 0000000..fd24966 --- /dev/null +++ b/site-lisp/use-package-2.4.6/use-package.el @@ -0,0 +1,56 @@ +;;; use-package.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*- + +;; Copyright (C) 2012-2024 Free Software Foundation, Inc. + +;; Author: John Wiegley <johnw@newartisans.com> +;; Maintainer: John Wiegley <johnw@newartisans.com> +;; Created: 17 Jun 2012 +;; Version: 2.4.6 +;; Package-Requires: ((emacs "24.3") (bind-key "2.4")) +;; Keywords: dotemacs startup speed config package extensions +;; URL: https://github.com/jwiegley/use-package + +;; This is a GNU ELPA :core package. Avoid functionality that is not +;; compatible with the version of Emacs recorded above. + +;; 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 <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; The `use-package' declaration macro allows you to isolate package +;; configuration in your init file 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! +;; +;; See the `use-package' info manual for more information. + +;;; Code: + +(require 'use-package-core) + +(require 'use-package-bind-key) +(require 'use-package-diminish) +(require 'use-package-delight) +(require 'use-package-ensure) + +(declare-function use-package-jump-to-package-form "use-package-jump") +(autoload #'use-package-jump-to-package-form "use-package-jump" nil t) + +(provide 'use-package) + +;;; use-package.el ends here diff --git a/site-lisp/use-package-2.4.6/use-package.info b/site-lisp/use-package-2.4.6/use-package.info new file mode 100644 index 0000000..2620d35 --- /dev/null +++ b/site-lisp/use-package-2.4.6/use-package.info @@ -0,0 +1,2554 @@ +This is docLApxXS.info, produced by makeinfo version 6.8 from +use-package.texi. + +This manual is for use-package 2.4.5 from GNU ELPA. + + Copyright © 2022–2024 Free Software Foundation, Inc. + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.3 or any later version published by the Free Software + Foundation; with no Invariant Sections, with the Front-Cover Texts + being “A GNU Manual”, and with the Back-Cover Texts as in (a) + below. A copy of the license is included in the section entitled + “GNU Free Documentation License”. + + (a) The FSF’s Back-Cover Text is: “You have the freedom to copy and + modify this GNU manual.” +INFO-DIR-SECTION Emacs misc features +START-INFO-DIR-ENTRY +* use-package: (use-package). Declarative package configuration for Emacs. +END-INFO-DIR-ENTRY + + +File: docLApxXS.info, Node: Top, Next: Basic Concepts, Up: (dir) + +use-package User Manual +*********************** + +The ‘use-package’ macro allows you to set up package customization in +your init file in a declarative way. It takes care of many things for +you that would otherwise require a lot of repetitive boilerplate code. +It can help with common customization, such as binding keys, setting up +hooks, customizing user options and faces, autoloading, and more. It +also helps you keep Emacs startup fast, even when you use many (even +hundreds) of packages. + + Note that use-package is not a package manager. Although use-package +does have the useful capability to interface with the Emacs package +manager, its primary purpose is help with the configuration and loading +of packages, not with managing their download, upgrades, and +installation. + + This manual is for use-package 2.4.5 from GNU ELPA. + + Copyright © 2022–2024 Free Software Foundation, Inc. + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.3 or any later version published by the Free Software + Foundation; with no Invariant Sections, with the Front-Cover Texts + being “A GNU Manual”, and with the Back-Cover Texts as in (a) + below. A copy of the license is included in the section entitled + “GNU Free Documentation License”. + + (a) The FSF’s Back-Cover Text is: “You have the freedom to copy and + modify this GNU manual.” + +* Menu: + +* Basic Concepts:: Basic concepts of use-package. +* Getting Started:: A gentle introduction to use-package. +* Loading Packages:: How and when packages are loaded. +* Configuring Packages:: Package configuration keywords. +* Installing packages:: Ensuring packages are available. +* Byte-compiling:: Byte-compiling your init file. +* Troubleshooting:: What to do when there’s trouble. + +Appendices +* Keyword extensions:: Adding new use-package keywords. +* History:: History and acknowledgments. +* GNU Free Documentation License:: The license for this manual. + +Index +* Index:: + + +File: docLApxXS.info, Node: Basic Concepts, Next: Getting Started, Prev: Top, Up: Top + +1 Basic Concepts +**************** + +use-package provides the ‘use-package’ macro, that simplifies the +customization and use of packages in Emacs. It was created for a few +basic reasons, each of which drove the design. Understanding these +reasons may help make some of those decisions clearer: + + 1. Allow gathering all the configuration details of a package into one + place, making it easier to copy, disable, or move it elsewhere in + the init file. + + 2. Reduce duplication and repetitive boilerplate, capturing several + common practices as mere keywords both easy and intuitive to use. + + 3. Make startup time of Emacs as short as possible, without + sacrificing the quantity of add-on packages used. + + 4. Ensure that errors encountered during startup disable only the + package(s) raising the error(s), and as little else as possible, + leaving Emacs as close to fully functional as possible. + + 5. Allow byte-compiling your init file, so that any warnings or errors + you see at startup are meaningful. In this way, even if + byte-compilation is not used for speed (see item 3 above), it can + still be used as a sanity check. + + It is worth noting that use-package is not intended to replace the +standard customization command ‘M-x customize’ (*note (emacs)Easy +Customization::). On the contrary, it is designed to work together with +it, for things that Customize cannot do. + + +File: docLApxXS.info, Node: Getting Started, Next: Loading Packages, Prev: Basic Concepts, Up: Top + +2 Getting Started +***************** + +This chapter provides instructions and examples for quickly getting +started with use-package. In this manual, we say that each call to the +‘use-package’ macro in your init file is a “declaration”, to highlight +the declarative nature of its syntax. + + To unconditionally load a package named ‘foo’, add the following +declaration to your init file: + + (use-package foo) + +This declaration is equivalent to using ‘require’ (*note (elisp)Named +Features::), with some use-package specific error handling added in. +Just like ‘require’, it needs the package ‘foo’ to be installed and +available via your ‘load-path’ (*note Installing packages::). + + To evaluate some Lisp _before_ the ‘foo’ package is loaded, use the +‘:init’ keyword: + + (use-package foo + :init + (setq foo-variable t)) + + Similarly, ‘:config’ can be used to execute code _after_ a package is +loaded. In cases where loading is done lazily (*note Loading +Packages::), this execution is deferred until after the loading actually +occurs. As you might expect, you can use ‘:init’ and ‘:config’ +together: + + (use-package foo + :init + (setq foo-variable t) + :config + (foo-mode 1)) + + The above declarations will load the ‘foo’ package immediately. In +most cases, this is not necessary or desirable, as that will slow down +Emacs startup. Instead, you should try to set things up so that +packages are only loaded when they are actually needed (this is known as +“autoloading”). If you have installed a package from GNU ELPA that +provides its own autoloads, it is often enough to say: + + (use-package foo + :defer t) + +This will avoid loading the package. Now, when you run any autoloaded +command, the package ‘foo’ is loaded automatically. (Which commands +from a package are marked to auto-load by default is the decision of the +package authors.) + + In some cases, you might need or want to provide your own autoloads. +The more complex example below autoloads the commands ‘isearch-moccur’ +and ‘isearch-all’ from the package ‘color-moccur.el’, and binds keys +both globally and in ‘isearch-mode-map’. When one of these two commands +are used, the package will be loaded. At that point, ‘moccur-edit’ is +also loaded, to allow editing of the ‘moccur’ buffer. + + (use-package color-moccur + :commands (isearch-moccur isearch-all) + :bind (("M-s O" . moccur) + :map isearch-mode-map + ("M-o" . isearch-moccur) + ("M-O" . isearch-moccur-all)) + :init + (setq isearch-lazy-highlight t) + :config + (use-package moccur-edit)) + + Some packages will suggest ready-made ‘use-package’ declarations that +you can use. Where possible, it is a good idea to copy them, and use +that as a starting point. + + That should be enough to get you started! + + +File: docLApxXS.info, Node: Loading Packages, Next: Configuring Packages, Prev: Getting Started, Up: Top + +3 Loading Packages +****************** + +Before use-package can load an Emacs Lisp package, it must be available +in a directory on your ‘load-path’. When you install packages using the +built-in ‘install-package’ command, it will do this automatically for +you. Packages shipped with Emacs (built-in packages) are always +available. + + Some packages have more than one library. In those cases, you might +need more than one ‘use-package’ declaration to make sure the package is +properly loaded. For complex configurations, you might also need more +than one declaration for a package with the same name. + + use-package can interface with ‘package.el’ to install packages on +Emacs start. *Note Installing packages::, for details. + +* Menu: + +* Loading basics:: How and when packages are loaded. +* Deferring loading:: Loading packages later. +* Forcing loading:: Loading packages immediately. +* Conditional loading:: Loading packages conditionally. +* Loading sequentially:: Loading packages in sequence. +* The emacs package:: Customizing built-in variables. +* Load dependencies:: Don’t load without dependencies. +* Manual installation:: Loading manually installed packages. + + +File: docLApxXS.info, Node: Loading basics, Next: Deferring loading, Up: Loading Packages + +3.1 How and when use-package loads packages +=========================================== + +The call to the ‘use-package’ macro will load a package either +immediately, or when the package is first used (via autoloading). In +the simplest case, a ‘use-package’ declaration loads a package when it +is evaluated.(1) If the declaration is in your init file, this happens +automatically each time Emacs is started. + + For example, the declaration below immediately loads the library +‘foo’, just like ‘require’ would: + + (use-package foo) + +If the library ‘foo’ is not available in your ‘load-path’, the +declaration logs a warning to the ‘*Messages*’ buffer. + + Note that a “package” is different from an Emacs Lisp “library”. The +above declaration tells use-package to load the _library_ ‘foo.el’, +which in the overwhelming majority of cases also resides in a _package_ +named ‘foo’. But the package ‘foo’ might also contain a library named +‘foo-extra.el’. If that library is not loaded automatically, you will +need a separate ‘use-package’ declaration to make sure that it is loaded +when needed. This manual will often use the terms “package” and +“library” interchangeably, as this distinction does not usually matter, +but you should keep it in mind for the cases when it does. + + The details of how and when you should load a package might differ +from one package to another. When in doubt, refer to the package +documentation for details. + + ---------- Footnotes ---------- + + (1) This happens both at run-time and at compile-time. *Note +Byte-compiling::. + + +File: docLApxXS.info, Node: Deferring loading, Next: Forcing loading, Prev: Loading basics, Up: Loading Packages + +3.2 Deferring package loading +============================= + +In the examples we have seen so far, use-package loads packages every +time you start Emacs, even if that package is never used. That will +make starting Emacs slower. use-package therefore allows setting things +up in such a way that packages are only loaded when some of the +package’s commands is first used (either with ‘M-x’ or via some key +binding). This is based on autoloading, a full description of which is +outside the scope of this manual. *Note (elisp)Autoload::, for the full +story. + + Some ‘use-package’ keywords provide autoload “triggers” that cause a +package to be loaded when certain events occur. For example, the +‘:hook’ keyword sets up a trigger that fires when the specified hook is +run, and then loads the package automatically. The other trigger +keywords, all of which are described later in this manual, are +‘:commands’, ‘:bind’, ‘:bind*’, ‘:bind-keymap’, ‘:bind-keymap*’, +‘:mode’, and ‘:interpreter’. + +The ‘:defer’ keyword +-------------------- + +If you did not specify any autoloading keyword, use-package will fall +back to loading the package immediately (typically when Emacs is +starting up). This can be overridden using the ‘:defer’ keyword. It +takes one boolean argument: a non-‘nil’ value means to stop this package +from being immediately loaded. Here is an example of using ‘:defer’ to +postpone loading the package ‘foo’: + + (use-package foo + :defer t) + + Using ‘:defer t’ by itself like this is rarely useful. Typically, +you would only use it together with a keyword like ‘:config’ (*note Lisp +Configuration::), or ‘:ensure’ (*note Installing packages::). + +Defer loading until idle for N seconds +-------------------------------------- + +You can also give a numeric argument N to ‘:defer’ to specify that a +package should be loaded (if it hasn’t already) after Emacs has been +idle for N seconds. For example, use the following to make use-package +load ‘foo’ after 30 seconds of idle time: + + (use-package foo + :defer 30) + +When to use ‘:defer’ +-------------------- + +When using autoloading keywords, there is no need to also use ‘:defer’. +It doesn’t hurt to add it in this case, perhaps for extra clarity, but +it is redundant. + + You should use ‘:defer’ to force deferred loading, in cases when +use-package isn’t creating any autoloads for you. For example, you +might know that some other package will already do something to cause +your package to load at the appropriate time. This is usually the case +when you install a package using ‘package-install’, as packages +installed in this way normally always have their own autoloads already +set up. + +Making ‘:defer t’ the default +----------------------------- + +If you customize the user option ‘use-package-always-defer’ to +non-‘nil’, the ‘use-package’ macro will behave as if ‘:defer t’ is +always specified. This can be overridden for individual declarations +using either ‘:defer nil’ or ‘:demand t’ (*note Forcing loading::). + + +File: docLApxXS.info, Node: Forcing loading, Next: Conditional loading, Prev: Deferring loading, Up: Loading Packages + +3.3 Forcing package to load immediately +======================================= + +The presence of autoloading trigger keywords can be overridden using +‘:demand t’, which forces the package to load immediately. Thus, even +if you use an autoloading keyword such as ‘:bind’ (*note Key +bindings::), adding ‘:demand’ will force loading to occur immediately. +It will also avoid creating an autoload for the bound key, as it would +be redundant. + + If you specify both ‘:demand t’ and ‘:defer t’, the ‘:defer’ keyword +will take precedence. + + +File: docLApxXS.info, Node: Conditional loading, Next: Loading sequentially, Prev: Forcing loading, Up: Loading Packages + +3.4 Loading packages conditionally +================================== + +The ‘:if’, ‘:when’, and ‘:unless’ keywords predicates the loading and +initialization of packages. They all accept one argument, an Emacs Lisp +form that is evaluated at run-time. + + If the argument of the ‘:if’ keyword evaluates to non-‘nil’, the +package will be loaded and initialized. The ‘:when’ keyword is provided +as an alias for ‘:if’. Finally, the ‘:unless’ keyword is the inverse of +‘:if’, such that ‘:unless foo’ means the same thing as ‘:if (not foo)’. + + For example, if you only want to load ‘foo’ in graphical Emacs +sessions, you could use the following: + + (use-package foo + :if (display-graphic-p)) + +Some common use cases +--------------------- + +Here are some common cases for conditional loading, and how to achieve +them. + + • Operating system + + The following example loads a package only on GNU/Linux. See the + docstring of ‘system-type’ for other valid values. + + :if (eq system-type 'gnu/linux) + + • Window system + + The example below loads a package only on macOS and X. See the + docstring of ‘window-system’ for valid values. + + :if (memq window-system '(ns x)) + + • Installed package + + The following example loads a package only when the ‘foo’ package + is installed. + + :if (package-installed-p 'foo) + + • Libraries in ‘load-path’ + + The example below loads a package only when ‘foo.el’ is available + in your ‘load-path’ (for example, if you installed that file + manually): + + :if (locate-library "foo.el") + +Making conditional loading affect ‘:preface’ and ‘:ensure’ +---------------------------------------------------------- + +If you need to make a use-package form conditional so that the condition +occurs before even ‘:ensure’ (*note Install package::) or ‘:preface’ +(*note Preface keyword::), use ‘when’ around the ‘use-package’ form +itself. For example: + + (when (memq window-system '(mac ns)) + (use-package foo + :ensure t)) + + +File: docLApxXS.info, Node: Loading sequentially, Next: The emacs package, Prev: Conditional loading, Up: Loading Packages + +3.5 Loading packages in sequence +================================ + +Sometimes it only makes sense to configure a package after another one +has been loaded, because certain variables or functions are not in scope +until that time. This can be achieved with the ‘:after’ keyword, which +allows a fairly rich description of the exact conditions when loading +should occur. The ‘:after’ keyword takes as argument either a symbol +indicating the package name, a list of such symbols, or a list of +selectors (see below). + + Here is an example of using the GNU ELPA packages ‘hydra’, ‘ivy’, and +‘ivy-hydra’. Note that ‘ivy-hydra’ will always be loaded last: + + (use-package hydra) + + (use-package ivy) + + (use-package ivy-hydra + :after (ivy hydra)) + + In this case, because the declarations are evaluated in the order +they occur, the use of ‘:after’ is not strictly necessary. However, if +‘hydra’ and ‘ivy’ were to be autoloaded, using ‘:after’ guarantees that +‘ivy-hydra’ is not loaded until it is actually needed. By using +‘:after’, the above code will also work even if the order of the +declaration changes. This means that moving things around in your init +file is less likely to break things. + +Using ‘:after’ selectors +------------------------ + +The ‘:after’ keyword also accepts a list of selectors. By default, +‘:after (foo bar)’ is the same as ‘:after (:all foo bar)’, meaning that +loading of the given package will not happen until both ‘foo’ and ‘bar’ +have been loaded. Here are some of the other possibilities: + +:after (foo bar) +:after (:all foo bar) +:after (:any foo bar) +:after (:all (:any foo bar) (:any baz quux)) +:after (:any (:all foo bar) (:all baz quux)) + + When you nest selectors, such as in +‘(:any (:all foo bar) (:all baz quux))’, it means that the package will +be loaded when either both ‘foo’ and ‘bar’ have been loaded, or when +both ‘baz’ and ‘quux’ have been loaded. + + Pay attention when setting ‘use-package-always-defer’ to a non-‘nil’ +value, and also using the ‘:after’ keyword. In that case, you will need +to specify how the declared package is to be loaded: for example, by +some ‘:bind’ (*note Global keybindings::). If you are not using one of +the keywords that registers autoloads, such as ‘:bind’ or ‘:hook’ (*note +Hooks::), and your package manager does not provide autoloads, it is +possible that your package will never be loaded if you do not add +‘:demand t’ to those declarations. + + +File: docLApxXS.info, Node: The emacs package, Next: Load dependencies, Prev: Loading sequentially, Up: Loading Packages + +3.6 Customizing built-in variables +================================== + +Some users want to put all their customizations in use-package +declarations, even for variables, hooks, and options that are always +available, without loading any package.(1) + + For that purpose, you can use the no-op ‘emacs’ package: + + (use-package emacs + :init + (setq custom-file "~/.emacs.d/emacs-custom.el") + (load custom-file) + (setq frame-title-format "%b") + :custom + (use-short-answers t)) + + This declaration takes advantage of the fact that ‘(featurep 'emacs)’ +always returns true, and has no special meaning beyond that. It simply +provides a way to organize your customizations, without loading +anything. + + ---------- Footnotes ---------- + + (1) In other words, they are either preloaded in Emacs or defined in +Emacs’s C sources. + + +File: docLApxXS.info, Node: Load dependencies, Next: Manual installation, Prev: The emacs package, Up: Loading Packages + +3.7 Prevent loading if dependencies are missing +=============================================== + +While the ‘:after’ keyword delays loading until the dependencies are +loaded, the somewhat simpler ‘:requires’ keyword _never_ loads the +package if the dependencies are not available when the ‘use-package’ +declaration is evaluated. In this context, “available” means that ‘foo’ +is available if ‘(featurep 'foo)’ evaluates to a non-‘nil’ value. For +example: + + (use-package abbrev + :requires foo) + +This is the same as: + + (use-package abbrev + :if (featurep 'foo)) + + As a convenience, a list of such packages may be specified: + + (use-package abbrev + :requires (foo bar baz)) + + For more complex logic, such as that supported by ‘:after’, simply +use ‘:if’ and the appropriate Lisp expression. + + +File: docLApxXS.info, Node: Manual installation, Prev: Load dependencies, Up: Loading Packages + +3.8 Manually installed package +============================== + +When installing packages manually, without Emacs’s built-in package +manager (‘package.el’), it will obviously not help you set up autoloads +or add it to your ‘load-path’. You must do it yourself. However, +use-package makes this more convenient. + +* Menu: + +* Load path:: Using a custom ‘load-path’. +* Manual autoloads:: Setting up autoloads manually. + + +File: docLApxXS.info, Node: Load path, Next: Manual autoloads, Up: Manual installation + +3.8.1 Setting a custom ‘load-path’ +---------------------------------- + +When installing packages manually, you must make sure its libraries are +available on your ‘load-path’. *Note (emacs)Lisp Libraries::, for more +details about package loading. + + The ‘:load-path’ keyword provides a convenient way to add directories +to your load path. It takes as argument a symbol, a function, a string +or a list of strings. If a directory is specified as a relative file +name, it is expanded relative to ‘user-emacs-directory’. + + For example: + + (use-package org + :load-path "site-lisp/org/lisp/" + :commands org-mode) + + When using a symbol or a function to provide a dynamically generated +list of directories, you must inform the byte-compiler of this +definition, so that the value is available at byte-compilation time. +This is done by using the special form ‘eval-and-compile’ (as opposed to +‘eval-when-compile’, *note (elisp)Eval During Compile::). Furthermore, +this value is fixed to the value it had during compilation. If the +operation is costly, you do not have to repeat it again on each startup. +For example: + + (eval-and-compile + (defun ess-site-load-path () + (shell-command-to-string "find ~ -path ess/lisp"))) + + (use-package ess-site + :load-path (lambda () (list (ess-site-load-path))) + :commands R) + + +File: docLApxXS.info, Node: Manual autoloads, Prev: Load path, Up: Manual installation + +3.8.2 Setting up autoloads manually +----------------------------------- + +Packages often document how to set up its autoloads when it is being +manually installed. If it does, follow those instructions. Otherwise, +you might want to set them up manually. + + To autoload an interactive command, use the ‘:commands’ keyword, +which takes either a symbol or a list of symbols as its argument. It +creates autoloads for those commands (which defers loading of the module +until those commands are used). + + The ‘:autoload’ keyword takes the same arguments as ‘:commands’, but +is used to autoload non-interactive functions. Here is an example: + + (use-package org-crypt + :autoload org-crypt-use-before-save-magic) + + +File: docLApxXS.info, Node: Configuring Packages, Next: Installing packages, Prev: Loading Packages, Up: Top + +4 Configuring Packages +********************** + +This chapter describes the various keywords provided by ‘use-package’ +that help you configure packages. + +* Menu: + +* Lisp Configuration:: Using Lisp to configure packages. +* Key bindings:: Making your own keybindings. +* Hooks:: Adding functions to hooks. +* Modes and interpreters:: Enabling modes automatically. +* Magic handlers:: Using regexps to enable modes. +* User options:: Setting user options. +* Faces:: Customizing faces. +* Hiding minor modes:: Tidying up the mode line. + + +File: docLApxXS.info, Node: Lisp Configuration, Next: Key bindings, Up: Configuring Packages + +4.1 Using Lisp code for configuring packages +============================================ + +The most general way to add customizations are the ‘:preface’, ‘:init’, +and ‘:config’ keywords. They all accept one or more Emacs Lisp forms, +up to the next keyword, that are evaluated in order. This lets you add +arbitrary Lisp code to your ‘use-package’ declarations. + + The only difference between these keywords is when they are +evaluated. + +* Menu: + +* Preface keyword:: Evaluate code before anything else. +* Init keyword:: Evaluate code before loading package. +* Config keyword:: Evaluate code after loading package. +* Best practices:: When to use ‘:config’, ‘:init’, and ‘:preface’. + + +File: docLApxXS.info, Node: Preface keyword, Next: Init keyword, Up: Lisp Configuration + +4.1.1 ‘:preface’ is evaluated first +----------------------------------- + +The ‘:preface’ section is evaluated before anything else, except +‘:disabled’ and ‘:ensure’. It can be used to establish function and +variable definitions that will: + + 1. Make the byte-compiler happy: it will not complain about functions + whose definitions are unknown. + + 2. Define functions and variables that will be used in an ‘:if’ test. + + Note that whatever is specified within ‘:preface’ is evaluated both +at load time and at byte-compilation time, in order to ensure that +definitions are seen by both the Lisp evaluator and the byte-compiler. +Therefore, you should avoid having any side-effects in your ‘:preface’ +forms, and restrict them to symbol declarations and definitions. + + +File: docLApxXS.info, Node: Init keyword, Next: Config keyword, Prev: Preface keyword, Up: Lisp Configuration + +4.1.2 ‘:init’ is evaluated before loading package +------------------------------------------------- + +The ‘:init’ section is evaluated just before the package is loaded. +Note that the ‘:init’ form is run unconditionally – even if the package +happens to not exist on your system. You must therefore remember to +restrict ‘:init’ code to what would succeed either way; put the rest in +the ‘:config’ section. ‘:init’ also always happens before package load, +whether ‘:config’ has been deferred or not. + + +File: docLApxXS.info, Node: Config keyword, Next: Best practices, Prev: Init keyword, Up: Lisp Configuration + +4.1.3 ‘:config’ is evaluated after loading package +-------------------------------------------------- + +The ‘:config’ section is evaluated after the package has been loaded. +If the package is loaded immediately, this happens immediately after +that, but if loading is done lazily (*note Loading Packages::), this is +deferred until after the package has been loaded. + + In general, you should keep ‘:init’ forms as simple and quick as +possible, and put as much as you can get away with into the ‘:config’ +section. That way, deferred loading can help your Emacs start as +quickly as possible. + + +File: docLApxXS.info, Node: Best practices, Prev: Config keyword, Up: Lisp Configuration + +4.1.4 When to use ‘:preface’, ‘:config’ and ‘:init’? +---------------------------------------------------- + +Where possible, it is better to avoid ‘:preface’, ‘:config’ and ‘:init’. +Instead, prefer autoloading keywords such as ‘:bind’ (*note Key +bindings::), ‘:hook’ (*note Hooks::), and ‘:mode’ (*note Modes and +interpreters::), as they will take care of setting up autoloads for you +without any need for boilerplate code. For example, consider the +following declaration: + + (use-package foo + :init + (add-hook 'some-hook 'foo-mode)) + +This has two problems. First, it will unconditionally load the package +‘foo’ on startup, which will make things slower. You can fix this by +adding ‘:defer t’: + + (use-package foo + :defer t + :init + (add-hook 'some-hook 'foo-mode)) + +This is better, as ‘foo’ is now only loaded when it is actually needed +(that is, when the hook ‘some-hook’ is run). + + The second problem is that there is a lot of boilerplate that you +have to write. In this case, it might not be so bad, but avoiding that +was what use-package was made to allow. The better option in this case +is therefore to use ‘:hook’ (*note Hooks::), which also implies +‘:defer t’. The above is thereby reduced down to: + + (use-package foo + :hook some-hook) + + Now use-package will set up autoloading for you, and your Emacs +startup time will not suffer one bit. + + +File: docLApxXS.info, Node: Key bindings, Next: Hooks, Prev: Lisp Configuration, Up: Configuring Packages + +4.2 Key bindings +================ + +One common thing to do when loading a package is to bind keys to +commands within that module. Without use-package, this would be done +using a combination of ‘keymap-local-set’, ‘keymap-global-set’ and +various autoloads. With use-package, you can simplify this using the +‘:bind’ keyword, as described in this section. + +* Menu: + +* Global keybindings:: Bindings you can use anywhere. +* Binding in keymaps:: Bindings for particular modes. +* Binding to a keymap:: Binding a key to a keymap. +* Binding to repeat-maps:: Binding repeating keys. +* Displaying keybindings:: Displaying personal key bindings. + + +File: docLApxXS.info, Node: Global keybindings, Next: Binding in keymaps, Up: Key bindings + +4.2.1 Global keybindings +------------------------ + +To bind keys globally, the ‘:bind’ keyword takes as its argument either +a single cons or a list of conses. Each cons has the form +‘(KEY . COMMAND)’, where KEY is a string indicating the key to bind, and +COMMAND is the name of a command (a symbol). The syntax for the keys is +similar to the syntax used by the ‘kbd’ function (see *note (emacs)Init +Rebinding::, for more information). + +Using ‘:bind’ with a single cons +-------------------------------- + +Here is an example of using a single cons: + + (use-package ace-jump-mode + :bind ("C-." . ace-jump-mode)) + +This does two things: first, it creates an autoload for the +‘ace-jump-mode’ command and defers loading of the ‘ace-jump-mode’ +package until you actually use it. Second, it binds the key ‘C-.’ to +that command globally. + +Using ‘:bind’ with a list of conses +----------------------------------- + +Here is an example of using ‘:bind’ with a list of conses: + + (use-package hi-lock + :bind (("M-o l" . highlight-lines-matching-regexp) + ("M-o r" . highlight-regexp) + ("M-o w" . highlight-phrase))) + +This binds the three key sequences to the corresponding commands. + +Using special keys +------------------ + +Inside key strings, special keys like ‘TAB’ or ‘F1’–‘F12’ have to be +written inside angle brackets, e.g., ‘"C-<up>"’. Standalone special +keys (and some combinations) can be written in square brackets, +e.g. ‘[tab]’ instead of ‘"<tab>"’. + + Examples: + + (use-package helm + :bind (("M-x" . helm-M-x) + ("M-<f5>" . helm-find-files) + ([f10] . helm-buffers-list) + ([S-f10] . helm-recentf))) + +Remapping commands +------------------ + +Remapping of commands with ‘:bind’ and ‘bind-key’ works as expected, +because when the binding is a vector, it is passed straight to +‘define-key’. *Note (elisp)Remapping Commands::, for more information +about command remapping. For example, the following declaration will +rebind ‘fill-paragraph’ (bound to ‘M-q’ by default) to ‘unfill-toggle’: + + (use-package unfill + :bind ([remap fill-paragraph] . unfill-toggle)) + +What ‘:bind’ does behind the scenes +----------------------------------- + +To understand what ‘:bind’ does behind the scenes, it might be useful to +consider an example: + + (use-package ace-jump-mode + :bind ("C-." . ace-jump-mode)) + +This could be expressed in a much more verbose way with the ‘:commands’ +and ‘:init’ keywords: + + (use-package ace-jump-mode + :commands ace-jump-mode + :init + (bind-key "C-." 'ace-jump-mode)) + +Without using even the ‘:commands’ keyword, we could also write the +above like so: + + (use-package ace-jump-mode + :defer t + :init + (autoload 'ace-jump-mode "ace-jump-mode" nil t) + (bind-key "C-." 'ace-jump-mode)) + + Although these three forms are all equivalent, the first form is +usually the best, as it will save some typing. + + +File: docLApxXS.info, Node: Binding in keymaps, Next: Binding to a keymap, Prev: Global keybindings, Up: Key bindings + +4.2.2 Key bindings in local keymaps +----------------------------------- + +Slightly different from binding a key to a keymap, is binding a key +_within_ a local keymap that only exists after the package is loaded. +‘use-package’ supports this with a ‘:map’ modifier, taking the local +keymap to bind to: + + (use-package helm + :bind (:map helm-command-map + ("C-c h" . helm-execute-persistent-action))) + +The effect of this is to wait until ‘helm’ has loaded, and then to bind +the key sequence ‘C-c h’ to ‘helm-execute-persistent-action’ within +Helm’s local keymap, ‘helm-command-map’. + + Multiple uses of ‘:map’ may be specified. Any binding occurring +before the first use of ‘:map’ are applied to the global keymap: + + (use-package term + :bind (("C-c t" . term) + :map term-mode-map + ("M-p" . term-send-up) + ("M-n" . term-send-down) + :map term-raw-map + ("M-o" . other-window) + ("M-p" . term-send-up) + ("M-n" . term-send-down))) + + +File: docLApxXS.info, Node: Binding to a keymap, Next: Binding to repeat-maps, Prev: Binding in keymaps, Up: Key bindings + +4.2.3 Binding to keymaps +------------------------ + +Normally ‘:bind’ expects that commands are functions that will be +autoloaded from the given package. However, this does not work if one +of those commands is actually a keymap, since keymaps are not functions, +and cannot be autoloaded using the built-in ‘autoload’ function. + + To handle this case, ‘use-package’ offers a special, limited variant +of ‘:bind’ called ‘:bind-keymap’. The only difference is that the +“commands” bound to by ‘:bind-keymap’ must be keymaps defined in the +package, rather than interactive functions. This is handled behind the +scenes by generating custom code that loads the package containing the +keymap, and then re-executes your keypress after the first load, to +reinterpret that keypress as a prefix key. + + For example: + + (use-package foo + :bind-keymap ("C-c p" . foo-command-map)) + + +File: docLApxXS.info, Node: Binding to repeat-maps, Next: Displaying keybindings, Prev: Binding to a keymap, Up: Key bindings + +4.2.4 Binding to repeat-maps +---------------------------- + +A special case of binding within a local keymap is when that keymap is +used by ‘repeat-mode’ (*note (emacs)Repeating::). These keymaps are +usually defined specifically for this. Using the ‘:repeat-map’ keyword, +and passing it a name for the map it defines, will bind all the +following keys inside that map, and (by default) set the ‘repeat-map’ +property of each bound command to that map. + + The following example creates a keymap called +‘git-gutter+-repeat-map’, makes four bindings in it, then sets the +‘repeat-map’ property of each bound command (‘git-gutter+-next-hunk’, +‘git-gutter+-previous-hunk’, ‘git-gutter+-stage-hunks’, and +‘git-gutter+-revert-hunk’) to that keymap. + + (use-package git-gutter+ + :bind + (:repeat-map git-gutter+-repeat-map + ("n" . git-gutter+-next-hunk) + ("p" . git-gutter+-previous-hunk) + ("s" . git-gutter+-stage-hunks) + ("r" . git-gutter+-revert-hunk))) + + Specifying ‘:exit’ inside the scope of ‘:repeat-map’ will prevent the +‘repeat-map’ property from being set, so that the command can be used +from within the repeat map, but after using it the repeat map will no +longer be available. This is useful for commands often used at the end +of a series of repeated commands. Example: + + (use-package git-gutter+ + :bind + (:repeat-map my/git-gutter+-repeat-map + ("n" . git-gutter+-next-hunk) + ("p" . git-gutter+-previous-hunk) + ("s" . git-gutter+-stage-hunks) + ("r" . git-gutter+-revert-hunk) + :exit + ("c" . magit-commit-create) + ("C" . magit-commit) + ("b" . magit-blame))) + + Specifying ‘:continue’ _forces_ setting the ‘repeat-map’ property +(just like _not_ specifying ‘:exit’), so the above snippet is equivalent +to: + + (use-package git-gutter+ + :bind + (:repeat-map my/git-gutter+-repeat-map + :exit + ("c" . magit-commit-create) + ("C" . magit-commit) + ("b" . magit-blame) + :continue + ("n" . git-gutter+-next-hunk) + ("p" . git-gutter+-previous-hunk) + ("s" . git-gutter+-stage-hunks) + ("r" . git-gutter+-revert-hunk))) + + +File: docLApxXS.info, Node: Displaying keybindings, Prev: Binding to repeat-maps, Up: Key bindings + +4.2.5 Displaying personal keybindings +------------------------------------- + +The ‘:bind’ keyword uses the ‘bind-keys’ macro from the ‘bind-key.el’ +library to set up keybindings. It keeps track of all keybindings you +make, so that you can display them separately from the default +keybindings. + + Use ‘M-x describe-personal-keybindings’ to see all keybindings you’ve +set using either the ‘:bind’ keyword or the ‘bind-keys’ macro. + + +File: docLApxXS.info, Node: Hooks, Next: Modes and interpreters, Prev: Key bindings, Up: Configuring Packages + +4.3 Hooks +========= + +The ‘:hook’ keyword allows adding functions to hooks. It takes one +argument of the form HOOKS, specifying one or more functions to add to +one or more hooks. For the purposes of ‘:hook’, the name of hook +variables should always exclude the ‘-hook’ suffix. It is appended +automatically for you, to save some typing. + + For example, consider the following ‘use-package’ declaration that +sets up autoloads for ‘company-mode’ from the ‘company’ package, and +adds ‘company-mode’ to ‘prog-mode-hook’: + + (use-package company + :commands company-mode + :init + (add-hook 'prog-mode-hook #'company-mode)) + + Using ‘:hook’, this can be simplified to: + + (use-package company + :hook (prog-mode . company-mode)) + + Here, ‘:hook’ will automatically set up autoloads for the +‘company-mode’ command, so there is no need to use ‘:commands’. + + The ‘:hook’ keyword will also assume that the name of the function +you want to add is the same as the package name with ‘-mode’ appended to +it. Taking this into account, you can simplify the above to the +equivalent: + + (use-package company + :hook prog-mode) + + You can also provide a list of hooks. When multiple hooks should be +applied, the following examples are all equivalent: + + (use-package company + :hook (prog-mode text-mode)) + + (use-package company + :hook ((prog-mode text-mode) . company-mode)) + + (use-package company + :hook ((prog-mode . company-mode) + (text-mode . company-mode))) + + (use-package company + :commands company-mode + :init + (add-hook 'prog-mode-hook #'company-mode) + (add-hook 'text-mode-hook #'company-mode)) + + One common mistake when using ‘:hook’ is to forget to omit the +‘-hook’ suffix, which, as already explained, is appended automatically. +Therefore, the following will not work, as it attempts to add a function +to non-existent ‘prog-mode-hook-hook’: + + ;; DOES NOT WORK + (use-package ace-jump-mode + :hook (prog-mode-hook . ace-jump-mode)) + + If you do not like this behavior, you can customize the user option +‘use-package-hook-name-suffix’ to ‘nil’. The value of this variable is +‘"-hook"’ by default. + + The use of ‘:hook’, as with ‘:bind’, ‘:mode’, ‘:interpreter’, etc., +causes the functions being hooked to implicitly be read as ‘:commands’. +This means that they will establish interactive ‘autoload’ definitions +for that module, if not already defined as functions), and so ‘:defer t’ +is also implied by ‘:hook’. + + +File: docLApxXS.info, Node: Modes and interpreters, Next: Magic handlers, Prev: Hooks, Up: Configuring Packages + +4.4 Modes and interpreters +========================== + +Similar to ‘:bind’, you can use ‘:mode’ and ‘:interpreter’ to establish +a deferred binding within the ‘auto-mode-alist’ and +‘interpreter-mode-alist’ variables (*note (elisp)Auto Major Mode::). +The specifier to either keyword can be a cons cell, a list of cons +cells, or a string or regexp. + + The following example reproduces the default ‘ruby-mode’ +configuration, exactly as it is in Emacs out-of-the-box. That mode is +enabled automatically when a file whose name matches the regexp +‘"\\.rb\\'"’ (a file with the ‘.rb’ extension), or when the first line +of the file (known as the “shebang”) matches the string ‘"ruby"’: + + (use-package ruby-mode + :mode "\\.rb\\'" + :interpreter "ruby") + + The default ‘python-mode’ configuration can be reproduced using the +declaration below. Note that the package that should be loaded differs +from the mode name in this case, so we must use a cons: + + ;; The package is "python" but the mode is "python-mode": + (use-package python + :mode ("\\.py\\'" . python-mode) + :interpreter ("python" . python-mode)) + + Both the ‘:mode’ and ‘:interpreter’ keywords also accept a list of +regexps: + + (use-package foo + ;; Equivalent to "\\(ba[rz]\\)\\'": + :mode ("\\.bar\\'" "\\.baz\\'") + ;; Equivalent to "\\(foo[ab]\\)": + :interpreter ("fooa" "foob")) + + +File: docLApxXS.info, Node: Magic handlers, Next: User options, Prev: Modes and interpreters, Up: Configuring Packages + +4.5 Magic handlers +================== + +Similar to ‘:mode’ and ‘:interpreter’, you can also use ‘:magic’ and +‘:magic-fallback’ to cause certain function to be run if the beginning +of a file matches a given regular expression, as if these regular +expressions were added to ‘magic-mode-alist’ and +‘magic-fallback-mode-alist’ (*note (elisp)Auto Major Mode::). The +difference between ‘:magic’ and ‘:magic-fallback’, is that the latter +has a lower priority than ‘:mode’. + + Here is an example: + + (use-package pdf-tools + :magic ("%PDF" . pdf-view-mode) + :config + (pdf-tools-install :no-query)) + + This registers an autoloaded command for ‘pdf-view-mode’, defers +loading of ‘pdf-tools’, and runs ‘pdf-view-mode’ if the beginning of a +buffer matches the string ‘"%PDF"’. + + +File: docLApxXS.info, Node: User options, Next: Faces, Prev: Magic handlers, Up: Configuring Packages + +4.6 User options +================ + +In Emacs, you normally set customizable variables (user options) using +the ‘M-x customize’ interface (*note (emacs)Easy Customization::). We +recommend this method for most users. However, it is also possible to +set them in your ‘use-package’ declarations by using the ‘:custom’ +keyword. + + (use-package comint + :defer t + :custom + (comint-buffer-maximum-size 20000 "Increase comint buffer size.") + (comint-prompt-read-only t "Make the prompt read only.")) + + This is better than using ‘setq’ in a ‘:config’ block, as +customizable variables might have some code associated with it that +Emacs will execute when you assign values to them. (In Emacs 29 and +later, there is also the new ‘setopt’ macro that does this for you.) + + Note that the values customized using ‘:custom’ are _not_ saved in +the standard Emacs ‘custom-file’ (*note (emacs)Saving Customizations::). +You should therefore set each user option using either the ‘:custom’ +keyword _or_ ‘M-x customize-option’ command; the latter will save +customized values in the Emacs ‘custom-file’. Do not use both for the +same variable, as this risks having conflicting values in your +use-package declaration and your ‘custom-file’, which can lead to +problems that are both tricky and tedious to debug. + + +File: docLApxXS.info, Node: Faces, Next: Hiding minor modes, Prev: User options, Up: Configuring Packages + +4.7 Faces +========= + +The ‘:custom-face’ keyword allows customization of package’s faces. +Example: + + (use-package eruby-mode + :custom-face + (eruby-standard-face ((t (:slant italic))))) + + (use-package example + :custom-face + (example-1-face ((t (:foreground "LightPink")))) + (example-2-face ((t (:foreground "LightGreen"))) face-defspec-spec)) + + (use-package zenburn-theme + :preface + (setq my/zenburn-colors-alist + '((fg . "#DCDCCC") (bg . "#1C1C1C") (cyan . "#93E0E3"))) + :custom-face + (region ((t (:background ,(alist-get my/zenburn-colors-alist 'cyan))))) + :config + (load-theme 'zenburn t)) + + +File: docLApxXS.info, Node: Hiding minor modes, Prev: Faces, Up: Configuring Packages + +4.8 Hiding minor modes with diminish and delight +================================================ + +‘use-package’ supports the ‘diminish’ and ‘delight’ packages, both of +which make it possible to remove or change minor mode strings in your +mode-line. Which one to use is up to you, but you should normally only +use one or the other – never both.(1) To use either of them, you must +first install the corresponding package from GNU ELPA. + +* Menu: + +* Diminish:: Hiding minor modes with Diminish. +* Delight:: Hiding minor modes with Delight. + + ---------- Footnotes ---------- + + (1) When in doubt, you might as well use ‘diminish’. + + +File: docLApxXS.info, Node: Diminish, Next: Delight, Up: Hiding minor modes + +4.8.1 Diminish +-------------- + +When diminish(1) is installed, you can use the ‘:diminish’ keyword. If +‘diminish’ is not installed, the ‘:diminish’ keyword does nothing. + + First, add the following declaration to the beginning of your init +file. + + (use-package diminish :ensure t) + +The optional ‘:ensure t’ makes sure the package is installed if it isn’t +already (*note Installing packages::). + + The ‘:diminish’ keyword takes as its argument either a minor mode +symbol, a cons of the symbol and its replacement string, or just a +replacement string, in which case the minor mode symbol is guessed to be +the package name with ‘-mode’ appended at the end: + + (use-package abbrev + :diminish abbrev-mode + :config + (if (file-exists-p abbrev-file-name) + (quietly-read-abbrev-file))) + + ---------- Footnotes ---------- + + (1) The ‘diminish’ package is installable from GNU ELPA. + + +File: docLApxXS.info, Node: Delight, Prev: Diminish, Up: Hiding minor modes + +4.8.2 Delight +------------- + +When ‘delight’(1) is installed, you can use the ‘:delight’ keyword. If +‘delight’ is not installed, the ‘:delight’ keyword does nothing. + + First, add the following declaration to the beginning of your init +file. + + (use-package delight :ensure t) + +The optional ‘:ensure t’ makes sure the package is installed if it isn’t +already (*note Installing packages::). + + The ‘:delight’ keyword takes as its argument a minor mode symbol, a +replacement string, or quoted mode line data (in which case the minor +mode symbol is assumed to be the package name with ‘-mode’ appended at +the end), both of these, or several lists of both. *Note (elisp)Mode +Line Data::. If no arguments are provided, the default mode name is +hidden completely. + + For example, the following hides everything for the ‘foo-mode’ minor +mode in the ‘foo’ package: + + (use-package foo + :delight) + + If the mode name doesn’t match the package name with ‘-mode’ +appended, provide a symbol instead. For example, the following hides +‘auto-revert-mode’ from the mode line: + + ;; Don't show anything for auto-revert-mode, which doesn't match + ;; its package name. + (use-package autorevert + :delight auto-revert-mode) + + You can also use arbitrary Lisp code as argument of ‘:delight’. For +example, to replace ‘foo-mode’ with the value of the current buffer: + + (use-package foo + :delight '(:eval buffer-file-name)) + + Here is an example of hiding several built-in minor modes: + + ;; Completely hide visual-line-mode and change auto-fill-mode to " AF". + (use-package emacs + :delight + (auto-fill-function " AF") + (visual-line-mode)) + + ---------- Footnotes ---------- + + (1) The ‘delight’ package is installable from GNU ELPA. + + +File: docLApxXS.info, Node: Installing packages, Next: Byte-compiling, Prev: Configuring Packages, Up: Top + +5 Installing packages automatically +*********************************** + +The standard Emacs package manager is documented in the Emacs manual +(*note (emacs)Package Installation::). The ‘use-package’ macro provides +the ‘:ensure’ and ‘:pin’ keywords that interface with that package +manager to automatically install packages. The ‘:vc’ keyword may be +used to control how package sources are downloaded; e.g., from remote +hosts (*note (emacs)Fetching Package Sources::). This is particularly +useful if you use your init file on more than one system. + +* Menu: + +* Install package:: +* Pinning packages:: +* Other package managers:: + + +File: docLApxXS.info, Node: Install package, Next: Pinning packages, Up: Installing packages + +5.1 Installing package +====================== + +The ‘:ensure’ keyword makes use-package ask the Emacs package manager to +install a package if it is not already present on your system. + + For example: + + (use-package magit + :ensure t) + + If you need to install a different package from the one named by +‘use-package’, you can use a symbol: + + (use-package tex + :ensure auctex) + + You can customize the user option ‘use-package-always-ensure’ to a +non-‘nil’ value if you want this behavior to be global for all packages: + + (require 'use-package-ensure) + (setq use-package-always-ensure t) + +You can override the above setting for a single package by adding +‘:ensure nil’ to its declaration. + + The ‘:vc’ keyword can be used to control how packages are downloaded +and/or installed. More specifically, it allows one to fetch and update +packages directly from a version control system. This is especially +convenient when wanting to install a package that is not on any package +archive. + + The keyword accepts the same arguments as specified in *note +(emacs)Fetching Package Sources::, except that a name need not +explicitly be given: it is inferred from the declaration. The accepted +property list is augmented by a ‘:rev’ keyword, which has the same shape +as the ‘REV’ argument to ‘package-vc-install’. Notably – even when not +specified – ‘:rev’ defaults to checking out the last release of the +package. You can use ‘:rev :newest’ to check out the latest commit. + + For example, + + (use-package bbdb + :vc (:url "https://git.savannah.nongnu.org/git/bbdb.git" + :rev :newest)) + + would try – by invoking ‘package-vc-install’ – to install the latest +commit of the package ‘foo’ from the specified remote. + + Alternatively, the ‘use-package-vc-prefer-newest’ user option exists +to always prefer the latest commit. + + The ‘:vc’ keyword can also be used for local packages, by combining +it with ‘:load-path’ (*note Load path::): + + ;; Use a local copy of BBDB instead of the one from GNU ELPA. + (use-package bbdb + :vc t + :load-path "/path/to/bbdb/dir/") + + The above dispatches to ‘package-vc-install-from-checkout’. + + +File: docLApxXS.info, Node: Pinning packages, Next: Other package managers, Prev: Install package, Up: Installing packages + +5.2 Pinning packages using ‘:pin’ +================================= + +use-package can “pin” a package to a specific archive using the ‘:pin’ +keyword.(1) This allows you to mix and match packages from different +archives. The primary use-case for this is preferring to install +packages from GNU ELPA or NonGNU ELPA (indicated by ‘gnu’ and ‘nongnu’, +respectively), while installing specific packages from third-party +archives. + + For example: + + (use-package company + :ensure t + :pin gnu) ; GNU ELPA + + Unfortunately, the third-party archive MELPA uses a versioning scheme +based on dates, which means that packages from that archive are always +preferred. If you are using that archive, we strongly encourage you to +customize ‘use-package-always-pin’ to ‘nongnu’. This guarantees that +you are using a version of that package that has been specifically +marked for release by its developer, and not a development snapshot. + + If you want to manually keep a package updated and ignore upstream +updates, you can pin it to ‘manual’. This will work as long as you have +not customized a repository to use that name in the ‘package-archives’ +variable. + + Example: + + (use-package org + :ensure t + ;; ignore org-mode from upstream and use a manually installed version + :pin manual) + + ‘use-package’ signals an error if you try to pin a package to an +archive that is not configured using ‘package-archives’ (except from the +special ‘manual’ archive). + + ---------- Footnotes ---------- + + (1) The ‘:pin’ keyword has no effect on Emacs versions older than +24.4. + + +File: docLApxXS.info, Node: Other package managers, Prev: Pinning packages, Up: Installing packages + +5.3 Non-standard package managers +================================= + +By default, use-package assumes that you are using the Emacs built-in +‘package.el’ package manager. We expect that most users will find that +it is capable enough, even for advanced use cases. + + However, some users might prefer to use a third-party package manager +for a specific circumstance or use case. By setting the user option +‘use-package-ensure-function’ to the name of a function, you can direct +‘:ensure’ to use a different package manager for installing packages. + + For more details, please see the documentation of the package manager +you are using. If you run into any bugs, it is often best to report +them directly to the developers of that package manager. + + +File: docLApxXS.info, Node: Byte-compiling, Next: Troubleshooting, Prev: Installing packages, Up: Top + +6 Byte-compiling your init file +******************************* + +Some users might want to byte-compile their init file to make Emacs +startup faster. This is not recommended in most cases, as the speed-up +is usually too small to be worth it, and it can lead to confusion if the +byte-compiled files are out-of-date. If you still want to do it, this +chapter explains how to do that. + + ‘use-package’ always loads every library that it can while a file is +being byte-compiled. This helps silence spurious warnings about unknown +variables and functions. + + However, there are times when this is just not enough. For those +times, use the ‘:defines’ and ‘:functions’ keywords to introduce dummy +variable and function declarations solely for the sake of silencing +byte-compiler warnings. For example: + + (use-package texinfo + :defines texinfo-section-list + :commands texinfo-mode + :init + (add-to-list 'auto-mode-alist '("\\.texi$" . texinfo-mode))) + + If you need to silence a missing function warning, you can use +‘:functions’: + + (use-package ruby-mode + :mode "\\.rb\\'" + :interpreter "ruby" + :functions inf-ruby-keys + :config + (defun my-ruby-mode-hook () + (require 'inf-ruby) + (inf-ruby-keys)) + (add-hook 'ruby-mode-hook 'my-ruby-mode-hook)) + + Normally, ‘use-package’ will load each package at compile time before +compiling the configuration, to ensure that any necessary symbols are in +scope to satisfy the byte-compiler. At times this can cause problems, +since a package may have special loading requirements, and all that you +want to use ‘use-package’ for is to add a configuration to the +‘eval-after-load’ hook. In such cases, use the ‘:no-require’ keyword: + + (use-package foo + :no-require t + :config + (message "Evaluate this immediately after loading `foo'")) + + +File: docLApxXS.info, Node: Troubleshooting, Next: Keyword extensions, Prev: Byte-compiling, Up: Top + +7 Troubleshooting +***************** + +If an error occurs while initializing or configuring a package, this +will not stop your Emacs from loading. Instead, ‘use-package’ captures +the error and reports it in a special ‘*Warnings*’ popup buffer, so that +you can debug the situation in an otherwise functional Emacs. + + If you are having trouble when starting Emacs, you can pass Emacs the +‘--debug-init’ command line flag. *Note (emacs)Initial Options::. To +get even more information when using that flag, add the following to +your init file (these options are documented below): + + (when init-file-debug + (setq use-package-verbose t + use-package-expand-minimally nil + use-package-compute-statistics t + debug-on-error t)) + + Since ‘use-package’ is a macro, the first step when you need to dig +deeper is usually to see what Emacs Lisp code your declaration expands +to. You can either use the command ‘M-x pp-macroexpand-last-sexp’, or +wrap the use-package declaration in ‘macroexpand’ and evaluate it. It +is a good idea to include their output in any bugs you file for +use-package. + +* Menu: + +* Troubleshooting Options:: +* Gathering Statistics:: +* Disabling a package:: + + +File: docLApxXS.info, Node: Troubleshooting Options, Next: Gathering Statistics, Up: Troubleshooting + +7.1 Options that help when troubleshooting +========================================== + +By default, use-package will attempts to catch and report errors that +occur during expansion of use-package declarations in your init file. +Customize the user option ‘use-package-expand-minimally’ to a non-‘nil’ +value to disable this checking. + + This behavior may be overridden locally using the ‘:catch’ keyword. +If ‘t’ or ‘nil’, it enables or disables catching errors at load time. +It can also be a function taking two arguments: the keyword being +processed at the time the error was encountered, and the error object +(as generated by ‘condition-case’). For example: + + (use-package example + ;; Note that errors are never trapped in the preface, since + ;; doing so would hide definitions from the byte-compiler. + :preface (message "I'm here at byte-compile and load time") + :init (message "I'm always here at startup") + :config + (message "I'm always here after the package is loaded") + (error "oops") + ;; Don't try to (require 'example), this is just an example! + :no-require t + :catch (lambda (keyword err) + (message (error-message-string err)))) + + Evaluating the above form will print these messages: + +I'm here at byte-compile and load time +I'm always here at startup +Configuring package example... +I'm always here after the package is loaded +oops + + +File: docLApxXS.info, Node: Gathering Statistics, Next: Disabling a package, Prev: Troubleshooting Options, Up: Troubleshooting + +7.2 Gathering Statistics +======================== + +When a package is loaded, and if you have ‘use-package-verbose’ set to +‘t’, or if the package takes longer than 0.1 seconds to load, you will +see a message to indicate this loading activity in the ‘*Messages*’ +buffer. The same will happen for configuration, or ‘:config’ blocks, +that take longer than 0.1 seconds to execute. + + If you’d like to see a summary how many packages you’ve loaded, what +stage of initialization they’ve reached, and how much aggregate time +they’ve spent (roughly), you can customize the user option +‘use-package-compute-statistics’ to a non-‘nil’ value. Then reload your +packages, normally by restarting Emacs, to make sure that use-package +can gather statistics for all your packages. + + Run the command ‘M-x use-package-report’ to see the results. The +buffer displayed is a tabulated list. To sort rows based on a +particular column, move point to it and type ‘S’, or click the column +name at the top of the buffer on graphical displays. + + To reset all statistics that use-package has gathered for the current +Emacs invocation, run the command ‘M-x use-package-reset-statistics’. + + Note that if you are setting ‘use-package-compute-statistics’ +directly in your init file, and not with ‘customize’, you must do this +after loading ‘use-package’, but before any ‘use-package’ forms. + + +File: docLApxXS.info, Node: Disabling a package, Prev: Gathering Statistics, Up: Troubleshooting + +7.3 Disabling a package +======================= + +The ‘:disabled’ keyword inhibits loading a package, and all its +customizations. It is equivalent to commenting out or deleting the +definition. + + You could use this, for example, to temporarily disable a package +that you’re having difficulties with, or to avoid loading a package that +you’re not currently using. + + This example disables the ‘foo’ package: + + (use-package foo + :disabled) + + When byte-compiling your init file, use-package omits disabled +declarations from the output entirely, in order to make Emacs startup +faster. + + +File: docLApxXS.info, Node: Keyword extensions, Next: History, Prev: Troubleshooting, Up: Top + +Appendix A Keyword extensions +***************************** + +use-package is based on an extensible framework that makes it easy for +package authors to add new keywords, or modify the behavior of existing +keywords. + + Some keyword extensions are included with ‘use-package’, and can be +optionally enabled. + +* Menu: + +* use-package-ensure-system-package:: +* Creating an extension:: + + +File: docLApxXS.info, Node: use-package-ensure-system-package, Next: Creating an extension, Up: Keyword extensions + +A.1 :use-package-ensure-system-package +====================================== + +The ‘:ensure-system-package’ keyword allows you to ensure certain +executables are available on your system alongside your package +declarations.(1) + + To use this extension, add this immediately after loading +‘use-package’: + + (use-package use-package-ensure-system-package) + + Now you can use the ‘:ensure-system-package’ keyword. Here’s an +example usage: + + (use-package foo + :ensure-system-package foo) + + This will expect a global binary package to exist called ‘foo’. If +it does not, it will use your system package manager to attempt an +install of a binary by the same name asynchronously. This requires the +GNU ELPA package ‘system-packages’ +(https://gitlab.com/jabranham/system-packages), so for this to work you +must install that first. + + One way of making sure it is installed is with ‘use-package’ together +with ‘:ensure’. + + (use-package system-packages + :ensure t) + + For example, on a Debian GNU/Linux system, this would call ‘apt-get +install foo’. + + If the package is named differently than the binary, you can use a +cons in the form of ‘(binary . package-name)’. For example: + + (use-package foo + :ensure-system-package + (foocmd . foo)) + + On a Debian GNU/Linux system, this would call ‘apt install foo’ if +Emacs could not locate the executable ‘foocmd’.(2) + + ‘:ensure-system-package’ can also take a cons where the ‘cdr’ is a +string that will get called by ‘(async-shell-command)’ to install if it +isn’t found. This does not depend on any external package. + + (use-package tern + :ensure-system-package (tern . "npm i -g tern")) + + To install several packages, you can pass in a list of conses: + + (use-package ruby-mode + :ensure-system-package + ((rubocop . "gem install rubocop") + (ruby-lint . "gem install ruby-lint") + (ripper-tags . "gem install ripper-tags") + (pry . "gem install pry"))) + + Finally, in case the package dependency does not provide a global +executable, you can ensure that packages exist by checking the presence +of a file by providing a string like so: + + (use-package dash-at-point + :if (eq system-type 'darwin) + :ensure-system-package + ("/Applications/Dash.app" . "brew cask install dash")) + + ‘:ensure-system-package’ will use ‘system-packages-install’ to +install system packages, except where a custom command has been +specified, in which case it will be executed verbatim by +‘async-shell-command’. + + The user options ‘system-packages-package-manager’ and +‘system-packages-use-sudo’ are honored, but not for custom commands. +Custom commands should include the call to sudo in the command if +needed. + + ---------- Footnotes ---------- + + (1) On macOS, your ‘exec-path’ might be different if you are starting +Emacs as a GUI app instead of from a shell. If you find that Emacs on +macOS cannot find some executables that you know are already installed, +you could try the ‘exec-path-from-shell’ +(https://github.com/purcell/exec-path-from-shell) package. + + (2) For manual testing, you could use the ‘executable-find’ function, +which is what ‘system-packages’ uses internally. + + +File: docLApxXS.info, Node: Creating an extension, Prev: use-package-ensure-system-package, Up: Keyword extensions + +A.2 How to create an extension keyword +====================================== + +This section describes how to create a new keyword. + + 1. Add the keyword. + + The first step is to add your keyword at the right place in + ‘use-package-keywords’. This list determines the order in which + things will happen in the expanded code. You should never change + this order, but it gives you a framework within which to decide + when your keyword should fire. + + 2. Create a normalizer. + + The job of the normalizer is take a list of arguments (possibly + ‘nil’), and turn it into the single argument (which could still be + a list) that should appear in the final property list used by + ‘use-package’. + + Define a normalizer for your keyword by defining a function named + after the keyword, for example: + + (defun use-package-normalize/:pin (name-symbol keyword args) + (use-package-only-one (symbol-name keyword) args + (lambda (label arg) + (cond + ((stringp arg) arg) + ((symbolp arg) (symbol-name arg)) + (t + (use-package-error + ":pin wants an archive name (a string)")))))) + + 3. Create a handler. + + Once you have a normalizer, you must create a handler for the + keyword. + + Handlers can affect the handling of keywords in two ways. First, + they can modify the ‘state’ plist before recursively processing the + remaining keywords, to influence keywords that pay attention to the + state (one example is the state keyword ‘:deferred’, not to be + confused with the ‘use-package’ keyword ‘:defer’). Then, once the + remaining keywords have been handled and their resulting forms + returned, the handlers may manipulate, extend, or just ignore those + forms. + + The task of each handler is to return a _list of forms_ + representing code to be inserted. It does not need to be a ‘progn’ + list, as this is handled automatically in other places. Thus it is + common to see the idiom of using ‘use-package-concat’ to add new + functionality before or after a code body, so that only the minimum + code necessary is emitted as the result of a ‘use-package’ + expansion. + + This is an example handler: + + (defun use-package-handler/:pin (name-symbol keyword archive-name rest state) + (let ((body (use-package-process-keywords name-symbol rest state))) + ;; This happens at macro expansion time, not when the expanded code is + ;; compiled or evaluated. + (if (null archive-name) + body + (use-package-pin-package name-symbol archive-name) + (use-package-concat + body + `((push '(,name-symbol . ,archive-name) + package-pinned-packages)))))) + + 4. Test it. + + After the keyword has been inserted into ‘use-package-keywords’, + and a normalizer and a handler has been defined, you can now test + the keyword by seeing how usages of the keyword will expand. For + this, use ‘M-x pp-macroexpand-last-sexp’ with the cursor set + immediately after the ‘(use-package ...)’ expression. + + +File: docLApxXS.info, Node: History, Next: GNU Free Documentation License, Prev: Keyword extensions, Up: Top + +Appendix B History and acknowledgments +************************************** + +use-package was written by John Wiegley. Its development started in +2012, and it got merged into Emacs in 2022, in preparation of the +release of Emacs 29.1. + + Dozens of people have contributed to use-package over the years with +bug reports, documentation and code. They are too many to list here, +but we thank them all for their contributions. + + This Texinfo manual was written by Stefan Kangas, as a significant +rewrite of the old use-package manual and ‘README’. + + +File: docLApxXS.info, Node: GNU Free Documentation License, Next: Index, Prev: History, Up: Top + +Appendix C GNU Free Documentation License +***************************************** + + Version 1.3, 3 November 2008 + + Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. + <https://fsf.org/> + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + 0. PREAMBLE + + The purpose of this License is to make a manual, textbook, or other + functional and useful document “free” in the sense of freedom: to + assure everyone the effective freedom to copy and redistribute it, + with or without modifying it, either commercially or + noncommercially. Secondarily, this License preserves for the + author and publisher a way to get credit for their work, while not + being considered responsible for modifications made by others. + + This License is a kind of “copyleft”, which means that derivative + works of the document must themselves be free in the same sense. + It complements the GNU General Public License, which is a copyleft + license designed for free software. + + We have designed this License in order to use it for manuals for + free software, because free software needs free documentation: a + free program should come with manuals providing the same freedoms + that the software does. But this License is not limited to + software manuals; it can be used for any textual work, regardless + of subject matter or whether it is published as a printed book. We + recommend this License principally for works whose purpose is + instruction or reference. + + 1. APPLICABILITY AND DEFINITIONS + + This License applies to any manual or other work, in any medium, + that contains a notice placed by the copyright holder saying it can + be distributed under the terms of this License. Such a notice + grants a world-wide, royalty-free license, unlimited in duration, + to use that work under the conditions stated herein. The + “Document”, below, refers to any such manual or work. Any member + of the public is a licensee, and is addressed as “you”. You accept + the license if you copy, modify or distribute the work in a way + requiring permission under copyright law. + + A “Modified Version” of the Document means any work containing the + Document or a portion of it, either copied verbatim, or with + modifications and/or translated into another language. + + A “Secondary Section” is a named appendix or a front-matter section + of the Document that deals exclusively with the relationship of the + publishers or authors of the Document to the Document’s overall + subject (or to related matters) and contains nothing that could + fall directly within that overall subject. (Thus, if the Document + is in part a textbook of mathematics, a Secondary Section may not + explain any mathematics.) The relationship could be a matter of + historical connection with the subject or with related matters, or + of legal, commercial, philosophical, ethical or political position + regarding them. + + The “Invariant Sections” are certain Secondary Sections whose + titles are designated, as being those of Invariant Sections, in the + notice that says that the Document is released under this License. + If a section does not fit the above definition of Secondary then it + is not allowed to be designated as Invariant. The Document may + contain zero Invariant Sections. If the Document does not identify + any Invariant Sections then there are none. + + The “Cover Texts” are certain short passages of text that are + listed, as Front-Cover Texts or Back-Cover Texts, in the notice + that says that the Document is released under this License. A + Front-Cover Text may be at most 5 words, and a Back-Cover Text may + be at most 25 words. + + A “Transparent” copy of the Document means a machine-readable copy, + represented in a format whose specification is available to the + general public, that is suitable for revising the document + straightforwardly with generic text editors or (for images composed + of pixels) generic paint programs or (for drawings) some widely + available drawing editor, and that is suitable for input to text + formatters or for automatic translation to a variety of formats + suitable for input to text formatters. A copy made in an otherwise + Transparent file format whose markup, or absence of markup, has + been arranged to thwart or discourage subsequent modification by + readers is not Transparent. An image format is not Transparent if + used for any substantial amount of text. A copy that is not + “Transparent” is called “Opaque”. + + Examples of suitable formats for Transparent copies include plain + ASCII without markup, Texinfo input format, LaTeX input format, + SGML or XML using a publicly available DTD, and standard-conforming + simple HTML, PostScript or PDF designed for human modification. + Examples of transparent image formats include PNG, XCF and JPG. + Opaque formats include proprietary formats that can be read and + edited only by proprietary word processors, SGML or XML for which + the DTD and/or processing tools are not generally available, and + the machine-generated HTML, PostScript or PDF produced by some word + processors for output purposes only. + + The “Title Page” means, for a printed book, the title page itself, + plus such following pages as are needed to hold, legibly, the + material this License requires to appear in the title page. For + works in formats which do not have any title page as such, “Title + Page” means the text near the most prominent appearance of the + work’s title, preceding the beginning of the body of the text. + + The “publisher” means any person or entity that distributes copies + of the Document to the public. + + A section “Entitled XYZ” means a named subunit of the Document + whose title either is precisely XYZ or contains XYZ in parentheses + following text that translates XYZ in another language. (Here XYZ + stands for a specific section name mentioned below, such as + “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.) + To “Preserve the Title” of such a section when you modify the + Document means that it remains a section “Entitled XYZ” according + to this definition. + + The Document may include Warranty Disclaimers next to the notice + which states that this License applies to the Document. These + Warranty Disclaimers are considered to be included by reference in + this License, but only as regards disclaiming warranties: any other + implication that these Warranty Disclaimers may have is void and + has no effect on the meaning of this License. + + 2. VERBATIM COPYING + + You may copy and distribute the Document in any medium, either + commercially or noncommercially, provided that this License, the + copyright notices, and the license notice saying this License + applies to the Document are reproduced in all copies, and that you + add no other conditions whatsoever to those of this License. You + may not use technical measures to obstruct or control the reading + or further copying of the copies you make or distribute. However, + you may accept compensation in exchange for copies. If you + distribute a large enough number of copies you must also follow the + conditions in section 3. + + You may also lend copies, under the same conditions stated above, + and you may publicly display copies. + + 3. COPYING IN QUANTITY + + If you publish printed copies (or copies in media that commonly + have printed covers) of the Document, numbering more than 100, and + the Document’s license notice requires Cover Texts, you must + enclose the copies in covers that carry, clearly and legibly, all + these Cover Texts: Front-Cover Texts on the front cover, and + Back-Cover Texts on the back cover. Both covers must also clearly + and legibly identify you as the publisher of these copies. The + front cover must present the full title with all words of the title + equally prominent and visible. You may add other material on the + covers in addition. Copying with changes limited to the covers, as + long as they preserve the title of the Document and satisfy these + conditions, can be treated as verbatim copying in other respects. + + If the required texts for either cover are too voluminous to fit + legibly, you should put the first ones listed (as many as fit + reasonably) on the actual cover, and continue the rest onto + adjacent pages. + + If you publish or distribute Opaque copies of the Document + numbering more than 100, you must either include a machine-readable + Transparent copy along with each Opaque copy, or state in or with + each Opaque copy a computer-network location from which the general + network-using public has access to download using public-standard + network protocols a complete Transparent copy of the Document, free + of added material. If you use the latter option, you must take + reasonably prudent steps, when you begin distribution of Opaque + copies in quantity, to ensure that this Transparent copy will + remain thus accessible at the stated location until at least one + year after the last time you distribute an Opaque copy (directly or + through your agents or retailers) of that edition to the public. + + It is requested, but not required, that you contact the authors of + the Document well before redistributing any large number of copies, + to give them a chance to provide you with an updated version of the + Document. + + 4. MODIFICATIONS + + You may copy and distribute a Modified Version of the Document + under the conditions of sections 2 and 3 above, provided that you + release the Modified Version under precisely this License, with the + Modified Version filling the role of the Document, thus licensing + distribution and modification of the Modified Version to whoever + possesses a copy of it. In addition, you must do these things in + the Modified Version: + + A. Use in the Title Page (and on the covers, if any) a title + distinct from that of the Document, and from those of previous + versions (which should, if there were any, be listed in the + History section of the Document). You may use the same title + as a previous version if the original publisher of that + version gives permission. + + B. List on the Title Page, as authors, one or more persons or + entities responsible for authorship of the modifications in + the Modified Version, together with at least five of the + principal authors of the Document (all of its principal + authors, if it has fewer than five), unless they release you + from this requirement. + + C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. + + D. Preserve all the copyright notices of the Document. + + E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. + + F. Include, immediately after the copyright notices, a license + notice giving the public permission to use the Modified + Version under the terms of this License, in the form shown in + the Addendum below. + + G. Preserve in that license notice the full lists of Invariant + Sections and required Cover Texts given in the Document’s + license notice. + + H. Include an unaltered copy of this License. + + I. Preserve the section Entitled “History”, Preserve its Title, + and add to it an item stating at least the title, year, new + authors, and publisher of the Modified Version as given on the + Title Page. If there is no section Entitled “History” in the + Document, create one stating the title, year, authors, and + publisher of the Document as given on its Title Page, then add + an item describing the Modified Version as stated in the + previous sentence. + + J. Preserve the network location, if any, given in the Document + for public access to a Transparent copy of the Document, and + likewise the network locations given in the Document for + previous versions it was based on. These may be placed in the + “History” section. You may omit a network location for a work + that was published at least four years before the Document + itself, or if the original publisher of the version it refers + to gives permission. + + K. For any section Entitled “Acknowledgements” or “Dedications”, + Preserve the Title of the section, and preserve in the section + all the substance and tone of each of the contributor + acknowledgements and/or dedications given therein. + + L. Preserve all the Invariant Sections of the Document, unaltered + in their text and in their titles. Section numbers or the + equivalent are not considered part of the section titles. + + M. Delete any section Entitled “Endorsements”. Such a section + may not be included in the Modified Version. + + N. Do not retitle any existing section to be Entitled + “Endorsements” or to conflict in title with any Invariant + Section. + + O. Preserve any Warranty Disclaimers. + + If the Modified Version includes new front-matter sections or + appendices that qualify as Secondary Sections and contain no + material copied from the Document, you may at your option designate + some or all of these sections as invariant. To do this, add their + titles to the list of Invariant Sections in the Modified Version’s + license notice. These titles must be distinct from any other + section titles. + + You may add a section Entitled “Endorsements”, provided it contains + nothing but endorsements of your Modified Version by various + parties—for example, statements of peer review or that the text has + been approved by an organization as the authoritative definition of + a standard. + + You may add a passage of up to five words as a Front-Cover Text, + and a passage of up to 25 words as a Back-Cover Text, to the end of + the list of Cover Texts in the Modified Version. Only one passage + of Front-Cover Text and one of Back-Cover Text may be added by (or + through arrangements made by) any one entity. If the Document + already includes a cover text for the same cover, previously added + by you or by arrangement made by the same entity you are acting on + behalf of, you may not add another; but you may replace the old + one, on explicit permission from the previous publisher that added + the old one. + + The author(s) and publisher(s) of the Document do not by this + License give permission to use their names for publicity for or to + assert or imply endorsement of any Modified Version. + + 5. COMBINING DOCUMENTS + + You may combine the Document with other documents released under + this License, under the terms defined in section 4 above for + modified versions, provided that you include in the combination all + of the Invariant Sections of all of the original documents, + unmodified, and list them all as Invariant Sections of your + combined work in its license notice, and that you preserve all + their Warranty Disclaimers. + + The combined work need only contain one copy of this License, and + multiple identical Invariant Sections may be replaced with a single + copy. If there are multiple Invariant Sections with the same name + but different contents, make the title of each such section unique + by adding at the end of it, in parentheses, the name of the + original author or publisher of that section if known, or else a + unique number. Make the same adjustment to the section titles in + the list of Invariant Sections in the license notice of the + combined work. + + In the combination, you must combine any sections Entitled + “History” in the various original documents, forming one section + Entitled “History”; likewise combine any sections Entitled + “Acknowledgements”, and any sections Entitled “Dedications”. You + must delete all sections Entitled “Endorsements.” + + 6. COLLECTIONS OF DOCUMENTS + + You may make a collection consisting of the Document and other + documents released under this License, and replace the individual + copies of this License in the various documents with a single copy + that is included in the collection, provided that you follow the + rules of this License for verbatim copying of each of the documents + in all other respects. + + You may extract a single document from such a collection, and + distribute it individually under this License, provided you insert + a copy of this License into the extracted document, and follow this + License in all other respects regarding verbatim copying of that + document. + + 7. AGGREGATION WITH INDEPENDENT WORKS + + A compilation of the Document or its derivatives with other + separate and independent documents or works, in or on a volume of a + storage or distribution medium, is called an “aggregate” if the + copyright resulting from the compilation is not used to limit the + legal rights of the compilation’s users beyond what the individual + works permit. When the Document is included in an aggregate, this + License does not apply to the other works in the aggregate which + are not themselves derivative works of the Document. + + If the Cover Text requirement of section 3 is applicable to these + copies of the Document, then if the Document is less than one half + of the entire aggregate, the Document’s Cover Texts may be placed + on covers that bracket the Document within the aggregate, or the + electronic equivalent of covers if the Document is in electronic + form. Otherwise they must appear on printed covers that bracket + the whole aggregate. + + 8. TRANSLATION + + Translation is considered a kind of modification, so you may + distribute translations of the Document under the terms of section + 4. Replacing Invariant Sections with translations requires special + permission from their copyright holders, but you may include + translations of some or all Invariant Sections in addition to the + original versions of these Invariant Sections. You may include a + translation of this License, and all the license notices in the + Document, and any Warranty Disclaimers, provided that you also + include the original English version of this License and the + original versions of those notices and disclaimers. In case of a + disagreement between the translation and the original version of + this License or a notice or disclaimer, the original version will + prevail. + + If a section in the Document is Entitled “Acknowledgements”, + “Dedications”, or “History”, the requirement (section 4) to + Preserve its Title (section 1) will typically require changing the + actual title. + + 9. TERMINATION + + You may not copy, modify, sublicense, or distribute the Document + except as expressly provided under this License. Any attempt + otherwise to copy, modify, sublicense, or distribute it is void, + and will automatically terminate your rights under this License. + + However, if you cease all violation of this License, then your + license from a particular copyright holder is reinstated (a) + provisionally, unless and until the copyright holder explicitly and + finally terminates your license, and (b) permanently, if the + copyright holder fails to notify you of the violation by some + reasonable means prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is + reinstated permanently if the copyright holder notifies you of the + violation by some reasonable means, this is the first time you have + received notice of violation of this License (for any work) from + that copyright holder, and you cure the violation prior to 30 days + after your receipt of the notice. + + Termination of your rights under this section does not terminate + the licenses of parties who have received copies or rights from you + under this License. If your rights have been terminated and not + permanently reinstated, receipt of a copy of some or all of the + same material does not give you any rights to use it. + + 10. FUTURE REVISIONS OF THIS LICENSE + + The Free Software Foundation may publish new, revised versions of + the GNU Free Documentation License from time to time. Such new + versions will be similar in spirit to the present version, but may + differ in detail to address new problems or concerns. See + <https://www.gnu.org/licenses/>. + + Each version of the License is given a distinguishing version + number. If the Document specifies that a particular numbered + version of this License “or any later version” applies to it, you + have the option of following the terms and conditions either of + that specified version or of any later version that has been + published (not as a draft) by the Free Software Foundation. If the + Document does not specify a version number of this License, you may + choose any version ever published (not as a draft) by the Free + Software Foundation. If the Document specifies that a proxy can + decide which future versions of this License can be used, that + proxy’s public statement of acceptance of a version permanently + authorizes you to choose that version for the Document. + + 11. RELICENSING + + “Massive Multiauthor Collaboration Site” (or “MMC Site”) means any + World Wide Web server that publishes copyrightable works and also + provides prominent facilities for anybody to edit those works. A + public wiki that anybody can edit is an example of such a server. + A “Massive Multiauthor Collaboration” (or “MMC”) contained in the + site means any set of copyrightable works thus published on the MMC + site. + + “CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 + license published by Creative Commons Corporation, a not-for-profit + corporation with a principal place of business in San Francisco, + California, as well as future copyleft versions of that license + published by that same organization. + + “Incorporate” means to publish or republish a Document, in whole or + in part, as part of another Document. + + An MMC is “eligible for relicensing” if it is licensed under this + License, and if all works that were first published under this + License somewhere other than this MMC, and subsequently + incorporated in whole or in part into the MMC, (1) had no cover + texts or invariant sections, and (2) were thus incorporated prior + to November 1, 2008. + + The operator of an MMC Site may republish an MMC contained in the + site under CC-BY-SA on the same site at any time before August 1, + 2009, provided the MMC is eligible for relicensing. + +ADDENDUM: How to use this License for your documents +==================================================== + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and license +notices just after the title page: + + Copyright (C) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. A copy of the license is included in the section entitled ``GNU + Free Documentation License''. + + If you have Invariant Sections, Front-Cover Texts and Back-Cover +Texts, replace the “with...Texts.” line with this: + + with the Invariant Sections being LIST THEIR TITLES, with + the Front-Cover Texts being LIST, and with the Back-Cover Texts + being LIST. + + If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + + If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of free +software license, such as the GNU General Public License, to permit +their use in free software. + + +File: docLApxXS.info, Node: Index, Prev: GNU Free Documentation License, Up: Top + +Index +***** + + +* Menu: + +* :after: Loading sequentially. (line 6) +* :all, (with :after): Loading sequentially. (line 35) +* :any, (with :after): Loading sequentially. (line 35) +* :autoload: Manual autoloads. (line 10) +* :bind: Global keybindings. (line 6) +* :bind, and function keys: Global keybindings. (line 41) +* :bind, and remapping of commands: Global keybindings. (line 57) +* :bind, internals: Global keybindings. (line 69) +* :bind-keymap: Binding to a keymap. (line 6) +* :catch: Troubleshooting Options. + (line 11) +* :commands: Manual autoloads. (line 10) +* :config: Config keyword. (line 6) +* :continue, inside :repeat-map and :bind: Binding to repeat-maps. + (line 45) +* :custom: User options. (line 6) +* :custom-face: Faces. (line 6) +* :defer: Deferring loading. (line 26) +* :defer, with a numeric argument: Deferring loading. (line 43) +* :defines: Byte-compiling. (line 16) +* :delight: Delight. (line 6) +* :demand: Forcing loading. (line 6) +* :diminish: Diminish. (line 6) +* :disabled: Disabling a package. (line 6) +* :ensure: Install package. (line 6) +* :ensure-system-package: use-package-ensure-system-package. + (line 6) +* :exit, inside :repeat-map and :bind: Binding to repeat-maps. + (line 27) +* :functions: Byte-compiling. (line 16) +* :hook: Hooks. (line 6) +* :if: Conditional loading. (line 6) +* :init: Init keyword. (line 6) +* :interpreter: Modes and interpreters. + (line 6) +* :load-path: Load path. (line 10) +* :magic: Magic handlers. (line 6) +* :magic-fallback: Magic handlers. (line 6) +* :map, inside :bind: Binding in keymaps. (line 6) +* :mode: Modes and interpreters. + (line 6) +* :no-require: Byte-compiling. (line 40) +* :pin: Pinning packages. (line 6) +* :preface: Preface keyword. (line 6) +* :repeat-map, inside :bind: Binding to repeat-maps. + (line 6) +* :requires: Load dependencies. (line 6) +* :unless: Conditional loading. (line 6) +* :vc: Install package. (line 29) +* :when: Conditional loading. (line 6) +* auto-mode-alist customization: Modes and interpreters. + (line 6) +* autoloading packages: Deferring loading. (line 6) +* autoloads for packages, setting up manually: Manual autoloads. + (line 10) +* binding commands used at end of repeat series: Binding to repeat-maps. + (line 27) +* binding function keys with :bind: Global keybindings. (line 41) +* binding keys for package commands: Key bindings. (line 6) +* binding keys to keymaps: Binding to a keymap. (line 6) +* byte-compiling your init file: Byte-compiling. (line 6) +* conditional loading: Conditional loading. (line 6) +* conditional loading before :preface or :ensure: Conditional loading. + (line 59) +* configure package using Lisp forms: Lisp Configuration. (line 6) +* configure packages using use-package: Configuring Packages. (line 6) +* custom load-path for loading a package: Load path. (line 6) +* customization of faces: Faces. (line 6) +* customization of variables: User options. (line 6) +* customize package configuration: Configuring Packages. (line 6) +* customizing built-in variables: The emacs package. (line 6) +* debugging use-package: Troubleshooting. (line 6) +* defer loading by default: Deferring loading. (line 69) +* deferring loading of package: Deferring loading. (line 6) +* describe-personal-keybindings: Displaying keybindings. + (line 6) +* disable package: Disabling a package. (line 6) +* display your keybindings: Displaying keybindings. + (line 6) +* expanding macro, for troubleshooting: Troubleshooting. (line 22) +* extending use-package keywords: Keyword extensions. (line 6) +* extension keywords: Creating an extension. + (line 6) +* faces, setting: Faces. (line 6) +* forcing immediate loading: Forcing loading. (line 6) +* gathering use-package statistics: Gathering Statistics. (line 6) +* global keybindings: Global keybindings. (line 6) +* hiding minor modes: Hiding minor modes. (line 6) +* hooks: Hooks. (line 6) +* installing package from specific archive: Pinning packages. (line 6) +* installing packages from archives: Install package. (line 6) +* installing using non-standard package managers: Other package managers. + (line 6) +* interpreter-mode-alist customization: Modes and interpreters. + (line 6) +* key bindings for package commands: Key bindings. (line 6) +* keybinding for repeat-mode keymaps: Binding to repeat-maps. + (line 6) +* keyword extension: Keyword extensions. (line 6) +* lazy loading by default: Deferring loading. (line 69) +* lazy loading of packages: Deferring loading. (line 6) +* list of selectors, for :after: Loading sequentially. (line 35) +* load-path, add directories for loading a package: Load path. (line 6) +* loading a package after other packages: Loading sequentially. + (line 6) +* loading conditions: Conditional loading. (line 6) +* loading lazily: Deferring loading. (line 6) +* loading packages with use-package: Loading Packages. (line 6) +* local keybindings: Binding in keymaps. (line 6) +* magic-mode-alist customization: Magic handlers. (line 6) +* manual update of packages: Pinning packages. (line 26) +* multiple hooks: Hooks. (line 37) +* non-standard package managers: Other package managers. + (line 6) +* options for troubleshooting: Troubleshooting Options. + (line 6) +* package autoloads, setting up manually: Manual autoloads. (line 10) +* package loading at byte-compilation time, prevent: Byte-compiling. + (line 40) +* package managers, other than package.el: Other package managers. + (line 6) +* package vs library: Loading basics. (line 20) +* pinning a package to archive: Pinning packages. (line 6) +* prevent a package from loading at compile-time: Byte-compiling. + (line 40) +* prevent loading package if dependencies are missing: Load dependencies. + (line 6) +* quick-start instructions: Getting Started. (line 6) +* reasons for developing use-package: Basic Concepts. (line 11) +* remapping commands with :bind: Global keybindings. (line 57) +* repeat-mode and use-package, using: Binding to repeat-maps. + (line 6) +* reporting bugs: Troubleshooting. (line 22) +* setting up major modes: Modes and interpreters. + (line 6) +* silence byte-compilation warnings: Byte-compiling. (line 16) +* tips for using :preface, :config, :init: Best practices. (line 6) +* triggers, for loading packages: Deferring loading. (line 15) +* troubleshooting use-package: Troubleshooting. (line 6) +* troubleshooting, options that help: Troubleshooting Options. + (line 6) +* usage statistics for use-package: Gathering Statistics. (line 6) +* use-package-always-defer: Deferring loading. (line 69) +* use-package-always-defer, with :after: Loading sequentially. (line 51) +* use-package-always-ensure: Install package. (line 20) +* use-package-always-pin: Pinning packages. (line 19) +* use-package-compute-statistics: Gathering Statistics. (line 12) +* use-package-ensure-function: Other package managers. + (line 10) +* use-package-expand-minimally: Troubleshooting Options. + (line 6) +* use-package-hook-name-suffix: Hooks. (line 65) +* use-package-report: Gathering Statistics. (line 19) +* use-package-reset-statistics: Gathering Statistics. (line 24) +* use-package-vc-prefer-newest: Install package. (line 52) +* use-package-verbose: Gathering Statistics. (line 6) +* user options, setting: User options. (line 6) +* variable customizations: User options. (line 6) + + + +Tag Table: +Node: Top918 +Node: Basic Concepts3154 +Node: Getting Started4671 +Node: Loading Packages7719 +Node: Loading basics9090 +Ref: Loading basics-Footnote-110729 +Node: Deferring loading10813 +Node: Forcing loading14066 +Node: Conditional loading14749 +Node: Loading sequentially17006 +Node: The emacs package19694 +Ref: The emacs package-Footnote-120596 +Node: Load dependencies20690 +Node: Manual installation21673 +Node: Load path22232 +Node: Manual autoloads23707 +Node: Configuring Packages24531 +Node: Lisp Configuration25287 +Node: Preface keyword26149 +Node: Init keyword27039 +Node: Config keyword27686 +Node: Best practices28409 +Node: Key bindings29966 +Node: Global keybindings30763 +Node: Binding in keymaps33926 +Node: Binding to a keymap35131 +Node: Binding to repeat-maps36167 +Node: Displaying keybindings38563 +Node: Hooks39125 +Node: Modes and interpreters41889 +Node: Magic handlers43458 +Node: User options44424 +Node: Faces45900 +Node: Hiding minor modes46701 +Ref: Hiding minor modes-Footnote-147422 +Node: Diminish47483 +Ref: Diminish-Footnote-148442 +Node: Delight48507 +Ref: Delight-Footnote-150371 +Node: Installing packages50435 +Node: Install package51194 +Node: Pinning packages53554 +Ref: Pinning packages-Footnote-155252 +Node: Other package managers55332 +Node: Byte-compiling56198 +Node: Troubleshooting58216 +Node: Troubleshooting Options59565 +Node: Gathering Statistics61119 +Node: Disabling a package62683 +Node: Keyword extensions63394 +Node: use-package-ensure-system-package63880 +Ref: use-package-ensure-system-package-Footnote-166873 +Ref: use-package-ensure-system-package-Footnote-267198 +Node: Creating an extension67329 +Node: History70760 +Node: GNU Free Documentation License71431 +Node: Index96781 + +End Tag Table + + +Local Variables: +coding: utf-8 +End: diff --git a/site-lisp/use-package-2.4.6/use-package.texi b/site-lisp/use-package-2.4.6/use-package.texi new file mode 100644 index 0000000..da3deb0 --- /dev/null +++ b/site-lisp/use-package-2.4.6/use-package.texi @@ -0,0 +1,2232 @@ +\input texinfo @c -*- texinfo -*- +@c %**start of header +@setfilename ../../info/use-package.info +@settitle use-package User Manual +@set USEP_VER 2.4.5 +@set USEP_DIST as distributed with Emacs @value{EMACSVER} +@include docstyle.texi +@syncodeindex vr cp +@syncodeindex fn cp +@include emacsver.texi +@c %**end of header + +@copying +This manual is for use-package @value{USEP_VER} @value{USEP_DIST}. + +Copyright @copyright{} 2022--2024 Free Software Foundation, Inc. + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 or +any later version published by the Free Software Foundation; with no +Invariant Sections, with the Front-Cover Texts being ``A GNU Manual'', +and with the Back-Cover Texts as in (a) below. A copy of the license +is included in the section entitled ``GNU Free Documentation License''. + +(a) The FSF's Back-Cover Text is: ``You have the freedom to copy and +modify this GNU manual.'' +@end quotation +@end copying + +@dircategory Emacs misc features +@direntry +* use-package: (use-package). Declarative package configuration for Emacs. +@end direntry + +@finalout +@titlepage +@title use-package User Manual +@subtitle for version USEP_VER +@author John Wiegley & Stefan Kangas +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@contents + +@ifnottex +@node Top +@top use-package User Manual + +The @code{use-package} macro allows you to set up package +customization in your init file in a declarative way. It takes care +of many things for you that would otherwise require a lot of +repetitive boilerplate code. It can help with common customization, +such as binding keys, setting up hooks, customizing user options and +faces, autoloading, and more. It also helps you keep Emacs startup +fast, even when you use many (even hundreds) of packages. + +Note that use-package is not a package manager. Although use-package +does have the useful capability to interface with the Emacs package +manager, its primary purpose is help with the configuration and +loading of packages, not with managing their download, upgrades, and +installation. + +@insertcopying + +@menu +* Basic Concepts:: Basic concepts of use-package. +* Getting Started:: A gentle introduction to use-package. +* Loading Packages:: How and when packages are loaded. +* Configuring Packages:: Package configuration keywords. +* Installing packages:: Ensuring packages are available. +* Byte-compiling:: Byte-compiling your init file. +* Troubleshooting:: What to do when there's trouble. + +Appendices +* Keyword extensions:: Adding new use-package keywords. +* History:: History and acknowledgments. +* GNU Free Documentation License:: The license for this manual. + +Index +* Index:: +@end menu +@end ifnottex + +@c ---------------------------------------------------------------------------- +@node Basic Concepts +@chapter Basic Concepts + +use-package provides the @code{use-package} macro, that simplifies the +customization and use of packages in Emacs. It was created for a few +basic reasons, each of which drove the design. Understanding these +reasons may help make some of those decisions clearer: + +@cindex reasons for developing use-package +@enumerate +@item +Allow gathering all the configuration details of a package into one +place, making it easier to copy, disable, or move it elsewhere in the +init file. + +@item +Reduce duplication and repetitive boilerplate, capturing several +common practices as mere keywords both easy and intuitive to use. + +@item +Make startup time of Emacs as short as possible, without sacrificing +the quantity of add-on packages used. + +@item +Ensure that errors encountered during startup disable only the +package(s) raising the error(s), and as little else as possible, +leaving Emacs as close to fully functional as possible. + +@item +Allow byte-compiling your init file, so that any warnings or errors +you see at startup are meaningful. In this way, even if +byte-compilation is not used for speed (see item 3 above), it can +still be used as a sanity check. +@end enumerate + +It is worth noting that use-package is not intended to replace the +standard customization command @w{@kbd{M-x customize}} (@pxref{Easy +Customization,,, emacs, GNU Emacs Manual}). On the contrary, it is +designed to work together with it, for things that Customize cannot +do. + +@c ---------------------------------------------------------------------------- +@node Getting Started +@chapter Getting Started +@cindex quick-start instructions + +This chapter provides instructions and examples for quickly getting +started with use-package. In this manual, we say that each call to +the @code{use-package} macro in your init file is a @dfn{declaration}, +to highlight the declarative nature of its syntax. + +To unconditionally load a package named @samp{foo}, add the following +declaration to your init file: + +@lisp +(use-package foo) +@end lisp + +@noindent +This declaration is equivalent to using @code{require} (@pxref{Named +Features,,, elisp, GNU Emacs Lisp Reference Manual}), with some +use-package specific error handling added in. Just like +@code{require}, it needs the package @samp{foo} to be installed and +available via your @code{load-path} (@pxref{Installing packages}). + +To evaluate some Lisp @emph{before} the @samp{foo} package is loaded, +use the @code{:init} keyword: + +@lisp +@group +(use-package foo + :init + (setq foo-variable t)) +@end group +@end lisp + +Similarly, @code{:config} can be used to execute code @emph{after} a +package is loaded. In cases where loading is done lazily +(@pxref{Loading Packages}), this execution is deferred until after the +loading actually occurs. As you might expect, you can use +@code{:init} and @code{:config} together: + +@lisp +@group +(use-package foo + :init + (setq foo-variable t) + :config + (foo-mode 1)) +@end group +@end lisp + +The above declarations will load the @samp{foo} package immediately. In +most cases, this is not necessary or desirable, as that will slow down +Emacs startup. Instead, you should try to set things up so that +packages are only loaded when they are actually needed (this is known as +``autoloading''). If you have installed a package from @acronym{GNU} +@acronym{ELPA} that provides its own autoloads, it is often enough to +say: + +@lisp +@group +(use-package foo + :defer t) +@end group +@end lisp + +@noindent +This will avoid loading the package. Now, when you run any autoloaded +command, the package @samp{foo} is loaded automatically. (Which +commands from a package are marked to auto-load by default is the +decision of the package authors.) + +In some cases, you might need or want to provide your own autoloads. +The more complex example below autoloads the commands +@code{isearch-moccur} and @code{isearch-all} from the package +@file{color-moccur.el}, and binds keys both globally and in +@code{isearch-mode-map}. When one of these two commands are used, the +package will be loaded. At that point, @code{moccur-edit} is also loaded, +to allow editing of the @code{moccur} buffer. + +@lisp +@group +(use-package color-moccur + :commands (isearch-moccur isearch-all) + :bind (("M-s O" . moccur) + :map isearch-mode-map + ("M-o" . isearch-moccur) + ("M-O" . isearch-moccur-all)) + :init + (setq isearch-lazy-highlight t) + :config + (use-package moccur-edit)) +@end group +@end lisp + +Some packages will suggest ready-made @code{use-package} declarations +that you can use. Where possible, it is a good idea to copy them, and +use that as a starting point. + +That should be enough to get you started! + +@c ---------------------------------------------------------------------------- +@node Loading Packages +@chapter Loading Packages +@cindex loading packages with use-package + +Before use-package can load an Emacs Lisp package, it must be +available in a directory on your @code{load-path}. When you install +packages using the built-in @code{install-package} command, it will do +this automatically for you. Packages shipped with Emacs (built-in +packages) are always available. + +Some packages have more than one library. In those cases, you might +need more than one @code{use-package} declaration to make sure the +package is properly loaded. For complex configurations, you might +also need more than one declaration for a package with the same name. + +use-package can interface with @samp{package.el} to install packages +on Emacs start. @xref{Installing packages}, for details. + +@menu +* Loading basics:: How and when packages are loaded. +* Deferring loading:: Loading packages later. +* Forcing loading:: Loading packages immediately. +* Conditional loading:: Loading packages conditionally. +* Loading sequentially:: Loading packages in sequence. +* The @code{emacs} package:: Customizing built-in variables. +* Load dependencies:: Don't load without dependencies. +* Manual installation:: Loading manually installed packages. +@end menu + +@node Loading basics +@section How and when use-package loads packages + +The call to the @code{use-package} macro will load a package either +immediately, or when the package is first used (via autoloading). In the +simplest case, a @code{use-package} declaration loads a package when +it is evaluated.@footnote{This happens both at run-time and at +compile-time. @xref{Byte-compiling}.} If the declaration is in your +init file, this happens automatically each time Emacs is started. + +For example, the declaration below immediately loads the library +@code{foo}, just like @code{require} would: + +@lisp +(use-package foo) +@end lisp + +@noindent +If the library @samp{foo} is not available in your @code{load-path}, +the declaration logs a warning to the @samp{*Messages*} buffer. + +@cindex package vs library +@c So, confusingly, (use-package foo) actually means to use the +@c _library_ foo.el, not all of the _package_ foo's libraries? +@c Should this be explicitly explained here? +Note that a ``package'' is different from an Emacs Lisp ``library''. +The above declaration tells use-package to load the @emph{library} +@file{foo.el}, which in the overwhelming majority of cases also +resides in a @emph{package} named @code{foo}. But the package +@code{foo} might also contain a library named @file{foo-extra.el}. If +that library is not loaded automatically, you will need a separate +@code{use-package} declaration to make sure that it is loaded when +needed. This manual will often use the terms ``package'' and +``library'' interchangeably, as this distinction does not usually +matter, but you should keep it in mind for the cases when it does. + +The details of how and when you should load a package might differ +from one package to another. When in doubt, refer to the package +documentation for details. + +@node Deferring loading +@section Deferring package loading +@cindex deferring loading of package + +@cindex autoloading packages +@cindex loading lazily +@cindex lazy loading of packages +In the examples we have seen so far, use-package loads packages every +time you start Emacs, even if that package is never used. That will +make starting Emacs slower. use-package therefore allows setting +things up in such a way that packages are only loaded when some of the +package's commands is first used (either with @kbd{M-x} or via some key +binding). This is based on autoloading, a full description of which +is outside the scope of this manual. @xref{Autoload,,, elisp, GNU +Emacs Lisp Reference Manual}, for the full story. + +@cindex triggers, for loading packages +Some @code{use-package} keywords provide autoload @dfn{triggers} that +cause a package to be loaded when certain events occur. For example, +the @code{:hook} keyword sets up a trigger that fires when the +specified hook is run, and then loads the package automatically. The +other trigger keywords, all of which are described later in this +manual, are @code{:commands}, @code{:bind}, @code{:bind*}, +@code{:bind-keymap}, @code{:bind-keymap*}, @code{:mode}, and +@code{:interpreter}. + +@subheading The @code{:defer} keyword + +@findex :defer +If you did not specify any autoloading keyword, use-package will fall +back to loading the package immediately (typically when Emacs is +starting up). This can be overridden using the @code{:defer} keyword. +It takes one boolean argument: a non-@code{nil} value means to stop +this package from being immediately loaded. Here is an example of +using @code{:defer} to postpone loading the package @samp{foo}: + +@lisp +@group +(use-package foo + :defer t) +@end group +@end lisp + +Using @code{:defer t} by itself like this is rarely useful. +Typically, you would only use it together with a keyword like +@code{:config} (@pxref{Lisp Configuration}), or @code{:ensure} +(@pxref{Installing packages}). + +@subheading Defer loading until idle for N seconds + +@findex :defer@r{, with a numeric argument} +You can also give a numeric argument @var{n} to @w{@code{:defer}} to +specify that a package should be loaded (if it hasn't already) after +Emacs has been idle for @var{n} seconds. For example, use the +following to make use-package load @samp{foo} after 30 seconds of idle +time: + +@lisp +@group +(use-package foo + :defer 30) +@end group +@end lisp + +@subheading When to use @code{:defer} + +When using autoloading keywords, there is no need to also use +@code{:defer}. It doesn't hurt to add it in this case, perhaps for +extra clarity, but it is redundant. + +You should use @code{:defer} to force deferred loading, in cases when +use-package isn't creating any autoloads for you. For example, you +might know that some other package will already do something to cause +your package to load at the appropriate time. This is usually the +case when you install a package using @code{package-install}, as +packages installed in this way normally always have their own +autoloads already set up. + +@subheading Making @w{@code{:defer t}} the default + +@cindex defer loading by default +@cindex lazy loading by default +@vindex use-package-always-defer +If you customize the user option @code{use-package-always-defer} to +non-@code{nil}, the @code{use-package} macro will behave as if +@w{@code{:defer t}} is always specified. This can be overridden for +individual declarations using either @w{@code{:defer nil}} or +@w{@code{:demand t}} (@pxref{Forcing loading}). + +@node Forcing loading +@section Forcing package to load immediately +@cindex forcing immediate loading + +@findex :demand +The presence of autoloading trigger keywords can be overridden using +@code{:demand t}, which forces the package to load immediately. Thus, +even if you use an autoloading keyword such as @code{:bind} +(@pxref{Key bindings}), adding @code{:demand} will force loading to +occur immediately. It will also avoid creating an autoload for the +bound key, as it would be redundant. + +If you specify both @w{@code{:demand t}} and @w{@code{:defer t}}, the +@code{:defer} keyword will take precedence. + +@node Conditional loading +@section Loading packages conditionally +@cindex conditional loading +@cindex loading conditions + +@findex :if +@findex :when +@findex :unless +The @code{:if}, @code{:when}, and @code{:unless} keywords predicates +the loading and initialization of packages. They all accept one +argument, an Emacs Lisp form that is evaluated at run-time. + +If the argument of the @code{:if} keyword evaluates to non-@code{nil}, +the package will be loaded and initialized. The @code{:when} keyword +is provided as an alias for @code{:if}. Finally, the @code{:unless} +keyword is the inverse of @code{:if}, such that @w{@code{:unless foo}} +means the same thing as @w{@code{:if (not foo)}}. + +For example, if you only want to load @samp{foo} in graphical Emacs +sessions, you could use the following: + +@lisp +@group +(use-package foo + :if (display-graphic-p)) +@end group +@end lisp + +@subheading Some common use cases + +Here are some common cases for conditional loading, and how to achieve +them. + +@c FIXME: Too many redundant examples? E.g., why do we need both an +@c example for system-type and window-system? or both of the last 2 +@c examples? +@itemize + +@item +Operating system + +The following example loads a package only on GNU/Linux. See the +docstring of @code{system-type} for other valid values. + +@lisp +:if (eq system-type 'gnu/linux) +@end lisp + +@item +Window system + +The example below loads a package only on macOS and X@. See the +docstring of @code{window-system} for valid values. + +@lisp +:if (memq window-system '(ns x)) +@end lisp + +@item +Installed package + +The following example loads a package only when the @samp{foo} package +is installed. + +@lisp +:if (package-installed-p 'foo) +@end lisp + +@item +Libraries in @code{load-path} + +The example below loads a package only when @file{foo.el} is available +in your @code{load-path} (for example, if you installed that file +manually): + +@lisp +:if (locate-library "foo.el") +@end lisp +@end itemize + +@subheading Making conditional loading affect @code{:preface} and @code{:ensure} + +@cindex conditional loading before @code{:preface} or @code{:ensure} +If you need to make a use-package form conditional so that the condition +occurs before even @code{:ensure} (@pxref{Install package}) or +@code{:preface} (@pxref{Preface keyword}), use @code{when} +around the @code{use-package} form itself. For example: + +@lisp +@group +(when (memq window-system '(mac ns)) + (use-package foo + :ensure t)) +@end group +@end lisp + +@node Loading sequentially +@section Loading packages in sequence +@cindex loading a package after other packages + +@findex :after +Sometimes it only makes sense to configure a package after another one +has been loaded, because certain variables or functions are not in +scope until that time. This can be achieved with the @code{:after} +keyword, which allows a fairly rich description of the exact +conditions when loading should occur. The @code{:after} keyword takes +as argument either a symbol indicating the package name, a list of +such symbols, or a list of selectors (see below). + +Here is an example of using the @acronym{GNU} @acronym{ELPA} packages +@file{hydra}, @file{ivy}, and @file{ivy-hydra}. Note that +@file{ivy-hydra} will always be loaded last: + +@lisp +(use-package hydra) + +(use-package ivy) + +@group +(use-package ivy-hydra + :after (ivy hydra)) +@end group +@end lisp + +In this case, because the declarations are evaluated in the order they +occur, the use of @code{:after} is not strictly necessary. However, +if @samp{hydra} and @samp{ivy} were to be autoloaded, using +@code{:after} guarantees that @samp{ivy-hydra} is not loaded until it +is actually needed. By using @code{:after}, the above code will also +work even if the order of the declaration changes. This means that +moving things around in your init file is less likely to break things. + +@subheading Using @code{:after} selectors + +@findex :all@r{, (with @code{:after})} +@findex :any@r{, (with @code{:after})} +@cindex list of selectors, for @code{:after} +The @code{:after} keyword also accepts a list of selectors. By +default, @w{@code{:after (foo bar)}} is the same as @w{@code{:after +(:all foo bar)}}, meaning that loading of the given package will not happen +until both @code{foo} and @code{bar} have been loaded. Here are some +of the other possibilities: + +@verbatim +:after (foo bar) +:after (:all foo bar) +:after (:any foo bar) +:after (:all (:any foo bar) (:any baz quux)) +:after (:any (:all foo bar) (:all baz quux)) +@end verbatim + +When you nest selectors, such as in @w{@code{(:any (:all foo bar) +(:all baz quux))}}, it means that the package will be loaded when +either both @code{foo} and @code{bar} have been loaded, or when both +@code{baz} and @code{quux} have been loaded. + +@cindex @code{use-package-always-defer}, with @code{:after} +Pay attention when setting @code{use-package-always-defer} to a +non-@code{nil} value, and also using the @code{:after} keyword. In +that case, you will need to specify how the declared package is to be +loaded: for example, by some @code{:bind} (@pxref{Global +keybindings}). If you are not using one of the keywords that +registers autoloads, such as @code{:bind} or @code{:hook} +(@pxref{Hooks}), and your package manager does not provide autoloads, +it is possible that your package will never be loaded if you do not +add @code{:demand t} to those declarations. + +@node The @code{emacs} package +@section Customizing built-in variables +@cindex customizing built-in variables + +Some users want to put all their customizations in use-package +declarations, even for variables, hooks, and options that are always +available, without loading any package.@footnote{In other words, they +are either preloaded in Emacs or defined in Emacs's C sources.} + +For that purpose, you can use the no-op @samp{emacs} package: + +@lisp +@group +(use-package emacs + :init + (setq custom-file "~/.emacs.d/emacs-custom.el") + (load custom-file) + (setq frame-title-format "%b") + :custom + (use-short-answers t)) +@end group +@end lisp + +This declaration takes advantage of the fact that @w{@code{(featurep +'emacs)}} always returns true, and has no special meaning beyond that. +It simply provides a way to organize your customizations, without +loading anything. + +@node Load dependencies +@section Prevent loading if dependencies are missing +@cindex prevent loading package if dependencies are missing + +@findex :requires +While the @code{:after} keyword delays loading until the dependencies +are loaded, the somewhat simpler @code{:requires} keyword @emph{never} +loads the package if the dependencies are not available when the +@code{use-package} declaration is evaluated. In this context, +``available'' means that @code{foo} is available if @w{@code{(featurep +'foo)}} evaluates to a non-@code{nil} value. For example: + +@lisp +@group +(use-package abbrev + :requires foo) +@end group +@end lisp + +@noindent +This is the same as: + +@lisp +@group +(use-package abbrev + :if (featurep 'foo)) +@end group +@end lisp + +As a convenience, a list of such packages may be specified: + +@lisp +@group +(use-package abbrev + :requires (foo bar baz)) +@end group +@end lisp + +For more complex logic, such as that supported by @code{:after}, +simply use @code{:if} and the appropriate Lisp expression. + +@node Manual installation +@section Manually installed package + +When installing packages manually, without Emacs's built-in package +manager (@file{package.el}), it will obviously not help you set up +autoloads or add it to your @code{load-path}. You must do it +yourself. However, use-package makes this more convenient. + +@menu +* Load path:: Using a custom @code{load-path}. +* Manual autoloads:: Setting up autoloads manually. +@end menu + +@node Load path +@subsection Setting a custom @code{load-path} +@cindex custom @code{load-path} for loading a package +@cindex @code{load-path}, add directories for loading a package + +When installing packages manually, you must make sure its libraries +are available on your @code{load-path}. @xref{Lisp Libraries,,, +emacs, GNU Emacs Manual}, for more details about package loading. + +@findex :load-path +The @code{:load-path} keyword provides a convenient way to add +directories to your load path. It takes as argument a symbol, a +function, a string or a list of strings. If a directory is specified +as a relative file name, it is expanded relative to +@code{user-emacs-directory}. + +For example: + +@lisp +@group +(use-package org + :load-path "site-lisp/org/lisp/" + :commands org-mode) +@end group +@end lisp + +When using a symbol or a function to provide a dynamically generated +list of directories, you must inform the byte-compiler of this +definition, so that the value is available at byte-compilation time. +This is done by using the special form @code{eval-and-compile} (as +opposed to @code{eval-when-compile}, @pxref{Eval During Compile,,, +elisp, GNU Emacs Lisp Reference Manual}). Furthermore, this value is +fixed to the value it had during compilation. If the operation is +costly, you do not have to repeat it again on each startup. For +example: + +@lisp +@group +(eval-and-compile + (defun ess-site-load-path () + (shell-command-to-string "find ~ -path ess/lisp"))) +@end group + +@group +(use-package ess-site + :load-path (lambda () (list (ess-site-load-path))) + :commands R) +@end group +@end lisp + +@node Manual autoloads +@subsection Setting up autoloads manually + +Packages often document how to set up its autoloads when it is being +manually installed. If it does, follow those instructions. +Otherwise, you might want to set them up manually. + +@cindex autoloads for packages, setting up manually +@cindex package autoloads, setting up manually + +@findex :commands +@findex :autoload +To autoload an interactive command, use the @code{:commands} keyword, +which takes either a symbol or a list of symbols as its argument. It +creates autoloads for those commands (which defers loading of the +module until those commands are used). + +The @code{:autoload} keyword takes the same arguments as +@code{:commands}, but is used to autoload non-interactive functions. +Here is an example: + +@lisp +@group +(use-package org-crypt + :autoload org-crypt-use-before-save-magic) +@end group +@end lisp + +@c ---------------------------------------------------------------------------- +@node Configuring Packages +@chapter Configuring Packages +@cindex configure packages using @code{use-package} +@cindex customize package configuration + +This chapter describes the various keywords provided by +@code{use-package} that help you configure packages. + +@menu +* Lisp Configuration:: Using Lisp to configure packages. +* Key bindings:: Making your own keybindings. +* Hooks:: Adding functions to hooks. +* Modes and interpreters:: Enabling modes automatically. +* Magic handlers:: Using regexps to enable modes. +* User options:: Setting user options. +* Faces:: Customizing faces. +* Hiding minor modes:: Tidying up the mode line. +@end menu + +@node Lisp Configuration +@section Using Lisp code for configuring packages +@cindex configure package using Lisp forms + +The most general way to add customizations are the @code{:preface}, +@code{:init}, and @code{:config} keywords. They all accept one or +more Emacs Lisp forms, up to the next keyword, that are evaluated in +order. This lets you add arbitrary Lisp code to your +@code{use-package} declarations. + +The only difference between these keywords is when they are evaluated. + +@menu +* Preface keyword:: Evaluate code before anything else. +* Init keyword:: Evaluate code before loading package. +* Config keyword:: Evaluate code after loading package. +* Best practices:: When to use @code{:config}, @code{:init}, and @code{:preface}. +@end menu + +@node Preface keyword +@subsection @code{:preface} is evaluated first + +@findex :preface +The @code{:preface} section is evaluated before anything else, except +@code{:disabled} and @code{:ensure}. It can be used to establish +function and variable definitions that will: + +@enumerate +@item +Make the byte-compiler happy: it will not complain about functions +whose definitions are unknown. + +@item +Define functions and variables that will be used in an @code{:if} +test. +@end enumerate + +Note that whatever is specified within @code{:preface} is evaluated +both at load time and at byte-compilation time, in order to ensure +that definitions are seen by both the Lisp evaluator and the +byte-compiler. Therefore, you should avoid having any side-effects in +your @code{:preface} forms, and restrict them to symbol declarations +and definitions. + +@node Init keyword +@subsection @code{:init} is evaluated before loading package + +@findex :init +The @code{:init} section is evaluated just before the package is +loaded. Note that the @code{:init} form is run unconditionally -- +even if the package happens to not exist on your system. You must +therefore remember to restrict @code{:init} code to what would succeed +either way; put the rest in the @code{:config} section. @code{:init} +also always happens before package load, whether @code{:config} has +been deferred or not. + +@node Config keyword +@subsection @code{:config} is evaluated after loading package + +@findex :config +The @code{:config} section is evaluated after the package has been +loaded. If the package is loaded immediately, this happens +immediately after that, but if loading is done lazily (@pxref{Loading +Packages}), this is deferred until after the package has been loaded. + +In general, you should keep @code{:init} forms as simple and quick as +possible, and put as much as you can get away with into the +@code{:config} section. That way, deferred loading can help your +Emacs start as quickly as possible. + +@node Best practices +@subsection When to use @code{:preface}, @code{:config} and @code{:init}? +@cindex tips for using @code{:preface}, @code{:config}, @code{:init} + +Where possible, it is better to avoid @code{:preface}, @code{:config} +and @code{:init}. Instead, prefer autoloading keywords such as +@code{:bind} (@pxref{Key bindings}), @code{:hook} (@pxref{Hooks}), and +@code{:mode} (@pxref{Modes and interpreters}), as they will take care +of setting up autoloads for you without any need for boilerplate code. +For example, consider the following declaration: + +@lisp +@group +(use-package foo + :init + (add-hook 'some-hook 'foo-mode)) +@end group +@end lisp + +@noindent +This has two problems. First, it will unconditionally load the +package @samp{foo} on startup, which will make things slower. You can +fix this by adding @w{@code{:defer t}}: + +@lisp +@group +(use-package foo + :defer t + :init + (add-hook 'some-hook 'foo-mode)) +@end group +@end lisp + +@noindent +This is better, as @samp{foo} is now only loaded when it is actually +needed (that is, when the hook @samp{some-hook} is run). + +The second problem is that there is a lot of boilerplate that you have +to write. In this case, it might not be so bad, but avoiding that was +what use-package was made to allow. The better option in this case is +therefore to use @code{:hook} (@pxref{Hooks}), which also implies +@w{@code{:defer t}}. The above is thereby reduced down to: + +@lisp +@group +(use-package foo + :hook some-hook) +@end group +@end lisp + +Now use-package will set up autoloading for you, and your Emacs +startup time will not suffer one bit. + +@node Key bindings +@section Key bindings + +@cindex binding keys for package commands +@cindex key bindings for package commands +One common thing to do when loading a package is to bind keys to +commands within that module. Without use-package, this would be done +using a combination of @code{keymap-local-set}, +@code{keymap-global-set} and various autoloads. With use-package, you +can simplify this using the @code{:bind} keyword, as described in this +section. + +@menu +* Global keybindings:: Bindings you can use anywhere. +* Binding in keymaps:: Bindings for particular modes. +* Binding to a keymap:: Binding a key to a keymap. +* Binding to repeat-maps:: Binding repeating keys. +* Displaying keybindings:: Displaying personal key bindings. +@end menu + +@node Global keybindings +@subsection Global keybindings +@cindex global keybindings + +@findex :bind +To bind keys globally, the @code{:bind} keyword takes as its argument +either a single cons or a list of conses. Each cons has the form +@w{@code{(@var{key} . @var{command})}}, where @var{key} is a string +indicating the key to bind, and @var{command} is the name of a command +(a symbol). The syntax for the keys is similar to the syntax used by +the @code{kbd} function (see @ref{Init Rebinding,,, emacs, GNU Emacs +Manual}, for more information). + +@subheading Using @code{:bind} with a single cons + +Here is an example of using a single cons: + +@lisp +@group +(use-package ace-jump-mode + :bind ("C-." . ace-jump-mode)) +@end group +@end lisp + +@noindent +This does two things: first, it creates an autoload for the +@code{ace-jump-mode} command and defers loading of the +@code{ace-jump-mode} package until you actually use it. Second, it +binds the key @code{C-.} to that command globally. + +@subheading Using @code{:bind} with a list of conses + +Here is an example of using @code{:bind} with a list of conses: + +@lisp +@group +(use-package hi-lock + :bind (("M-o l" . highlight-lines-matching-regexp) + ("M-o r" . highlight-regexp) + ("M-o w" . highlight-phrase))) +@end group +@end lisp + +@noindent +This binds the three key sequences to the corresponding commands. + +@subheading Using special keys +@cindex binding function keys with @code{:bind} +@cindex @code{:bind}, and function keys + +@c FIXME: TAB vs [tab] -- is letter-case important? In general, these +@c are two different keys: one is an ASCII character, the other a +@c function key on GUI frames. +Inside key strings, special keys like @kbd{TAB} or @kbd{F1}--@kbd{F12} +have to be written inside angle brackets, e.g., @code{"C-<up>"}. +@c FIXME: ``Some combinations''? which ones? +Standalone special keys (and some combinations) can be written in +square brackets, e.g.@ @code{[tab]} instead of @code{"<tab>"}. + +Examples: + +@lisp +@group +(use-package helm + :bind (("M-x" . helm-M-x) + ("M-<f5>" . helm-find-files) + ([f10] . helm-buffers-list) + ([S-f10] . helm-recentf))) +@end group +@end lisp + +@subheading Remapping commands +@cindex remapping commands with @code{:bind} +@cindex @code{:bind}, and remapping of commands + +Remapping of commands with @code{:bind} and @code{bind-key} works as +expected, because when the binding is a vector, it is passed straight +to @code{define-key}. @xref{Remapping Commands,,, elisp, GNU Emacs +Lisp Reference Manual}, for more information about command remapping. +For example, the following declaration will rebind +@code{fill-paragraph} (bound to @kbd{M-q} by default) to +@code{unfill-toggle}: + +@lisp +@group +(use-package unfill + :bind ([remap fill-paragraph] . unfill-toggle)) +@end group +@end lisp + +@c FIXME: Should the below be an Appendix? +@subheading What @code{:bind} does behind the scenes +@cindex @code{:bind}, internals + +To understand what @code{:bind} does behind the scenes, it might be +useful to consider an example: + +@lisp +@group +(use-package ace-jump-mode + :bind ("C-." . ace-jump-mode)) +@end group +@end lisp + +@noindent +This could be expressed in a much more verbose way with the +@code{:commands} and @code{:init} keywords: + +@lisp +@group +(use-package ace-jump-mode + :commands ace-jump-mode + :init + (bind-key "C-." 'ace-jump-mode)) +@end group +@end lisp + +@noindent +Without using even the @code{:commands} keyword, we could also write +the above like so: + +@lisp +@group +(use-package ace-jump-mode + :defer t + :init + (autoload 'ace-jump-mode "ace-jump-mode" nil t) + (bind-key "C-." 'ace-jump-mode)) +@end group +@end lisp + +Although these three forms are all equivalent, the first form is +usually the best, as it will save some typing. + +@node Binding in keymaps +@subsection Key bindings in local keymaps +@cindex local keybindings + +@findex :map@r{, inside} :bind +Slightly different from binding a key to a keymap, is binding a key +@emph{within} a local keymap that only exists after the package is +loaded. @code{use-package} supports this with a @code{:map} modifier, +taking the local keymap to bind to: + +@lisp +@group +(use-package helm + :bind (:map helm-command-map + ("C-c h" . helm-execute-persistent-action))) +@end group +@end lisp + +@noindent +The effect of this is to wait until @code{helm} has loaded, and then +to bind the key sequence @kbd{C-c h} to +@code{helm-execute-persistent-action} within Helm's local keymap, +@code{helm-command-map}. + +Multiple uses of @code{:map} may be specified. Any binding occurring +before the first use of @code{:map} are applied to the global keymap: + +@lisp +@group +(use-package term + :bind (("C-c t" . term) + :map term-mode-map + ("M-p" . term-send-up) + ("M-n" . term-send-down) + :map term-raw-map + ("M-o" . other-window) + ("M-p" . term-send-up) + ("M-n" . term-send-down))) +@end group +@end lisp + +@node Binding to a keymap +@subsection Binding to keymaps +@cindex binding keys to keymaps + +@findex :bind-keymap +Normally @code{:bind} expects that commands are functions that will be +autoloaded from the given package. However, this does not work if one of +those commands is actually a keymap, since keymaps are not functions, +and cannot be autoloaded using the built-in @code{autoload} function. + +To handle this case, @code{use-package} offers a special, limited +variant of @code{:bind} called @code{:bind-keymap}. The only difference +is that the ``commands'' bound to by @code{:bind-keymap} must be keymaps +defined in the package, rather than interactive functions. This is handled +behind the scenes by generating custom code that loads the package +containing the keymap, and then re-executes your keypress after the +first load, to reinterpret that keypress as a prefix key. + +For example: + +@lisp +@group +(use-package foo + :bind-keymap ("C-c p" . foo-command-map)) +@end group +@end lisp + +@node Binding to repeat-maps +@subsection Binding to repeat-maps +@cindex keybinding for @code{repeat-mode} keymaps + +@findex :repeat-map@r{, inside} :bind +@cindex @code{repeat-mode} and use-package, using +A special case of binding within a local keymap is when that keymap is +used by @code{repeat-mode} (@pxref{Repeating,,, emacs, GNU Emacs +Manual}). These keymaps are usually defined specifically for +this. Using the @code{:repeat-map} keyword, and passing it a name for +the map it defines, will bind all the following keys inside that map, and +(by default) set the @code{repeat-map} property of each bound command +to that map. + +The following example creates a keymap called +@code{git-gutter+-repeat-map}, makes four bindings in it, then sets +the @code{repeat-map} property of each bound command +(@code{git-gutter+-next-hunk}, @code{git-gutter+-previous-hunk}, +@code{git-gutter+-stage-hunks}, and @code{git-gutter+-revert-hunk}) to +that keymap. + +@lisp +@group +(use-package git-gutter+ + :bind + (:repeat-map git-gutter+-repeat-map + ("n" . git-gutter+-next-hunk) + ("p" . git-gutter+-previous-hunk) + ("s" . git-gutter+-stage-hunks) + ("r" . git-gutter+-revert-hunk))) +@end group +@end lisp + +@findex :exit@r{, inside} :repeat-map@r{ and} :bind +@cindex binding commands used at end of repeat series +Specifying @code{:exit} inside the scope of @code{:repeat-map} will +prevent the @code{repeat-map} property from being set, so that the command +can be used from within the repeat map, but after using it the repeat +map will no longer be available. This is useful for commands often used +at the end of a series of repeated commands. Example: + +@lisp +@group +(use-package git-gutter+ + :bind + (:repeat-map my/git-gutter+-repeat-map + ("n" . git-gutter+-next-hunk) + ("p" . git-gutter+-previous-hunk) + ("s" . git-gutter+-stage-hunks) + ("r" . git-gutter+-revert-hunk) + :exit + ("c" . magit-commit-create) + ("C" . magit-commit) + ("b" . magit-blame))) +@end group +@end lisp + +@findex :continue@r{, inside} :repeat-map@r{ and} :bind +Specifying @code{:continue} @emph{forces} setting the +@code{repeat-map} property (just like @emph{not} specifying +@code{:exit}), so the above snippet is equivalent to: + +@lisp +@group +(use-package git-gutter+ + :bind + (:repeat-map my/git-gutter+-repeat-map + :exit + ("c" . magit-commit-create) + ("C" . magit-commit) + ("b" . magit-blame) + :continue + ("n" . git-gutter+-next-hunk) + ("p" . git-gutter+-previous-hunk) + ("s" . git-gutter+-stage-hunks) + ("r" . git-gutter+-revert-hunk))) +@end group +@end lisp + +@node Displaying keybindings +@subsection Displaying personal keybindings +@cindex display your keybindings + +@findex describe-personal-keybindings +The @code{:bind} keyword uses the @code{bind-keys} macro from the +@samp{bind-key.el} library to set up keybindings. It keeps track of +all keybindings you make, so that you can display them separately from +the default keybindings. + +Use @w{@kbd{M-x describe-personal-keybindings}} to see all +keybindings you've set using either the @code{:bind} keyword or the +@code{bind-keys} macro. + +@node Hooks +@section Hooks + +@cindex hooks +@findex :hook +The @code{:hook} keyword allows adding functions to hooks. It takes +@c FIXME: The actual forms accepted by :hook are different, see below! +one argument of the form @var{hooks}, specifying one or more functions +to add to one or more hooks. For the purposes of @code{:hook}, the +name of hook variables should always exclude the @samp{-hook} suffix. +It is appended automatically for you, to save some typing. + +For example, consider the following @code{use-package} declaration +that sets up autoloads for @code{company-mode} from the @samp{company} +package, and adds @samp{company-mode} to @code{prog-mode-hook}: + +@lisp +@group +(use-package company + :commands company-mode + :init + (add-hook 'prog-mode-hook #'company-mode)) +@end group +@end lisp + +Using @code{:hook}, this can be simplified to: + +@lisp +@group +(use-package company + :hook (prog-mode . company-mode)) +@end group +@end lisp + +Here, @code{:hook} will automatically set up autoloads for the +@code{company-mode} command, so there is no need to use +@code{:commands}. + +The @code{:hook} keyword will also assume that the name of the +function you want to add is the same as the package name with +@samp{-mode} appended to it. Taking this into account, you can +simplify the above to the equivalent: + +@lisp +@group +(use-package company + :hook prog-mode) +@end group +@end lisp + +@cindex multiple hooks +You can also provide a list of hooks. When multiple hooks should be +applied, the following examples are all equivalent: + +@lisp +@group +(use-package company + :hook (prog-mode text-mode)) +@end group + +@group +(use-package company + :hook ((prog-mode text-mode) . company-mode)) +@end group + +@group +(use-package company + :hook ((prog-mode . company-mode) + (text-mode . company-mode))) +@end group + +@group +(use-package company + :commands company-mode + :init + (add-hook 'prog-mode-hook #'company-mode) + (add-hook 'text-mode-hook #'company-mode)) +@end group +@end lisp + +One common mistake when using @code{:hook} is to forget to omit the +@samp{-hook} suffix, which, as already explained, is appended +automatically. Therefore, the following will not work, as it attempts +to add a function to non-existent @code{prog-mode-hook-hook}: + +@lisp +@group +;; DOES NOT WORK +(use-package ace-jump-mode + :hook (prog-mode-hook . ace-jump-mode)) +@end group +@end lisp + +@vindex use-package-hook-name-suffix +If you do not like this behavior, you can customize the user option +@code{use-package-hook-name-suffix} to @code{nil}. The value of this +variable is @samp{"-hook"} by default. + +The use of @code{:hook}, as with @code{:bind}, @code{:mode}, +@code{:interpreter}, etc., causes the functions being hooked to +implicitly be read as @code{:commands}. This means that they will +establish interactive @code{autoload} definitions for that module, if +not already defined as functions), and so @code{:defer t} is also +implied by @code{:hook}. + +@node Modes and interpreters +@section Modes and interpreters +@cindex @code{auto-mode-alist} customization +@cindex @code{interpreter-mode-alist} customization +@cindex setting up major modes + +@findex :mode +@findex :interpreter +Similar to @code{:bind}, you can use @code{:mode} and +@code{:interpreter} to establish a deferred binding within the +@code{auto-mode-alist} and @code{interpreter-mode-alist} variables +(@pxref{Auto Major Mode,,, elisp, GNU Emacs Lisp Reference Manual}). +The specifier to either keyword can be a cons cell, a list of cons +cells, or a string or regexp. + +The following example reproduces the default @code{ruby-mode} +configuration, exactly as it is in Emacs out-of-the-box. That mode is +enabled automatically when a file whose name matches the regexp +@code{"\\.rb\\'"} (a file with the @file{.rb} extension), or when the +first line of the file (known as the ``shebang'') matches the string +@code{"ruby"}: + +@lisp +@group +(use-package ruby-mode + :mode "\\.rb\\'" + :interpreter "ruby") +@end group +@end lisp + +The default @code{python-mode} configuration can be reproduced using +the declaration below. Note that the package that should be loaded +differs from the mode name in this case, so we must use a cons: + +@lisp +@group +;; The package is "python" but the mode is "python-mode": +(use-package python + :mode ("\\.py\\'" . python-mode) + :interpreter ("python" . python-mode)) +@end group +@end lisp + +Both the @code{:mode} and @code{:interpreter} keywords also accept a +list of regexps: + +@lisp +@group +(use-package foo + ;; Equivalent to "\\(ba[rz]\\)\\'": + :mode ("\\.bar\\'" "\\.baz\\'") + ;; Equivalent to "\\(foo[ab]\\)": + :interpreter ("fooa" "foob")) +@end group +@end lisp + +@node Magic handlers +@section Magic handlers +@cindex @code{magic-mode-alist} customization + +@findex :magic +@findex :magic-fallback +Similar to @code{:mode} and @code{:interpreter}, you can also use +@code{:magic} and @code{:magic-fallback} to cause certain function to +be run if the beginning of a file matches a given regular expression, +as if these regular expressions were added to @code{magic-mode-alist} +and @code{magic-fallback-mode-alist} (@pxref{Auto Major Mode,,, elisp, +GNU Emacs Lisp Reference Manual}). The difference between +@code{:magic} and @code{:magic-fallback}, is that the latter has a +lower priority than @code{:mode}. + +Here is an example: + +@lisp +@group +(use-package pdf-tools + :magic ("%PDF" . pdf-view-mode) + :config + (pdf-tools-install :no-query)) +@end group +@end lisp + +This registers an autoloaded command for @code{pdf-view-mode}, defers +loading of @code{pdf-tools}, and runs @code{pdf-view-mode} if the +beginning of a buffer matches the string @code{"%PDF"}. + +@node User options +@section User options +@cindex customization of variables +@cindex variable customizations +@cindex user options, setting + +@findex :custom +In Emacs, you normally set customizable variables (user options) using +the @code{M-x customize} interface (@pxref{Easy Customization,,, +emacs, GNU Emacs Manual}). We recommend this method for most users. +However, it is also possible to set them in your @code{use-package} +declarations by using the @code{:custom} keyword. + +@lisp +@group +(use-package comint + :defer t + :custom + (comint-buffer-maximum-size 20000 "Increase comint buffer size.") + (comint-prompt-read-only t "Make the prompt read only.")) +@end group +@end lisp + +This is better than using @code{setq} in a @code{:config} block, as +customizable variables might have some code associated with it that +Emacs will execute when you assign values to them. (In Emacs 29 and +later, there is also the new @code{setopt} macro that does this for +you.) + +Note that the values customized using @code{:custom} are @emph{not} +saved in the standard Emacs @code{custom-file} (@pxref{Saving +Customizations,,, emacs, GNU Emacs Manual}). You should therefore set +each user option using either the @code{:custom} keyword @emph{or} +@w{@kbd{M-x customize-option}} command; the latter will save +customized values in the Emacs @code{custom-file}. Do not use both +for the same variable, as this risks having conflicting values in your +use-package declaration and your @code{custom-file}, which can lead to +problems that are both tricky and tedious to debug. + +@node Faces +@section Faces +@cindex faces, setting +@cindex customization of faces + +@findex :custom-face +The @code{:custom-face} keyword allows customization of package's +faces. Example: + +@lisp +@group +(use-package eruby-mode + :custom-face + (eruby-standard-face ((t (:slant italic))))) +@end group + +@group +(use-package example + :custom-face + (example-1-face ((t (:foreground "LightPink")))) + (example-2-face ((t (:foreground "LightGreen"))) face-defspec-spec)) +@end group + +@group +(use-package zenburn-theme + :preface + (setq my/zenburn-colors-alist + '((fg . "#DCDCCC") (bg . "#1C1C1C") (cyan . "#93E0E3"))) + :custom-face + (region ((t (:background ,(alist-get my/zenburn-colors-alist 'cyan))))) + :config + (load-theme 'zenburn t)) +@end group +@end lisp + +@node Hiding minor modes +@section Hiding minor modes with diminish and delight +@cindex hiding minor modes + +@code{use-package} supports the @file{diminish} and @file{delight} +packages, both of which make it possible to remove or change minor mode +strings in your mode-line. Which one to use is up to you, but you +should normally only use one or the other -- never both.@footnote{When +in doubt, you might as well use @file{diminish}.} To use either of them, you +must first install the corresponding package from @acronym{GNU} @acronym{ELPA}. + +@menu +* Diminish:: Hiding minor modes with Diminish. +* Delight:: Hiding minor modes with Delight. +@end menu + +@node Diminish +@subsection Diminish + +@findex :diminish +When diminish@footnote{The @file{diminish} package is installable from +@acronym{GNU} @acronym{ELPA}.} is installed, you can use the @code{:diminish} +keyword. If @file{diminish} is not installed, the @code{:diminish} keyword +does nothing. + +First, add the following declaration to the beginning of your init +file. + +@lisp +(use-package diminish :ensure t) +@end lisp + +@noindent +The optional @w{@code{:ensure t}} makes sure the package is installed +if it isn't already (@pxref{Installing packages}). + +The @code{:diminish} keyword takes as its argument either a minor mode +symbol, a cons of the symbol and its replacement string, or just a +replacement string, in which case the minor mode symbol is guessed to +be the package name with @samp{-mode} appended at the end: + +@lisp +@group +(use-package abbrev + :diminish abbrev-mode + :config + (if (file-exists-p abbrev-file-name) + (quietly-read-abbrev-file))) +@end group +@end lisp + +@node Delight +@subsection Delight + +@findex :delight +When @file{delight}@footnote{The @file{delight} package is installable from +@acronym{GNU} @acronym{ELPA}.} is installed, you can use the +@code{:delight} keyword. If @file{delight} is not installed, the +@code{:delight} keyword does nothing. + +First, add the following declaration to the beginning of your init +file. + +@lisp +(use-package delight :ensure t) +@end lisp + +@noindent +The optional @w{@code{:ensure t}} makes sure the package is installed +if it isn't already (@pxref{Installing packages}). + +The @code{:delight} keyword takes as its argument a minor mode symbol, +a replacement string, or quoted mode line data (in which case the +minor mode symbol is assumed to be the package name with @samp{-mode} +appended at the end), both of these, or several lists of both. +@xref{Mode Line Data,,, elisp, GNU Emacs Lisp Reference Manual}. If +no arguments are provided, the default mode name is hidden completely. + +For example, the following hides everything for the @samp{foo-mode} +minor mode in the @samp{foo} package: + +@lisp +@group +(use-package foo + :delight) +@end group +@end lisp + +If the mode name doesn't match the package name with @samp{-mode} +appended, provide a symbol instead. For example, the following hides +@code{auto-revert-mode} from the mode line: + +@lisp +@group +;; Don't show anything for auto-revert-mode, which doesn't match +;; its package name. +(use-package autorevert + :delight auto-revert-mode) +@end group +@end lisp + +You can also use arbitrary Lisp code as argument of @code{:delight}. +For example, to replace @samp{foo-mode} with the value of the current +buffer: + +@lisp +@group +(use-package foo + :delight '(:eval buffer-file-name)) +@end group +@end lisp + +Here is an example of hiding several built-in minor modes: + +@lisp +@group +;; Completely hide visual-line-mode and change auto-fill-mode to " AF". +(use-package emacs + :delight + (auto-fill-function " AF") + (visual-line-mode)) +@end group +@end lisp + +@c ---------------------------------------------------------------------------- +@node Installing packages +@chapter Installing packages automatically + +The standard Emacs package manager is documented in the Emacs manual +(@pxref{Package Installation,,, emacs, GNU Emacs Manual}). The +@code{use-package} macro provides the @code{:ensure} and @code{:pin} +keywords that interface with that package manager to automatically +install packages. The @code{:vc} keyword may be used to control how +package sources are downloaded; e.g., from remote hosts +(@pxref{Fetching Package Sources,,, emacs, GNU Emacs Manual}). This +is particularly useful if you use your init file on more than one +system. + +@menu +* Install package:: +* Pinning packages:: +* Other package managers:: +@end menu + +@node Install package +@section Installing package +@cindex installing packages from archives + +@findex :ensure +The @code{:ensure} keyword makes use-package ask the Emacs package +manager to install a package if it is not already present on your +system. + +For example: + +@lisp +@group +(use-package magit + :ensure t) +@end group +@end lisp + +If you need to install a different package from the one named by +@code{use-package}, you can use a symbol: + +@lisp +@group +(use-package tex + :ensure auctex) +@end group +@end lisp + +@vindex use-package-always-ensure +You can customize the user option @code{use-package-always-ensure} to +a non-@code{nil} value if you want this behavior to be global for all +packages: + +@lisp +@group +(require 'use-package-ensure) +(setq use-package-always-ensure t) +@end group +@end lisp + +@noindent +You can override the above setting for a single package by adding +@w{@code{:ensure nil}} to its declaration. + +@findex :vc +The @code{:vc} keyword can be used to control how packages are +downloaded and/or installed. More specifically, it allows one to fetch +and update packages directly from a version control system. This is +especially convenient when wanting to install a package that is not on +any package archive. + +The keyword accepts the same arguments as specified in +@pxref{Fetching Package Sources,,, emacs, GNU Emacs Manual}, except +that a name need not explicitly be given: it is inferred from the +declaration. The accepted property list is augmented by a @code{:rev} +keyword, which has the same shape as the @code{REV} argument to +@code{package-vc-install}. Notably -- even when not specified -- +@code{:rev} defaults to checking out the last release of the package. +You can use @code{:rev :newest} to check out the latest commit. + +For example, + +@example +@group +(use-package bbdb + :vc (:url "https://git.savannah.nongnu.org/git/bbdb.git" + :rev :newest)) +@end group +@end example + +would try -- by invoking @code{package-vc-install} -- to install the +latest commit of the package @code{foo} from the specified remote. + +@vindex use-package-vc-prefer-newest +Alternatively, the @code{use-package-vc-prefer-newest} user option +exists to always prefer the latest commit. + +The @code{:vc} keyword can also be used for local packages, by +combining it with @code{:load-path} (@pxref{Load path}): + +@example +@group +;; Use a local copy of BBDB instead of the one from GNU ELPA. +(use-package bbdb + :vc t + :load-path "/path/to/bbdb/dir/") +@end group +@end example + +The above dispatches to @code{package-vc-install-from-checkout}. + +@node Pinning packages +@section Pinning packages using @code{:pin} +@cindex installing package from specific archive +@cindex pinning a package to archive + +@findex :pin +use-package can @dfn{pin} a package to a specific archive using the +@code{:pin} keyword.@footnote{The @code{:pin} keyword has no effect on +Emacs versions older than 24.4.} This allows you to mix and match +packages from different archives. The primary use-case for this is +preferring to install packages from @acronym{GNU} @acronym{ELPA} or +@acronym{NonGNU} @acronym{ELPA} (indicated by @code{gnu} and @code{nongnu}, +respectively), while installing specific packages from third-party +archives. + +For example: + +@lisp +@group +(use-package company + :ensure t + :pin gnu) ; GNU ELPA +@end group +@end lisp + +@vindex use-package-always-pin +Unfortunately, the third-party archive @acronym{MELPA} uses a +versioning scheme based on dates, which means that packages from that +archive are always preferred. If you are using that archive, we +strongly encourage you to customize @code{use-package-always-pin} to +@code{nongnu}. This guarantees that you are using a version of that +package that has been specifically marked for release by its +developer, and not a development snapshot. + +@cindex manual update of packages +@c FIXME: This needs clarifying. AFAIK, :ensure does not update packages. +If you want to manually keep a package updated and ignore upstream +updates, you can pin it to @samp{manual}. This will work as long as +you have not customized a repository to use that name in the +@code{package-archives} variable. + +Example: + +@lisp +@group +(use-package org + :ensure t + ;; ignore org-mode from upstream and use a manually installed version + :pin manual) +@end group +@end lisp + +@code{use-package} signals an error if you try to pin a package to an +archive that is not configured using @code{package-archives} (except +from the special @samp{manual} archive). + +@node Other package managers +@section Non-standard package managers +@cindex non-standard package managers +@cindex package managers, other than @file{package.el} +@cindex installing using non-standard package managers + +By default, use-package assumes that you are using the Emacs built-in +@file{package.el} package manager. We expect that most users will +find that it is capable enough, even for advanced use cases. + +@vindex use-package-ensure-function +However, some users might prefer to use a third-party package manager +for a specific circumstance or use case. By setting the user option +@code{use-package-ensure-function} to the name of a function, you can +direct @code{:ensure} to use a different package manager for +installing packages. + +For more details, please see the documentation of the package manager +you are using. If you run into any bugs, it is often best to report +them directly to the developers of that package manager. + +@c ---------------------------------------------------------------------------- +@node Byte-compiling +@chapter Byte-compiling your init file +@cindex byte-compiling your init file + +Some users might want to byte-compile their init file to make Emacs +startup faster. This is not recommended in most cases, as the +speed-up is usually too small to be worth it, and it can lead to +confusion if the byte-compiled files are out-of-date. If you still +want to do it, this chapter explains how to do that. + +@code{use-package} always loads every library that it can while a file +is being byte-compiled. This helps silence spurious warnings about +unknown variables and functions. + +@findex :defines +@findex :functions +@cindex silence byte-compilation warnings +However, there are times when this is just not enough. For those +times, use the @code{:defines} and @code{:functions} keywords to +introduce dummy variable and function declarations solely for the sake +of silencing byte-compiler warnings. For example: + +@lisp +@group +(use-package texinfo + :defines texinfo-section-list + :commands texinfo-mode + :init + (add-to-list 'auto-mode-alist '("\\.texi$" . texinfo-mode))) +@end group +@end lisp + +If you need to silence a missing function warning, you can use +@code{:functions}: + +@lisp +@group +(use-package ruby-mode + :mode "\\.rb\\'" + :interpreter "ruby" + :functions inf-ruby-keys + :config + (defun my-ruby-mode-hook () + (require 'inf-ruby) + (inf-ruby-keys)) + (add-hook 'ruby-mode-hook 'my-ruby-mode-hook)) +@end group +@end lisp + +@findex :no-require +@cindex prevent a package from loading at compile-time +@cindex package loading at byte-compilation time, prevent +Normally, @code{use-package} will load each package at compile time +before compiling the configuration, to ensure that any necessary +symbols are in scope to satisfy the byte-compiler. At times this can +cause problems, since a package may have special loading requirements, +and all that you want to use @code{use-package} for is to add a +configuration to the @code{eval-after-load} hook. In such cases, use +the @code{:no-require} keyword: + +@lisp +@group +(use-package foo + :no-require t + :config + (message "Evaluate this immediately after loading `foo'")) +@end group +@end lisp + +@c ---------------------------------------------------------------------------- +@node Troubleshooting +@chapter Troubleshooting + +@cindex troubleshooting use-package +@cindex debugging use-package +If an error occurs while initializing or configuring a package, this +will not stop your Emacs from loading. Instead, @code{use-package} +captures the error and reports it in a special @file{*Warnings*} popup +buffer, so that you can debug the situation in an otherwise functional +Emacs. + +If you are having trouble when starting Emacs, you can pass Emacs the +@samp{--debug-init} command line flag. @xref{Initial Options,,, +emacs, GNU Emacs Manual}. To get even more information when using +that flag, add the following to your init file (these options are +documented below): + +@lisp +@group +(when init-file-debug + (setq use-package-verbose t + use-package-expand-minimally nil + use-package-compute-statistics t + debug-on-error t)) +@end group +@end lisp + +@cindex reporting bugs +@cindex expanding macro, for troubleshooting +Since @code{use-package} is a macro, the first step when you need to +dig deeper is usually to see what Emacs Lisp code your declaration +expands to. You can either use the command @w{@kbd{M-x +pp-macroexpand-last-sexp}}, or wrap the use-package declaration in +@code{macroexpand} and evaluate it. It is a good idea to include +their output in any bugs you file for use-package. + +@menu +* Troubleshooting Options:: +* Gathering Statistics:: +* Disabling a package:: +@end menu + +@node Troubleshooting Options +@section Options that help when troubleshooting +@cindex options for troubleshooting +@cindex troubleshooting, options that help + +@vindex use-package-expand-minimally +By default, use-package will attempts to catch and report errors that +occur during expansion of use-package declarations in your init file. +Customize the user option @code{use-package-expand-minimally} to a +non-@code{nil} value to disable this checking. + +@findex :catch +This behavior may be overridden locally using the @code{:catch} +keyword. If @code{t} or @code{nil}, it enables or disables catching +errors at load time. It can also be a function taking two arguments: +the keyword being processed at the time the error was encountered, and +the error object (as generated by @code{condition-case}). For +example: + +@lisp +@group +(use-package example + ;; Note that errors are never trapped in the preface, since + ;; doing so would hide definitions from the byte-compiler. + :preface (message "I'm here at byte-compile and load time") + :init (message "I'm always here at startup") + :config + (message "I'm always here after the package is loaded") + (error "oops") + ;; Don't try to (require 'example), this is just an example! + :no-require t + :catch (lambda (keyword err) + (message (error-message-string err)))) +@end group +@end lisp + +Evaluating the above form will print these messages: + +@verbatim +I'm here at byte-compile and load time +I'm always here at startup +Configuring package example... +I'm always here after the package is loaded +oops +@end verbatim + +@node Gathering Statistics +@section Gathering Statistics +@cindex gathering use-package statistics +@cindex usage statistics for use-package + +@vindex use-package-verbose +When a package is loaded, and if you have @code{use-package-verbose} +set to @code{t}, or if the package takes longer than 0.1 seconds to +load, you will see a message to indicate this loading activity in the +@code{*Messages*} buffer. The same will happen for configuration, or +@code{:config} blocks, that take longer than 0.1 seconds to execute. + +@vindex use-package-compute-statistics +If you'd like to see a summary how many packages you've loaded, what +stage of initialization they've reached, and how much aggregate time +they've spent (roughly), you can customize the user option +@code{use-package-compute-statistics} to a non-@code{nil} value. Then +reload your packages, normally by restarting Emacs, to make sure that +use-package can gather statistics for all your packages. + +@cindex use-package-report +Run the command @kbd{M-x use-package-report} to see the results. The +buffer displayed is a tabulated list. To sort rows based on a +particular column, move point to it and type @kbd{S}, or click the +column name at the top of the buffer on graphical displays. + +@findex use-package-reset-statistics +To reset all statistics that use-package has gathered for the current +Emacs invocation, run the command @kbd{M-x use-package-reset-statistics}. + +Note that if you are setting @code{use-package-compute-statistics} +directly in your init file, and not with @code{customize}, you must do +this after loading @code{use-package}, but before any +@code{use-package} forms. + +@node Disabling a package +@section Disabling a package +@cindex disable package + +@findex :disabled +The @code{:disabled} keyword inhibits loading a package, and all its +customizations. It is equivalent to commenting out or deleting the +definition. + +You could use this, for example, to temporarily disable a package that +you're having difficulties with, or to avoid loading a package that +you're not currently using. + +This example disables the @samp{foo} package: + +@lisp +@group +(use-package foo + :disabled) +@end group +@end lisp + +When byte-compiling your init file, use-package omits disabled +declarations from the output entirely, in order to make Emacs startup +faster. + +@c ---------------------------------------------------------------------------- +@node Keyword extensions +@appendix Keyword extensions +@cindex keyword extension +@cindex extending use-package keywords + +use-package is based on an extensible framework that makes it easy for +package authors to add new keywords, or modify the behavior of +existing keywords. + +Some keyword extensions are included with @code{use-package}, and can +be optionally enabled. + +@menu +* use-package-ensure-system-package:: +* Creating an extension:: +@end menu + +@node use-package-ensure-system-package +@appendixsec :use-package-ensure-system-package + +@findex :ensure-system-package +The @code{:ensure-system-package} keyword allows you to ensure certain +executables are available on your system alongside your package +declarations.@footnote{On macOS, your @code{exec-path} might be +different if you are starting Emacs as a GUI app instead of from a +shell. If you find that Emacs on macOS cannot find some executables +that you know are already installed, you could try the +@uref{https://github.com/purcell/exec-path-from-shell,@samp{exec-path-from-shell}} +package.} + +To use this extension, add this immediately after loading +@code{use-package}: + +@lisp +(use-package use-package-ensure-system-package) +@end lisp + +Now you can use the @code{:ensure-system-package} keyword. +Here's an example usage: + +@lisp +@group +(use-package foo + :ensure-system-package foo) +@end group +@end lisp + +This will expect a global binary package to exist called @code{foo}. +If it does not, it will use your system package manager to attempt an +install of a binary by the same name asynchronously. This requires +the @acronym{GNU} @acronym{ELPA} package +@uref{https://gitlab.com/jabranham/system-packages,@samp{system-packages}}, +so for this to work you must install that first. + +One way of making sure it is installed is with @code{use-package} +together with @code{:ensure}. + +@lisp +@group +(use-package system-packages + :ensure t) +@end group +@end lisp + +For example, on a Debian GNU/Linux system, this would call +@samp{apt-get install foo}. + +If the package is named differently than the binary, you can use a +cons in the form of @code{(binary . package-name)}. For example: + +@lisp +@group +(use-package foo + :ensure-system-package + (foocmd . foo)) +@end group +@end lisp + +On a Debian GNU/Linux system, this would call @code{apt install foo} +if Emacs could not locate the executable @code{foocmd}.@footnote{For +manual testing, you could use the @code{executable-find} function, +which is what @samp{system-packages} uses internally.} + +@code{:ensure-system-package} can also take a cons where the +@code{cdr} is a string that will get called by +@code{(async-shell-command)} to install if it isn't found. This does +not depend on any external package. + +@lisp +@group +(use-package tern + :ensure-system-package (tern . "npm i -g tern")) +@end group +@end lisp + +To install several packages, you can pass in a list of conses: + +@lisp +@group +(use-package ruby-mode + :ensure-system-package + ((rubocop . "gem install rubocop") + (ruby-lint . "gem install ruby-lint") + (ripper-tags . "gem install ripper-tags") + (pry . "gem install pry"))) +@end group +@end lisp + +Finally, in case the package dependency does not provide a global +executable, you can ensure that packages exist by checking the +presence of a file by providing a string like so: + +@lisp +@group +(use-package dash-at-point + :if (eq system-type 'darwin) + :ensure-system-package + ("/Applications/Dash.app" . "brew cask install dash")) +@end group +@end lisp + +@code{:ensure-system-package} will use @code{system-packages-install} +to install system packages, except where a custom command has been +specified, in which case it will be executed verbatim by +@code{async-shell-command}. + +The user options @code{system-packages-package-manager} and +@code{system-packages-use-sudo} are honored, but not for custom +commands. Custom commands should include the call to sudo in the +command if needed. + +@node Creating an extension +@appendixsec How to create an extension keyword +@cindex extension keywords + +This section describes how to create a new keyword. + +@enumerate +@item +Add the keyword. + +The first step is to add your keyword at the right place in +@code{use-package-keywords}. This list determines the order in which +things will happen in the expanded code. You should never change this +order, but it gives you a framework within which to decide when your +keyword should fire. + +@item +Create a normalizer. + +The job of the normalizer is take a list of arguments (possibly +@code{nil}), and turn it into the single argument (which could still +be a list) that should appear in the final property list used by +@code{use-package}. + +Define a normalizer for your keyword by defining a function named +after the keyword, for example: + +@lisp +@group +(defun use-package-normalize/:pin (name-symbol keyword args) + (use-package-only-one (symbol-name keyword) args + (lambda (label arg) + (cond + ((stringp arg) arg) + ((symbolp arg) (symbol-name arg)) + (t + (use-package-error + ":pin wants an archive name (a string)")))))) +@end group +@end lisp + +@item +Create a handler. + +Once you have a normalizer, you must create a handler for the keyword. + +Handlers can affect the handling of keywords in two ways. First, they +can modify the @code{state} plist before recursively processing the +remaining keywords, to influence keywords that pay attention to the +state (one example is the state keyword @code{:deferred}, not to be +confused with the @code{use-package} keyword @code{:defer}). Then, +once the remaining keywords have been handled and their resulting +forms returned, the handlers may manipulate, extend, or just ignore +those forms. + +The task of each handler is to return a @emph{list of forms} +representing code to be inserted. It does not need to be a +@code{progn} list, as this is handled automatically in other places. +Thus it is common to see the idiom of using @code{use-package-concat} +to add new functionality before or after a code body, so that only the +minimum code necessary is emitted as the result of a +@code{use-package} expansion. + +This is an example handler: + +@lisp +@group +(defun use-package-handler/:pin (name-symbol keyword archive-name rest state) + (let ((body (use-package-process-keywords name-symbol rest state))) + ;; This happens at macro expansion time, not when the expanded code is + ;; compiled or evaluated. + (if (null archive-name) + body + (use-package-pin-package name-symbol archive-name) + (use-package-concat + body + `((push '(,name-symbol . ,archive-name) + package-pinned-packages)))))) +@end group +@end lisp + +@item +Test it. + +After the keyword has been inserted into @code{use-package-keywords}, +and a normalizer and a handler has been defined, you can now test the +keyword by seeing how usages of the keyword will expand. For this, +use @w{@kbd{M-x pp-macroexpand-last-sexp}} with the cursor set +immediately after the @code{(use-package @dots{})} expression. +@end enumerate + +@c ---------------------------------------------------------------------------- +@node History +@appendix History and acknowledgments + +use-package was written by John Wiegley. Its development started in +2012, and it got merged into Emacs in 2022, in preparation of the +release of Emacs 29.1. + +Dozens of people have contributed to use-package over the years with +bug reports, documentation and code. They are too many to list here, +but we thank them all for their contributions. + +This Texinfo manual was written by Stefan Kangas, as a significant +rewrite of the old use-package manual and @file{README}. + +@node GNU Free Documentation License +@appendix GNU Free Documentation License +@include doclicense.texi + +@node Index +@unnumbered Index +@printindex cp + +@bye |
