From 31ea42e15eb66dd238936e057ef1c6787d8d429e Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 17 Jun 2012 04:40:25 -0500 Subject: [PATCH 001/606] README and other updates --- lisp/use-package/bind-key.el | 218 +++++++++++++++++++++ lisp/use-package/use-package.el | 322 ++++++++++++++++++++++++++++++++ 2 files changed, 540 insertions(+) create mode 100644 lisp/use-package/bind-key.el create mode 100644 lisp/use-package/use-package.el diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el new file mode 100644 index 00000000000..75e3b12d9f7 --- /dev/null +++ b/lisp/use-package/bind-key.el @@ -0,0 +1,218 @@ +;;; bind-key --- A simple way to manage personal keybindings + +;; Copyright (C) 2012 John Wiegley + +;; Author: John Wiegley +;; Created: 16 Jun 2012 +;; Version: 1.0 +;; Keywords: keys keybinding config dotemacs +;; X-URL: https://github.com/jwiegley/bind-key + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or (at +;; your option) any later version. + +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; If you have lots of keybindings set in your .emacs file, it can be hard to +;; know which ones you haven't set yet, and which may now be overriding some +;; new default in a new Emacs version. This module aims to solve that +;; problem. +;; +;; Bind keys as follows in your .emacs: +;; +;; (require 'bind-key) +;; +;; (bind-key "C-c x" 'my-ctrl-c-x-command) +;; +;; If you want the keybinding to override all minor modes that may also bind +;; the same key, use the `bind-key*' form: +;; +;; (bind*-key "" 'other-window) +;; +;; If you want to rebind a key only in a particular key, 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) +;; +;; After Emacs loads, you can see a summary of all your personal keybindings +;; currently in effect with this command: +;; +;; M-x describe-personal-keybindings +;; +;; This display will tell you if you've overriden a default keybinding, and +;; what the default was. Also, it will tell you if the key was rebound after +;; your binding it with `bind-key', and what it was rebound it to. + +(require 'easy-mmode) + +(defgroup bind-key nil + "A simple way to manage personal keybindings" + :group 'emacs) + +(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) + +;; Create override-global-mode to force key remappings + +(defvar override-global-map (make-keymap) + "override-global-mode keymap") + +(define-minor-mode override-global-mode + "A minor mode so that keymap settings override other modes." + t "" override-global-map) + +(add-hook 'after-init-hook + (function + (lambda () + (override-global-mode 1)))) + +(defvar personal-keybindings nil) + +(defmacro bind-key (key-name command &optional keymap) + (let ((namevar (make-symbol "name")) + (keyvar (make-symbol "key")) + (bindingvar (make-symbol "binding")) + (entryvar (make-symbol "entry"))) + `(let* ((,namevar ,(eval key-name)) + (,keyvar (read-kbd-macro ,namevar)) + (,bindingvar (lookup-key (or ,keymap global-map) + ,keyvar))) + (let ((,entryvar (assoc (cons ,namevar (quote ,keymap)) + personal-keybindings))) + (if ,entryvar + (setq personal-keybindings + (delq ,entryvar personal-keybindings)))) + (setq personal-keybindings + (cons (list (cons ,namevar (quote ,keymap)) + ,command + (unless (numberp ,bindingvar) ,bindingvar)) + personal-keybindings)) + (define-key (or ,keymap global-map) ,keyvar ,command)))) + +(defmacro unbind-key (key-name &optional keymap) + `(bind-key ,key-name nil ,keymap)) + +(defmacro bind-key* (key-name command) + `(progn + (bind-key ,key-name ,command) + (define-key override-global-map ,(read-kbd-macro key-name) ,command))) + +(defun get-binding-description (elem) + (cond + ((listp elem) + (cond + ((eq 'lambda (car elem)) + "#") + ((eq 'closure (car elem)) + "#") + ((eq 'keymap (car elem)) + "#") + (t + elem))) + ((keymapp elem) + "#") + ((symbolp elem) + elem) + (t + "#"))) + +(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))))) + +(defun describe-personal-keybindings () + (interactive) + (with-current-buffer (get-buffer-create "*Personal Keybindings*") + (delete-region (point-min) (point-max)) + (insert "Key name Command Comments +----------------- --------------------------------------- --------------------- +") + (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))) + (insert ?\n (format "\n%s\n%s\n\n" + (cdar binding) + (make-string 79 ?-))) + (if (and last-binding + (cdr (compare-keybindings last-binding binding))) + (insert ?\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)) + ) + (insert + (format + "%-18s%-40s%s\n" + key-name command-desc + (if (string= command-desc at-present-desc) + (if (or (null was-command) + (string= command-desc was-command-desc)) + "" + (format "(%s)" was-command-desc)) + (format "[now: %s]" at-present))))) + + (setq last-binding binding))) + + (goto-char (point-min)) + (display-buffer (current-buffer)))) + +(provide 'bind-key) + +;;; bind-key.el ends here diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el new file mode 100644 index 00000000000..5bd8df7f9e4 --- /dev/null +++ b/lisp/use-package/use-package.el @@ -0,0 +1,322 @@ +;;; use-package --- A use-package declaration for simplifying your .emacs + +;; Copyright (C) 2012 John Wiegley + +;; Author: John Wiegley +;; Created: 17 Jun 2012 +;; Version: 1.0 +;; Keywords: dotemacs startup speed config package +;; X-URL: https://github.com/jwiegley/use-package + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or (at +;; your option) any later version. + +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; The `use-package' declaration macro allows you to isolate package +;; configuration in your ".emacs" in a way that is performance-oriented and, +;; well, just tidy. I created it because I have over 80 packages that I use +;; in Emacs, and things were getting difficult to manage. Yet with this +;; utility my total load time is just under 1 second, with no loss of +;; functionality! +;; +;; Here is the simplest `use-package' declaration: +;; +;; (use-package foo) +;; +;; This loads in the package foo, but only if foo is available on your system. +;; If not, a warning is logged to your `*Messages*' buffer. If it succeeds a +;; message about "Loading foo" is logged, along with the time it took to load, +;; if that time is over 0.01s. +;; +;; Use the :init keywoard to do some stuff to initialize foo, but only if foo +;; actually gets loaded: +;; +;; (use-package foo +;; :init +;; (progn +;; (setq foo-variable t) +;; (foo-mode 1))) +;; +;; A very command thing to do when loading a module is to bind a key to +;; primary commands within that module: +;; +;; (use-package ace-jump-mode +;; :bind ("C-." . ace-jump-mode)) +;; +;; This does two things: first, it creates autoload for the `ace-jump-mode' +;; command, and defers loading of `ace-jump-mode' until you actually use it. +;; Second, it binds the key `C-.' to that command. After loading, you can use +;; `M-x describe-personal-keybindings' to see all such bindings you've set +;; throughout your Emacs. +;; +;; A more literal way to do the exact same thing is: +;; +;; (use-package ace-jump-mode +;; :commands ace-jump-mode +;; :init +;; (bind-key "C-." 'ace-jump-mode)) +;; +;; When you use the `:commands' keyword, it creates autoloads for those +;; commands and defers loading of the module until they are used. In this +;; case, the `:init' form is always run -- even if ace-jump-mode might not be +;; on your system. So remember to keep `:init' activities to only those that +;; would succeed either way. +;; +;; If you aren't used `:commands' or `:bind' (which implies `:commands'), you +;; can still defer loading with `:defer' keyword: +;; +;; (use-package ace-jump-mode +;; :defer t +;; :init +;; (progn +;; (autoload 'ace-jump-mode "ace-jump-mode" nil t) +;; (bind-key "C-." 'ace-jump-mode))) +;; +;; This does exactly the same thing as the other two commands above. +;; +;; A companion to the `:init' keyword is `:config'. Although `:init' always +;; happens in the case of deferred modules (which are likely to be the most +;; common kind), `:config' form only run after the module has been loaded by +;; Emacs: +;; +;; (use-package ace-jump-mode +;; :bind ("C-." . ace-jump-mode) +;; :config +;; (message "Yay, ace-jump-mode was actually loaded!")) +;; +;; You will see a "Configured..." message in your `*Messages*' log when a +;; package is configured, and a timing if the configuration time was longer +;; than 0.01s. You should keep `:init' forms as simple as possible, and put +;; as much as you can get away with on the `:config' side. +;; +;; You can have both `:init' and `:config': +;; +;; (use-package haskell-mode +;; :commands haskell-mode +;; :init +;; (add-to-list 'auto-mode-alist '("\\.l?hs$" . haskell-mode)) +;; :config +;; (progn +;; (use-package inf-haskell) +;; (use-package hs-lint))) +;; +;; In this case, I want to autoload the command `haskell-mode' from +;; "haskell-mode.el", add it to `auto-mode-alist' at the time ".emacs" is +;; loaded, but wait until after I've opened a Haskell file before loading +;; "inf-haskell.el" and "hs-lint.el". +;; +;; The `:bind' keyword takes either a cons or a list of conses: +;; +;; (use-package hi-lock +;; :bind (("M-o l" . highlight-lines-matching-regexp) +;; ("M-o r" . highlight-regexp) +;; ("M-o w" . highlight-phrase))) +;; +;; The `:commands' keyword likewise takes either a symbol or a list of +;; symbols. +;; +;; You can use the `:if' keyword to predicate the loading and initialization +;; of a module. For example, I only want an `edit-server' running for my +;; main, graphical Emacs, not for Emacsen I may start at the command line: +;; +;; (use-package edit-server +;; :if window-system +;; :init +;; (progn +;; (add-hook 'after-init-hook 'server-start t) +;; (add-hook 'after-init-hook 'edit-server-start t))) +;; +;; The `:disabled' keyword can be used to turn off a module that you're having +;; difficulties with, or to stop loading something you're not really using at +;; the present time: +;; +;; (use-package ess-site +;; :disabled t +;; :commands R) +;; +;; Another feature of `use-package' is that it always loads every file that it +;; can when your ".emacs" is being byte-compiled (if you do that, which I +;; recommend). This helps to silence spurious warnings about unknown +;; variables and functions. +;; +;; However, there are times when this is just not enough. For those times, +;; use the `:defines' keyword to introduce empty variable definitions solely +;; for the sake of the byte-compiler: +;; +;; (use-package texinfo +;; :defines texinfo-section-list +;; :commands texinfo-mode +;; :init +;; (add-to-list 'auto-mode-alist '("\\.texi$" . texinfo-mode))) +;; +;; If you need to silence a missing function warning, do it with an autoload +;; stub in your `:init' block: +;; +;; (use-package w3m +;; :commands (w3m-browse-url w3m-session-crash-recovery-remove) +;; :init +;; (eval-when-compile +;; (autoload 'w3m-search-escape-query-string "w3m-search"))) +;; +;; Lastly, `use-package' provides built-in support for the diminish utility, +;; if you have that installed. It's purpose is to remove strings from your +;; mode-line that would otherwise always be there and provide no useful +;; information. It is invoked with the `:diminish' keyword, which is passed +;; the minor mode symbol: +;; +;; (use-package abbrev +;; :diminish abbrev-mode +;; :init +;; (if (file-exists-p abbrev-file-name) +;; (quietly-read-abbrev-file)) +;; +;; :config +;; (add-hook 'expand-load-hook +;; (lambda () +;; (add-hook 'expand-expand-hook 'indent-according-to-mode) +;; (add-hook 'expand-jump-hook 'indent-according-to-mode)))) +;; +;; If you noticed that this declaration has neither a `:bind', `:commands' or +;; `:defer' keyword: congratulations, you're an A student! What it means is +;; that both the `:init' and `:config' forms will be executed when ".emacs" is +;; loaded, with no delays until later. Is this useful? Not really. I just +;; happen to like separating my configuration into things that must happen at +;; startup time, and things that could potentioally wait until after the +;; actual load. In this case, everything could be put inside `:init' and +;; there would be no difference. + +(require 'bind-key) + +(defgroup use-package nil + "A use-package declaration for simplifying your .emacs" + :group 'startup) + +;;;_ , Create use-package macro, to simplify customizations + +(eval-when-compile + (require 'cl)) + +(require 'bind-key) +(require 'diminish nil t) + +(defvar use-package-verbose t) + +(defmacro with-elapsed-timer (text &rest forms) + `(let ((now ,(if use-package-verbose + '(current-time)))) + ,(if use-package-verbose + `(message "%s..." ,text)) + ,@forms + ,(when use-package-verbose + `(let ((elapsed + (float-time (time-subtract (current-time) now)))) + (if (> elapsed 0.01) + (message "%s...done (%.3fs)" ,text elapsed) + (message "%s...done" ,text)))))) + +(put 'with-elapsed-timer 'lisp-indent-function 1) + +(defmacro use-package (name &rest args) + (let* ((commands (plist-get args :commands)) + (init-body (plist-get args :init)) + (config-body (plist-get args :config)) + (diminish-var (plist-get args :diminish)) + (defines (plist-get args :defines)) + (keybindings (plist-get args :bind)) + (predicate (plist-get args :if)) + (defines-eval (if (null defines) + nil + (if (listp defines) + (mapcar (lambda (var) `(defvar ,var)) defines) + `((defvar ,defines))))) + (requires (plist-get args :requires)) + (requires-test (if (null requires) + t + (if (listp requires) + `(not (member nil (mapcar #'featurep + (quote ,requires)))) + `(featurep (quote ,requires))))) + (name-string (if (stringp name) name + (symbol-name name)))) + + (if diminish-var + (setq config-body + `(progn + ,config-body + (ignore-errors + ,@(if (listp diminish-var) + (mapcar (lambda (var) `(diminish (quote ,var))) + diminish-var) + `((diminish (quote ,diminish-var)))))))) + + (when keybindings + (if (and commands (symbolp commands)) + (setq commands (list commands))) + (setq init-body + `(progn + ,init-body + ,@(mapcar #'(lambda (binding) + (push (cdr binding) commands) + `(bind-key ,(car binding) + (quote ,(cdr binding)))) + (if (and (consp keybindings) + (stringp (car keybindings))) + (list keybindings) + keybindings))))) + + (unless (plist-get args :disabled) + `(progn + (eval-when-compile + ,@defines-eval + ,(if (stringp name) + `(load ,name t) + `(require ',name nil t))) + ,(if (or commands (plist-get args :defer)) + (let (form) + (unless (listp commands) + (setq commands (list commands))) + (mapc #'(lambda (command) + (push `(autoload (function ,command) + ,name-string nil t) form)) + commands) + + `(when ,(or predicate t) + ,@form + ,init-body + ,(unless (null config-body) + `(eval-after-load ,name-string + '(if ,requires-test + (with-elapsed-timer + ,(format "Configuring package %s" name-string) + ,config-body)))) + t)) + `(if (and ,(or predicate t) + ,requires-test) + (if ,(if (stringp name) + `(load ,name t) + `(require ',name nil t)) + (with-elapsed-timer + ,(format "Loading package %s" name-string) + ,init-body + ,config-body + t) + (message "Could not load package %s" ,name-string)))))))) + +(put 'use-package 'lisp-indent-function 1) + +(provide 'use-package) + +;;; use-package.el ends here From bf6c23044bedf6659536fcb193a34101a08fefb5 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 17 Jun 2012 04:50:07 -0500 Subject: [PATCH 002/606] Fixed a typo in bind-key.el --- lisp/use-package/bind-key.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 75e3b12d9f7..0d3039e5e01 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -39,7 +39,7 @@ ;; If you want the keybinding to override all minor modes that may also bind ;; the same key, use the `bind-key*' form: ;; -;; (bind*-key "" 'other-window) +;; (bind-key* "" 'other-window) ;; ;; If you want to rebind a key only in a particular key, use: ;; From 4bd492f606f29f3ec527e4a2527a1cf00ea77c14 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 17 Jun 2012 05:12:13 -0500 Subject: [PATCH 003/606] Have loading timer include time to require --- lisp/use-package/use-package.el | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 5bd8df7f9e4..7ee39875eeb 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -305,15 +305,15 @@ t)) `(if (and ,(or predicate t) ,requires-test) - (if ,(if (stringp name) - `(load ,name t) - `(require ',name nil t)) - (with-elapsed-timer - ,(format "Loading package %s" name-string) - ,init-body - ,config-body - t) - (message "Could not load package %s" ,name-string)))))))) + (with-elapsed-timer + ,(format "Loading package %s" name-string) + (if (not ,(if (stringp name) + `(load ,name t) + `(require ',name nil t))) + (message "Could not load package %s" ,name-string) + ,init-body + ,config-body + t)))))))) (put 'use-package 'lisp-indent-function 1) From 01c8245b2951f546c609c91945fbd4d913304596 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 17 Jun 2012 05:52:59 -0500 Subject: [PATCH 004/606] Make use-package-verbose customizable --- lisp/use-package/use-package.el | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 7ee39875eeb..51c724dd35e 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -212,7 +212,10 @@ (require 'bind-key) (require 'diminish nil t) -(defvar use-package-verbose t) +(defcustom use-package-verbose t + "Whether to report about loading and configuration details." + :type 'boolean + :group 'use-package) (defmacro with-elapsed-timer (text &rest forms) `(let ((now ,(if use-package-verbose From 334f6e085e2575473413888d701906ee59a38627 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 17 Jun 2012 09:18:12 -0500 Subject: [PATCH 005/606] Integrated support for working with el-get --- lisp/use-package/use-package.el | 67 +++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 51c724dd35e..297452dcc9e 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -197,6 +197,44 @@ ;; startup time, and things that could potentioally wait until after the ;; actual load. In this case, everything could be put inside `:init' and ;; there would be no difference. +;; +;; * For el-get users +;; +;; You can use `use-package' as a way to create source definitions for el-get. +;; All that's needed is to add a `:type' keyword to your declaration. When +;; this is present, certain keywords get translated to what el-get expects in +;; the `el-get-sources' list: +;; +;; :config -> :after +;; :requires -> :depends +;; +;; A `:name' will be added also, if one is not provided explicitly, which will +;; be the same as the name of the package. +;; +;; But why would you want to use `use-package' when you have el-get? My +;; answer is that I'd like to use el-get to install and update some packages, +;; but I don't want it managing configuration. Just loading el-get -- without +;; call (el-get 'sync) -- takes a quarter second on my machine. That's 25% of +;; my load time! `use-package' is designed for performance, so I only want to +;; load el-get when it's time to install or update on of my used packages. +;; +;; Here is the `use-package' declaration I use for setting up el-get, but only +;; when I want to install or update. +;; +;; (defvar el-get-sources nil) +;; +;; (use-package el-get +;; :commands (el-get +;; el-get-install +;; el-get-update +;; el-get-list-packages) +;; :config +;; (progn +;; (defun el-get-read-status-file () +;; (mapcar #'(lambda (entry) +;; (cons (plist-get entry :symbol) +;; `(status "installed" recipe ,entry))) +;; el-get-sources)))) (require 'bind-key) @@ -240,6 +278,7 @@ (defines (plist-get args :defines)) (keybindings (plist-get args :bind)) (predicate (plist-get args :if)) + (pkg-load-path (plist-get args :load-path)) (defines-eval (if (null defines) nil (if (listp defines) @@ -282,11 +321,39 @@ (unless (plist-get args :disabled) `(progn + ,@(mapcar + #'(lambda (path) + `(add-to-list 'load-path + ,(expand-file-name path user-emacs-directory))) + (if (stringp pkg-load-path) + (list pkg-load-path) + pkg-load-path)) + (eval-when-compile ,@defines-eval ,(if (stringp name) `(load ,name t) `(require ',name nil t))) + + ,(when (and (boundp 'el-get-sources) + (plist-get args :type)) + (setq args + (mapcar #'(lambda (arg) + (cond + ((eq arg :config) + :after) + ((eq arg :requires) + :depends) + (t + arg))) + args)) + (unless (plist-get args :name) + (nconc args (list :name (if (stringp name) + name (symbol-name name))))) + (nconc args (list :symbol (if (stringp name) + (intern name) name))) + `(push (quote ,args) el-get-sources)) + ,(if (or commands (plist-get args :defer)) (let (form) (unless (listp commands) From 80b010a748f043d7a29d174862a2224c182b33c7 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 17 Jun 2012 09:18:47 -0500 Subject: [PATCH 006/606] Minor grammatical nit --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 297452dcc9e..69998b8118f 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -219,7 +219,7 @@ ;; load el-get when it's time to install or update on of my used packages. ;; ;; Here is the `use-package' declaration I use for setting up el-get, but only -;; when I want to install or update. +;; when I want to install or update: ;; ;; (defvar el-get-sources nil) ;; From aea35b2370de79fee18247bc675c64947fb04ee2 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 17 Jun 2012 09:38:11 -0500 Subject: [PATCH 007/606] Minor reformatting --- lisp/use-package/use-package.el | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 69998b8118f..0d9d26ef45f 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -229,12 +229,11 @@ ;; el-get-update ;; el-get-list-packages) ;; :config -;; (progn -;; (defun el-get-read-status-file () -;; (mapcar #'(lambda (entry) -;; (cons (plist-get entry :symbol) -;; `(status "installed" recipe ,entry))) -;; el-get-sources)))) +;; (defun el-get-read-status-file () +;; (mapcar #'(lambda (entry) +;; (cons (plist-get entry :symbol) +;; `(status "installed" recipe ,entry))) +;; el-get-sources))) (require 'bind-key) From debf2c23f33d801479b68eb550faeaee813ead27 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 17 Jun 2012 09:41:34 -0500 Subject: [PATCH 008/606] Fixed a typo --- lisp/use-package/use-package.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 0d9d26ef45f..691287c8aea 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -50,8 +50,8 @@ ;; (setq foo-variable t) ;; (foo-mode 1))) ;; -;; A very command thing to do when loading a module is to bind a key to -;; primary commands within that module: +;; A very common thing to do when loading a module is to bind a key to primary +;; commands within that module: ;; ;; (use-package ace-jump-mode ;; :bind ("C-." . ace-jump-mode)) From 0bde0b4c02c439a91e70f9d8bd1d0294dccc2c54 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 17 Jun 2012 09:43:33 -0500 Subject: [PATCH 009/606] Die typos, die --- lisp/use-package/use-package.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 691287c8aea..b1004b3dbe2 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -75,8 +75,8 @@ ;; on your system. So remember to keep `:init' activities to only those that ;; would succeed either way. ;; -;; If you aren't used `:commands' or `:bind' (which implies `:commands'), you -;; can still defer loading with `:defer' keyword: +;; If you aren't using `:commands' or `:bind' (which implies `:commands'), you +;; can still defer loading with the `:defer' keyword: ;; ;; (use-package ace-jump-mode ;; :defer t From f6d65ce876d444e64553edcba7d3557d2b42ffa8 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 17 Jun 2012 16:44:49 -0500 Subject: [PATCH 010/606] If :load-path is absolute, don't expand it --- lisp/use-package/use-package.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index b1004b3dbe2..8c8fd27f28d 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -323,7 +323,9 @@ ,@(mapcar #'(lambda (path) `(add-to-list 'load-path - ,(expand-file-name path user-emacs-directory))) + ,(if (file-name-absolute-p path) + path + (expand-file-name path user-emacs-directory)))) (if (stringp pkg-load-path) (list pkg-load-path) pkg-load-path)) From 0736be8e67dfee3e87b61bb851b36a313b84fa07 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 17 Jun 2012 16:47:01 -0500 Subject: [PATCH 011/606] Add a note about how to use :load-path --- lisp/use-package/use-package.el | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 8c8fd27f28d..716d2730e70 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -171,6 +171,15 @@ ;; (eval-when-compile ;; (autoload 'w3m-search-escape-query-string "w3m-search"))) ;; +;; If your package needs a directory added to the `load-path' in order load, +;; use `:load-path'. It takes a string or a list of strings. If the path is +;; relative, it will be expanded within `user-emacs-directory': +;; +;; (use-package ess-site +;; :disabled t +;; :load-path "site-lisp/ess/lisp/" +;; :commands R) +;; ;; Lastly, `use-package' provides built-in support for the diminish utility, ;; if you have that installed. It's purpose is to remove strings from your ;; mode-line that would otherwise always be there and provide no useful From bdf1505f444c856148ab823f98bac874eac4a8a4 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 17 Jun 2012 20:25:58 -0500 Subject: [PATCH 012/606] Added :mode and :interpreter keywords --- lisp/use-package/use-package.el | 143 ++++++++++++++++++++++---------- 1 file changed, 97 insertions(+), 46 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 716d2730e70..2d1182a0835 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -75,8 +75,17 @@ ;; on your system. So remember to keep `:init' activities to only those that ;; would succeed either way. ;; -;; If you aren't using `:commands' or `:bind' (which implies `:commands'), you -;; can still defer loading with the `:defer' keyword: +;; Similar to `:bind', you can use `:mode' and `:interpreter' to establish a +;; deferred binding within `auto-mode-alist' and `auto-interpreter-alist'. +;; The specifier to either keyword can be a single cons or a list: +;; +;; (use-package python-mode +;; :mode ("\\.py$" . python-mode) +;; :interpreter ("python" . python-mode)) +;; +;; If you aren't using `:commands', `:bind', `:mode', or `:interpreter' (all +;; of which imply `:commands'), you can still defer loading with the `:defer' +;; keyword: ;; ;; (use-package ace-jump-mode ;; :defer t @@ -243,6 +252,8 @@ ;; (cons (plist-get entry :symbol) ;; `(status "installed" recipe ,entry))) ;; el-get-sources))) + +;;; Code: (require 'bind-key) @@ -250,8 +261,6 @@ "A use-package declaration for simplifying your .emacs" :group 'startup) -;;;_ , Create use-package macro, to simplify customizations - (eval-when-compile (require 'cl)) @@ -278,13 +287,35 @@ (put 'with-elapsed-timer 'lisp-indent-function 1) +(defun use-package-discover-el-get-type (args) + (let* ((pkg-name (plist-get args :name)) + (git-config (expand-file-name + (concat pkg-name "/.git/config") + user-site-lisp-directory))) + + (catch 'found + ;; Look for a readable .git/config with at least one defined remote. + (if (file-readable-p git-config) + (with-temp-buffer + (insert-file-contents-literally git-config) + (while (re-search-forward "\\[remote" nil t) + (if (re-search-forward "url = \\(.+\\)" + (save-excursion + (re-search-forward "\\[remote" nil t) + (point)) t) + (nconc args (list :type 'git + :url (match-string 1)))))))) + args)) + (defmacro use-package (name &rest args) (let* ((commands (plist-get args :commands)) (init-body (plist-get args :init)) (config-body (plist-get args :config)) (diminish-var (plist-get args :diminish)) (defines (plist-get args :defines)) - (keybindings (plist-get args :bind)) + (keybindings ) + (mode-alist ) + (interpreter-alist ) (predicate (plist-get args :if)) (pkg-load-path (plist-get args :load-path)) (defines-eval (if (null defines) @@ -302,32 +333,50 @@ (name-string (if (stringp name) name (symbol-name name)))) - (if diminish-var - (setq config-body - `(progn - ,config-body - (ignore-errors - ,@(if (listp diminish-var) - (mapcar (lambda (var) `(diminish (quote ,var))) - diminish-var) - `((diminish (quote ,diminish-var)))))))) + (unless (plist-get args :disabled) + (if diminish-var + (setq config-body + `(progn + ,config-body + (ignore-errors + ,@(if (listp diminish-var) + (mapcar (lambda (var) `(diminish (quote ,var))) + diminish-var) + `((diminish (quote ,diminish-var)))))))) - (when keybindings (if (and commands (symbolp commands)) (setq commands (list commands))) - (setq init-body - `(progn - ,init-body - ,@(mapcar #'(lambda (binding) - (push (cdr binding) commands) - `(bind-key ,(car binding) - (quote ,(cdr binding)))) - (if (and (consp keybindings) - (stringp (car keybindings))) - (list keybindings) - keybindings))))) - (unless (plist-get args :disabled) + (flet ((init-for-commands + (func sym-or-list) + (let ((cons-list (if (and (consp sym-or-list) + (stringp (car sym-or-list))) + (list sym-or-list) + sym-or-list))) + (if cons-list + (setq init-body + `(progn + ,init-body + ,@(mapcar #'(lambda (elem) + (push (cdr elem) commands) + (funcall func elem)) + cons-list))))))) + + (init-for-commands #'(lambda (binding) + `(bind-key ,(car binding) + (quote ,(cdr binding)))) + (plist-get args :bind)) + + (init-for-commands #'(lambda (mode) + `(add-to-list 'auto-mode-alist + (quote ,mode))) + (plist-get args :mode)) + + (init-for-commands #'(lambda (interpreter) + `(add-to-list 'interpreter-mode-alist + (quote ,interpreter))) + (plist-get args :interpreter))) + `(progn ,@(mapcar #'(lambda (path) @@ -345,29 +394,31 @@ `(load ,name t) `(require ',name nil t))) - ,(when (and (boundp 'el-get-sources) - (plist-get args :type)) - (setq args - (mapcar #'(lambda (arg) - (cond - ((eq arg :config) - :after) - ((eq arg :requires) - :depends) - (t - arg))) - args)) + ,(when (boundp 'el-get-sources) (unless (plist-get args :name) - (nconc args (list :name (if (stringp name) - name (symbol-name name))))) - (nconc args (list :symbol (if (stringp name) - (intern name) name))) - `(push (quote ,args) el-get-sources)) + (nconc args (list :name name-string))) + + (unless (plist-get args :type) + (setq args (use-package-discover-el-get-type args))) + + (when (plist-get args :type) + (setq args + (mapcar #'(lambda (arg) + (cond + ((eq arg :config) + :after) + ((eq arg :requires) + :depends) + (t + arg))) + args)) + + (nconc args (list :symbol (intern name-string))) + + `(push (quote ,args) el-get-sources))) ,(if (or commands (plist-get args :defer)) (let (form) - (unless (listp commands) - (setq commands (list commands))) (mapc #'(lambda (command) (push `(autoload (function ,command) ,name-string nil t) form)) From 82a8d10a46a418c09772b3ed07213fa31777d3e6 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 20 Jun 2012 21:35:50 -0500 Subject: [PATCH 013/606] Establish autoloads after :init --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 2d1182a0835..204dcae4a71 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -425,8 +425,8 @@ commands) `(when ,(or predicate t) - ,@form ,init-body + ,@form ,(unless (null config-body) `(eval-after-load ,name-string '(if ,requires-test From d9f6c0f370db01df410c8346c02eeb57103a937f Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 20 Jun 2012 23:03:27 -0500 Subject: [PATCH 014/606] Added :pre-init --- lisp/use-package/use-package.el | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 204dcae4a71..1f8f7b4c503 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -309,6 +309,7 @@ (defmacro use-package (name &rest args) (let* ((commands (plist-get args :commands)) + (pre-init-body (plist-get args :pre-init)) (init-body (plist-get args :init)) (config-body (plist-get args :config)) (diminish-var (plist-get args :diminish)) @@ -425,8 +426,9 @@ commands) `(when ,(or predicate t) - ,init-body + ,pre-init-body ,@form + ,init-body ,(unless (null config-body) `(eval-after-load ,name-string '(if ,requires-test @@ -442,6 +444,7 @@ `(load ,name t) `(require ',name nil t))) (message "Could not load package %s" ,name-string) + ,pre-init-body ,init-body ,config-body t)))))))) From ece5f93919f62d19045e7a31d4013b1098a6c349 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 22 Jun 2012 01:32:59 -0500 Subject: [PATCH 015/606] Byte-compilation related fix --- lisp/use-package/use-package.el | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 1f8f7b4c503..768df4f003a 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -256,16 +256,15 @@ ;;; Code: (require 'bind-key) - -(defgroup use-package nil - "A use-package declaration for simplifying your .emacs" - :group 'startup) +(require 'bytecomp) +(require 'diminish nil t) (eval-when-compile (require 'cl)) -(require 'bind-key) -(require 'diminish nil t) +(defgroup use-package nil + "A use-package declaration for simplifying your .emacs" + :group 'startup) (defcustom use-package-verbose t "Whether to report about loading and configuration details." @@ -389,7 +388,7 @@ (list pkg-load-path) pkg-load-path)) - (eval-when-compile + (when byte-compile-current-file ,@defines-eval ,(if (stringp name) `(load ,name t) From 28c6509148b3e2c5f895b22f17e2582d31daab56 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 22 Jun 2012 05:02:38 -0500 Subject: [PATCH 016/606] More updates to support el-get --- lisp/use-package/use-package.el | 57 ++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 768df4f003a..f70396195a3 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -271,6 +271,11 @@ :type 'boolean :group 'use-package) +(defcustom use-package-debug nil + "Whether to report more information, mostly regarding el-get" + :type 'boolean + :group 'use-package) + (defmacro with-elapsed-timer (text &rest forms) `(let ((now ,(if use-package-verbose '(current-time)))) @@ -330,8 +335,8 @@ `(not (member nil (mapcar #'featurep (quote ,requires)))) `(featurep (quote ,requires))))) - (name-string (if (stringp name) name - (symbol-name name)))) + (name-string (if (stringp name) name (symbol-name name))) + (name-symbol (if (stringp name) (intern name) name))) (unless (plist-get args :disabled) (if diminish-var @@ -395,27 +400,41 @@ `(require ',name nil t))) ,(when (boundp 'el-get-sources) - (unless (plist-get args :name) - (nconc args (list :name name-string))) + (require 'el-get) - (unless (plist-get args :type) - (setq args (use-package-discover-el-get-type args))) + (let ((recipe (ignore-errors + (el-get-read-recipe name-symbol)))) + (if (null recipe) + (if use-package-debug + (message "No el-get recipe found for package `%s'" + name-symbol)) + (setq args + (mapcar #'(lambda (arg) + (cond + ((eq arg :config) + :after) + ((eq arg :requires) + :depends) + (t + arg))) + args)) - (when (plist-get args :type) - (setq args - (mapcar #'(lambda (arg) - (cond - ((eq arg :config) - :after) - ((eq arg :requires) - :depends) - (t - arg))) - args)) + (nconc args (list :symbol (intern name-string))) - (nconc args (list :symbol (intern name-string))) + (let ((elem args)) + (while elem + (unless (plist-get recipe (car elem)) + (plist-put recipe (car elem) (cadr elem))) + (setq elem (cddr elem)))) - `(push (quote ,args) el-get-sources))) + (unless (plist-get recipe :name) + (nconc recipe (list :name name-string))) + + (unless (plist-get recipe :type) + (setq recipe (use-package-discover-el-get-type recipe))) + + (ignore + (setq el-get-sources (cons recipe el-get-sources)))))) ,(if (or commands (plist-get args :defer)) (let (form) From 89a844fd9cc09df9535a6227d1d094fbaec4f522 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 26 Jun 2012 06:59:54 -0500 Subject: [PATCH 017/606] Correct return value from with-elapsed-timer --- lisp/use-package/use-package.el | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index f70396195a3..35c2fad07d4 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -281,13 +281,14 @@ '(current-time)))) ,(if use-package-verbose `(message "%s..." ,text)) - ,@forms - ,(when use-package-verbose - `(let ((elapsed - (float-time (time-subtract (current-time) now)))) - (if (> elapsed 0.01) - (message "%s...done (%.3fs)" ,text elapsed) - (message "%s...done" ,text)))))) + (prog1 + ,@forms + ,(when use-package-verbose + `(let ((elapsed + (float-time (time-subtract (current-time) now)))) + (if (> elapsed 0.01) + (message "%s...done (%.3fs)" ,text elapsed) + (message "%s...done" ,text))))))) (put 'with-elapsed-timer 'lisp-indent-function 1) From fe7997d2b77e893674a16cfc8a8e4b9b5cdf28f7 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 11 Jul 2012 01:24:30 -0500 Subject: [PATCH 018/606] Only use user-site-lisp-directory if defined --- lisp/use-package/use-package.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 35c2fad07d4..b378c03900a 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -296,7 +296,9 @@ (let* ((pkg-name (plist-get args :name)) (git-config (expand-file-name (concat pkg-name "/.git/config") - user-site-lisp-directory))) + (if (boundp 'user-site-lisp-directory) + user-site-lisp-directory + user-emacs-directory)))) (catch 'found ;; Look for a readable .git/config with at least one defined remote. From 8b93cee99b4ddee2acce69aff809432913b4be36 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 30 Jul 2012 17:36:13 -0500 Subject: [PATCH 019/606] Use-package now accepts function as argument --- lisp/use-package/use-package.el | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index b378c03900a..26b388432a3 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -392,9 +392,12 @@ ,(if (file-name-absolute-p path) path (expand-file-name path user-emacs-directory)))) - (if (stringp pkg-load-path) - (list pkg-load-path) - pkg-load-path)) + (cond ((stringp pkg-load-path) + (list pkg-load-path)) + ((functionp pkg-load-path) + (funcall pkg-load-path)) + (t + pkg-load-path))) (when byte-compile-current-file ,@defines-eval From fbead837318534f7b58424d993106620c2e06778 Mon Sep 17 00:00:00 2001 From: Phil Hudson Date: Wed, 21 Nov 2012 00:46:17 +0000 Subject: [PATCH 020/606] Support diminishing to a replacement string as well as to nothing `diminish' accepts an optional second argument, a replacement string. This change supports all the following arguments to ':diminish': * package * (package . "pkg") * (package1 package2) * ((package1 . "p1") (package2 . "p2)) The second and fourth formats are new with this change. --- lisp/use-package/use-package.el | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 26b388432a3..f9bc5c2b32e 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -193,7 +193,7 @@ ;; if you have that installed. It's purpose is to remove strings from your ;; mode-line that would otherwise always be there and provide no useful ;; information. It is invoked with the `:diminish' keyword, which is passed -;; the minor mode symbol: +;; either the minor mode symbol, or a cons of the symbol and a replacement string: ;; ;; (use-package abbrev ;; :diminish abbrev-mode @@ -348,8 +348,14 @@ ,config-body (ignore-errors ,@(if (listp diminish-var) - (mapcar (lambda (var) `(diminish (quote ,var))) - diminish-var) + (if (listp (cdr diminish-var)) + (mapcar (lambda (var) + (if (listp var) + `(diminish (quote ,(car var)) ,(cdr var)) + `(diminish (quote ,var)))) + diminish-var) + `((diminish (quote ,(car diminish-var)) ,(cdr diminish-var))) + ) `((diminish (quote ,diminish-var)))))))) (if (and commands (symbolp commands)) From c28874e95644085e3ee33f528ea6cc7b72f8f330 Mon Sep 17 00:00:00 2001 From: Phillip Lord Date: Mon, 31 Dec 2012 17:58:45 +0100 Subject: [PATCH 021/606] ELPA package support --- lisp/use-package/use-package.el | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index f9bc5c2b32e..3dce341e9da 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -314,6 +314,12 @@ :url (match-string 1)))))))) args)) + +(defun use-package-ensure-elpa (package) + (when (not (package-installed-p package)) + (package-install package))) + + (defmacro use-package (name &rest args) (let* ((commands (plist-get args :commands)) (pre-init-body (plist-get args :pre-init)) @@ -342,6 +348,11 @@ (name-symbol (if (stringp name) (intern name) name))) (unless (plist-get args :disabled) + + ;; force this immediately -- one off cost! + (if (plist-get args :ensure) + (use-package-ensure-elpa name)) + (if diminish-var (setq config-body `(progn From abc0ebc92dc1cf9ef9adfe133d0b30bf7382b65c Mon Sep 17 00:00:00 2001 From: Phillip Lord Date: Thu, 17 Jan 2013 21:22:57 +0000 Subject: [PATCH 022/606] Documentation for the use-package macro --- lisp/use-package/use-package.el | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 3dce341e9da..43466d7c666 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -321,6 +321,28 @@ (defmacro use-package (name &rest args) +"Use a package with configuration options. + +For full documentation. please see commentary. + + (use-package package-name + :keyword option) + +:init Code to run when `use-package' form evals. +:bind Perform key bindings, and define autoload for bound + commands. +:commands Define autoloads for given commands. +:mode Form to be added to `auto-mode-alist'. +:interpreter Form to be added to `auto-interpreter-alist'. +:defer Defer loading of package -- automatic + if :commands, :bind, :mode or :interpreter are used. +:config Runs if and when package loads. +:if Conditional loading. +:disabled Ignore everything. +:defines Define vars to silence byte-compiler. +:load-path Add to `load-path' before loading. +:diminish Support for diminish package (if it's installed). +" (let* ((commands (plist-get args :commands)) (pre-init-body (plist-get args :pre-init)) (init-body (plist-get args :init)) @@ -350,8 +372,13 @@ (unless (plist-get args :disabled) ;; force this immediately -- one off cost! - (if (plist-get args :ensure) - (use-package-ensure-elpa name)) + (let* ((ensure (plist-get args :ensure)) + (package-name + (or (and (eq ensure t) + name) + ensure))) + (when package-name + (use-package-ensure-elpa package-name))) (if diminish-var (setq config-body From b8406ce9f00e792ae3a93abddf4d17b678410e88 Mon Sep 17 00:00:00 2001 From: Phillip Lord Date: Thu, 17 Jan 2013 21:55:53 +0000 Subject: [PATCH 023/606] Reverting "Documentation for the use-package macro." Revert "Documentation for the use-package macro." This reverts commit abc0ebc92dc1cf9ef9adfe133d0b30bf7382b65c. --- lisp/use-package/use-package.el | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 43466d7c666..3dce341e9da 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -321,28 +321,6 @@ (defmacro use-package (name &rest args) -"Use a package with configuration options. - -For full documentation. please see commentary. - - (use-package package-name - :keyword option) - -:init Code to run when `use-package' form evals. -:bind Perform key bindings, and define autoload for bound - commands. -:commands Define autoloads for given commands. -:mode Form to be added to `auto-mode-alist'. -:interpreter Form to be added to `auto-interpreter-alist'. -:defer Defer loading of package -- automatic - if :commands, :bind, :mode or :interpreter are used. -:config Runs if and when package loads. -:if Conditional loading. -:disabled Ignore everything. -:defines Define vars to silence byte-compiler. -:load-path Add to `load-path' before loading. -:diminish Support for diminish package (if it's installed). -" (let* ((commands (plist-get args :commands)) (pre-init-body (plist-get args :pre-init)) (init-body (plist-get args :init)) @@ -372,13 +350,8 @@ For full documentation. please see commentary. (unless (plist-get args :disabled) ;; force this immediately -- one off cost! - (let* ((ensure (plist-get args :ensure)) - (package-name - (or (and (eq ensure t) - name) - ensure))) - (when package-name - (use-package-ensure-elpa package-name))) + (if (plist-get args :ensure) + (use-package-ensure-elpa name)) (if diminish-var (setq config-body From 8d72a6c1d68caf95e94d72f5d465e7ea33050e77 Mon Sep 17 00:00:00 2001 From: Phillip Lord Date: Thu, 17 Jan 2013 21:57:39 +0000 Subject: [PATCH 024/606] Documentation for the use-package macro --- lisp/use-package/use-package.el | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 3dce341e9da..63223a3a26a 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -321,6 +321,28 @@ (defmacro use-package (name &rest args) +"Use a package with configuration options. + +For full documentation. please see commentary. + + (use-package package-name + :keyword option) + +:init Code to run when `use-package' form evals. +:bind Perform key bindings, and define autoload for bound + commands. +:commands Define autoloads for given commands. +:mode Form to be added to `auto-mode-alist'. +:interpreter Form to be added to `auto-interpreter-alist'. +:defer Defer loading of package -- automatic + if :commands, :bind, :mode or :interpreter are used. +:config Runs if and when package loads. +:if Conditional loading. +:disabled Ignore everything. +:defines Define vars to silence byte-compiler. +:load-path Add to `load-path' before loading. +:diminish Support for diminish package (if it's installed). +" (let* ((commands (plist-get args :commands)) (pre-init-body (plist-get args :pre-init)) (init-body (plist-get args :init)) From eaf96774091913fcb49b2c57bc9c85cb0cd006b0 Mon Sep 17 00:00:00 2001 From: Phillip Lord Date: Fri, 18 Jan 2013 10:44:17 +0000 Subject: [PATCH 025/606] Support packages where autoload and elpa name are different Some packages such as ECB already provide an autoload file, so it is this that use-package needs to require. However, the ELPA name is ecb. This commit allows ensure to take an argument (other than t). --- lisp/use-package/use-package.el | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 63223a3a26a..3b5174700d5 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -369,12 +369,17 @@ For full documentation. please see commentary. (name-string (if (stringp name) name (symbol-name name))) (name-symbol (if (stringp name) (intern name) name))) + ;; force this immediately -- one off cost (unless (plist-get args :disabled) - - ;; force this immediately -- one off cost! - (if (plist-get args :ensure) - (use-package-ensure-elpa name)) - + (let* ((ensure (plist-get args :ensure)) + (package-name + (or (and (eq ensure t) + name) + ensure))) + (when package-name + (use-package-ensure-elpa package-name))) + + (if diminish-var (setq config-body `(progn From 593f18aff56e8a9f492143c4a397fba0840816b2 Mon Sep 17 00:00:00 2001 From: Phil Hudson Date: Wed, 23 Jan 2013 20:33:15 +0000 Subject: [PATCH 026/606] Macroexpand quoted eval-after-load block early The main `use-package' macro incorrectly planted code containing a call to the `with-elapsed-timer' macro in a quoted block to be run by `eval-after-load'. If package use-package was not loaded at runtime, the block would error saying correctly that `with-elapsed-timer' is undefined. This mod correctly macroexpands the block at code generation time. --- lisp/use-package/use-package.el | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index f9bc5c2b32e..53c96ae1f6c 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -461,10 +461,12 @@ ,init-body ,(unless (null config-body) `(eval-after-load ,name-string - '(if ,requires-test - (with-elapsed-timer - ,(format "Configuring package %s" name-string) - ,config-body)))) + (quote + (if ,requires-test + ,(macroexpand-all + `(with-elapsed-timer + ,(format "Configuring package %s" name-string) + ,config-body)))))) t)) `(if (and ,(or predicate t) ,requires-test) From c680b57ebfe021fa8af3f704c58e51af2b9b07de Mon Sep 17 00:00:00 2001 From: "Berk D. Demir" Date: Mon, 28 Jan 2013 00:38:39 -0800 Subject: [PATCH 027/606] Cleanup trailing whitespace Just `M-x delete-trailing-whitespace' on use-package.el --- lisp/use-package/use-package.el | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index d88f2311043..ea051ef91e7 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -323,11 +323,11 @@ (defmacro use-package (name &rest args) "Use a package with configuration options. -For full documentation. please see commentary. +For full documentation. please see commentary. (use-package package-name :keyword option) - + :init Code to run when `use-package' form evals. :bind Perform key bindings, and define autoload for bound commands. @@ -372,13 +372,13 @@ For full documentation. please see commentary. ;; force this immediately -- one off cost (unless (plist-get args :disabled) (let* ((ensure (plist-get args :ensure)) - (package-name + (package-name (or (and (eq ensure t) name) ensure))) - (when package-name + (when package-name (use-package-ensure-elpa package-name))) - + (if diminish-var (setq config-body From aa8d5fab19254adee83dde0f94e0216558e091dc Mon Sep 17 00:00:00 2001 From: Phillip Lord Date: Tue, 5 Feb 2013 21:46:02 +0000 Subject: [PATCH 028/606] Added minimum load time display option Makes the minimum load time before use-package displays a message a customizable option. --- lisp/use-package/use-package.el | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index ea051ef91e7..b2ab8190630 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -276,6 +276,12 @@ :type 'boolean :group 'use-package) +(defcustom use-package-minimum-reported-time 0.01 + "Minimal load time that will be reported" + :type 'number + :group 'use-package + ) + (defmacro with-elapsed-timer (text &rest forms) `(let ((now ,(if use-package-verbose '(current-time)))) @@ -286,7 +292,7 @@ ,(when use-package-verbose `(let ((elapsed (float-time (time-subtract (current-time) now)))) - (if (> elapsed 0.01) + (if (> elapsed use-package-minimum-reported-time) (message "%s...done (%.3fs)" ,text elapsed) (message "%s...done" ,text))))))) From 35685f120bbc6ca1db837d82b3efeb84263e5af9 Mon Sep 17 00:00:00 2001 From: Phillip Lord Date: Tue, 12 Feb 2013 10:22:06 +0000 Subject: [PATCH 029/606] idle initiation of packages A new feature which adds support for idle startup and loading of packages. --- lisp/use-package/use-package.el | 74 ++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index b2ab8190630..17f2cc97fb6 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -127,6 +127,25 @@ ;; loaded, but wait until after I've opened a Haskell file before loading ;; "inf-haskell.el" and "hs-lint.el". ;; +;; Another similar option to `:init' is `:idle'. Like `:init' this always run, +;; however, it does so when Emacs is idle at some time in the future after +;; load. This is particularly useful for convienience minor modes which can be +;; slow to load. For instance, in this case, I want Emacs to always use +;; `global-pabbrev-mode'. `:commands' creates an appropriate autoload; `:idle' +;; will run this command at some point in the future. If you start Emacs and +;; beginning typing straight-away, loading will happen eventually. +;; +;; (use-package pabbrev +;; :commands global-pabbrev-mode +;; :idle (global-pabbrev-mode)) +;; +;; Idle functions are run in the order in which they are evaluated. If you +;; have many, it may take sometime for all to run. `use-package' will always +;; tell you if there is an error in the form which can otherwise be difficult +;; to debug. It may tell you about functions being eval'd, depending on the +;; value of `use-package-verbose'. Other good candidates for `:idle' are +;; `yasnippet', `auto-complete' and `autopair'. +;; ;; The `:bind' keyword takes either a cons or a list of conses: ;; ;; (use-package hi-lock @@ -320,6 +339,46 @@ :url (match-string 1)))))))) args)) +(defvar use-package-idle-timer nil) +(defvar use-package-idle-forms nil) + +(defun use-package-start-idle-timer () + "Ensure that the idle timer is running" + (unless use-package-idle-timer + (setq use-package-idle-timer + (run-with-idle-timer + 3 t + 'use-package-idle-eval)))) + +(defun use-package-init-on-idle (form) + "Add a new form to the idle queue" + (use-package-start-idle-timer) + (if use-package-idle-forms + (add-to-list 'use-package-idle-forms + form t) + (setq use-package-idle-forms (list form)) + )) + +(defun use-package-idle-eval() + "Start to eval idle-commands from the idle queue" + (let ((next (pop use-package-idle-forms))) + (if next + (progn + (when use-package-verbose + (message "use-package idle:%s" next)) + + (condition-case e + (funcall next) + (error + (message + "Failure on use-package idle. Form: %s, Error: %s" + next e))) + ;; recurse after a bit + (when (sit-for 3) + (use-package-idle-eval))) + ;; finished (so far!) + (cancel-timer use-package-idle-timer) + (setq use-package-idle-timer nil)))) (defun use-package-ensure-elpa (package) (when (not (package-installed-p package)) @@ -348,6 +407,7 @@ For full documentation. please see commentary. :defines Define vars to silence byte-compiler. :load-path Add to `load-path' before loading. :diminish Support for diminish package (if it's installed). +:idle adds a form to run on an idle timer " (let* ((commands (plist-get args :commands)) (pre-init-body (plist-get args :pre-init)) @@ -355,6 +415,7 @@ For full documentation. please see commentary. (config-body (plist-get args :config)) (diminish-var (plist-get args :diminish)) (defines (plist-get args :defines)) + (idle-body (plist-get args :idle)) (keybindings ) (mode-alist ) (interpreter-alist ) @@ -382,8 +443,9 @@ For full documentation. please see commentary. (or (and (eq ensure t) name) ensure))) - (when package-name - (use-package-ensure-elpa package-name))) + + (when package-name + (use-package-ensure-elpa package-name))) (if diminish-var @@ -405,6 +467,14 @@ For full documentation. please see commentary. (if (and commands (symbolp commands)) (setq commands (list commands))) + + (when idle-body + (setq init-body + `(progn + (use-package-init-on-idle (lambda () ,idle-body)) + ,init-body))) + + (flet ((init-for-commands (func sym-or-list) (let ((cons-list (if (and (consp sym-or-list) From 1758c5faeacb1b342b409ccdeaac20fde11e359b Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 18 Feb 2013 17:52:58 -0600 Subject: [PATCH 030/606] Corrected a typo --- lisp/use-package/use-package.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 17f2cc97fb6..8a26e6b9b4e 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -76,7 +76,7 @@ ;; would succeed either way. ;; ;; Similar to `:bind', you can use `:mode' and `:interpreter' to establish a -;; deferred binding within `auto-mode-alist' and `auto-interpreter-alist'. +;; deferred binding within `auto-mode-alist' and `interpreter-mode-alist'. ;; The specifier to either keyword can be a single cons or a list: ;; ;; (use-package python-mode @@ -398,7 +398,7 @@ For full documentation. please see commentary. commands. :commands Define autoloads for given commands. :mode Form to be added to `auto-mode-alist'. -:interpreter Form to be added to `auto-interpreter-alist'. +:interpreter Form to be added to `interpreter-mode-alist'. :defer Defer loading of package -- automatic if :commands, :bind, :mode or :interpreter are used. :config Runs if and when package loads. From 34d3f115dddeb1bf030577402bce7aa96222c97c Mon Sep 17 00:00:00 2001 From: Phil Hudson Date: Sat, 23 Mar 2013 11:31:15 +0000 Subject: [PATCH 031/606] Runtime client code independence redux Tweak to previous fix for expanding macros correctly at code-planting time. Specifically, eval `use-package-minimum-reported-time' at code-planting time not at runtime (which would require use-package.el to be loaded first). --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 8a26e6b9b4e..68216c6a7a9 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -311,7 +311,7 @@ ,(when use-package-verbose `(let ((elapsed (float-time (time-subtract (current-time) now)))) - (if (> elapsed use-package-minimum-reported-time) + (if (> elapsed ,use-package-minimum-reported-time) (message "%s...done (%.3fs)" ,text elapsed) (message "%s...done" ,text))))))) From 09b9ef3ae3dacd871a3f283a5f3a13e6fb6d8a94 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 13 Apr 2013 16:09:27 -0400 Subject: [PATCH 032/606] let bind-key* override minor modes with emulation-mode-map-alists --- lisp/use-package/bind-key.el | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 0d3039e5e01..5d125199e70 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -80,7 +80,12 @@ (define-minor-mode override-global-mode "A minor mode so that keymap settings override other modes." - t "" override-global-map) + t "") + +;; the keymaps in `emulation-mode-map-alists' take precedence over +;; `minor-mode-map-alist' +(add-to-list 'emulation-mode-map-alists + `((override-global-mode . ,override-global-map))) (add-hook 'after-init-hook (function From 2abe5f9480332476e22a58ad5f83d0cfa20eb7c2 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sun, 14 Apr 2013 15:01:37 -0400 Subject: [PATCH 033/606] let :diminish "string" guess correct mode symbol --- lisp/use-package/use-package.el | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 68216c6a7a9..17f7309cf55 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -212,7 +212,9 @@ ;; if you have that installed. It's purpose is to remove strings from your ;; mode-line that would otherwise always be there and provide no useful ;; information. It is invoked with the `:diminish' keyword, which is passed -;; either the minor mode symbol, or a cons of the symbol and a replacement string: +;; either the minor mode symbol, a cons of the symbol and a replacement string, +;; or just a replacement string in which case the minor mode symbol is guessed +;; to be the package name with "-mode" at the end: ;; ;; (use-package abbrev ;; :diminish abbrev-mode @@ -453,16 +455,20 @@ For full documentation. please see commentary. `(progn ,config-body (ignore-errors - ,@(if (listp diminish-var) - (if (listp (cdr diminish-var)) - (mapcar (lambda (var) - (if (listp var) - `(diminish (quote ,(car var)) ,(cdr var)) - `(diminish (quote ,var)))) - diminish-var) - `((diminish (quote ,(car diminish-var)) ,(cdr diminish-var))) - ) - `((diminish (quote ,diminish-var)))))))) + ,@(cond + ((stringp diminish-var) + `(diminish (quote ,(intern (concat name-string "-mode"))) + ,diminish-var)) + ((symbolp diminish-var) + `(diminish (quote ,diminish-var))) + ((and (consp diminish-var) (stringp (cdr diminish-var))) + `(diminish (quote ,(car diminish-var)) ,(cdr diminish-var))) + (t ; list of symbols or (symbol . "string") pairs + (mapcar (lambda (var) + (if (listp var) + `(diminish (quote ,(car var)) ,(cdr var)) + `(diminish (quote ,var)))) + diminish-var))))))) (if (and commands (symbolp commands)) (setq commands (list commands))) From 0df0e18c4be912133220c14c4999fccbc92cb52c Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Tue, 16 Apr 2013 11:29:32 -0400 Subject: [PATCH 034/606] needed extra layer of nesting for diminish calls --- lisp/use-package/use-package.el | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 17f7309cf55..82868731cb5 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -457,12 +457,12 @@ For full documentation. please see commentary. (ignore-errors ,@(cond ((stringp diminish-var) - `(diminish (quote ,(intern (concat name-string "-mode"))) - ,diminish-var)) + `((diminish (quote ,(intern (concat name-string "-mode"))) + ,diminish-var))) ((symbolp diminish-var) - `(diminish (quote ,diminish-var))) + `((diminish (quote ,diminish-var)))) ((and (consp diminish-var) (stringp (cdr diminish-var))) - `(diminish (quote ,(car diminish-var)) ,(cdr diminish-var))) + `((diminish (quote ,(car diminish-var)) ,(cdr diminish-var)))) (t ; list of symbols or (symbol . "string") pairs (mapcar (lambda (var) (if (listp var) From b90161860706739b0835360c8fc58aea26409509 Mon Sep 17 00:00:00 2001 From: Steve Purcell Date: Tue, 23 Apr 2013 11:25:10 +0200 Subject: [PATCH 035/606] Add Package-Requires header for ELPA installations --- lisp/use-package/use-package.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 82868731cb5..896edeade97 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -5,6 +5,7 @@ ;; Author: John Wiegley ;; Created: 17 Jun 2012 ;; Version: 1.0 +;; Package-Requires: ((bind-key "1.0") (diminish "0.44")) ;; Keywords: dotemacs startup speed config package ;; X-URL: https://github.com/jwiegley/use-package From 17a1a4659a490275917e0dcdb0df428307bf8258 Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Sat, 27 Apr 2013 17:04:47 +0200 Subject: [PATCH 036/606] enforce use of spaces for indentation --- lisp/use-package/bind-key.el | 4 +++- lisp/use-package/use-package.el | 8 +++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 5d125199e70..95dc0c8a605 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -219,5 +219,7 @@ (display-buffer (current-buffer)))) (provide 'bind-key) - +;; Local Variables: +;; indent-tabs-mode: nil +;; End: ;;; bind-key.el ends here diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 896edeade97..46b46278c07 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -376,9 +376,9 @@ (message "Failure on use-package idle. Form: %s, Error: %s" next e))) - ;; recurse after a bit + ;; recurse after a bit (when (sit-for 3) - (use-package-idle-eval))) + (use-package-idle-eval))) ;; finished (so far!) (cancel-timer use-package-idle-timer) (setq use-package-idle-timer nil)))) @@ -605,5 +605,7 @@ For full documentation. please see commentary. (put 'use-package 'lisp-indent-function 1) (provide 'use-package) - +;; Local Variables: +;; indent-tabs-mode: nil +;; End: ;;; use-package.el ends here From 82903da9d8d50bf446a9fc90d65e4fefd18f17eb Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Sat, 27 Apr 2013 17:09:12 +0200 Subject: [PATCH 037/606] don't use obsolete flet Unfortunately there isn't a proper dynamically scoped replacement, so we have to resort to using funcall. --- lisp/use-package/use-package.el | 55 +++++++++++++++++---------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 46b46278c07..f4db4e3259a 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -482,35 +482,38 @@ For full documentation. please see commentary. ,init-body))) - (flet ((init-for-commands - (func sym-or-list) - (let ((cons-list (if (and (consp sym-or-list) - (stringp (car sym-or-list))) - (list sym-or-list) - sym-or-list))) - (if cons-list - (setq init-body - `(progn - ,init-body - ,@(mapcar #'(lambda (elem) - (push (cdr elem) commands) - (funcall func elem)) - cons-list))))))) + (let ((init-for-commands + (lambda (func sym-or-list) + (let ((cons-list (if (and (consp sym-or-list) + (stringp (car sym-or-list))) + (list sym-or-list) + sym-or-list))) + (if cons-list + (setq init-body + `(progn + ,init-body + ,@(mapcar #'(lambda (elem) + (push (cdr elem) commands) + (funcall func elem)) + cons-list)))))))) - (init-for-commands #'(lambda (binding) - `(bind-key ,(car binding) - (quote ,(cdr binding)))) - (plist-get args :bind)) + (funcall init-for-commands + #'(lambda (binding) + `(bind-key ,(car binding) + (quote ,(cdr binding)))) + (plist-get args :bind)) - (init-for-commands #'(lambda (mode) - `(add-to-list 'auto-mode-alist - (quote ,mode))) - (plist-get args :mode)) + (funcall init-for-commands + #'(lambda (mode) + `(add-to-list 'auto-mode-alist + (quote ,mode))) + (plist-get args :mode)) - (init-for-commands #'(lambda (interpreter) - `(add-to-list 'interpreter-mode-alist - (quote ,interpreter))) - (plist-get args :interpreter))) + (funcall init-for-commands + #'(lambda (interpreter) + `(add-to-list 'interpreter-mode-alist + (quote ,interpreter))) + (plist-get args :interpreter))) `(progn ,@(mapcar From a5e4a6d93836b88fb8dc15c3f5084bd8a0ea29b6 Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Sat, 27 Apr 2013 17:09:52 +0200 Subject: [PATCH 038/606] quiet byte-compiler; ensure package.el is loaded --- lisp/use-package/use-package.el | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index f4db4e3259a..0438deade7d 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -284,6 +284,9 @@ (eval-when-compile (require 'cl)) +(declare-function package-installed-p 'package) +(declare-function el-get-read-recipe 'el-get) + (defgroup use-package nil "A use-package declaration for simplifying your .emacs" :group 'startup) @@ -448,6 +451,7 @@ For full documentation. please see commentary. ensure))) (when package-name + (require 'package) (use-package-ensure-elpa package-name))) From d2460b92769e6ed78057c36dfcb450bd0d3e97cc Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Sat, 27 Apr 2013 17:11:16 +0200 Subject: [PATCH 039/606] add dots; cleanup whitespace --- lisp/use-package/use-package.el | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 0438deade7d..5b2cb03580d 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -288,7 +288,7 @@ (declare-function el-get-read-recipe 'el-get) (defgroup use-package nil - "A use-package declaration for simplifying your .emacs" + "A use-package declaration for simplifying your `.emacs'." :group 'startup) (defcustom use-package-verbose t @@ -297,15 +297,14 @@ :group 'use-package) (defcustom use-package-debug nil - "Whether to report more information, mostly regarding el-get" + "Whether to report more information, mostly regarding el-get." :type 'boolean :group 'use-package) (defcustom use-package-minimum-reported-time 0.01 "Minimal load time that will be reported" :type 'number - :group 'use-package - ) + :group 'use-package) (defmacro with-elapsed-timer (text &rest forms) `(let ((now ,(if use-package-verbose @@ -349,7 +348,7 @@ (defvar use-package-idle-forms nil) (defun use-package-start-idle-timer () - "Ensure that the idle timer is running" + "Ensure that the idle timer is running." (unless use-package-idle-timer (setq use-package-idle-timer (run-with-idle-timer @@ -357,16 +356,15 @@ 'use-package-idle-eval)))) (defun use-package-init-on-idle (form) - "Add a new form to the idle queue" + "Add a new form to the idle queue." (use-package-start-idle-timer) (if use-package-idle-forms (add-to-list 'use-package-idle-forms form t) - (setq use-package-idle-forms (list form)) - )) + (setq use-package-idle-forms (list form)))) (defun use-package-idle-eval() - "Start to eval idle-commands from the idle queue" + "Start to eval idle-commands from the idle queue." (let ((next (pop use-package-idle-forms))) (if next (progn @@ -413,8 +411,7 @@ For full documentation. please see commentary. :defines Define vars to silence byte-compiler. :load-path Add to `load-path' before loading. :diminish Support for diminish package (if it's installed). -:idle adds a form to run on an idle timer -" +:idle adds a form to run on an idle timer" (let* ((commands (plist-get args :commands)) (pre-init-body (plist-get args :pre-init)) (init-body (plist-get args :init)) From 5b696d19187efec222d1e50bdb750d3a6477e12e Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Sat, 27 Apr 2013 17:42:36 +0200 Subject: [PATCH 040/606] fontify use-package form --- lisp/use-package/use-package.el | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 896edeade97..275a8b9ee4d 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -604,6 +604,13 @@ For full documentation. please see commentary. (put 'use-package 'lisp-indent-function 1) +(defconst use-package-font-lock-keywords + '(("(\\(use-package\\)\\> *\\(\\sw+\\)?" + (1 font-lock-keyword-face) + (2 font-lock-constant-face)))) + +(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords) + (provide 'use-package) ;;; use-package.el ends here From 19c65ea3ab3a5f6035383fbfb6165e3aa897f603 Mon Sep 17 00:00:00 2001 From: Donald Curtis Date: Wed, 15 May 2013 09:01:37 -0500 Subject: [PATCH 041/606] package header should, hold, sold be the full filename + ext this fixes a bug in using `(package-buffer-info)` --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 50fa4edd8ad..4778c399dea 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1,4 +1,4 @@ -;;; use-package --- A use-package declaration for simplifying your .emacs +;;; use-package.el --- A use-package declaration for simplifying your .emacs ;; Copyright (C) 2012 John Wiegley From 7161c09b30dcf4dd5dad7eacea9652c5f34fe07a Mon Sep 17 00:00:00 2001 From: Phillip Lord Date: Wed, 26 Jun 2013 10:28:35 +0100 Subject: [PATCH 042/606] Documentation added for :ensure keyword --- lisp/use-package/use-package.el | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 4778c399dea..c16f2ee2748 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -238,6 +238,17 @@ ;; actual load. In this case, everything could be put inside `:init' and ;; there would be no difference. ;; +;; * For package.el user +;; +;; You can use `use-package' to load packages from ELPA with package.el. This +;; is particularly useful if you share your .emacs between several machines; +;; the relevant packages will download automatically once placed in your +;; .emacs. The `:ensure' key will install the package automatically if it is +;; not already present. +;; +;; (use-package tex-site +;; :ensure auctex) +;; ;; * For el-get users ;; ;; You can use `use-package' as a way to create source definitions for el-get. From 01cfa0358f2d51e50b0def40c667ea4fcd81c130 Mon Sep 17 00:00:00 2001 From: Phillip Lord Date: Wed, 26 Jun 2013 12:12:25 +0100 Subject: [PATCH 043/606] Added documentation to use-package macro --- lisp/use-package/use-package.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index c16f2ee2748..5b5d0995913 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -422,7 +422,8 @@ For full documentation. please see commentary. :defines Define vars to silence byte-compiler. :load-path Add to `load-path' before loading. :diminish Support for diminish package (if it's installed). -:idle adds a form to run on an idle timer" +:idle adds a form to run on an idle timer +:ensure loads package using package.el if necessary." (let* ((commands (plist-get args :commands)) (pre-init-body (plist-get args :pre-init)) (init-body (plist-get args :init)) From f98b9d08fed81f4c1b606e32d22e54118b58e9af Mon Sep 17 00:00:00 2001 From: Phil Hudson Date: Fri, 14 Jun 2013 10:53:49 +0100 Subject: [PATCH 044/606] Validate keywords. Error if any keyword is unrecognized Conflicts: use-package.el --- lisp/use-package/use-package.el | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 5b5d0995913..20344799b8a 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -399,6 +399,44 @@ (when (not (package-installed-p package)) (package-install package))) +(defvar use-package-keywords + '( + :bind + :commands + :config + :defer + :defines + :diminish + :disabled + :ensure + :idle + :if + :init + :interpreter + :load-path + :mode + :pre-init + :requires + ) + "Keywords recognized by `use-package'.") + +(defun plist-keys (plist) + "Return a list containing all the keys in PLIST." + (when plist + (cons + (car plist) + (plist-keys + (cddr plist))))) + +(defun use-package-validate-keywords (args) + "Error if any keyword given in ARGS is not recognized. +Return the list of recognized keywords." + (mapc + (function + (lambda (keyword) + (unless (memq keyword use-package-keywords) + (error "Unrecognized keyword: %s" keyword)))) + (plist-keys args))) (defmacro use-package (name &rest args) "Use a package with configuration options. @@ -424,6 +462,7 @@ For full documentation. please see commentary. :diminish Support for diminish package (if it's installed). :idle adds a form to run on an idle timer :ensure loads package using package.el if necessary." + (use-package-validate-keywords args) ; error if any bad keyword, ignore result (let* ((commands (plist-get args :commands)) (pre-init-body (plist-get args :pre-init)) (init-body (plist-get args :init)) From a5859a7c8d911e84986c5845cbb195b3b8b4bbe5 Mon Sep 17 00:00:00 2001 From: Steve Purcell Date: Sun, 28 Jul 2013 09:45:06 +0100 Subject: [PATCH 045/606] Fix initial line to satisfy package.el --- lisp/use-package/bind-key.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 95dc0c8a605..3f61feeb760 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -1,4 +1,4 @@ -;;; bind-key --- A simple way to manage personal keybindings +;;; bind-key.el --- A simple way to manage personal keybindings ;; Copyright (C) 2012 John Wiegley From 2a1e7e418a7bb72be4aa2011f605aca6f691b924 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sun, 11 Aug 2013 16:05:06 -0400 Subject: [PATCH 046/606] refine use-package highlighting regexp --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 20344799b8a..33c6e18a626 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -660,7 +660,7 @@ For full documentation. please see commentary. (put 'use-package 'lisp-indent-function 1) (defconst use-package-font-lock-keywords - '(("(\\(use-package\\)\\> *\\(\\sw+\\)?" + '(("(\\(use-package\\)\\_>[\n[:space:]]+\\(\\(?:\\s_\\|\\sw\\)+\\)" (1 font-lock-keyword-face) (2 font-lock-constant-face)))) From e7a343828ac2ca57231b2a124f4673db18f7ca50 Mon Sep 17 00:00:00 2001 From: Phillip Lord Date: Tue, 13 Aug 2013 11:40:54 +0100 Subject: [PATCH 047/606] Add a ":first" keyword for those occasions that it's necessary --- lisp/use-package/use-package.el | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 4778c399dea..7fd276efae7 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -147,6 +147,11 @@ ;; value of `use-package-verbose'. Other good candidates for `:idle' are ;; `yasnippet', `auto-complete' and `autopair'. ;; +;; Finally, you may wish to use `:first'. This form runs before everything +;; else whenever the `use-package' form evals; the package in question will +;; never have been required. This can be useful, if you wish for instance, to +;; pull files from a git repository, or mount a file system. +;; ;; The `:bind' keyword takes either a cons or a list of conses: ;; ;; (use-package hi-lock @@ -401,6 +406,9 @@ For full documentation. please see commentary. :bind Perform key bindings, and define autoload for bound commands. :commands Define autoloads for given commands. +:first Code to run when `use-package' form evals and before + anything else. Unlike :init this form runs before the + package is required or autoloads added. :mode Form to be added to `auto-mode-alist'. :interpreter Form to be added to `interpreter-mode-alist'. :defer Defer loading of package -- automatic @@ -414,6 +422,7 @@ For full documentation. please see commentary. :idle adds a form to run on an idle timer" (let* ((commands (plist-get args :commands)) (pre-init-body (plist-get args :pre-init)) + (first-body (plist-get args :first)) (init-body (plist-get args :init)) (config-body (plist-get args :config)) (diminish-var (plist-get args :diminish)) @@ -441,6 +450,7 @@ For full documentation. please see commentary. ;; force this immediately -- one off cost (unless (plist-get args :disabled) + (let* ((ensure (plist-get args :ensure)) (package-name (or (and (eq ensure t) @@ -517,6 +527,7 @@ For full documentation. please see commentary. (plist-get args :interpreter))) `(progn + ,first-body ,@(mapcar #'(lambda (path) `(add-to-list 'load-path From ac0c9633bc9c1451f3c6fa0c3fee1f5956c732aa Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Tue, 13 Aug 2013 19:13:16 -0400 Subject: [PATCH 048/606] use `eval-when-compile' for loading package at compile time, fixes issue GitHub-reference: https://github.com/jwiegley/use-package/issues/29 --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 33c6e18a626..59ecf93b278 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -581,7 +581,7 @@ For full documentation. please see commentary. (t pkg-load-path))) - (when byte-compile-current-file + (eval-when-compile ,@defines-eval ,(if (stringp name) `(load ,name t) From a76d16730dfadaf11e7e186937a8624c9c9a4af1 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Tue, 13 Aug 2013 19:25:26 -0400 Subject: [PATCH 049/606] use lambda around deferred :config forms to compile them, fixes issue GitHub-reference: https://github.com/jwiegley/use-package/issues/30 --- lisp/use-package/use-package.el | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 59ecf93b278..72e287c376a 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -637,12 +637,12 @@ For full documentation. please see commentary. ,init-body ,(unless (null config-body) `(eval-after-load ,name-string - (quote - (if ,requires-test - ,(macroexpand-all - `(with-elapsed-timer - ,(format "Configuring package %s" name-string) - ,config-body)))))) + `(,(lambda () + (if ,requires-test + ,(macroexpand-all + `(with-elapsed-timer + ,(format "Configuring package %s" name-string) + ,config-body))))))) t)) `(if (and ,(or predicate t) ,requires-test) From aa357bc96ae4b6e2d05031343e187156c3fd4e58 Mon Sep 17 00:00:00 2001 From: Phillip Lord Date: Thu, 15 Aug 2013 11:54:29 +0100 Subject: [PATCH 050/606] Changed :first to :pre-load Updated and extended documentation. --- lisp/use-package/use-package.el | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 7fd276efae7..1ff776ccdf7 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -147,10 +147,11 @@ ;; value of `use-package-verbose'. Other good candidates for `:idle' are ;; `yasnippet', `auto-complete' and `autopair'. ;; -;; Finally, you may wish to use `:first'. This form runs before everything +;; Finally, you may wish to use `:pre-load'. This form runs before everything ;; else whenever the `use-package' form evals; the package in question will ;; never have been required. This can be useful, if you wish for instance, to -;; pull files from a git repository, or mount a file system. +;; pull files from a git repository, or mount a file system. Like :init, +;; keeping this form as simple as possible makes sense. ;; ;; The `:bind' keyword takes either a cons or a list of conses: ;; @@ -406,7 +407,7 @@ For full documentation. please see commentary. :bind Perform key bindings, and define autoload for bound commands. :commands Define autoloads for given commands. -:first Code to run when `use-package' form evals and before +:pre-load Code to run when `use-package' form evals and before anything else. Unlike :init this form runs before the package is required or autoloads added. :mode Form to be added to `auto-mode-alist'. @@ -422,7 +423,7 @@ For full documentation. please see commentary. :idle adds a form to run on an idle timer" (let* ((commands (plist-get args :commands)) (pre-init-body (plist-get args :pre-init)) - (first-body (plist-get args :first)) + (pre-load-body (plist-get args :pre-load)) (init-body (plist-get args :init)) (config-body (plist-get args :config)) (diminish-var (plist-get args :diminish)) @@ -527,7 +528,7 @@ For full documentation. please see commentary. (plist-get args :interpreter))) `(progn - ,first-body + ,pre-load-body ,@(mapcar #'(lambda (path) `(add-to-list 'load-path From 48975f791b409fe9aa68dc757d489c37a19a7579 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Thu, 15 Aug 2013 21:35:38 -0400 Subject: [PATCH 051/606] also check `byte-compile-current-file' for compile time loads, fixes issue `eval-when-compile' is really `eval-when-macroexpand' which includes loading from source GitHub-reference: https://github.com/jwiegley/use-package/issues/44 --- lisp/use-package/use-package.el | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 72e287c376a..8077f2e8798 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -582,10 +582,11 @@ For full documentation. please see commentary. pkg-load-path))) (eval-when-compile - ,@defines-eval - ,(if (stringp name) - `(load ,name t) - `(require ',name nil t))) + (when (bound-and-true-p byte-compile-current-file) + ,@defines-eval + ,(if (stringp name) + `(load ,name t) + `(require ',name nil t)))) ,(when (boundp 'el-get-sources) (require 'el-get) From 57f80d4ff164fd1f3c89d4998128a0b9d8b6b102 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Tue, 13 Aug 2013 23:33:18 -0400 Subject: [PATCH 052/606] highlight use-package before typing package name This follow the same pattern as the highlighting for provide and require from `lisp-font-lock-keywords-2' in font-lock.el --- lisp/use-package/use-package.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 8077f2e8798..fea1aea0fce 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -661,9 +661,9 @@ For full documentation. please see commentary. (put 'use-package 'lisp-indent-function 1) (defconst use-package-font-lock-keywords - '(("(\\(use-package\\)\\_>[\n[:space:]]+\\(\\(?:\\s_\\|\\sw\\)+\\)" + '(("(\\(use-package\\)\\_>[ \t']*\\(\\sw+\\)?" (1 font-lock-keyword-face) - (2 font-lock-constant-face)))) + (2 font-lock-constant-face nil t)))) (font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords) From 8de5c29ed5cd0d489c677e03ab30d6069046a53c Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Wed, 4 Sep 2013 22:40:55 +0800 Subject: [PATCH 053/606] Improve (describe-personal-keybindings) output Create *Personal Keybindings* by with-output-to-temp-buffer. It redirects standard output to the buffer and display it in help mode. So we can get help mode keybindings such as "q" for free. Quote the command-desc output so that it is made into a hyperlink. --- lisp/use-package/bind-key.el | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 3f61feeb760..c4b3f19deb4 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -170,10 +170,10 @@ (cons (string< (caar l) (caar r)) nil))))) (defun describe-personal-keybindings () + "Display all the personal keybindings defined by `bind-key'." (interactive) - (with-current-buffer (get-buffer-create "*Personal Keybindings*") - (delete-region (point-min) (point-max)) - (insert "Key name Command Comments + (with-output-to-temp-buffer "*Personal Keybindings*" + (princ "Key name Command Comments ----------------- --------------------------------------- --------------------- ") (let (last-binding) @@ -184,12 +184,12 @@ (car (compare-keybindings l r)))))) (if (not (eq (cdar last-binding) (cdar binding))) - (insert ?\n (format "\n%s\n%s\n\n" - (cdar binding) - (make-string 79 ?-))) + (princ (format "\n\n%s\n%s\n\n" + (cdar binding) + (make-string 79 ?-))) (if (and last-binding (cdr (compare-keybindings last-binding binding))) - (insert ?\n))) + (princ "\n"))) (let* ((key-name (caar binding)) (at-present (lookup-key (or (symbol-value (cdar binding)) @@ -202,10 +202,10 @@ (get-binding-description was-command))) (at-present-desc (get-binding-description at-present)) ) - (insert + (princ (format "%-18s%-40s%s\n" - key-name command-desc + key-name (format "`%s\'" command-desc) (if (string= command-desc at-present-desc) (if (or (null was-command) (string= command-desc was-command-desc)) @@ -213,10 +213,7 @@ (format "(%s)" was-command-desc)) (format "[now: %s]" at-present))))) - (setq last-binding binding))) - - (goto-char (point-min)) - (display-buffer (current-buffer)))) + (setq last-binding binding))))) (provide 'bind-key) ;; Local Variables: From bbf2b5034b06e6ccbe223fa6cfdc2087d87985da Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Fri, 13 Sep 2013 21:17:09 +0800 Subject: [PATCH 054/606] Fix highlight use-package for Emacs snapshot The commit 57f80d4 fixed the highlight by following the regexp as for require. However in Emacs truck, it only highlights first part of the package name. This change follows the regexp for require on emacs truck. See line 2327 on font-lock.el in the following patch. http://bzr.savannah.gnu.org/lh/emacs/trunk/revision/111821 --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index fea1aea0fce..1e3efd9045b 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -661,7 +661,7 @@ For full documentation. please see commentary. (put 'use-package 'lisp-indent-function 1) (defconst use-package-font-lock-keywords - '(("(\\(use-package\\)\\_>[ \t']*\\(\\sw+\\)?" + '(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" (1 font-lock-keyword-face) (2 font-lock-constant-face nil t)))) From c6d79d2cb40bd141f62eaca6dca47fb2e8e6943f Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Mon, 16 Sep 2013 13:59:16 -0400 Subject: [PATCH 055/606] pass name (not name-string) to eval-after-load Fixes https://github.com/jwiegley/use-package/issues/52: the :config block would be triggered when loading a config file with the same name as the package and again when loading the package itself. --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 1e3efd9045b..d817db119a9 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -637,7 +637,7 @@ For full documentation. please see commentary. ,@form ,init-body ,(unless (null config-body) - `(eval-after-load ,name-string + `(eval-after-load ,(if (stringp name) name `',name) `(,(lambda () (if ,requires-test ,(macroexpand-all From fd8af80f08c7fd3bc938c458482e618dff6717b2 Mon Sep 17 00:00:00 2001 From: Nicolas Dudebout Date: Tue, 17 Sep 2013 09:58:57 -0400 Subject: [PATCH 056/606] Enables using variables and functions as arguments This change an extra level on indirection for two cases: + when an association or an alist is required, it is possible to pass a variable containing an association or an alist + when a sexp to be evaluated is required, it is possible to pass a function instead --- lisp/use-package/use-package.el | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index d817db119a9..ec2436e730b 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -438,6 +438,18 @@ Return the list of recognized keywords." (error "Unrecognized keyword: %s" keyword)))) (plist-keys args))) +(defun plist-get-sexp (plist prop) + (let ((sexp-or-function (plist-get plist prop))) + (if (functionp sexp-or-function) + (funcall sexp-or-function) + sexp-or-function))) + +(defun plist-get-value (plist prop) + (let ((value-or-symbol (plist-get plist prop))) + (if (symbolp value-or-symbol) + (symbol-value value-or-symbol) + value-or-symbol))) + (defmacro use-package (name &rest args) "Use a package with configuration options. @@ -464,15 +476,15 @@ For full documentation. please see commentary. :ensure loads package using package.el if necessary." (use-package-validate-keywords args) ; error if any bad keyword, ignore result (let* ((commands (plist-get args :commands)) - (pre-init-body (plist-get args :pre-init)) - (init-body (plist-get args :init)) - (config-body (plist-get args :config)) + (pre-init-body (plist-get-sexp args :pre-init)) + (init-body (plist-get-sexp args :init)) + (config-body (plist-get-sexp args :config)) (diminish-var (plist-get args :diminish)) (defines (plist-get args :defines)) - (idle-body (plist-get args :idle)) - (keybindings ) - (mode-alist ) - (interpreter-alist ) + (idle-body (plist-get-sexp args :idle)) + (keybindings-alist (plist-get-value args :bind)) + (mode-alist (plist-get-value args :mode)) + (interpreter-alist (plist-get-value args :interpreter)) (predicate (plist-get args :if)) (pkg-load-path (plist-get args :load-path)) (defines-eval (if (null defines) @@ -553,19 +565,19 @@ For full documentation. please see commentary. #'(lambda (binding) `(bind-key ,(car binding) (quote ,(cdr binding)))) - (plist-get args :bind)) + keybindings-alist) (funcall init-for-commands #'(lambda (mode) `(add-to-list 'auto-mode-alist (quote ,mode))) - (plist-get args :mode)) + mode-alist) (funcall init-for-commands #'(lambda (interpreter) `(add-to-list 'interpreter-mode-alist (quote ,interpreter))) - (plist-get args :interpreter))) + interpreter-alist)) `(progn ,@(mapcar From 818c78f4666edd3890fc0b58c50d06c422bafd82 Mon Sep 17 00:00:00 2001 From: Nicolas Dudebout Date: Wed, 25 Sep 2013 14:02:29 -0400 Subject: [PATCH 057/606] Removes `plist-get-sexp` This function was not working as advertised. Then `funcall` was evaluated too early and all the benefits of late evaluation for autoloads was lost. Furthermore, this function was not really needed in the first place: ``` (use-package foo :config my-foo-function) ``` can easily be replaced by the following: ``` (use-package foo :config (my-foo-function)) ``` --- lisp/use-package/use-package.el | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index ec2436e730b..68270657a9b 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -438,12 +438,6 @@ Return the list of recognized keywords." (error "Unrecognized keyword: %s" keyword)))) (plist-keys args))) -(defun plist-get-sexp (plist prop) - (let ((sexp-or-function (plist-get plist prop))) - (if (functionp sexp-or-function) - (funcall sexp-or-function) - sexp-or-function))) - (defun plist-get-value (plist prop) (let ((value-or-symbol (plist-get plist prop))) (if (symbolp value-or-symbol) @@ -476,12 +470,12 @@ For full documentation. please see commentary. :ensure loads package using package.el if necessary." (use-package-validate-keywords args) ; error if any bad keyword, ignore result (let* ((commands (plist-get args :commands)) - (pre-init-body (plist-get-sexp args :pre-init)) - (init-body (plist-get-sexp args :init)) - (config-body (plist-get-sexp args :config)) + (pre-init-body (plist-get args :pre-init)) + (init-body (plist-get args :init)) + (config-body (plist-get args :config)) (diminish-var (plist-get args :diminish)) (defines (plist-get args :defines)) - (idle-body (plist-get-sexp args :idle)) + (idle-body (plist-get args :idle)) (keybindings-alist (plist-get-value args :bind)) (mode-alist (plist-get-value args :mode)) (interpreter-alist (plist-get-value args :interpreter)) From dd20db220dd3273d595f98a3fb0c541d1d91f74d Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Wed, 25 Sep 2013 22:24:45 -0400 Subject: [PATCH 058/606] plist-get-value treats arg as backquoted This allows use of variables or even arbitrary expressions to construct use-package arguments: (use-package some-package :mode ,mode-spec :bind (,binding ,@more-bindings ,@(cl-loop for i from ?a to ?z collect `(,(string i) . nifty-function)))) --- lisp/use-package/use-package.el | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 68270657a9b..e1ba6e28c09 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -439,10 +439,8 @@ Return the list of recognized keywords." (plist-keys args))) (defun plist-get-value (plist prop) - (let ((value-or-symbol (plist-get plist prop))) - (if (symbolp value-or-symbol) - (symbol-value value-or-symbol) - value-or-symbol))) + "Return the value of PROP in PLIST as if it was backquoted." + (eval (list '\` (plist-get plist prop)))) (defmacro use-package (name &rest args) "Use a package with configuration options. From 8c1c572857bb314d44211c7b078ad7640da007ce Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Wed, 25 Sep 2013 22:29:59 -0400 Subject: [PATCH 059/606] use plist-get-value for all non-sexp args --- lisp/use-package/use-package.el | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index e1ba6e28c09..f20987a51f2 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -471,20 +471,20 @@ For full documentation. please see commentary. (pre-init-body (plist-get args :pre-init)) (init-body (plist-get args :init)) (config-body (plist-get args :config)) - (diminish-var (plist-get args :diminish)) - (defines (plist-get args :defines)) + (diminish-var (plist-get-value args :diminish)) + (defines (plist-get-value args :defines)) (idle-body (plist-get args :idle)) (keybindings-alist (plist-get-value args :bind)) (mode-alist (plist-get-value args :mode)) (interpreter-alist (plist-get-value args :interpreter)) (predicate (plist-get args :if)) - (pkg-load-path (plist-get args :load-path)) + (pkg-load-path (plist-get-value args :load-path)) (defines-eval (if (null defines) nil (if (listp defines) (mapcar (lambda (var) `(defvar ,var)) defines) `((defvar ,defines))))) - (requires (plist-get args :requires)) + (requires (plist-get-value args :requires)) (requires-test (if (null requires) t (if (listp requires) From 119a30f2ba833146fc6bdb0165ea773223580362 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Tue, 13 Aug 2013 23:37:23 -0400 Subject: [PATCH 060/606] cl not needed since flet was removed in 82903da --- lisp/use-package/use-package.el | 3 --- 1 file changed, 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 74ed4c36dab..ed63bd05620 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -298,9 +298,6 @@ (require 'bytecomp) (require 'diminish nil t) -(eval-when-compile - (require 'cl)) - (declare-function package-installed-p 'package) (declare-function el-get-read-recipe 'el-get) From 29abf59bad60ab9098231ddf2957ee8c9e68637a Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Wed, 14 Aug 2013 00:40:20 -0400 Subject: [PATCH 061/606] macroexpand not needed Since lambda thunking replaced quoting in a76d167. To see why, observe that cases 3 and 4 disassemble to identical code. The difference between cases 1 and 2 shows why the macroexpand was needed originally. (defmacro test-quote (name-string) `(eval-after-load "foo" `(with-elapsed-timer ,(format "Configuring package %s" name-string) (message "test-quote")))) (defmacro test-expand-quote (name-string) `(eval-after-load "foo" ,(macroexpand-all `(with-elapsed-timer ,(format "Configuring package %s" name-string) (message "test-expand-quote"))))) (defmacro test-lambda (name-string) `(eval-after-load "foo" `(,(lambda () (with-elapsed-timer ,(format "Configuring package %s" name-string) (message "test-lambda")))))) (defmacro test-expand-lambda (name-string) `(eval-after-load "foo" `(,(lambda () ,(macroexpand-all `(with-elapsed-timer ,(format "Configuring package %s" name-string) (message "test-lambda"))))))) (disassemble (lambda () (test-quote "testing..."))) (disassemble (lambda () (test-expand-quote "testing..."))) (disassemble (lambda () (test-lambda "testing..."))) (disassemble (lambda () (test-expand-lambda "testing..."))) --- lisp/use-package/use-package.el | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index ed63bd05620..eb3c7030108 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -653,10 +653,9 @@ For full documentation. please see commentary. `(eval-after-load ,(if (stringp name) name `',name) `(,(lambda () (if ,requires-test - ,(macroexpand-all - `(with-elapsed-timer - ,(format "Configuring package %s" name-string) - ,config-body))))))) + (with-elapsed-timer + ,(format "Configuring package %s" name-string) + ,config-body)))))) t)) `(if (and ,(or predicate t) ,requires-test) From 9921a76e86751c4e11ba099eb5aaf179742e82d0 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Wed, 14 Aug 2013 01:12:47 -0400 Subject: [PATCH 062/606] remove after-init-hook for override-global-mode The INIT-VALUE argument to define-minor-mode is t, so it's enabled by default. --- lisp/use-package/bind-key.el | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index c4b3f19deb4..2bae1bf0730 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -87,11 +87,6 @@ (add-to-list 'emulation-mode-map-alists `((override-global-mode . ,override-global-map))) -(add-hook 'after-init-hook - (function - (lambda () - (override-global-mode 1)))) - (defvar personal-keybindings nil) (defmacro bind-key (key-name command &optional keymap) From 61fd933807ff23be89289c23cbc54caa3bdb2426 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 31 Aug 2013 10:30:08 -0400 Subject: [PATCH 063/606] with-elapsed-timer: only check verbosity once --- lisp/use-package/use-package.el | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index eb3c7030108..33aa332fd16 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -321,18 +321,16 @@ :group 'use-package) (defmacro with-elapsed-timer (text &rest forms) - `(let ((now ,(if use-package-verbose - '(current-time)))) - ,(if use-package-verbose - `(message "%s..." ,text)) - (prog1 - ,@forms - ,(when use-package-verbose - `(let ((elapsed - (float-time (time-subtract (current-time) now)))) - (if (> elapsed ,use-package-minimum-reported-time) - (message "%s...done (%.3fs)" ,text elapsed) - (message "%s...done" ,text))))))) + (if use-package-verbose + `(let ((now (current-time))) + (message "%s..." ,text) + (prog1 ,@forms + (let ((elapsed + (float-time (time-subtract (current-time) now)))) + (if (> elapsed ,use-package-minimum-reported-time) + (message "%s...done (%.3fs)" ,text elapsed) + (message "%s...done" ,text))))) + `(prog1 ,@forms))) (put 'with-elapsed-timer 'lisp-indent-function 1) From 3d871c79947351459ab5f1b65a4f8ff81bcf570c Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 12 Oct 2013 13:52:57 -0400 Subject: [PATCH 064/606] make `with-elapsed-timer' hygienic --- lisp/use-package/use-package.el | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 33aa332fd16..9e5d2cbc945 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -322,14 +322,15 @@ (defmacro with-elapsed-timer (text &rest forms) (if use-package-verbose - `(let ((now (current-time))) - (message "%s..." ,text) - (prog1 ,@forms - (let ((elapsed - (float-time (time-subtract (current-time) now)))) - (if (> elapsed ,use-package-minimum-reported-time) - (message "%s...done (%.3fs)" ,text elapsed) - (message "%s...done" ,text))))) + (let ((nowvar (make-symbol "now"))) + `(let ((,nowvar (current-time))) + (message "%s..." ,text) + (prog1 ,@forms + (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)))))) `(prog1 ,@forms))) (put 'with-elapsed-timer 'lisp-indent-function 1) From 026c46c057f85335ffd70e84eaf38e8deaf1865a Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 12 Oct 2013 13:58:37 -0400 Subject: [PATCH 065/606] let with-elapsed-timer return last form --- lisp/use-package/use-package.el | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 9e5d2cbc945..f940816c2cc 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -321,17 +321,18 @@ :group 'use-package) (defmacro with-elapsed-timer (text &rest forms) - (if use-package-verbose - (let ((nowvar (make-symbol "now"))) - `(let ((,nowvar (current-time))) - (message "%s..." ,text) - (prog1 ,@forms - (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)))))) - `(prog1 ,@forms))) + (let ((body `(progn ,@forms))) + (if use-package-verbose + (let ((nowvar (make-symbol "now"))) + `(let ((,nowvar (current-time))) + (message "%s..." ,text) + (prog1 ,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 'with-elapsed-timer 'lisp-indent-function 1) From 94072fba77aa5181799e960271b9ac60f2605ec2 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Mon, 14 Oct 2013 12:59:41 -0400 Subject: [PATCH 066/606] remove extra comma (added by 026c46c) --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index f940816c2cc..736228742c8 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -332,7 +332,7 @@ (if (> elapsed ,use-package-minimum-reported-time) (message "%s...done (%.3fs)" ,text elapsed) (message "%s...done" ,text)))))) - ,body))) + body))) (put 'with-elapsed-timer 'lisp-indent-function 1) From a116fc2136f66281846653b974413147a9765260 Mon Sep 17 00:00:00 2001 From: Phil Hudson Date: Tue, 15 Oct 2013 17:53:58 +0100 Subject: [PATCH 067/606] Properly enable runtime dependency for :idle stanza (issue) See issue https://github.com/jwiegley/use-package/issues/60. GitHub-reference: https://github.com/jwiegley/use-package/issues/60 --- lisp/use-package/use-package.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 736228742c8..316e37ee330 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -542,6 +542,7 @@ For full documentation. please see commentary. (when idle-body (setq init-body `(progn + (require 'use-package) (use-package-init-on-idle (lambda () ,idle-body)) ,init-body))) From 36cf13ef477f7b70a0e9ae86534ec526bdef6a9e Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Sat, 26 Oct 2013 00:09:20 +0800 Subject: [PATCH 068/606] Add :pre-load to use-package-keywords The :pre-load keyword cannot be used unless it is in `use-package-keywords' list. --- lisp/use-package/use-package.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 316e37ee330..704b0815238 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -419,6 +419,7 @@ :load-path :mode :pre-init + :pre-load :requires ) "Keywords recognized by `use-package'.") From c7560f7be7ca62a17af74854fc5e9823b1638386 Mon Sep 17 00:00:00 2001 From: Philippe Vaucher Date: Tue, 5 Nov 2013 10:31:18 +0100 Subject: [PATCH 069/606] Remove el-get support --- lisp/use-package/use-package.el | 102 -------------------------------- 1 file changed, 102 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 704b0815238..a6f19056820 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -254,43 +254,6 @@ ;; ;; (use-package tex-site ;; :ensure auctex) -;; -;; * For el-get users -;; -;; You can use `use-package' as a way to create source definitions for el-get. -;; All that's needed is to add a `:type' keyword to your declaration. When -;; this is present, certain keywords get translated to what el-get expects in -;; the `el-get-sources' list: -;; -;; :config -> :after -;; :requires -> :depends -;; -;; A `:name' will be added also, if one is not provided explicitly, which will -;; be the same as the name of the package. -;; -;; But why would you want to use `use-package' when you have el-get? My -;; answer is that I'd like to use el-get to install and update some packages, -;; but I don't want it managing configuration. Just loading el-get -- without -;; call (el-get 'sync) -- takes a quarter second on my machine. That's 25% of -;; my load time! `use-package' is designed for performance, so I only want to -;; load el-get when it's time to install or update on of my used packages. -;; -;; Here is the `use-package' declaration I use for setting up el-get, but only -;; when I want to install or update: -;; -;; (defvar el-get-sources nil) -;; -;; (use-package el-get -;; :commands (el-get -;; el-get-install -;; el-get-update -;; el-get-list-packages) -;; :config -;; (defun el-get-read-status-file () -;; (mapcar #'(lambda (entry) -;; (cons (plist-get entry :symbol) -;; `(status "installed" recipe ,entry))) -;; el-get-sources))) ;;; Code: @@ -299,7 +262,6 @@ (require 'diminish nil t) (declare-function package-installed-p 'package) -(declare-function el-get-read-recipe 'el-get) (defgroup use-package nil "A use-package declaration for simplifying your `.emacs'." @@ -310,11 +272,6 @@ :type 'boolean :group 'use-package) -(defcustom use-package-debug nil - "Whether to report more information, mostly regarding el-get." - :type 'boolean - :group 'use-package) - (defcustom use-package-minimum-reported-time 0.01 "Minimal load time that will be reported" :type 'number @@ -336,28 +293,6 @@ (put 'with-elapsed-timer 'lisp-indent-function 1) -(defun use-package-discover-el-get-type (args) - (let* ((pkg-name (plist-get args :name)) - (git-config (expand-file-name - (concat pkg-name "/.git/config") - (if (boundp 'user-site-lisp-directory) - user-site-lisp-directory - user-emacs-directory)))) - - (catch 'found - ;; Look for a readable .git/config with at least one defined remote. - (if (file-readable-p git-config) - (with-temp-buffer - (insert-file-contents-literally git-config) - (while (re-search-forward "\\[remote" nil t) - (if (re-search-forward "url = \\(.+\\)" - (save-excursion - (re-search-forward "\\[remote" nil t) - (point)) t) - (nconc args (list :type 'git - :url (match-string 1)))))))) - args)) - (defvar use-package-idle-timer nil) (defvar use-package-idle-forms nil) @@ -603,43 +538,6 @@ For full documentation. please see commentary. `(load ,name t) `(require ',name nil t)))) - ,(when (boundp 'el-get-sources) - (require 'el-get) - - (let ((recipe (ignore-errors - (el-get-read-recipe name-symbol)))) - (if (null recipe) - (if use-package-debug - (message "No el-get recipe found for package `%s'" - name-symbol)) - (setq args - (mapcar #'(lambda (arg) - (cond - ((eq arg :config) - :after) - ((eq arg :requires) - :depends) - (t - arg))) - args)) - - (nconc args (list :symbol (intern name-string))) - - (let ((elem args)) - (while elem - (unless (plist-get recipe (car elem)) - (plist-put recipe (car elem) (cadr elem))) - (setq elem (cddr elem)))) - - (unless (plist-get recipe :name) - (nconc recipe (list :name name-string))) - - (unless (plist-get recipe :type) - (setq recipe (use-package-discover-el-get-type recipe))) - - (ignore - (setq el-get-sources (cons recipe el-get-sources)))))) - ,(if (or commands (plist-get args :defer)) (let (form) (mapc #'(lambda (command) From 90ca8adc4135f725ada799f29a0cb00c1cb94055 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 2 Dec 2013 03:06:27 -0700 Subject: [PATCH 070/606] Default use-package-verbose to nil --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index a6f19056820..f91be03b22b 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -267,7 +267,7 @@ "A use-package declaration for simplifying your `.emacs'." :group 'startup) -(defcustom use-package-verbose t +(defcustom use-package-verbose nil "Whether to report about loading and configuration details." :type 'boolean :group 'use-package) From f3e9e871a6c8f8db5f8ee327984a643f5161cdde Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 2 Dec 2013 10:44:28 -0800 Subject: [PATCH 071/606] Backward compatibility with emacs-22.1 This change supports the emacs that ships with MacOS X, the last version not encumbered by GPLv3. --- lisp/use-package/use-package.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index f91be03b22b..03bec74602a 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -261,7 +261,8 @@ (require 'bytecomp) (require 'diminish nil t) -(declare-function package-installed-p 'package) +(when fboundp 'declare-function + (declare-function package-installed-p 'package)) (defgroup use-package nil "A use-package declaration for simplifying your `.emacs'." From 9d395a4019719ed6708c9aa99748d005cd33d602 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 4 Dec 2013 13:31:25 -0600 Subject: [PATCH 072/606] fboundp is a function, not a variable Fixes https://github.com/jwiegley/use-package/issues/68 --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 03bec74602a..d2e065a3ffa 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -261,7 +261,7 @@ (require 'bytecomp) (require 'diminish nil t) -(when fboundp 'declare-function +(when (fboundp 'declare-function) (declare-function package-installed-p 'package)) (defgroup use-package nil From c3704ac36eb52b185bf54844541c134a7b74fb82 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 4 Dec 2013 19:44:09 -0600 Subject: [PATCH 073/606] Add a :demand directive, to override deferred loading () GitHub-reference: https://github.com/jwiegley/use-package/issues/65 --- lisp/use-package/use-package.el | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index d2e065a3ffa..f4d5e7b6f38 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -345,6 +345,7 @@ :config :defer :defines + :demand :diminish :disabled :ensure @@ -383,7 +384,7 @@ Return the list of recognized keywords." (eval (list '\` (plist-get plist prop)))) (defmacro use-package (name &rest args) -"Use a package with configuration options. + "Use a package with configuration options. For full documentation. please see commentary. @@ -401,6 +402,7 @@ For full documentation. please see commentary. :interpreter Form to be added to `interpreter-mode-alist'. :defer Defer loading of package -- automatic if :commands, :bind, :mode or :interpreter are used. +:demand Prevent deferred loading in all cases. :config Runs if and when package loads. :if Conditional loading. :disabled Ignore everything. @@ -465,7 +467,7 @@ For full documentation. please see commentary. `((diminish (quote ,diminish-var)))) ((and (consp diminish-var) (stringp (cdr diminish-var))) `((diminish (quote ,(car diminish-var)) ,(cdr diminish-var)))) - (t ; list of symbols or (symbol . "string") pairs + (t ; list of symbols or (symbol . "string") pairs (mapcar (lambda (var) (if (listp var) `(diminish (quote ,(car var)) ,(cdr var)) @@ -481,7 +483,7 @@ For full documentation. please see commentary. `(progn (require 'use-package) (use-package-init-on-idle (lambda () ,idle-body)) - ,init-body))) + ,init-body))) (let ((init-for-commands @@ -534,12 +536,13 @@ For full documentation. please see commentary. (eval-when-compile (when (bound-and-true-p byte-compile-current-file) - ,@defines-eval - ,(if (stringp name) - `(load ,name t) - `(require ',name nil t)))) + ,@defines-eval + ,(if (stringp name) + `(load ,name t) + `(require ',name nil t)))) - ,(if (or commands (plist-get args :defer)) + ,(if (and (or commands (plist-get args :defer)) + (not (plist-get args :demand))) (let (form) (mapc #'(lambda (command) (push `(autoload (function ,command) From d588d0b382ee3f084615f0c3fe7d58c772ebc06f Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Tue, 10 Dec 2013 00:33:02 +0100 Subject: [PATCH 074/606] use-package: use defun as lisp-indent-function When `use-package' is called with only one keyword it is useful to write: (use-package foo :init (progn ... long lines ...)) instead of (use-package foo :init (progn ... *too* long lines ...)) or (use-package foo :init (progn ... long lines ...)) Even when there are multiple keywords or when one never wants to format the calls to `use-package' as in the first example the use of `defun' does not really pose a problem. --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index f4d5e7b6f38..2d75c549b21 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -574,7 +574,7 @@ For full documentation. please see commentary. ,config-body t)))))))) -(put 'use-package 'lisp-indent-function 1) +(put 'use-package 'lisp-indent-function 'defun) (defconst use-package-font-lock-keywords '(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" From 75206228dd7800b9bf3b7878e08c188dcf723c32 Mon Sep 17 00:00:00 2001 From: Adam Spiers Date: Mon, 16 Dec 2013 12:16:56 +0000 Subject: [PATCH 075/606] allow :mode and :interpreter to accept a string Fixes https://github.com/jwiegley/use-package/issues/72. --- lisp/use-package/use-package.el | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 2d75c549b21..a9ba4e5353f 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -78,10 +78,16 @@ ;; ;; Similar to `:bind', you can use `:mode' and `:interpreter' to establish a ;; deferred binding within `auto-mode-alist' and `interpreter-mode-alist'. -;; The specifier to either keyword can be a single cons or a list: +;; The specifier to either keyword can be a single cons, or a list, or just +;; a string: ;; -;; (use-package python-mode -;; :mode ("\\.py$" . python-mode) +;; (use-package ruby-mode +;; :mode "\\.rb\\'" +;; :interpreter "ruby") +;; +;; ;; The package is "python" but the mode is "python-mode": +;; (use-package python +;; :mode ("\\.py\\'" . python-mode) ;; :interpreter ("python" . python-mode)) ;; ;; If you aren't using `:commands', `:bind', `:mode', or `:interpreter' (all @@ -421,8 +427,12 @@ For full documentation. please see commentary. (defines (plist-get-value args :defines)) (idle-body (plist-get args :idle)) (keybindings-alist (plist-get-value args :bind)) - (mode-alist (plist-get-value args :mode)) - (interpreter-alist (plist-get-value args :interpreter)) + (mode (plist-get-value args :mode)) + (mode-alist + (if (stringp mode) (cons mode name) mode)) + (interpreter (plist-get-value args :interpreter)) + (interpreter-alist + (if (stringp interpreter) (cons interpreter name) interpreter)) (predicate (plist-get args :if)) (pkg-load-path (plist-get-value args :load-path)) (defines-eval (if (null defines) From 984850be80d947144f0f0d4823636941e463d1d1 Mon Sep 17 00:00:00 2001 From: Adam Spiers Date: Sat, 4 Jan 2014 12:06:41 +0000 Subject: [PATCH 076/606] hyperlink functions in Comments column Previously, only the functions in the Command column were hyper-linked. Also clarify the meaning of the "was" entries in the Comments column. --- lisp/use-package/bind-key.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 2bae1bf0730..f5e07ba7831 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -205,8 +205,8 @@ (if (or (null was-command) (string= command-desc was-command-desc)) "" - (format "(%s)" was-command-desc)) - (format "[now: %s]" at-present))))) + (format "was `%s\'" was-command-desc)) + (format "[now: `%s\']" at-present))))) (setq last-binding binding))))) From 2dbee4cd751cabe6cddcb5cccdc833d58d109b21 Mon Sep 17 00:00:00 2001 From: Adam Spiers Date: Mon, 6 Jan 2014 12:38:00 +0000 Subject: [PATCH 077/606] fix DRY violation by only having documentation in one place The documentation in README.md was previously identical to that in the Commentary section of use-package.el, modulo the following differences: - No elisp comment ";; " prefix - Code blocks indented 4 columns not 2, as required by Markdown - Elisp symbols marked in backtick delimiters for monospace, not emacs backtick/forward tick pairs. Unfortunately due to this duplication, sometimes only one of the two files got updated, so they got out of sync. With us all being human, this is likely to continue to happen as long as the duplication exists ;-) Therefore since most users are likely to encounter README.md before the elisp, and bearing in mind that Markdown is a much more flexible format for documentation than elisp comments (richer formatting, can be exported to numerous other formats etc.), it is better to replace the docs in use-package.el with a pointer to the README.md. --- lisp/use-package/use-package.el | 228 +------------------------------- 1 file changed, 1 insertion(+), 227 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index a9ba4e5353f..df0d2310da9 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -33,233 +33,7 @@ ;; utility my total load time is just under 1 second, with no loss of ;; functionality! ;; -;; Here is the simplest `use-package' declaration: -;; -;; (use-package foo) -;; -;; This loads in the package foo, but only if foo is available on your system. -;; If not, a warning is logged to your `*Messages*' buffer. If it succeeds a -;; message about "Loading foo" is logged, along with the time it took to load, -;; if that time is over 0.01s. -;; -;; Use the :init keywoard to do some stuff to initialize foo, but only if foo -;; actually gets loaded: -;; -;; (use-package foo -;; :init -;; (progn -;; (setq foo-variable t) -;; (foo-mode 1))) -;; -;; A very common thing to do when loading a module is to bind a key to primary -;; commands within that module: -;; -;; (use-package ace-jump-mode -;; :bind ("C-." . ace-jump-mode)) -;; -;; This does two things: first, it creates autoload for the `ace-jump-mode' -;; command, and defers loading of `ace-jump-mode' until you actually use it. -;; Second, it binds the key `C-.' to that command. After loading, you can use -;; `M-x describe-personal-keybindings' to see all such bindings you've set -;; throughout your Emacs. -;; -;; A more literal way to do the exact same thing is: -;; -;; (use-package ace-jump-mode -;; :commands ace-jump-mode -;; :init -;; (bind-key "C-." 'ace-jump-mode)) -;; -;; When you use the `:commands' keyword, it creates autoloads for those -;; commands and defers loading of the module until they are used. In this -;; case, the `:init' form is always run -- even if ace-jump-mode might not be -;; on your system. So remember to keep `:init' activities to only those that -;; would succeed either way. -;; -;; Similar to `:bind', you can use `:mode' and `:interpreter' to establish a -;; deferred binding within `auto-mode-alist' and `interpreter-mode-alist'. -;; The specifier to either keyword can be a single cons, or a list, or just -;; a string: -;; -;; (use-package ruby-mode -;; :mode "\\.rb\\'" -;; :interpreter "ruby") -;; -;; ;; The package is "python" but the mode is "python-mode": -;; (use-package python -;; :mode ("\\.py\\'" . python-mode) -;; :interpreter ("python" . python-mode)) -;; -;; If you aren't using `:commands', `:bind', `:mode', or `:interpreter' (all -;; of which imply `:commands'), you can still defer loading with the `:defer' -;; keyword: -;; -;; (use-package ace-jump-mode -;; :defer t -;; :init -;; (progn -;; (autoload 'ace-jump-mode "ace-jump-mode" nil t) -;; (bind-key "C-." 'ace-jump-mode))) -;; -;; This does exactly the same thing as the other two commands above. -;; -;; A companion to the `:init' keyword is `:config'. Although `:init' always -;; happens in the case of deferred modules (which are likely to be the most -;; common kind), `:config' form only run after the module has been loaded by -;; Emacs: -;; -;; (use-package ace-jump-mode -;; :bind ("C-." . ace-jump-mode) -;; :config -;; (message "Yay, ace-jump-mode was actually loaded!")) -;; -;; You will see a "Configured..." message in your `*Messages*' log when a -;; package is configured, and a timing if the configuration time was longer -;; than 0.01s. You should keep `:init' forms as simple as possible, and put -;; as much as you can get away with on the `:config' side. -;; -;; You can have both `:init' and `:config': -;; -;; (use-package haskell-mode -;; :commands haskell-mode -;; :init -;; (add-to-list 'auto-mode-alist '("\\.l?hs$" . haskell-mode)) -;; :config -;; (progn -;; (use-package inf-haskell) -;; (use-package hs-lint))) -;; -;; In this case, I want to autoload the command `haskell-mode' from -;; "haskell-mode.el", add it to `auto-mode-alist' at the time ".emacs" is -;; loaded, but wait until after I've opened a Haskell file before loading -;; "inf-haskell.el" and "hs-lint.el". -;; -;; Another similar option to `:init' is `:idle'. Like `:init' this always run, -;; however, it does so when Emacs is idle at some time in the future after -;; load. This is particularly useful for convienience minor modes which can be -;; slow to load. For instance, in this case, I want Emacs to always use -;; `global-pabbrev-mode'. `:commands' creates an appropriate autoload; `:idle' -;; will run this command at some point in the future. If you start Emacs and -;; beginning typing straight-away, loading will happen eventually. -;; -;; (use-package pabbrev -;; :commands global-pabbrev-mode -;; :idle (global-pabbrev-mode)) -;; -;; Idle functions are run in the order in which they are evaluated. If you -;; have many, it may take sometime for all to run. `use-package' will always -;; tell you if there is an error in the form which can otherwise be difficult -;; to debug. It may tell you about functions being eval'd, depending on the -;; value of `use-package-verbose'. Other good candidates for `:idle' are -;; `yasnippet', `auto-complete' and `autopair'. -;; -;; Finally, you may wish to use `:pre-load'. This form runs before everything -;; else whenever the `use-package' form evals; the package in question will -;; never have been required. This can be useful, if you wish for instance, to -;; pull files from a git repository, or mount a file system. Like :init, -;; keeping this form as simple as possible makes sense. -;; -;; The `:bind' keyword takes either a cons or a list of conses: -;; -;; (use-package hi-lock -;; :bind (("M-o l" . highlight-lines-matching-regexp) -;; ("M-o r" . highlight-regexp) -;; ("M-o w" . highlight-phrase))) -;; -;; The `:commands' keyword likewise takes either a symbol or a list of -;; symbols. -;; -;; You can use the `:if' keyword to predicate the loading and initialization -;; of a module. For example, I only want an `edit-server' running for my -;; main, graphical Emacs, not for Emacsen I may start at the command line: -;; -;; (use-package edit-server -;; :if window-system -;; :init -;; (progn -;; (add-hook 'after-init-hook 'server-start t) -;; (add-hook 'after-init-hook 'edit-server-start t))) -;; -;; The `:disabled' keyword can be used to turn off a module that you're having -;; difficulties with, or to stop loading something you're not really using at -;; the present time: -;; -;; (use-package ess-site -;; :disabled t -;; :commands R) -;; -;; Another feature of `use-package' is that it always loads every file that it -;; can when your ".emacs" is being byte-compiled (if you do that, which I -;; recommend). This helps to silence spurious warnings about unknown -;; variables and functions. -;; -;; However, there are times when this is just not enough. For those times, -;; use the `:defines' keyword to introduce empty variable definitions solely -;; for the sake of the byte-compiler: -;; -;; (use-package texinfo -;; :defines texinfo-section-list -;; :commands texinfo-mode -;; :init -;; (add-to-list 'auto-mode-alist '("\\.texi$" . texinfo-mode))) -;; -;; If you need to silence a missing function warning, do it with an autoload -;; stub in your `:init' block: -;; -;; (use-package w3m -;; :commands (w3m-browse-url w3m-session-crash-recovery-remove) -;; :init -;; (eval-when-compile -;; (autoload 'w3m-search-escape-query-string "w3m-search"))) -;; -;; If your package needs a directory added to the `load-path' in order load, -;; use `:load-path'. It takes a string or a list of strings. If the path is -;; relative, it will be expanded within `user-emacs-directory': -;; -;; (use-package ess-site -;; :disabled t -;; :load-path "site-lisp/ess/lisp/" -;; :commands R) -;; -;; Lastly, `use-package' provides built-in support for the diminish utility, -;; if you have that installed. It's purpose is to remove strings from your -;; mode-line that would otherwise always be there and provide no useful -;; information. It is invoked with the `:diminish' keyword, which is passed -;; either the minor mode symbol, a cons of the symbol and a replacement string, -;; or just a replacement string in which case the minor mode symbol is guessed -;; to be the package name with "-mode" at the end: -;; -;; (use-package abbrev -;; :diminish abbrev-mode -;; :init -;; (if (file-exists-p abbrev-file-name) -;; (quietly-read-abbrev-file)) -;; -;; :config -;; (add-hook 'expand-load-hook -;; (lambda () -;; (add-hook 'expand-expand-hook 'indent-according-to-mode) -;; (add-hook 'expand-jump-hook 'indent-according-to-mode)))) -;; -;; If you noticed that this declaration has neither a `:bind', `:commands' or -;; `:defer' keyword: congratulations, you're an A student! What it means is -;; that both the `:init' and `:config' forms will be executed when ".emacs" is -;; loaded, with no delays until later. Is this useful? Not really. I just -;; happen to like separating my configuration into things that must happen at -;; startup time, and things that could potentioally wait until after the -;; actual load. In this case, everything could be put inside `:init' and -;; there would be no difference. -;; -;; * For package.el user -;; -;; You can use `use-package' to load packages from ELPA with package.el. This -;; is particularly useful if you share your .emacs between several machines; -;; the relevant packages will download automatically once placed in your -;; .emacs. The `:ensure' key will install the package automatically if it is -;; not already present. -;; -;; (use-package tex-site -;; :ensure auctex) +;; Please see README.md from the same repository for documentation. ;;; Code: From 8f7e878caf03abbf42a4b59dd31edf03a1bc5bb3 Mon Sep 17 00:00:00 2001 From: Adam Spiers Date: Wed, 18 Dec 2013 11:33:51 +0000 Subject: [PATCH 078/606] add 'use-package-' prefix to 'with-elapsed-timer' Fixes https://github.com/jwiegley/use-package/issues/35. --- lisp/use-package/use-package.el | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index df0d2310da9..1a99e1258c9 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -58,7 +58,7 @@ :type 'number :group 'use-package) -(defmacro with-elapsed-timer (text &rest forms) +(defmacro use-package-with-elapsed-timer (text &rest forms) (let ((body `(progn ,@forms))) (if use-package-verbose (let ((nowvar (make-symbol "now"))) @@ -72,7 +72,7 @@ (message "%s...done" ,text)))))) body))) -(put 'with-elapsed-timer 'lisp-indent-function 1) +(put 'use-package-with-elapsed-timer 'lisp-indent-function 1) (defvar use-package-idle-timer nil) (defvar use-package-idle-forms nil) @@ -341,13 +341,13 @@ For full documentation. please see commentary. `(eval-after-load ,(if (stringp name) name `',name) `(,(lambda () (if ,requires-test - (with-elapsed-timer + (use-package-with-elapsed-timer ,(format "Configuring package %s" name-string) ,config-body)))))) t)) `(if (and ,(or predicate t) ,requires-test) - (with-elapsed-timer + (use-package-with-elapsed-timer ,(format "Loading package %s" name-string) (if (not ,(if (stringp name) `(load ,name t) From 21cabfd334083628fc28641c0944540a97c11ada Mon Sep 17 00:00:00 2001 From: Adam Spiers Date: Wed, 18 Dec 2013 11:45:26 +0000 Subject: [PATCH 079/606] fix bind-key URL (fixes) Also makes a start on https://github.com/jwiegley/use-package/issues/32. GitHub-reference: https://github.com/jwiegley/use-package/issues/58 --- lisp/use-package/bind-key.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index f5e07ba7831..68146c05c2a 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -6,7 +6,7 @@ ;; Created: 16 Jun 2012 ;; Version: 1.0 ;; Keywords: keys keybinding config dotemacs -;; X-URL: https://github.com/jwiegley/bind-key +;; URL: https://github.com/jwiegley/use-package ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as From 58ca076647fad421f8173c2b5a93c5516314150e Mon Sep 17 00:00:00 2001 From: Adam Spiers Date: Wed, 5 Feb 2014 16:19:56 +0000 Subject: [PATCH 080/606] stop describe-personal-keybindings adding trailing space When emacs is configured to highlight trailing whitespace, the *Personal Keybindings* buffer looked pretty ugly. This fixes that. --- lisp/use-package/bind-key.el | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 68146c05c2a..36de06023dc 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -197,16 +197,19 @@ (get-binding-description was-command))) (at-present-desc (get-binding-description at-present)) ) - (princ - (format - "%-18s%-40s%s\n" - 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))))) + (let ((line + (format + "%-18s%-40s%s\n" + 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))))) From 2676ff5d959b30e0119bb7e72fa3f90144d62f38 Mon Sep 17 00:00:00 2001 From: Nicolas Richard Date: Mon, 10 Feb 2014 18:02:59 +0100 Subject: [PATCH 081/606] Allow multiple forms after keywords * use-package.el (use-package-mplist-get): (use-package-plist-get): (use-package-mplist-keys): new functions (plist-get-value): (use-package): use new functions (plist-keys): remove function The idea is to allow a modified kind of plist where keys are all keywords that appear in the list, and values are the intermediary elements. If a keyword is present but it's another keyword just after it (like (use-package :defer :config (setq foo 'bar))), its associated value will be t. If a keyword is not present, its value associated value will be nil. Otherwise the value will be the list of elements between the keyword and the next keyword. --- lisp/use-package/use-package.el | 117 ++++++++++++++++++++++++-------- 1 file changed, 89 insertions(+), 28 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 1a99e1258c9..89f8987e715 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -141,13 +141,74 @@ ) "Keywords recognized by `use-package'.") -(defun plist-keys (plist) - "Return a list containing all the keys in PLIST." - (when plist - (cons - (car plist) - (plist-keys - (cddr plist))))) +(defun use-package-mplist-get (plist prop) + "Get the values associated to PROP in PLIST, a modified plist. + +A modified plist is one where keys are keywords and values are +all non-keywords elements that follow it. + +As a special case : if the first occurrence of the keyword PROP +is followed by another keyword or is the last element in the +list, the function returns t. + +Currently this function infloops when the list is circular." + (let ((tail plist) + found + result) + (while (and + (consp tail) + (not + (eq prop (car tail)))) + (pop tail)) + (when (eq prop (pop tail)) + (setq found t)) + (while (and (consp tail) + (not (keywordp (car tail)))) + (push (pop tail) result)) + (or (nreverse result) found))) + +(ert-deftest use-package-mplist-get () + (let ((mplist '(:foo bar baz bal :blob plap plup :blam)) + (tests '((:foo . (bar baz bal)) + (:blob . (plap plup)) + (:blam . t) + (:blow . nil)))) + (mapc (lambda (test) + (should + (equal + (use-package-mplist-get mplist + (car test)) + (cdr test)))) + tests))) + +(defun use-package-plist-get (plist prop) + "Compatibility layer between classical and modified plists. + +If `use-package-mplist-get' returns exactly one value, that is +returned ; otherwise the list is returned wrapped in a `progn'." + (let ((values (use-package-mplist-get plist prop))) + (when values + (cond ((not (listp values)) + values) + ((eq 1 (length values)) + (car values)) + (t (cons 'progn values)))))) + +(defun use-package-mplist-keys (plist) + "Get the keys in PLIST, a modified plist. + +A modified plist is one where properties are keywords and values +are all non-keywords elements that follow it." + (let ((result)) + (mapc (lambda (elt) + (when (keywordp elt) + (push elt result))) + plist) + (nreverse result))) +(ert-deftest use-package-mplist-keys () + (should (equal (use-package-mplist-keys + '(:foo bar baz bal :blob plap plup :blam)) + '(:foo :blob :blam)))) (defun use-package-validate-keywords (args) "Error if any keyword given in ARGS is not recognized. @@ -157,11 +218,11 @@ Return the list of recognized keywords." (lambda (keyword) (unless (memq keyword use-package-keywords) (error "Unrecognized keyword: %s" keyword)))) - (plist-keys args))) + (use-package-mplist-keys args))) -(defun plist-get-value (plist prop) +(defun use-package-plist-get-value (plist prop) "Return the value of PROP in PLIST as if it was backquoted." - (eval (list '\` (plist-get plist prop)))) + (eval (list '\` (use-package-plist-get plist prop)))) (defmacro use-package (name &rest args) "Use a package with configuration options. @@ -192,29 +253,29 @@ For full documentation. please see commentary. :idle adds a form to run on an idle timer :ensure loads package using package.el if necessary." (use-package-validate-keywords args) ; error if any bad keyword, ignore result - (let* ((commands (plist-get args :commands)) - (pre-init-body (plist-get args :pre-init)) - (pre-load-body (plist-get args :pre-load)) - (init-body (plist-get args :init)) - (config-body (plist-get args :config)) - (diminish-var (plist-get-value args :diminish)) - (defines (plist-get-value args :defines)) - (idle-body (plist-get args :idle)) - (keybindings-alist (plist-get-value args :bind)) - (mode (plist-get-value args :mode)) + (let* ((commands (use-package-plist-get args :commands)) + (pre-init-body (use-package-plist-get args :pre-init)) + (pre-load-body (use-package-plist-get args :pre-load)) + (init-body (use-package-plist-get args :init)) + (config-body (use-package-plist-get args :config)) + (diminish-var (use-package-plist-get-value args :diminish)) + (defines (use-package-plist-get-value args :defines)) + (idle-body (use-package-plist-get args :idle)) + (keybindings-alist (use-package-plist-get-value args :bind)) + (mode (use-package-plist-get-value args :mode)) (mode-alist (if (stringp mode) (cons mode name) mode)) - (interpreter (plist-get-value args :interpreter)) + (interpreter (use-package-plist-get-value args :interpreter)) (interpreter-alist (if (stringp interpreter) (cons interpreter name) interpreter)) - (predicate (plist-get args :if)) - (pkg-load-path (plist-get-value args :load-path)) + (predicate (use-package-plist-get args :if)) + (pkg-load-path (use-package-plist-get-value args :load-path)) (defines-eval (if (null defines) nil (if (listp defines) (mapcar (lambda (var) `(defvar ,var)) defines) `((defvar ,defines))))) - (requires (plist-get-value args :requires)) + (requires (use-package-plist-get-value args :requires)) (requires-test (if (null requires) t (if (listp requires) @@ -225,9 +286,9 @@ For full documentation. please see commentary. (name-symbol (if (stringp name) (intern name) name))) ;; force this immediately -- one off cost - (unless (plist-get args :disabled) + (unless (use-package-plist-get args :disabled) - (let* ((ensure (plist-get args :ensure)) + (let* ((ensure (use-package-plist-get args :ensure)) (package-name (or (and (eq ensure t) name) @@ -325,8 +386,8 @@ For full documentation. please see commentary. `(load ,name t) `(require ',name nil t)))) - ,(if (and (or commands (plist-get args :defer)) - (not (plist-get args :demand))) + ,(if (and (or commands (use-package-plist-get args :defer)) + (not (use-package-plist-get args :demand))) (let (form) (mapc #'(lambda (command) (push `(autoload (function ,command) From dd937c4e3637dbd80451b17267bdb4954e7470dc Mon Sep 17 00:00:00 2001 From: Nicolas Richard Date: Wed, 12 Feb 2014 22:30:12 +0100 Subject: [PATCH 082/606] Move tests to separate file --- lisp/use-package/use-package.el | 18 -------- test/lisp/use-package/use-package-tests.el | 50 ++++++++++++++++++++++ 2 files changed, 50 insertions(+), 18 deletions(-) create mode 100644 test/lisp/use-package/use-package-tests.el diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 89f8987e715..45d361a4dd8 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -167,20 +167,6 @@ Currently this function infloops when the list is circular." (push (pop tail) result)) (or (nreverse result) found))) -(ert-deftest use-package-mplist-get () - (let ((mplist '(:foo bar baz bal :blob plap plup :blam)) - (tests '((:foo . (bar baz bal)) - (:blob . (plap plup)) - (:blam . t) - (:blow . nil)))) - (mapc (lambda (test) - (should - (equal - (use-package-mplist-get mplist - (car test)) - (cdr test)))) - tests))) - (defun use-package-plist-get (plist prop) "Compatibility layer between classical and modified plists. @@ -205,10 +191,6 @@ are all non-keywords elements that follow it." (push elt result))) plist) (nreverse result))) -(ert-deftest use-package-mplist-keys () - (should (equal (use-package-mplist-keys - '(:foo bar baz bal :blob plap plup :blam)) - '(:foo :blob :blam)))) (defun use-package-validate-keywords (args) "Error if any keyword given in ARGS is not recognized. diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el new file mode 100644 index 00000000000..869b818e54b --- /dev/null +++ b/test/lisp/use-package/use-package-tests.el @@ -0,0 +1,50 @@ +;;; use-package-tests.el --- Tests for use-package.el + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or (at +;; your option) any later version. + +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; + + +;;; Code: + +(require 'ert) +(require 'use-package) + +(ert-deftest use-package-mplist-get () + (let ((mplist '(:foo bar baz bal :blob plap plup :blam)) + (tests '((:foo . (bar baz bal)) + (:blob . (plap plup)) + (:blam . t) + (:blow . nil)))) + (mapc (lambda (test) + (should + (equal + (use-package-mplist-get mplist + (car test)) + (cdr test)))) + tests))) + +(ert-deftest use-package-mplist-keys () + (should (equal (use-package-mplist-keys + '(:foo bar baz bal :blob plap plup :blam)) + '(:foo :blob :blam)))) + +;; Local Variables: +;; indent-tabs-mode: nil +;; End: +;;; use-package-tests.el ends here From 7d0779114ed82fa893260910edd67c26624fa91a Mon Sep 17 00:00:00 2001 From: Matus Goljer Date: Thu, 13 Feb 2014 12:55:17 +0100 Subject: [PATCH 083/606] Add `bind-keys` macro --- lisp/use-package/bind-key.el | 61 ++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 36de06023dc..c15a4321ef9 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -51,6 +51,28 @@ ;; ;; (unbind-key "C-c x" some-other-mode-map) ;; +;; To bind multiple keys at once, or set up a prefix map, a +;; `bind-keys' macro is provided. It accepts keyword arguments, see +;; its documentation for detailed description. +;; +;; To add keys into a specific map, use :map argument +;; +;; (bind-keys :map dired-mode-map +;; ("o" . dired-omit-mode) +;; ("a" . some-custom-dired-function)) +;; +;; To set up a prefix map, use :prefix-map and :prefix +;; arguments (both are required) +;; +;; (bind-keys :prefix-map my-customize-prefix-map +;; :prefix "C-c c" +;; ("f" . customize-face) +;; ("v" . customize-variable)) +;; +;; You can combine all the keywords together. +;; Additionally, :prefix-docstring can be specified to set +;; documentation of created :prefix-map variable. +;; ;; After Emacs loads, you can see a summary of all your personal keybindings ;; currently in effect with this command: ;; @@ -118,6 +140,45 @@ (bind-key ,key-name ,command) (define-key override-global-map ,(read-kbd-macro key-name) ,command))) +(defmacro bind-keys (&rest args) + "Bind multiple keys at once. + +Accepts keyword arguments: +:map - a keymap into which the keybindings should be added +:prefix-map - name of the prefix map that should be created for + these bindings +:prefix - prefix key for these bindings +:prefix-docstring - docstring for the prefix-map variable + +The rest of the arguments are conses of keybinding string and a +function symbol (unquoted)." + (let ((map (plist-get args :map)) + (doc (plist-get args :prefix-docstring)) + (prefix-map (plist-get args :prefix-map)) + (prefix (plist-get args :prefix)) + (key-bindings (progn + (while (keywordp (car args)) + (pop args) + (pop args)) + args))) + (when (or (and prefix-map + (not prefix)) + (and prefix + (not prefix-map))) + (error "Both :prefix-map and :prefix must be supplied")) + `(progn + ,@(when prefix-map + `((defvar ,prefix-map) + ,@(when doc `((put ',prefix-map'variable-documentation ,doc))) + (define-prefix-command ',prefix-map) + (bind-key ,prefix ',prefix-map ,@(when map (list map))))) + ,@(mapcar (lambda (form) `(bind-key ,(if prefix + (concat prefix " " (car form)) + (car form)) + ',(cdr form) + ,@(when map (list map)))) + key-bindings)))) + (defun get-binding-description (elem) (cond ((listp elem) From f90d65e1492a67433270402551608b46b75fca32 Mon Sep 17 00:00:00 2001 From: Matus Goljer Date: Tue, 18 Feb 2014 13:40:25 +0100 Subject: [PATCH 084/606] Add better descriptions for lambdas, closures, keymaps --- lisp/use-package/bind-key.el | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index c15a4321ef9..a6bba121fe7 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -95,6 +95,11 @@ :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) @@ -184,15 +189,25 @@ function symbol (unquoted)." ((listp elem) (cond ((eq 'lambda (car elem)) - "#") + (if (and bind-key-describe-special-forms + (stringp (nth 2 elem))) + (nth 2 elem) + "#")) ((eq 'closure (car elem)) - "#") + (if (and bind-key-describe-special-forms + (stringp (nth 3 elem))) + (nth 3 elem) + "#")) ((eq 'keymap (car elem)) "#") (t elem))) ((keymapp elem) - "#") + (if (and bind-key-describe-special-forms + (symbolp elem) + (get elem 'variable-documentation)) + (format "%s" (get elem 'variable-documentation)) + "#")) ((symbolp elem) elem) (t From 38d4d2e2dac995a086af5060f42ba823aab7c039 Mon Sep 17 00:00:00 2001 From: Matus Goljer Date: Tue, 18 Feb 2014 13:52:25 +0100 Subject: [PATCH 085/606] Add variable column width --- lisp/use-package/bind-key.el | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index c15a4321ef9..bf80140344f 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -88,6 +88,11 @@ "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 @@ -229,9 +234,11 @@ function symbol (unquoted)." "Display all the personal keybindings defined by `bind-key'." (interactive) (with-output-to-temp-buffer "*Personal Keybindings*" - (princ "Key name Command Comments ------------------ --------------------------------------- --------------------- -") + (princ (format "Key name%s Command%s Comments\n%s %s ---------------------\n" + (make-string (- (car bind-key-column-widths) 9) ? ) + (make-string (- (cdr bind-key-column-widths) 8) ? ) + (make-string (1- (car bind-key-column-widths)) ?-) + (make-string (1- (cdr bind-key-column-widths)) ?-))) (let (last-binding) (dolist (binding (setq personal-keybindings @@ -242,7 +249,7 @@ function symbol (unquoted)." (if (not (eq (cdar last-binding) (cdar binding))) (princ (format "\n\n%s\n%s\n\n" (cdar binding) - (make-string 79 ?-))) + (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"))) @@ -260,7 +267,7 @@ function symbol (unquoted)." ) (let ((line (format - "%-18s%-40s%s\n" + (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) From f0776c2aeb3f7f0af66597e10a3e4469ca26629d Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 1 Mar 2014 20:16:59 -0500 Subject: [PATCH 086/606] let bind-key accept vectors, add docstring --- lisp/use-package/bind-key.el | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 1081486b99f..5ef7570cdef 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -122,12 +122,19 @@ (defvar personal-keybindings nil) (defmacro bind-key (key-name command &optional keymap) + "Bind KEY-NAME to COMMAND in KEYMAP (`global-map' if not passed). + +KEY-NAME may be a vector, in which case it passed straight to +`define-key'. Or it may be a string to be interpreted as +spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of +`edmacro-mode' for details." (let ((namevar (make-symbol "name")) (keyvar (make-symbol "key")) (bindingvar (make-symbol "binding")) (entryvar (make-symbol "entry"))) `(let* ((,namevar ,(eval key-name)) - (,keyvar (read-kbd-macro ,namevar)) + (,keyvar (if (vectorp ,namevar) ,namevar + (read-kbd-macro ,namevar))) (,bindingvar (lookup-key (or ,keymap global-map) ,keyvar))) (let ((,entryvar (assoc (cons ,namevar (quote ,keymap)) From ea3a475d0be35a26429f8f7adf06ebabc8179586 Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Sun, 9 Mar 2014 18:50:01 +0100 Subject: [PATCH 087/606] use-package-with-elapsed-timer: respect option at runtime Previously the option `use-package-verbose' was consulted at macro expansion time, and as a result customizing the option did nothing, without also recompiling `use-package.el'. --- lisp/use-package/use-package.el | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 45d361a4dd8..473eefb5090 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -58,19 +58,18 @@ :type 'number :group 'use-package) -(defmacro use-package-with-elapsed-timer (text &rest forms) - (let ((body `(progn ,@forms))) - (if use-package-verbose - (let ((nowvar (make-symbol "now"))) - `(let ((,nowvar (current-time))) - (message "%s..." ,text) - (prog1 ,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))) +(defmacro use-package-with-elapsed-timer (text &rest body) + (let ((nowvar (make-symbol "now"))) + `(if use-package-verbose + (let ((,nowvar (current-time))) + (message "%s..." ,text) + (prog1 (progn ,@body) + (let ((elapsed + (float-time (time-subtract (current-time) ,nowvar)))) + (if (> elapsed ,use-package-minimum-reported-time) + (message "%s...done (%.3fs)" ,text elapsed) + (message "%s...done" ,text))))) + ,@body))) (put 'use-package-with-elapsed-timer 'lisp-indent-function 1) From 2d7ecd867a233e070bfcd377445060a2a0ced572 Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Sun, 9 Mar 2014 18:55:54 +0100 Subject: [PATCH 088/606] use-package-with-elapsed-timer: add declare indent rule --- lisp/use-package/use-package.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 473eefb5090..6e97e9346f4 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -59,6 +59,7 @@ :group 'use-package) (defmacro use-package-with-elapsed-timer (text &rest body) + (declare (indent 1)) (let ((nowvar (make-symbol "now"))) `(if use-package-verbose (let ((,nowvar (current-time))) From f32d24350c4c842e9f9b6a399167c4ce744f9a86 Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Sun, 9 Mar 2014 18:59:06 +0100 Subject: [PATCH 089/606] use-package-font-lock-keywords: add use-package-with-elapsed-timer --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 6e97e9346f4..2523921a1f4 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -404,7 +404,7 @@ For full documentation. please see commentary. (put 'use-package 'lisp-indent-function 'defun) (defconst use-package-font-lock-keywords - '(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" + '(("(\\(use-package\\(?:-with-elapsed-timer\\)?\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" (1 font-lock-keyword-face) (2 font-lock-constant-face nil t)))) From 6b30c15823d34e90e9d88aa945780c76db39323e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20F=C3=A9votte?= Date: Mon, 17 Mar 2014 09:56:10 +0100 Subject: [PATCH 090/606] :idle-priority keyword to change the running order of idle functions Lower-priority idle functions are run first. Idle functions with no specified priority default to 5 and all functions with the same priority are run in the order in which they are evaluated, meaning the behaviour is backwards compatible. Updated documentation as well. --- lisp/use-package/use-package.el | 45 +++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 2523921a1f4..a4973fbf627 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -75,7 +75,7 @@ (put 'use-package-with-elapsed-timer 'lisp-indent-function 1) (defvar use-package-idle-timer nil) -(defvar use-package-idle-forms nil) +(defvar use-package-idle-forms (make-hash-table)) (defun use-package-start-idle-timer () "Ensure that the idle timer is running." @@ -85,17 +85,38 @@ 3 t 'use-package-idle-eval)))) -(defun use-package-init-on-idle (form) +(defun use-package-init-on-idle (form priority) "Add a new form to the idle queue." (use-package-start-idle-timer) - (if use-package-idle-forms - (add-to-list 'use-package-idle-forms - form t) - (setq use-package-idle-forms (list form)))) + (puthash priority + (append (gethash priority use-package-idle-forms) + (list form)) + use-package-idle-forms)) + +(defun use-package-idle-priorities () + "Get a list of all priorities in the idle queue. +The list is sorted in the order forms should be run." + (let ((priorities nil)) + (maphash (lambda (priority forms) + (setq priorities (cons priority priorities))) + use-package-idle-forms) + (sort priorities '<))) + +(defun use-package-idle-pop () + "Pop the top-priority task from the idle queue. +Return nil when the queue is empty." + (let* ((priority (car (use-package-idle-priorities))) + (forms (gethash priority use-package-idle-forms)) + (first-form (car forms)) + (forms-remaining (cdr forms))) + (if forms-remaining + (puthash priority forms-remaining use-package-idle-forms) + (remhash priority use-package-idle-forms)) + first-form)) (defun use-package-idle-eval() "Start to eval idle-commands from the idle queue." - (let ((next (pop use-package-idle-forms))) + (let ((next (use-package-idle-pop))) (if next (progn (when use-package-verbose @@ -130,6 +151,7 @@ :disabled :ensure :idle + :idle-priority :if :init :interpreter @@ -233,6 +255,10 @@ For full documentation. please see commentary. :load-path Add to `load-path' before loading. :diminish Support for diminish package (if it's installed). :idle adds a form to run on an idle timer +:idle-priority schedules the :idle form to run with the given + priority (lower priorities run first). Default priority + is 5; forms with the same priority are run in the order in + which they are evaluated. :ensure loads package using package.el if necessary." (use-package-validate-keywords args) ; error if any bad keyword, ignore result (let* ((commands (use-package-plist-get args :commands)) @@ -243,6 +269,7 @@ For full documentation. please see commentary. (diminish-var (use-package-plist-get-value args :diminish)) (defines (use-package-plist-get-value args :defines)) (idle-body (use-package-plist-get args :idle)) + (idle-priority (use-package-plist-get args :idle-priority)) (keybindings-alist (use-package-plist-get-value args :bind)) (mode (use-package-plist-get-value args :mode)) (mode-alist @@ -306,10 +333,12 @@ For full documentation. please see commentary. (when idle-body + (when (null idle-priority) + (setq idle-priority 5)) (setq init-body `(progn (require 'use-package) - (use-package-init-on-idle (lambda () ,idle-body)) + (use-package-init-on-idle (lambda () ,idle-body) ,idle-priority) ,init-body))) From 0ab0d77691873d25f478c1b6ed5070ee76aeb67d Mon Sep 17 00:00:00 2001 From: Nicolas Richard Date: Sun, 16 Feb 2014 11:59:59 +0100 Subject: [PATCH 091/606] Add new option use-package-idle-interval * use-package.el (use-package-idle-interval): new defcustom (use-package-start-idle-timer): use it (use-package-idle-eval): use it * README.md: document it This addresses bug https://github.com/jwiegley/use-package/issues/77 --- lisp/use-package/use-package.el | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index a4973fbf627..36e7e0b757e 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -58,6 +58,11 @@ :type 'number :group 'use-package) +(defcustom use-package-idle-interval 3 + "Time to wait when using :idle in a `use-package' specification." + :type 'number + :group 'use-package) + (defmacro use-package-with-elapsed-timer (text &rest body) (declare (indent 1)) (let ((nowvar (make-symbol "now"))) @@ -82,7 +87,7 @@ (unless use-package-idle-timer (setq use-package-idle-timer (run-with-idle-timer - 3 t + use-package-idle-interval t 'use-package-idle-eval)))) (defun use-package-init-on-idle (form priority) @@ -129,7 +134,7 @@ Return nil when the queue is empty." "Failure on use-package idle. Form: %s, Error: %s" next e))) ;; recurse after a bit - (when (sit-for 3) + (when (sit-for use-package-idle-interval) (use-package-idle-eval))) ;; finished (so far!) (cancel-timer use-package-idle-timer) From 053a1514a1ec1690b4a5e4c07618fc8c4b083359 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sun, 13 Apr 2014 23:59:36 -0400 Subject: [PATCH 092/606] fix typo Actually the reader accepts (list 'a'b) = (list 'a 'b); it still looks wrong. --- lisp/use-package/bind-key.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 5ef7570cdef..bb4bf13f518 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -186,7 +186,7 @@ function symbol (unquoted)." `(progn ,@(when prefix-map `((defvar ,prefix-map) - ,@(when doc `((put ',prefix-map'variable-documentation ,doc))) + ,@(when doc `((put ',prefix-map 'variable-documentation ,doc))) (define-prefix-command ',prefix-map) (bind-key ,prefix ',prefix-map ,@(when map (list map))))) ,@(mapcar (lambda (form) `(bind-key ,(if prefix From 869ff53ab906e818d92656f315ad2113118ea49e Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Mon, 14 Apr 2014 00:01:28 -0400 Subject: [PATCH 093/606] bind-keys: ,@(when map (list map)) => map Omitting map is same as passing nil. --- lisp/use-package/bind-key.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index bb4bf13f518..bd8aa626cba 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -188,12 +188,12 @@ function symbol (unquoted)." `((defvar ,prefix-map) ,@(when doc `((put ',prefix-map 'variable-documentation ,doc))) (define-prefix-command ',prefix-map) - (bind-key ,prefix ',prefix-map ,@(when map (list map))))) + (bind-key ,prefix ',prefix-map ,map))) ,@(mapcar (lambda (form) `(bind-key ,(if prefix (concat prefix " " (car form)) (car form)) ',(cdr form) - ,@(when map (list map)))) + ,map)) key-bindings)))) (defun get-binding-description (elem) From 01196c81ac8aa530781d2d0f30e41621b2c7a3f2 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sun, 13 Apr 2014 23:55:06 -0400 Subject: [PATCH 094/606] bind-keys: bind directly to prefix-map instead of constructing equivalent key sequence by string concatenation. This allows specifying vector key sequences, as in bind-key (since f0776c2aeb3f7f0af66597e10a3e4469ca26629d). --- lisp/use-package/bind-key.el | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index bd8aa626cba..d2a21f3986b 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -189,11 +189,9 @@ function symbol (unquoted)." ,@(when doc `((put ',prefix-map 'variable-documentation ,doc))) (define-prefix-command ',prefix-map) (bind-key ,prefix ',prefix-map ,map))) - ,@(mapcar (lambda (form) `(bind-key ,(if prefix - (concat prefix " " (car form)) - (car form)) - ',(cdr form) - ,map)) + ,@(mapcar (lambda (form) + `(bind-key ,(car form) ',(cdr form) + ,(or prefix-map map))) key-bindings)))) (defun get-binding-description (elem) From 9ca3690b59d0923188b168c3e6901790c7021a11 Mon Sep 17 00:00:00 2001 From: Nicolas Richard Date: Mon, 14 Apr 2014 19:56:54 +0200 Subject: [PATCH 095/606] * bind-key.el (bind-key): don't eval key-name at macro expansion time --- lisp/use-package/bind-key.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index d2a21f3986b..2ddbae2f082 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -132,7 +132,7 @@ spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of (keyvar (make-symbol "key")) (bindingvar (make-symbol "binding")) (entryvar (make-symbol "entry"))) - `(let* ((,namevar ,(eval key-name)) + `(let* ((,namevar ,key-name) (,keyvar (if (vectorp ,namevar) ,namevar (read-kbd-macro ,namevar))) (,bindingvar (lookup-key (or ,keymap global-map) From 4e80d29dafe11999b97de88fd1c3f5870aee6668 Mon Sep 17 00:00:00 2001 From: Nicolas Richard Date: Thu, 6 Mar 2014 10:46:33 +0100 Subject: [PATCH 096/606] Eval backquote earlier and support non-`progn' lists * use-package.el (use-package-plist-get): add optional args: `eval-backquote' and `no-progn' to control how arguments are retrieved. (use-package-plist-get-value): remove this function (use-package): replace calls to old function to modified function. Fixes issue https://github.com/jwiegley/use-package/issues/94. Rationale : - use-package-plist-get-value was just another layer for no good reason, and IMO its name was totally unclear. - we now eval-as-backquote earlier, allowing constructs like: (let ((my-list-of-commands-in-foo '(foo1 foo2))) (use-package foo :commands ,@my-list-of-commands-in-foo)) --- lisp/use-package/use-package.el | 34 ++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 36e7e0b757e..0012d26597d 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -194,18 +194,26 @@ Currently this function infloops when the list is circular." (push (pop tail) result)) (or (nreverse result) found))) -(defun use-package-plist-get (plist prop) +(defun use-package-plist-get (plist prop &optional eval-backquote no-progn) "Compatibility layer between classical and modified plists. If `use-package-mplist-get' returns exactly one value, that is -returned ; otherwise the list is returned wrapped in a `progn'." +returned ; otherwise the list is returned wrapped in a `progn' +unless NO-PROGN is non-nil. + +When EVAL-BACKQUOTE is non-nil, the value is first evaluated as +if it were backquoted." (let ((values (use-package-mplist-get plist prop))) + (when eval-backquote + (setq values (eval (list 'backquote values)))) (when values (cond ((not (listp values)) values) ((eq 1 (length values)) (car values)) - (t (cons 'progn values)))))) + (t (if no-progn + values + (cons 'progn values))))))) (defun use-package-mplist-keys (plist) "Get the keys in PLIST, a modified plist. @@ -229,10 +237,6 @@ Return the list of recognized keywords." (error "Unrecognized keyword: %s" keyword)))) (use-package-mplist-keys args))) -(defun use-package-plist-get-value (plist prop) - "Return the value of PROP in PLIST as if it was backquoted." - (eval (list '\` (use-package-plist-get plist prop)))) - (defmacro use-package (name &rest args) "Use a package with configuration options. @@ -266,30 +270,30 @@ For full documentation. please see commentary. which they are evaluated. :ensure loads package using package.el if necessary." (use-package-validate-keywords args) ; error if any bad keyword, ignore result - (let* ((commands (use-package-plist-get args :commands)) + (let* ((commands (use-package-plist-get args :commands t t)) (pre-init-body (use-package-plist-get args :pre-init)) (pre-load-body (use-package-plist-get args :pre-load)) (init-body (use-package-plist-get args :init)) (config-body (use-package-plist-get args :config)) - (diminish-var (use-package-plist-get-value args :diminish)) - (defines (use-package-plist-get-value args :defines)) + (diminish-var (use-package-plist-get args :diminish t)) + (defines (use-package-plist-get args :defines t t)) (idle-body (use-package-plist-get args :idle)) (idle-priority (use-package-plist-get args :idle-priority)) - (keybindings-alist (use-package-plist-get-value args :bind)) - (mode (use-package-plist-get-value args :mode)) + (keybindings-alist (use-package-plist-get args :bind t t)) + (mode (use-package-plist-get args :mode t t)) (mode-alist (if (stringp mode) (cons mode name) mode)) - (interpreter (use-package-plist-get-value args :interpreter)) + (interpreter (use-package-plist-get args :interpreter t t)) (interpreter-alist (if (stringp interpreter) (cons interpreter name) interpreter)) (predicate (use-package-plist-get args :if)) - (pkg-load-path (use-package-plist-get-value args :load-path)) + (pkg-load-path (use-package-plist-get args :load-path t t)) (defines-eval (if (null defines) nil (if (listp defines) (mapcar (lambda (var) `(defvar ,var)) defines) `((defvar ,defines))))) - (requires (use-package-plist-get-value args :requires)) + (requires (use-package-plist-get args :requires t)) (requires-test (if (null requires) t (if (listp requires) From 6d02a320f6e6274a27d4cdd721a92d65ff6c3226 Mon Sep 17 00:00:00 2001 From: Alex Kosorukoff Date: Tue, 6 May 2014 19:29:48 -0700 Subject: [PATCH 097/606] if package can't be located, treat it the same way as disabled There will be a message "Unable to locate " in the log. --- lisp/use-package/use-package.el | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 36e7e0b757e..4f5c545d0a1 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -300,7 +300,16 @@ For full documentation. please see commentary. (name-symbol (if (stringp name) (intern name) name))) ;; force this immediately -- one off cost - (unless (use-package-plist-get args :disabled) + (unless + (or (use-package-plist-get args :disabled) + (if (locate-library + name-string nil + (mapcar + (lambda (path) (expand-file-name path user-emacs-directory)) + (cond ((stringp pkg-load-path) (list pkg-load-path)) + ((functionp pkg-load-path) (funcall pkg-load-path)) + (t pkg-load-path)))) nil + (message "Unable to locate %s" name-string))) (let* ((ensure (use-package-plist-get args :ensure)) (package-name From a4939e7ef349e0faa0a0ec45e50a5d0821c96c07 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 8 May 2014 13:25:39 -0500 Subject: [PATCH 098/606] Revert "Merge pull request from alexko/master" This reverts commit 8c04377608bd9b27d6fc6c37990984185563a907, reversing changes made to a9ba368fa79e4c15b624de73e30c87c98475d466. GitHub-reference: https://github.com/jwiegley/use-package/issues/104 --- lisp/use-package/use-package.el | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 51c4dfaae20..0012d26597d 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -304,16 +304,7 @@ For full documentation. please see commentary. (name-symbol (if (stringp name) (intern name) name))) ;; force this immediately -- one off cost - (unless - (or (use-package-plist-get args :disabled) - (if (locate-library - name-string nil - (mapcar - (lambda (path) (expand-file-name path user-emacs-directory)) - (cond ((stringp pkg-load-path) (list pkg-load-path)) - ((functionp pkg-load-path) (funcall pkg-load-path)) - (t pkg-load-path)))) nil - (message "Unable to locate %s" name-string))) + (unless (use-package-plist-get args :disabled) (let* ((ensure (use-package-plist-get args :ensure)) (package-name From 1c82b2377ffb2e05e60c6b3232c2555d1f66355c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Fr=C3=B6ssman?= Date: Sat, 17 May 2014 10:28:41 +0200 Subject: [PATCH 099/606] Don't abort compiling if package loading fails --- lisp/use-package/use-package.el | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 0012d26597d..7b370380d4b 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -402,9 +402,10 @@ For full documentation. please see commentary. (eval-when-compile (when (bound-and-true-p byte-compile-current-file) ,@defines-eval - ,(if (stringp name) - `(load ,name t) - `(require ',name nil t)))) + (with-demoted-errors + ,(if (stringp name) + `(load ,name t) + `(require ',name nil t))))) ,(if (and (or commands (use-package-plist-get args :defer)) (not (use-package-plist-get args :demand))) From c4ebcaa953ebfcf2445086d5f879f01ef03cc32e Mon Sep 17 00:00:00 2001 From: Alex Kost Date: Sun, 25 May 2014 13:04:00 +0400 Subject: [PATCH 100/606] Add bind-keys* macro --- lisp/use-package/bind-key.el | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 2ddbae2f082..0e75fd567ec 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -73,6 +73,14 @@ ;; 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: ;; @@ -194,6 +202,10 @@ function symbol (unquoted)." ,(or prefix-map map))) key-bindings)))) +(defmacro bind-keys* (&rest args) + `(bind-keys :map override-global-map + ,@args)) + (defun get-binding-description (elem) (cond ((listp elem) From 91b439c8e7439466ebb26bbcf3e335ae29ef47f4 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 31 May 2014 15:03:17 -0400 Subject: [PATCH 101/606] personal-keybindings: add docstring fix typo in bind-key docstring --- lisp/use-package/bind-key.el | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 0e75fd567ec..58a36eabeb7 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -127,12 +127,15 @@ (add-to-list 'emulation-mode-map-alists `((override-global-mode . ,override-global-map))) -(defvar personal-keybindings nil) +(defvar personal-keybindings nil + "List of bindings performed by `bind-key'. + +Elements have the form ((KEY . [MAP]) CMD ORIGINAL-CMD)") (defmacro bind-key (key-name command &optional keymap) "Bind KEY-NAME to COMMAND in KEYMAP (`global-map' if not passed). -KEY-NAME may be a vector, in which case it passed straight to +KEY-NAME may be a vector, in which case it is passed straight to `define-key'. Or it may be a string to be interpreted as spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of `edmacro-mode' for details." From de9f6814e79f422b389f1f6ceefc06b16a9d4b9b Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 31 May 2014 14:58:07 -0400 Subject: [PATCH 102/606] bind-key: no vector keys in personal-keybindings describe-personal-keybindings requires the key sequences to be stored as strings. --- lisp/use-package/bind-key.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 58a36eabeb7..bf28e202388 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -154,7 +154,9 @@ spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of (setq personal-keybindings (delq ,entryvar personal-keybindings)))) (setq personal-keybindings - (cons (list (cons ,namevar (quote ,keymap)) + (cons (list (cons (if (stringp ,namevar) ,namevar + (key-description ,namevar)) + (quote ,keymap)) ,command (unless (numberp ,bindingvar) ,bindingvar)) personal-keybindings)) From b3e96443ad7e7d6f9675c72c2a48527728d7218f Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 31 May 2014 15:21:44 -0400 Subject: [PATCH 103/606] bind-key: cleanup --- lisp/use-package/bind-key.el | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index bf28e202388..e52ec07ed87 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -141,25 +141,24 @@ spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of `edmacro-mode' for details." (let ((namevar (make-symbol "name")) (keyvar (make-symbol "key")) + (kdescvar (make-symbol "kdesc")) (bindingvar (make-symbol "binding")) (entryvar (make-symbol "entry"))) `(let* ((,namevar ,key-name) (,keyvar (if (vectorp ,namevar) ,namevar (read-kbd-macro ,namevar))) + (,kdescvar (cons (if (stringp ,namevar) ,namevar + (key-description ,namevar)) + (quote ,keymap))) (,bindingvar (lookup-key (or ,keymap global-map) - ,keyvar))) - (let ((,entryvar (assoc (cons ,namevar (quote ,keymap)) - personal-keybindings))) - (if ,entryvar - (setq personal-keybindings - (delq ,entryvar personal-keybindings)))) - (setq personal-keybindings - (cons (list (cons (if (stringp ,namevar) ,namevar - (key-description ,namevar)) - (quote ,keymap)) - ,command - (unless (numberp ,bindingvar) ,bindingvar)) - personal-keybindings)) + ,keyvar)) + (,entryvar (assoc ,kdescvar personal-keybindings))) + (when ,entryvar + (setq personal-keybindings + (delq ,entryvar personal-keybindings))) + (push (list ,kdescvar ,command + (unless (numberp ,bindingvar) ,bindingvar)) + personal-keybindings) (define-key (or ,keymap global-map) ,keyvar ,command)))) (defmacro unbind-key (key-name &optional keymap) From 471869269a2ab0a847c3d3ae34e8c7327a5919d8 Mon Sep 17 00:00:00 2001 From: Bernard Hurley Date: Fri, 20 Jun 2014 05:45:51 +0100 Subject: [PATCH 104/606] bind-keys macro changed to allow prefix map to have a menu string --- lisp/use-package/bind-key.el | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index e52ec07ed87..e5f990ef0f2 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -178,6 +178,7 @@ Accepts keyword arguments: these bindings :prefix - prefix key for these bindings :prefix-docstring - docstring for the prefix-map variable +:menu-name - optional menu string for prefix map The rest of the arguments are conses of keybinding string and a function symbol (unquoted)." @@ -185,6 +186,7 @@ function symbol (unquoted)." (doc (plist-get args :prefix-docstring)) (prefix-map (plist-get args :prefix-map)) (prefix (plist-get args :prefix)) + (menu-name (plist-get args :menu-name)) (key-bindings (progn (while (keywordp (car args)) (pop args) @@ -195,11 +197,15 @@ function symbol (unquoted)." (and prefix (not prefix-map))) (error "Both :prefix-map and :prefix must be supplied")) + (when (and menu-name (not prefix)) + (error "If :menu-name is supplied, :prefix must be too")) `(progn ,@(when prefix-map `((defvar ,prefix-map) ,@(when doc `((put ',prefix-map 'variable-documentation ,doc))) - (define-prefix-command ',prefix-map) + ,@(if menu-name + `((define-prefix-command ',prefix-map nil ,menu-name)) + `((define-prefix-command ',prefix-map))) (bind-key ,prefix ',prefix-map ,map))) ,@(mapcar (lambda (form) `(bind-key ,(car form) ',(cdr form) @@ -281,7 +287,7 @@ function symbol (unquoted)." (sort personal-keybindings #'(lambda (l r) (car (compare-keybindings l r)))))) - + (if (not (eq (cdar last-binding) (cdar binding))) (princ (format "\n\n%s\n%s\n\n" (cdar binding) @@ -289,7 +295,7 @@ function symbol (unquoted)." (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)) @@ -314,7 +320,7 @@ function symbol (unquoted)." (princ (if (string-match "[ \t]+\n" line) (replace-match "\n" t t line) line)))) - + (setq last-binding binding))))) (provide 'bind-key) From 31bb0cde56785731398b59af5cb0b48b016fcd36 Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Sun, 7 Sep 2014 14:43:56 +0200 Subject: [PATCH 105/606] assume the declare-function macro exists Since `declare-function' was added in Emacs 23.1 (five years ago), we don't need to assert that it is defined. If the assertion was without any problems there would be no harm in keeping it, but unfortunately it causes a compile warning. Because `declare-function' is a macro with always expands to `nil' the value of (fboundp 'declare-function) ends up being unused. --- lisp/use-package/use-package.el | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 7b370380d4b..7e4738fc9fe 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -41,8 +41,7 @@ (require 'bytecomp) (require 'diminish nil t) -(when (fboundp 'declare-function) - (declare-function package-installed-p 'package)) +(declare-function package-installed-p 'package) (defgroup use-package nil "A use-package declaration for simplifying your `.emacs'." From 351c10201092a6fb534728c3c19df1e87aa8fc1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Fr=C3=B6ssman?= Date: Sun, 14 Sep 2014 12:57:44 +0200 Subject: [PATCH 106/606] Display which package that has compile errors --- lisp/use-package/use-package.el | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 7e4738fc9fe..34ea1ca30e5 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -401,10 +401,11 @@ For full documentation. please see commentary. (eval-when-compile (when (bound-and-true-p byte-compile-current-file) ,@defines-eval - (with-demoted-errors - ,(if (stringp name) - `(load ,name t) - `(require ',name nil t))))) + (condition-case err + ,(if (stringp name) + `(load ,name t) + `(require ',name nil t)) + (error (message "Error compiling %s: %s" ',name err) nil)))) ,(if (and (or commands (use-package-plist-get args :defer)) (not (use-package-plist-get args :demand))) From f07ecde5a1ba7d07405b4fd228b99529b37613a3 Mon Sep 17 00:00:00 2001 From: Philippe Vaucher Date: Tue, 16 Sep 2014 18:34:42 +0200 Subject: [PATCH 107/606] Fix "compiling" typo --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 34ea1ca30e5..fa8edb2f946 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -405,7 +405,7 @@ For full documentation. please see commentary. ,(if (stringp name) `(load ,name t) `(require ',name nil t)) - (error (message "Error compiling %s: %s" ',name err) nil)))) + (error (message "Error requiring %s: %s" ',name err) nil)))) ,(if (and (or commands (use-package-plist-get args :defer)) (not (use-package-plist-get args :demand))) From e8ce1b20ca3a99a5763e2d5404941d9697252a01 Mon Sep 17 00:00:00 2001 From: Justin Talbott Date: Tue, 16 Sep 2014 16:38:58 -0400 Subject: [PATCH 108/606] add :bind* keyword for `bind-key*` --- lisp/use-package/use-package.el | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 34ea1ca30e5..68aa3c9d0b6 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -146,6 +146,7 @@ Return nil when the queue is empty." (defvar use-package-keywords '( :bind + :bind* :commands :config :defer @@ -247,6 +248,8 @@ For full documentation. please see commentary. :init Code to run when `use-package' form evals. :bind Perform key bindings, and define autoload for bound commands. +:bind* Perform key bindings, and define autoload for bound + commands, overriding all minor mode bindings. :commands Define autoloads for given commands. :pre-load Code to run when `use-package' form evals and before anything else. Unlike :init this form runs before the @@ -254,7 +257,7 @@ For full documentation. please see commentary. :mode Form to be added to `auto-mode-alist'. :interpreter Form to be added to `interpreter-mode-alist'. :defer Defer loading of package -- automatic - if :commands, :bind, :mode or :interpreter are used. + if :commands, :bind, :bind*, :mode or :interpreter are used. :demand Prevent deferred loading in all cases. :config Runs if and when package loads. :if Conditional loading. @@ -279,6 +282,7 @@ For full documentation. please see commentary. (idle-body (use-package-plist-get args :idle)) (idle-priority (use-package-plist-get args :idle-priority)) (keybindings-alist (use-package-plist-get args :bind t t)) + (overriding-keybindings-alist (use-package-plist-get args :bind* t t)) (mode (use-package-plist-get args :mode t t)) (mode-alist (if (stringp mode) (cons mode name) mode)) @@ -371,6 +375,12 @@ For full documentation. please see commentary. (quote ,(cdr binding)))) keybindings-alist) + (funcall init-for-commands + #'(lambda (binding) + `(bind-key* ,(car binding) + (quote ,(cdr binding)))) + overriding-keybindings-alist) + (funcall init-for-commands #'(lambda (mode) `(add-to-list 'auto-mode-alist From fe7fe61528008cf9bcfb5633c845d06da9c582bc Mon Sep 17 00:00:00 2001 From: Peter Hoeg Date: Thu, 11 Dec 2014 14:44:27 +0800 Subject: [PATCH 109/606] support for pinning package to archive --- lisp/use-package/use-package.el | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index bc2dec27380..570044970ea 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -139,6 +139,13 @@ Return nil when the queue is empty." (cancel-timer use-package-idle-timer) (setq use-package-idle-timer nil)))) +(defun use-package-pin-package (package archive) + "Pin PACKAGE to ARCHIVE." + (unless (boundp 'package-pinned-packages) + (setq package-pinned-packages '())) + (add-to-list 'package-pinned-packages (cons package archive)) + (package-initialize t)) + (defun use-package-ensure-elpa (package) (when (not (package-installed-p package)) (package-install package))) @@ -162,6 +169,7 @@ Return nil when the queue is empty." :interpreter :load-path :mode + :pin :pre-init :pre-load :requires @@ -270,7 +278,8 @@ For full documentation. please see commentary. priority (lower priorities run first). Default priority is 5; forms with the same priority are run in the order in which they are evaluated. -:ensure loads package using package.el if necessary." +:ensure loads package using package.el if necessary. +:pin pin package to archive." (use-package-validate-keywords args) ; error if any bad keyword, ignore result (let* ((commands (use-package-plist-get args :commands t t)) (pre-init-body (use-package-plist-get args :pre-init)) @@ -291,6 +300,7 @@ For full documentation. please see commentary. (if (stringp interpreter) (cons interpreter name) interpreter)) (predicate (use-package-plist-get args :if)) (pkg-load-path (use-package-plist-get args :load-path t t)) + (archive-name (use-package-plist-get args :pin)) (defines-eval (if (null defines) nil (if (listp defines) @@ -309,6 +319,9 @@ For full documentation. please see commentary. ;; force this immediately -- one off cost (unless (use-package-plist-get args :disabled) + (when archive-name + (use-package-pin-package name archive-name)) + (let* ((ensure (use-package-plist-get args :ensure)) (package-name (or (and (eq ensure t) From 435d4b407859f4f82b19662f57ceb7f72b567437 Mon Sep 17 00:00:00 2001 From: Peter Hoeg Date: Wed, 17 Dec 2014 05:45:53 +0800 Subject: [PATCH 110/606] pure cleanup --- lisp/use-package/use-package.el | 64 ++++++++++++++++----------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 570044970ea..83b5bd3f08d 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -113,10 +113,10 @@ Return nil when the queue is empty." (forms (gethash priority use-package-idle-forms)) (first-form (car forms)) (forms-remaining (cdr forms))) - (if forms-remaining - (puthash priority forms-remaining use-package-idle-forms) - (remhash priority use-package-idle-forms)) - first-form)) + (if forms-remaining + (puthash priority forms-remaining use-package-idle-forms) + (remhash priority use-package-idle-forms)) + first-form)) (defun use-package-idle-eval() "Start to eval idle-commands from the idle queue." @@ -152,28 +152,28 @@ Return nil when the queue is empty." (defvar use-package-keywords '( - :bind - :bind* - :commands - :config - :defer - :defines - :demand - :diminish - :disabled - :ensure - :idle - :idle-priority - :if - :init - :interpreter - :load-path - :mode - :pin - :pre-init - :pre-load - :requires - ) + :bind + :bind* + :commands + :config + :defer + :defines + :demand + :diminish + :disabled + :ensure + :idle + :idle-priority + :if + :init + :interpreter + :load-path + :mode + :pin + :pre-init + :pre-load + :requires + ) "Keywords recognized by `use-package'.") (defun use-package-mplist-get (plist prop) @@ -239,11 +239,11 @@ are all non-keywords elements that follow it." "Error if any keyword given in ARGS is not recognized. Return the list of recognized keywords." (mapc - (function - (lambda (keyword) - (unless (memq keyword use-package-keywords) - (error "Unrecognized keyword: %s" keyword)))) - (use-package-mplist-keys args))) + (function + (lambda (keyword) + (unless (memq keyword use-package-keywords) + (error "Unrecognized keyword: %s" keyword)))) + (use-package-mplist-keys args))) (defmacro use-package (name &rest args) "Use a package with configuration options. @@ -391,7 +391,7 @@ For full documentation. please see commentary. (funcall init-for-commands #'(lambda (binding) `(bind-key* ,(car binding) - (quote ,(cdr binding)))) + (quote ,(cdr binding)))) overriding-keybindings-alist) (funcall init-for-commands From a2b23f8326d06690c8092ecc5e83ba2e4dd3c336 Mon Sep 17 00:00:00 2001 From: Nicolas Richard Date: Thu, 11 Dec 2014 08:42:53 +0100 Subject: [PATCH 111/606] Don't add autoload for existing commands --- lisp/use-package/use-package.el | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 570044970ea..654ed8d02b0 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -434,8 +434,10 @@ For full documentation. please see commentary. (not (use-package-plist-get args :demand))) (let (form) (mapc #'(lambda (command) - (push `(autoload (function ,command) - ,name-string nil t) form)) + (push `(unless (fboundp (quote ,command)) + (autoload (function ,command) + ,name-string nil t)) + form)) commands) `(when ,(or predicate t) From b3bf1b2587dee759e46cdb5941bf0689d54530f2 Mon Sep 17 00:00:00 2001 From: Peter Hoeg Date: Thu, 18 Dec 2014 04:34:49 +0800 Subject: [PATCH 112/606] Check if package-archives are valid when pinning --- lisp/use-package/use-package.el | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 83b5bd3f08d..950d0bf0ec2 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -142,9 +142,25 @@ Return nil when the queue is empty." (defun use-package-pin-package (package archive) "Pin PACKAGE to ARCHIVE." (unless (boundp 'package-pinned-packages) - (setq package-pinned-packages '())) - (add-to-list 'package-pinned-packages (cons package archive)) - (package-initialize t)) + (setq package-pinned-packages ())) + (let ((archive-symbol (if (symbolp archive) archive (intern archive))) + (archive-name (if (stringp archive) archive (symbol-name archive)))) + (if (use-package--archive-exists-p archive-symbol) + (add-to-list 'package-pinned-packages (cons package archive-name)) + (error (message "Archive '%s' requested for package '%s' is not available." archive-name package))) + (package-initialize t))) + +(defun use-package--archive-exists-p (archive) + "Check if a given ARCHIVE is enabled. + +ARCHIVE can be a string or a symbol or 'manual to indicate a manually updated package." + (if (member archive '(manual "manual")) + 't + (let ((valid nil)) + (dolist (pa package-archives) + (when (member archive (list (car pa) (intern (car pa)))) + (setq valid 't))) + valid))) (defun use-package-ensure-elpa (package) (when (not (package-installed-p package)) From 5a5aeca79736410462743f28d84dccde789efae3 Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Fri, 19 Dec 2014 23:12:47 -0500 Subject: [PATCH 113/606] Do not quote lambda expressions http://emacs.stackexchange.com/a/3596 Quoting lambda expressions is at best redundant and at worst detrimental; this commit removes all use of the sharp-quote to reduce confusion. --- lisp/use-package/bind-key.el | 4 +-- lisp/use-package/use-package.el | 50 ++++++++++++++++----------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index e5f990ef0f2..2ac32365ecf 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -285,8 +285,8 @@ function symbol (unquoted)." (dolist (binding (setq personal-keybindings (sort personal-keybindings - #'(lambda (l r) - (car (compare-keybindings l r)))))) + (lambda (l r) + (car (compare-keybindings l r)))))) (if (not (eq (cdar last-binding) (cdar binding))) (princ (format "\n\n%s\n%s\n\n" diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 57a80824fcc..3c0a7033af0 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -393,43 +393,43 @@ For full documentation. please see commentary. (setq init-body `(progn ,init-body - ,@(mapcar #'(lambda (elem) - (push (cdr elem) commands) - (funcall func elem)) + ,@(mapcar (lambda (elem) + (push (cdr elem) commands) + (funcall func elem)) cons-list)))))))) (funcall init-for-commands - #'(lambda (binding) - `(bind-key ,(car binding) - (quote ,(cdr binding)))) + (lambda (binding) + `(bind-key ,(car binding) + (quote ,(cdr binding)))) keybindings-alist) (funcall init-for-commands - #'(lambda (binding) - `(bind-key* ,(car binding) - (quote ,(cdr binding)))) + (lambda (binding) + `(bind-key* ,(car binding) + (quote ,(cdr binding)))) overriding-keybindings-alist) (funcall init-for-commands - #'(lambda (mode) - `(add-to-list 'auto-mode-alist - (quote ,mode))) + (lambda (mode) + `(add-to-list 'auto-mode-alist + (quote ,mode))) mode-alist) (funcall init-for-commands - #'(lambda (interpreter) - `(add-to-list 'interpreter-mode-alist - (quote ,interpreter))) + (lambda (interpreter) + `(add-to-list 'interpreter-mode-alist + (quote ,interpreter))) interpreter-alist)) `(progn ,pre-load-body ,@(mapcar - #'(lambda (path) - `(add-to-list 'load-path - ,(if (file-name-absolute-p path) - path - (expand-file-name path user-emacs-directory)))) + (lambda (path) + `(add-to-list 'load-path + ,(if (file-name-absolute-p path) + path + (expand-file-name path user-emacs-directory)))) (cond ((stringp pkg-load-path) (list pkg-load-path)) ((functionp pkg-load-path) @@ -449,11 +449,11 @@ For full documentation. please see commentary. ,(if (and (or commands (use-package-plist-get args :defer)) (not (use-package-plist-get args :demand))) (let (form) - (mapc #'(lambda (command) - (push `(unless (fboundp (quote ,command)) - (autoload (function ,command) - ,name-string nil t)) - form)) + (mapc (lambda (command) + (push `(unless (fboundp (quote ,command)) + (autoload (function ,command) + ,name-string nil t)) + form)) commands) `(when ,(or predicate t) From 1ae22368542380e51fa97066f454e72f0bdaa1fd Mon Sep 17 00:00:00 2001 From: Russell Black Date: Wed, 31 Dec 2014 17:02:25 -0700 Subject: [PATCH 114/606] :bind-keymap - bind a key prefix to an autoloaded package keymap --- lisp/use-package/use-package.el | 73 +++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 3c0a7033af0..ee7a5c41228 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -189,6 +189,8 @@ ARCHIVE can be a string or a symbol or 'manual to indicate a manually updated pa :pre-init :pre-load :requires + :bind-keymap + :bind-keymap* ) "Keywords recognized by `use-package'.") @@ -274,6 +276,10 @@ For full documentation. please see commentary. commands. :bind* Perform key bindings, and define autoload for bound commands, overriding all minor mode bindings. +:bind-keymap Bind key prefix to an auto-loaded keymap that + is defined in the package. Like bind but for keymaps + instead of commands. +:bind-keymap* like bind-keymap, but overrides all minor mode bindings :commands Define autoloads for given commands. :pre-load Code to run when `use-package' form evals and before anything else. Unlike :init this form runs before the @@ -308,6 +314,8 @@ For full documentation. please see commentary. (idle-priority (use-package-plist-get args :idle-priority)) (keybindings-alist (use-package-plist-get args :bind t t)) (overriding-keybindings-alist (use-package-plist-get args :bind* t t)) + (keymap-alist (use-package-plist-get args :bind-keymap t t)) + (overriding-keymap-alist (use-package-plist-get args :bind-keymap* t t)) (mode (use-package-plist-get args :mode t t)) (mode-alist (if (stringp mode) (cons mode name) mode)) @@ -382,9 +390,8 @@ For full documentation. please see commentary. (use-package-init-on-idle (lambda () ,idle-body) ,idle-priority) ,init-body))) - - (let ((init-for-commands - (lambda (func sym-or-list) + (let ((init-for-commands-or-keymaps + (lambda (func sym-or-list &optional keymap) (let ((cons-list (if (and (consp sym-or-list) (stringp (car sym-or-list))) (list sym-or-list) @@ -394,29 +401,50 @@ For full documentation. please see commentary. `(progn ,init-body ,@(mapcar (lambda (elem) - (push (cdr elem) commands) + (when (not keymap) + (push (cdr elem) commands)) (funcall func elem)) cons-list)))))))) - (funcall init-for-commands + (funcall init-for-commands-or-keymaps + (lambda (binding) + `(bind-key ,(car binding) + (lambda () (interactive) + (use-package-autoload-keymap + (quote ,(cdr binding)) + ,(if (stringp name) name `',name) + nil)))) + keymap-alist) + + (funcall init-for-commands-or-keymaps + (lambda (binding) + `(bind-key ,(car binding) + (lambda () (interactive) + (use-package-autoload-keymap + (quote ,(cdr binding)) + ,(if (stringp name) name `',name) + t)))) + overriding-keymap-alist) + + (funcall init-for-commands-or-keymaps (lambda (binding) `(bind-key ,(car binding) (quote ,(cdr binding)))) keybindings-alist) - (funcall init-for-commands + (funcall init-for-commands-or-keymaps (lambda (binding) `(bind-key* ,(car binding) (quote ,(cdr binding)))) overriding-keybindings-alist) - (funcall init-for-commands + (funcall init-for-commands-or-keymaps (lambda (mode) `(add-to-list 'auto-mode-alist (quote ,mode))) mode-alist) - (funcall init-for-commands + (funcall init-for-commands-or-keymaps (lambda (interpreter) `(add-to-list 'interpreter-mode-alist (quote ,interpreter))) @@ -446,7 +474,9 @@ For full documentation. please see commentary. `(require ',name nil t)) (error (message "Error requiring %s: %s" ',name err) nil)))) - ,(if (and (or commands (use-package-plist-get args :defer)) + ,(if (and (or commands (use-package-plist-get args :defer) + (use-package-plist-get args :bind-keymap) + (use-package-plist-get args :bind-keymap*)) (not (use-package-plist-get args :demand))) (let (form) (mapc (lambda (command) @@ -481,6 +511,31 @@ For full documentation. please see commentary. ,config-body t)))))))) +(defun use-package-autoload-keymap (keymap-symbol package override) + "Loads PACKAGE and then binds the key sequence used to invoke this function to +KEYMAP-SYMBOL. It then simulates pressing the same key sequence a again, so +that the next key pressed is routed to the newly loaded keymap. + +This function supports use-package's :bind-keymap keyword. It works +by binding the given key sequence to an invocation of this function for a +particular keymap. The keymap is expected to be defined by the package. In +this way, loading the package is deferred until the prefix key sequence is +pressed." + (if (if (stringp package) (load package t) (require package nil t)) + (if (and (boundp keymap-symbol) (keymapp (symbol-value keymap-symbol))) + (let ((key (key-description (this-command-keys-vector))) + (keymap (symbol-value keymap-symbol))) + (progn + (if override + `(eval `(bind-key* ,key ,keymap)) ; eval form is necessary to avoid compiler error + (bind-key key keymap)) + (setq unread-command-events + (listify-key-sequence (this-command-keys-vector))))) + (error + "use-package: package %s failed to define keymap %s" + package keymap-symbol)) + (error "Could not load package %s" package))) + (put 'use-package 'lisp-indent-function 'defun) (defconst use-package-font-lock-keywords From 7db9b920dfb8571b6a8a942dad6f70f471a7580b Mon Sep 17 00:00:00 2001 From: Thiago Barroso Perrotta Date: Fri, 2 Jan 2015 13:58:49 -0200 Subject: [PATCH 115/606] fix small typo (key > keymap) --- lisp/use-package/bind-key.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 2ac32365ecf..fd143888d5d 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -41,7 +41,7 @@ ;; ;; (bind-key* "" 'other-window) ;; -;; If you want to rebind a key only in a particular key, use: +;; If you want to rebind a key only in a particular keymap, use: ;; ;; (bind-key "C-c x" 'my-ctrl-c-x-command some-other-mode-map) ;; From b8f0799ce8f404f1bd9182174970d43dd53b0db3 Mon Sep 17 00:00:00 2001 From: Russell Black Date: Sat, 3 Jan 2015 13:53:38 -0700 Subject: [PATCH 116/606] Passing t into keymap function --- lisp/use-package/use-package.el | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index ee7a5c41228..7802e5a9549 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -414,7 +414,8 @@ For full documentation. please see commentary. (quote ,(cdr binding)) ,(if (stringp name) name `',name) nil)))) - keymap-alist) + keymap-alist + t) (funcall init-for-commands-or-keymaps (lambda (binding) @@ -424,7 +425,8 @@ For full documentation. please see commentary. (quote ,(cdr binding)) ,(if (stringp name) name `',name) t)))) - overriding-keymap-alist) + overriding-keymap-alist + t) (funcall init-for-commands-or-keymaps (lambda (binding) From 719115cf4778482f70c2b18613c0bc4e84d5259d Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Sun, 18 Jan 2015 11:41:13 +0100 Subject: [PATCH 117/606] Allow using expanded macro without loading feature In the macro `use-package-with-elapased-timer' use `bound-and-true-p' go get the values of the customizable options `use-package-verbose' and `use-package-minimum-reported-time'. This way the library only has to be required at compile time, provided these options are not actually customized. If the user has changed the values, then she also has to load the library at runtime or the macros fall back to the default of doing their job silently. See https://github.com/jwiegley/use-package/issues/149. --- lisp/use-package/use-package.el | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 7802e5a9549..28d8587de00 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -48,12 +48,27 @@ :group 'startup) (defcustom use-package-verbose nil - "Whether to report about loading and configuration details." + "Whether to report about loading and configuration details. + +If you customize this, then you should require the `use-package' +feature in files that use one of the macros `use-package' or +`use-package-with-elapsed-timer', even if these files only +contain compiled expansions of the macros. If you don't do so, +then the expanded macros do their job silently." :type 'boolean :group 'use-package) (defcustom use-package-minimum-reported-time 0.01 - "Minimal load time that will be reported" + "Minimal load time that will be reported. + +Note that `use-package-verbose' has to be set to t, for anything +to be reported at all. + +If you customize this, then you should require the `use-package' +feature in files that use one of the macros `use-package' or +`use-package-with-elapsed-timer', even if these files only +contain compiled expansions of the macros. If you don't do so, +then the expanded macros do their job silently." :type 'number :group 'use-package) @@ -65,13 +80,15 @@ (defmacro use-package-with-elapsed-timer (text &rest body) (declare (indent 1)) (let ((nowvar (make-symbol "now"))) - `(if use-package-verbose + `(if (bound-and-true-p use-package-verbose) (let ((,nowvar (current-time))) (message "%s..." ,text) (prog1 (progn ,@body) (let ((elapsed (float-time (time-subtract (current-time) ,nowvar)))) - (if (> elapsed ,use-package-minimum-reported-time) + (if (> elapsed + (or (bound-and-true-p use-package-minimum-reported-time) + "0.01")) (message "%s...done (%.3fs)" ,text elapsed) (message "%s...done" ,text))))) ,@body))) From aa6e3f47c74470dc4591697873e2530871e04555 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 13 Mar 2015 02:58:37 -0500 Subject: [PATCH 118/606] Show more informative errors when they occur --- lisp/use-package/use-package.el | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 7b370380d4b..41127b0174b 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -403,9 +403,10 @@ For full documentation. please see commentary. (when (bound-and-true-p byte-compile-current-file) ,@defines-eval (with-demoted-errors - ,(if (stringp name) - `(load ,name t) - `(require ',name nil t))))) + ,(format "Error in %s: %%S" name) + ,(if (stringp name) + `(load ,name t) + `(require ',name nil t))))) ,(if (and (or commands (use-package-plist-get args :defer)) (not (use-package-plist-get args :demand))) From f8bf1b0986e41af266dac20cff845f41e1c1df8d Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 13 Mar 2015 03:13:31 -0500 Subject: [PATCH 119/606] Minor style edits --- lisp/use-package/use-package.el | 66 ++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 450d5cf9d80..b619dcf0ce4 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -23,7 +23,7 @@ ;; along with GNU Emacs; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. - + ;;; Commentary: ;; The `use-package' declaration macro allows you to isolate package @@ -34,7 +34,7 @@ ;; functionality! ;; ;; Please see README.md from the same repository for documentation. - + ;;; Code: (require 'bind-key) @@ -156,6 +156,10 @@ Return nil when the queue is empty." (cancel-timer use-package-idle-timer) (setq use-package-idle-timer nil)))) +(eval-when-compile + (defvar package-pinned-packages) + (defvar package-archives)) + (defun use-package-pin-package (package archive) "Pin PACKAGE to ARCHIVE." (unless (boundp 'package-pinned-packages) @@ -164,13 +168,15 @@ Return nil when the queue is empty." (archive-name (if (stringp archive) archive (symbol-name archive)))) (if (use-package--archive-exists-p archive-symbol) (add-to-list 'package-pinned-packages (cons package archive-name)) - (error (message "Archive '%s' requested for package '%s' is not available." archive-name package))) + (error "Archive '%s' requested for package '%s' is not available." + archive-name package)) (package-initialize t))) (defun use-package--archive-exists-p (archive) "Check if a given ARCHIVE is enabled. -ARCHIVE can be a string or a symbol or 'manual to indicate a manually updated package." +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)) @@ -332,7 +338,8 @@ For full documentation. please see commentary. (keybindings-alist (use-package-plist-get args :bind t t)) (overriding-keybindings-alist (use-package-plist-get args :bind* t t)) (keymap-alist (use-package-plist-get args :bind-keymap t t)) - (overriding-keymap-alist (use-package-plist-get args :bind-keymap* t t)) + (overriding-keymap-alist + (use-package-plist-get args :bind-keymap* t t)) (mode (use-package-plist-get args :mode t t)) (mode-alist (if (stringp mode) (cons mode name) mode)) @@ -375,24 +382,26 @@ For full documentation. please see commentary. (if diminish-var - (setq config-body - `(progn - ,config-body - (ignore-errors - ,@(cond - ((stringp diminish-var) - `((diminish (quote ,(intern (concat name-string "-mode"))) - ,diminish-var))) - ((symbolp diminish-var) - `((diminish (quote ,diminish-var)))) - ((and (consp diminish-var) (stringp (cdr diminish-var))) - `((diminish (quote ,(car diminish-var)) ,(cdr diminish-var)))) - (t ; list of symbols or (symbol . "string") pairs - (mapcar (lambda (var) - (if (listp var) - `(diminish (quote ,(car var)) ,(cdr var)) - `(diminish (quote ,var)))) - diminish-var))))))) + (setq + config-body + `(progn + ,config-body + (ignore-errors + ,@(cond + ((stringp diminish-var) + `((diminish (quote ,(intern (concat name-string "-mode"))) + ,diminish-var))) + ((symbolp diminish-var) + `((diminish (quote ,diminish-var)))) + ((and (consp diminish-var) (stringp (cdr diminish-var))) + `((diminish (quote ,(car diminish-var)) + ,(cdr diminish-var)))) + (t ; list of symbols or (symbol . "string") pairs + (mapcar (lambda (var) + (if (listp var) + `(diminish (quote ,(car var)) ,(cdr var)) + `(diminish (quote ,var)))) + diminish-var))))))) (if (and commands (symbolp commands)) (setq commands (list commands))) @@ -404,7 +413,8 @@ For full documentation. please see commentary. (setq init-body `(progn (require 'use-package) - (use-package-init-on-idle (lambda () ,idle-body) ,idle-priority) + (use-package-init-on-idle (lambda () ,idle-body) + ,idle-priority) ,init-body))) (let ((init-for-commands-or-keymaps @@ -512,7 +522,8 @@ For full documentation. please see commentary. `(,(lambda () (if ,requires-test (use-package-with-elapsed-timer - ,(format "Configuring package %s" name-string) + ,(format "Configuring package %s" + name-string) ,config-body)))))) t)) `(if (and ,(or predicate t) @@ -544,7 +555,8 @@ pressed." (keymap (symbol-value keymap-symbol))) (progn (if override - `(eval `(bind-key* ,key ,keymap)) ; eval form is necessary to avoid compiler error + ;; eval form is necessary to avoid compiler error + `(eval `(bind-key* ,key ,keymap)) (bind-key key keymap)) (setq unread-command-events (listify-key-sequence (this-command-keys-vector))))) @@ -563,7 +575,9 @@ pressed." (font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords) (provide 'use-package) + ;; Local Variables: ;; indent-tabs-mode: nil ;; End: + ;;; use-package.el ends here From 30da0769bf91124af0bde01bab65f206a6be9e91 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 13 Mar 2015 03:25:32 -0500 Subject: [PATCH 120/606] Stylistic changes --- lisp/use-package/use-package.el | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index b619dcf0ce4..aa80eb0547f 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -135,7 +135,7 @@ Return nil when the queue is empty." (remhash priority use-package-idle-forms)) first-form)) -(defun use-package-idle-eval() +(defun use-package-idle-eval () "Start to eval idle-commands from the idle queue." (let ((next (use-package-idle-pop))) (if next @@ -366,7 +366,6 @@ For full documentation. please see commentary. ;; force this immediately -- one off cost (unless (use-package-plist-get args :disabled) - (when archive-name (use-package-pin-package name archive-name)) @@ -380,7 +379,6 @@ For full documentation. please see commentary. (require 'package) (use-package-ensure-elpa package-name))) - (if diminish-var (setq config-body @@ -406,7 +404,6 @@ For full documentation. please see commentary. (if (and commands (symbolp commands)) (setq commands (list commands))) - (when idle-body (when (null idle-priority) (setq idle-priority 5)) @@ -457,26 +454,22 @@ For full documentation. please see commentary. (funcall init-for-commands-or-keymaps (lambda (binding) - `(bind-key ,(car binding) - (quote ,(cdr binding)))) + `(bind-key ,(car binding) (quote ,(cdr binding)))) keybindings-alist) (funcall init-for-commands-or-keymaps (lambda (binding) - `(bind-key* ,(car binding) - (quote ,(cdr binding)))) + `(bind-key* ,(car binding) (quote ,(cdr binding)))) overriding-keybindings-alist) (funcall init-for-commands-or-keymaps (lambda (mode) - `(add-to-list 'auto-mode-alist - (quote ,mode))) + `(add-to-list 'auto-mode-alist (quote ,mode))) mode-alist) (funcall init-for-commands-or-keymaps (lambda (interpreter) - `(add-to-list 'interpreter-mode-alist - (quote ,interpreter))) + `(add-to-list 'interpreter-mode-alist (quote ,interpreter))) interpreter-alist)) `(progn From a4a696572df141c87198f04b69a012f111b21bef Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 13 Mar 2015 03:26:09 -0500 Subject: [PATCH 121/606] Revert "Don't add autoload for existing commands" This reverts commit a2b23f8326d06690c8092ecc5e83ba2e4dd3c336. --- lisp/use-package/use-package.el | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index aa80eb0547f..15012741280 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -499,11 +499,9 @@ For full documentation. please see commentary. ,(if (and (or commands (use-package-plist-get args :defer)) (not (use-package-plist-get args :demand))) (let (form) - (mapc (lambda (command) - (push `(unless (fboundp (quote ,command)) - (autoload (function ,command) - ,name-string nil t)) - form)) + (mapc #'(lambda (command) + (push `(autoload (function ,command) + ,name-string nil t) form)) commands) `(when ,(or predicate t) From 0f76d766d9013bec03cbe1fd0c48f92243a16611 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 13 Mar 2015 04:47:07 -0500 Subject: [PATCH 122/606] Many stylistics cleanups and simplifications --- lisp/use-package/use-package.el | 375 +++++++++++++++----------------- 1 file changed, 170 insertions(+), 205 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 15012741280..72f6250f404 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -83,7 +83,8 @@ then the expanded macros do their job silently." `(if (bound-and-true-p use-package-verbose) (let ((,nowvar (current-time))) (message "%s..." ,text) - (prog1 (progn ,@body) + (prog1 + (progn ,@body) (let ((elapsed (float-time (time-subtract (current-time) ,nowvar)))) (if (> elapsed @@ -102,9 +103,8 @@ then the expanded macros do their job silently." "Ensure that the idle timer is running." (unless use-package-idle-timer (setq use-package-idle-timer - (run-with-idle-timer - use-package-idle-interval t - 'use-package-idle-eval)))) + (run-with-idle-timer use-package-idle-interval t + 'use-package-idle-eval)))) (defun use-package-init-on-idle (form priority) "Add a new form to the idle queue." @@ -118,8 +118,8 @@ then the expanded macros do their job silently." "Get a list of all priorities in the idle queue. The list is sorted in the order forms should be run." (let ((priorities nil)) - (maphash (lambda (priority forms) - (setq priorities (cons priority priorities))) + (maphash #'(lambda (priority forms) + (setq priorities (cons priority priorities))) use-package-idle-forms) (sort priorities '<))) @@ -142,13 +142,10 @@ Return nil when the queue is empty." (progn (when use-package-verbose (message "use-package idle:%s" next)) - (condition-case e (funcall next) - (error - (message - "Failure on use-package idle. Form: %s, Error: %s" - next e))) + (error "Failure on use-package idle. Form: %s, Error: %s" + next e)) ;; recurse after a bit (when (sit-for use-package-idle-interval) (use-package-idle-eval))) @@ -164,10 +161,15 @@ Return nil when the queue is empty." "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)))) + (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)) + (add-to-list 'package-pinned-packages + (cons package archive-name)) (error "Archive '%s' requested for package '%s' is not available." archive-name package)) (package-initialize t))) @@ -190,8 +192,7 @@ manually updated package." (package-install package))) (defvar use-package-keywords - '( - :bind + '(:bind :bind* :commands :config @@ -213,8 +214,7 @@ manually updated package." :pre-load :requires :bind-keymap - :bind-keymap* - ) + :bind-keymap*) "Keywords recognized by `use-package'.") (defun use-package-mplist-get (plist prop) @@ -228,13 +228,9 @@ is followed by another keyword or is the last element in the list, the function returns t. Currently this function infloops when the list is circular." - (let ((tail plist) - found - result) - (while (and - (consp tail) - (not - (eq prop (car tail)))) + (let ((tail plist) found result) + (while (and (consp tail) + (not (eq prop (car tail)))) (pop tail)) (when (eq prop (pop tail)) (setq found t)) @@ -270,21 +266,26 @@ if it were backquoted." A modified plist is one where properties are keywords and values are all non-keywords elements that follow it." (let ((result)) - (mapc (lambda (elt) - (when (keywordp elt) - (push elt result))) + (mapc #'(lambda (elt) + (when (keywordp elt) + (push elt result))) plist) (nreverse result))) (defun use-package-validate-keywords (args) "Error if any keyword given in ARGS is not recognized. Return the list of recognized keywords." - (mapc - (function - (lambda (keyword) - (unless (memq keyword use-package-keywords) - (error "Unrecognized keyword: %s" keyword)))) - (use-package-mplist-keys args))) + (mapc #'(lambda (keyword) + (unless (memq keyword use-package-keywords) + (error "Unrecognized keyword: %s" keyword))) + (use-package-mplist-keys args))) + +(defsubst use-package-maybe-list (sym-or-list) + "If SYM-OR-LIST is just (a . b), return ((a . b))" + (if (and (consp sym-or-list) + (stringp (car sym-or-list))) + (list sym-or-list) + sym-or-list)) (defmacro use-package (name &rest args) "Use a package with configuration options. @@ -326,55 +327,51 @@ For full documentation. please see commentary. :ensure loads package using package.el if necessary. :pin pin package to archive." (use-package-validate-keywords args) ; error if any bad keyword, ignore result - (let* ((commands (use-package-plist-get args :commands t t)) - (pre-init-body (use-package-plist-get args :pre-init)) - (pre-load-body (use-package-plist-get args :pre-load)) - (init-body (use-package-plist-get args :init)) - (config-body (use-package-plist-get args :config)) - (diminish-var (use-package-plist-get args :diminish t)) - (defines (use-package-plist-get args :defines t t)) - (idle-body (use-package-plist-get args :idle)) - (idle-priority (use-package-plist-get args :idle-priority)) - (keybindings-alist (use-package-plist-get args :bind t t)) - (overriding-keybindings-alist (use-package-plist-get args :bind* t t)) - (keymap-alist (use-package-plist-get args :bind-keymap t t)) - (overriding-keymap-alist - (use-package-plist-get args :bind-keymap* t t)) - (mode (use-package-plist-get args :mode t t)) - (mode-alist - (if (stringp mode) (cons mode name) mode)) - (interpreter (use-package-plist-get args :interpreter t t)) - (interpreter-alist - (if (stringp interpreter) (cons interpreter name) interpreter)) - (predicate (use-package-plist-get args :if)) - (pkg-load-path (use-package-plist-get args :load-path t t)) - (archive-name (use-package-plist-get args :pin)) - (defines-eval (if (null defines) - nil - (if (listp defines) - (mapcar (lambda (var) `(defvar ,var)) defines) - `((defvar ,defines))))) - (requires (use-package-plist-get args :requires t)) - (requires-test (if (null requires) - t - (if (listp requires) - `(not (member nil (mapcar #'featurep - (quote ,requires)))) - `(featurep (quote ,requires))))) - (name-string (if (stringp name) name (symbol-name name))) - (name-symbol (if (stringp name) (intern name) name))) + ;; force this immediately -- one off cost + (unless (use-package-plist-get args :disabled) + (let* ((commands (use-package-plist-get args :commands t t)) + (pre-init-body (use-package-plist-get args :pre-init)) + (pre-load-body (use-package-plist-get args :pre-load)) + init-body + (config-body (use-package-plist-get args :config)) + (diminish-var (use-package-plist-get args :diminish t)) + (defines (use-package-plist-get args :defines t t)) + (idle-body (use-package-plist-get args :idle)) + (idle-priority (use-package-plist-get args :idle-priority)) + (keybindings-alist (use-package-plist-get args :bind t t)) + (overriding-keybindings-alist (use-package-plist-get args :bind* t t)) + (keymap-alist (use-package-plist-get args :bind-keymap t t)) + (overriding-keymap-alist + (use-package-plist-get args :bind-keymap* t t)) + (mode (use-package-plist-get args :mode t t)) + (mode-alist + (if (stringp mode) (cons mode name) mode)) + (interpreter (use-package-plist-get args :interpreter t t)) + (interpreter-alist + (if (stringp interpreter) (cons interpreter name) interpreter)) + (predicate (use-package-plist-get args :if)) + (pkg-load-path (use-package-plist-get args :load-path t t)) + (archive-name (use-package-plist-get args :pin)) + (defines-eval (if (null defines) + nil + (if (listp defines) + (mapcar #'(lambda (var) `(defvar ,var)) defines) + `((defvar ,defines))))) + (requires (use-package-plist-get args :requires t)) + (requires-test (if (null requires) + t + (if (listp requires) + `(not (member nil (mapcar #'featurep + (quote ,requires)))) + `(featurep (quote ,requires))))) + (name-string (if (stringp name) name (symbol-name name))) + (name-symbol (if (stringp name) (intern name) name))) - ;; force this immediately -- one off cost - (unless (use-package-plist-get args :disabled) (when archive-name (use-package-pin-package name archive-name)) (let* ((ensure (use-package-plist-get args :ensure)) - (package-name - (or (and (eq ensure t) - name) - ensure))) - + (package-name (or (and (eq ensure t) name) ensure))) (when package-name (require 'package) (use-package-ensure-elpa package-name))) @@ -395,166 +392,134 @@ For full documentation. please see commentary. `((diminish (quote ,(car diminish-var)) ,(cdr diminish-var)))) (t ; list of symbols or (symbol . "string") pairs - (mapcar (lambda (var) - (if (listp var) - `(diminish (quote ,(car var)) ,(cdr var)) - `(diminish (quote ,var)))) + (mapcar #'(lambda (var) + (if (listp var) + `(diminish (quote ,(car var)) ,(cdr var)) + `(diminish (quote ,var)))) diminish-var))))))) (if (and commands (symbolp commands)) (setq commands (list commands))) - (when idle-body - (when (null idle-priority) - (setq idle-priority 5)) - (setq init-body - `(progn - (require 'use-package) - (use-package-init-on-idle (lambda () ,idle-body) - ,idle-priority) - ,init-body))) + (setq + init-body + (append + (mapcar #'(lambda (mode) + (push (cdr mode) commands) + `(add-to-list 'auto-mode-alist ',mode)) + (use-package-maybe-list mode-alist)) - (let ((init-for-commands-or-keymaps - (lambda (func sym-or-list &optional keymap) - (let ((cons-list (if (and (consp sym-or-list) - (stringp (car sym-or-list))) - (list sym-or-list) - sym-or-list))) - (if cons-list - (setq init-body - `(progn - ,init-body - ,@(mapcar (lambda (elem) - (when (not keymap) - (push (cdr elem) commands)) - (funcall func elem)) - cons-list)))))))) + (mapcar #'(lambda (interpreter) + (push (cdr interpreter) commands) + `(add-to-list 'interpreter-mode-alist ',interpreter)) + (use-package-maybe-list interpreter-alist)) - (funcall init-for-commands-or-keymaps - (lambda (binding) - `(bind-key ,(car binding) - (lambda () (interactive) - (use-package-autoload-keymap - (quote ,(cdr binding)) - ,(if (stringp name) name `',name) - nil)))) - keymap-alist - t) + (mapcar #'(lambda (binding) + (push (cdr binding) commands) + `(bind-key ,(car binding) #',(cdr binding))) + (use-package-maybe-list keybindings-alist)) - (funcall init-for-commands-or-keymaps - (lambda (binding) - `(bind-key ,(car binding) - (lambda () (interactive) - (use-package-autoload-keymap - (quote ,(cdr binding)) - ,(if (stringp name) name `',name) - t)))) - overriding-keymap-alist - t) + (mapcar #'(lambda (binding) + (push (cdr binding) commands) + `(bind-key* ,(car binding) #',(cdr binding))) + (use-package-maybe-list overriding-keybindings-alist)) - (funcall init-for-commands-or-keymaps - (lambda (binding) - `(bind-key ,(car binding) (quote ,(cdr binding)))) - keybindings-alist) + (mapcar #'(lambda (binding) + `(bind-key ,(car binding) + #'(lambda () (interactive) + (use-package-autoload-keymap + ',(cdr binding) ,name-symbol nil)))) + (use-package-maybe-list keymap-alist)) - (funcall init-for-commands-or-keymaps - (lambda (binding) - `(bind-key* ,(car binding) (quote ,(cdr binding)))) - overriding-keybindings-alist) + (mapcar #'(lambda (binding) + `(bind-key ,(car binding) + #'(lambda () (interactive) + (use-package-autoload-keymap + ',(cdr binding) ,name-symbol t)))) + (use-package-maybe-list overriding-keymap-alist)) - (funcall init-for-commands-or-keymaps - (lambda (mode) - `(add-to-list 'auto-mode-alist (quote ,mode))) - mode-alist) + ;; First, execute the user's initializations + (list (use-package-plist-get args :init)) - (funcall init-for-commands-or-keymaps - (lambda (interpreter) - `(add-to-list 'interpreter-mode-alist (quote ,interpreter))) - interpreter-alist)) + (when idle-body + (when (null idle-priority) + (setq idle-priority 5)) + (list + `(progn + (require 'use-package) + (use-package-init-on-idle #'(lambda () ,idle-body) + ,idle-priority)))))) `(progn ,pre-load-body ,@(mapcar - (lambda (path) - `(add-to-list 'load-path - ,(if (file-name-absolute-p path) - path - (expand-file-name path user-emacs-directory)))) + #'(lambda (path) + `(add-to-list 'load-path + ,(if (file-name-absolute-p path) + path + (expand-file-name path user-emacs-directory)))) (cond ((stringp pkg-load-path) (list pkg-load-path)) ((functionp pkg-load-path) (funcall pkg-load-path)) - (t - pkg-load-path))) + (t pkg-load-path))) (eval-when-compile (when (bound-and-true-p byte-compile-current-file) ,@defines-eval (with-demoted-errors ,(format "Error in %s: %%S" name) - ,(if (stringp name) - `(load ,name t) - `(require ',name nil t))))) + (require ',name-symbol nil t)))) ,(if (and (or commands (use-package-plist-get args :defer)) (not (use-package-plist-get args :demand))) - (let (form) - (mapc #'(lambda (command) - (push `(autoload (function ,command) - ,name-string nil t) form)) - commands) - - `(when ,(or predicate t) + `(when ,(or predicate t) + ,pre-init-body + ,@(mapcar #'(lambda (command) + `(autoload #',command ,name-string nil t)) + commands) + ,@init-body + ,(if (and config-body requires-test) + `(eval-after-load ,name-string + '(use-package-with-elapsed-timer + ,(format "Configuring package %s" name-string) + ,config-body))) + t) + `(when (and ,(or predicate t) ,requires-test) + (use-package-with-elapsed-timer + ,(format "Loading package %s" name-string) + (if (not (require ',name-symbol nil t)) + (message "Could not load package %s" ,name-string) ,pre-init-body - ,@form - ,init-body - ,(unless (null config-body) - `(eval-after-load ,(if (stringp name) name `',name) - `(,(lambda () - (if ,requires-test - (use-package-with-elapsed-timer - ,(format "Configuring package %s" - name-string) - ,config-body)))))) - t)) - `(if (and ,(or predicate t) - ,requires-test) - (use-package-with-elapsed-timer - ,(format "Loading package %s" name-string) - (if (not ,(if (stringp name) - `(load ,name t) - `(require ',name nil t))) - (message "Could not load package %s" ,name-string) - ,pre-init-body - ,init-body - ,config-body - t)))))))) + ,@init-body + ,config-body + t)))))))) (defun use-package-autoload-keymap (keymap-symbol package override) - "Loads PACKAGE and then binds the key sequence used to invoke this function to -KEYMAP-SYMBOL. It then simulates pressing the same key sequence a again, so -that the next key pressed is routed to the newly loaded keymap. + "Loads PACKAGE and then binds the key sequence used to invoke +this function to KEYMAP-SYMBOL. It then simulates pressing the +same key sequence a again, so that the next key pressed is routed +to the newly loaded keymap. -This function supports use-package's :bind-keymap keyword. It works -by binding the given key sequence to an invocation of this function for a -particular keymap. The keymap is expected to be defined by the package. In -this way, loading the package is deferred until the prefix key sequence is -pressed." - (if (if (stringp package) (load package t) (require package nil t)) - (if (and (boundp keymap-symbol) (keymapp (symbol-value keymap-symbol))) - (let ((key (key-description (this-command-keys-vector))) - (keymap (symbol-value keymap-symbol))) - (progn - (if override - ;; eval form is necessary to avoid compiler error - `(eval `(bind-key* ,key ,keymap)) - (bind-key key keymap)) - (setq unread-command-events - (listify-key-sequence (this-command-keys-vector))))) - (error - "use-package: package %s failed to define keymap %s" - package keymap-symbol)) - (error "Could not load package %s" package))) +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)) + (error "Could not load package %s" package) + (if (and (boundp keymap-symbol) + (keymapp (symbol-value keymap-symbol))) + (let ((key (key-description (this-command-keys-vector))) + (keymap (symbol-value keymap-symbol))) + (if override + ;; eval form is necessary to avoid compiler error + `(eval `(bind-key* ,key ,keymap)) + (bind-key key keymap)) + (setq unread-command-events + (listify-key-sequence (this-command-keys-vector)))) + (error "use-package: package %s failed to define keymap %s" + package keymap-symbol)))) (put 'use-package 'lisp-indent-function 'defun) From 4ae584f3ff0e9bda05420ec3b8598e59374b0899 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 14 Mar 2015 05:22:43 -0500 Subject: [PATCH 123/606] Begin refactoring for 2.0; NOTE: BREAKING CHANGES The major change is that :init is now always performed before loading a file, whether loading is deferred or not. This is a change from before, where the semantics of :init varied between demand and defer. The new usage is now entirely consistent. Also, because :init and :config now mean "before" and "after", the :pre-* and :post-* keywords are gone, as they should no longer be necessary. Lastly, an effort has been made to make your Emacs start even in the presence of use-package configuration failures. So after this change, be sure to check your *Messages* buffer. Most likely, you will have several instances where you are using :init, but should be using :config (this was the case for me in a number of places). --- lisp/use-package/use-package.el | 827 ++++++++++++++++++-------------- 1 file changed, 476 insertions(+), 351 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 72f6250f404..75d5ee6187c 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -4,7 +4,7 @@ ;; Author: John Wiegley ;; Created: 17 Jun 2012 -;; Version: 1.0 +;; Version: 2.0 ;; Package-Requires: ((bind-key "1.0") (diminish "0.44")) ;; Keywords: dotemacs startup speed config package ;; X-URL: https://github.com/jwiegley/use-package @@ -58,7 +58,7 @@ then the expanded macros do their job silently." :type 'boolean :group 'use-package) -(defcustom use-package-minimum-reported-time 0.01 +(defcustom use-package-minimum-reported-time 0.1 "Minimal load time that will be reported. Note that `use-package-verbose' has to be set to t, for anything @@ -72,16 +72,11 @@ then the expanded macros do their job silently." :type 'number :group 'use-package) -(defcustom use-package-idle-interval 3 - "Time to wait when using :idle in a `use-package' specification." - :type 'number - :group 'use-package) - (defmacro use-package-with-elapsed-timer (text &rest body) (declare (indent 1)) (let ((nowvar (make-symbol "now"))) - `(if (bound-and-true-p use-package-verbose) - (let ((,nowvar (current-time))) + (if (bound-and-true-p use-package-verbose) + `(let ((,nowvar (current-time))) (message "%s..." ,text) (prog1 (progn ,@body) @@ -92,9 +87,466 @@ then the expanded macros do their job silently." "0.01")) (message "%s...done (%.3fs)" ,text elapsed) (message "%s...done" ,text))))) - ,@body))) + `(progn ,@body)))) -(put 'use-package-with-elapsed-timer 'lisp-indent-function 1) +(defsubst use-package-error (msg) + "Report MSG as an error, so the user knows it came from this package." + (error "use-package: %s" msg)) + +(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"))) + (if (= (length args) 1) + (car args) + (cons 'progn args))) + +(defsubst use-package-normalize-value (label arg) + "Normalize a value." + (cond ((symbolp arg) + `(symbol-value ',arg)) + ((functionp arg) + `(funcall #',arg)) + (t arg))) + +(defun use-package-normalize-diminish (name-symbol label arg &optional recursed) + "Normalize the arguments to diminish down to a list of one of two forms: + SYMBOL + (SYMBOL . STRING)" + (cond + ((symbolp arg) + (list arg)) + ((stringp arg) + (list (cons (intern (concat (symbol-name name-symbol) "-mode")) arg))) + ((and (consp arg) (stringp (cdr arg))) + (list arg)) + ((and (not recursed) (listp arg) (listp (cdr arg))) + (mapcar #'(lambda (x) (car (use-package-normalize-diminish + name-symbol label x t))) arg)) + (t + (use-package-error + (concat label " wants a string, symbol, " + "(symbol . string) or list of these"))))) + +(defun use-package-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"))))) + +(defun use-package-as-one (label args f) + "Call F on the first element of ARGS if it has one element, or all of ARGS." + (declare (indent 1)) + (if (and (listp args) (listp (cdr args))) + (if (= (length args) 1) + (funcall f label (car args)) + (funcall f label args)) + (use-package-error + (concat label " wants a list")))) + +(defsubst use-package-is-sympair (x) + "Return t if X has the type (STRING . SYMBOL)." + (and (consp x) + (stringp (car x)) + (symbolp (cdr x)))) + +(defun use-package-normalize-pairs (name-symbol label arg &optional recursed) + "Normalize a list of string/symbol pairs." + (cond + ((stringp arg) + (list (cons arg name-symbol))) + ((use-package-is-sympair arg) + (list arg)) + ((and (not recursed) (listp arg) (listp (cdr arg))) + (mapcar #'(lambda (x) (car (use-package-normalize-pairs + name-symbol label x t))) arg)) + (t + (use-package-error + (concat label " wants a string, (string . symbol) or list of these"))))) + +(defun use-package-normalize-symbols (label arg &optional recursed) + "Normalize a list of symbols." + (cond + ((symbolp arg) + (list arg)) + ((and (not recursed) (listp arg) (listp (cdr arg))) + (mapcar #'(lambda (x) (car (use-package-normalize-symbols label x t))) arg)) + (t + (use-package-error + (concat label " wants a symbol, or list of symbols"))))) + +(defun use-package-normalize-paths (label arg &optional recursed) + "Normalize a list of filesystem paths." + (cond + ((or (symbolp arg) (functionp arg)) + (let ((value (use-package-normalize-value label arg))) + (use-package-normalize-paths label (eval value)))) + ((stringp arg) + (let ((path (if (file-name-absolute-p arg) + arg + (expand-file-name arg user-emacs-directory)))) + (if (file-directory-p path) + (list path) + (use-package-error + (concat label " wants a directory path, or list of paths"))))) + ((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-split-list (pred xs) + (let ((ys (list nil)) (zs (list nil)) flip) + (dolist (x xs) + (if flip + (nconc zs (list x)) + (if (funcall pred x) + (progn + (setq flip t) + (nconc zs (list x))) + (nconc ys (list x))))) + (cons (cdr ys) (cdr zs)))) + +(defun use-package-normalize-plist (name-symbol input) + "Given a pseudo-plist, normalize it to a regular plist." + (if (null input) + nil + (let* ((head (car input)) + (xs (use-package-split-list #'keywordp (cdr input))) + (args (car xs)) + (tail (cdr xs))) + (append + (list + (cond ((memq head '(:when :unless)) :if) + (t head)) + (pcase head + ((or :bind :bind* :bind-keymap :bind-keymap* :interpreter :mode) + (use-package-as-one (symbol-name head) args + (apply-partially #'use-package-normalize-pairs name-symbol))) + + ((or :commands :defines :functions :requires) + (use-package-as-one (symbol-name head) args + #'use-package-normalize-symbols)) + + ((or :defer :demand :disabled :ensure) + (if (null args) + t + (use-package-only-one (symbol-name head) args + #'use-package-normalize-value))) + + ((or :if :when :unless) + (use-package-only-one (symbol-name head) args + #'use-package-normalize-value)) + + (:diminish + (use-package-as-one (symbol-name head) args + (apply-partially #'use-package-normalize-diminish name-symbol))) + + ((or :init :config :idle) + (use-package-normalize-form (symbol-name head) args)) + + (:idle-priority + (if (null args) + 5 + (use-package-only-one (symbol-name head) args + (lambda (label arg) + (if (numberp arg) + arg + (use-package-error + ":idle-priority wants an optional number")))))) + + (:load-path + (use-package-as-one (symbol-name head) args + #'use-package-normalize-paths)) + + (:pin + (use-package-only-one (symbol-name head) args + (lambda (label arg) + (if (stringp arg) + arg + (use-package-error ":pin wants an archive name (a string)"))))) + + (_ (use-package-error (format "Unrecognized keyword: %s" head))))) + (use-package-normalize-plist name-symbol tail))))) + +(defsubst use-package-cat-maybes (&rest elems) + "Delete all empty lists from ELEMS (nil or (list nil)), and append them." + (apply #'nconc (delete nil (delete (list nil) elems)))) + +(defsubst use-package-expand (name label form) + (declare (indent 1)) + (and form + `(with-demoted-errors + ,(format "Failure in %s of %s: %%S" label name) + ,form))) + +(defun use--package (name-symbol name-string args) + "See docstring for `use-package'." + (let* + ((commands (plist-get args :commands)) + + ;; Note: evaluation of this forms possibly extends the value of + ;; `commands'. + (bindings + (append + (mapcar #'(lambda (binding) + `(bind-key ,(car binding) + #'(lambda () (interactive) + (use-package-autoload-keymap + ',(cdr binding) ,name-symbol nil)))) + (plist-get args :bind-keymap)) + + (mapcar #'(lambda (binding) + `(bind-key ,(car binding) + #'(lambda () (interactive) + (use-package-autoload-keymap + ',(cdr binding) ,name-symbol t)))) + (plist-get args :bind-keymap*)) + + (mapcar #'(lambda (mode) + (push (cdr mode) commands) + `(add-to-list 'auto-mode-alist ',mode)) + (plist-get args :mode)) + + (mapcar #'(lambda (interpreter) + (push (cdr interpreter) commands) + `(add-to-list 'interpreter-mode-alist ',interpreter)) + (plist-get args :interpreter)) + + (mapcar #'(lambda (binding) + (push (cdr binding) commands) + `(bind-key ,(car binding) #',(cdr binding))) + (plist-get args :bind)) + + (mapcar #'(lambda (binding) + (push (cdr binding) commands) + `(bind-key* ,(car binding) #',(cdr binding))) + (plist-get args :bind*)))) + + ;; Should we defer loading of the package lazily? + (defer-loading (and (not (plist-get args :demand)) + (or commands (plist-get args :defer)))) + + ;; These are all the configurations to be made after the package has + ;; loaded. + (config-body + (use-package-cat-maybes + (list (use-package-expand name-string ":config" + (plist-get args :config))) + + (mapcar #'(lambda (var) + (if (listp var) + `(diminish (quote ,(car var)) ,(cdr var)) + `(diminish (quote ,var)))) + (plist-get args :diminish))))) + + ;; Return the main body of the macro + (use-package-cat-maybes + ;; Setup the load-path + (mapcar #'(lambda (path) `(add-to-list 'load-path ,path)) + (plist-get args :load-path)) + + ;; Setup any required autoloads + (if defer-loading + (mapcar #'(lambda (command) `(autoload #',command ,name-string nil t)) + commands)) + + (when (bound-and-true-p byte-compile-current-file) + (mapcar #'(lambda (fn) + `(declare-function ,fn ,name-string)) + (append (plist-get args* :functions) commands))) + + ;; The user's initializations + (list (use-package-expand name-string ":init" + (plist-get args :init))) + + (if defer-loading + (use-package-cat-maybes + bindings + (if config-body + (let ((body + `(use-package-with-elapsed-timer + ,(format "Configuring package %s" + name-string) + ,@config-body))) + (list `(eval-after-load ,name-string + ',body))))) + `((use-package-with-elapsed-timer + ,(format "Loading package %s" name-string) + (if (not (require ',name-symbol nil t)) + (message "Could not load package %s" ,name-string) + ,@(use-package-cat-maybes + bindings + config-body) + t)))) + + ;; Any :idle form that should be executed later + (let ((idle-body (plist-get args :idle))) + (when idle-body + `((require 'use-package) + (use-package-init-on-idle + #'(lambda () ,(use-package-expand name-string ":idle" idle-body)) + ,(plist-get args :idle-priority))))) + + (list t)))) + +(defmacro use-package (name &rest args) + "Declare an Emacs package by specifying a group of configuration options. + +For full documentation, please see the README file that came with +this file. Usage: + + (use-package package-name + [:keyword [option]]...) + +:init Code to run before PACKAGE-NAME has been loaded. +:config Code to run after PACKAGE-NAME has been loaded. Note that if + loading is deferred for any reason, this code does not execute + until the lazy load has occurred. + +:mode Form to be added to `auto-mode-alist'. +:interpreter Form to be added to `interpreter-mode-alist'. + +:commands Define autoloads for commands that will be defined by the + package. This is useful if the package is being lazily loaded, + and you wish to conditionally call functions in your `:init' + block that are defined in the package. + +:bind Bind keys, and define autoloads for the bound commands. +:bind* Bind keys, and define autoloads for the bound commands, + *overriding all minor mode bindings*. +:bind-keymap Bind a key prefix to an auto-loaded keymap defined in the + package. This is like `:bind', but for keymaps. +:bind-keymap* Like `:bind-keymap', but overrides all minor mode bindings + +:defer Defer loading of a package -- this is implied when using + `:commands', `:bind', `:bind*', `:mode' or `:interpreter'. +:demand Prevent deferred loading in all cases. + +:if EXPR Initialize and load only if EXPR evaluates to a non-nil value. +:disabled The package is ignored completely, the same as `:if nil'. +: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). +:idle Adds a form to be run on an idle timer after initialization. +:idle-priority Schedules the :idle form to run with the given priority (lower + priorities run first). Default priority is 5; forms with the + same priority are run in the order in which they are evaluated. +:ensure Loads the package using package.el if necessary. +:pin Pin the package to an archive." + (declare (indent 1)) + (unless (member :disabled args) + (let* ((name-string (if (stringp name) name (symbol-name name))) + (name-symbol (if (stringp name) (intern name) name)) + (args* + (condition-case-unless-debug err + (use-package-normalize-plist name-symbol args) + (error (message (error-message-string err)))))) + + ;; Pin any packages that have been marked with `:pin'. + (let ((archive-name (plist-get args* :pin))) + (when archive-name + (use-package-pin-package name archive-name))) + + ;; Ensure that the package has been installed, if marked with + ;; `:ensure'. + (let* ((ensure (plist-get args* :ensure)) + (package-name (or (and (eq ensure t) name) ensure))) + (when package-name + (require 'package) + (use-package-ensure-elpa package-name))) + + ;; At this point, we can expand the macro using the helper function. + ;; `use--package'. + (let* + ((body (use--package name-symbol name-string args*)) + (pred (plist-get args* :if)) + (expansion (if pred + `(when ,pred ,@body) + (if (= (length body) 1) + (car body) + `(progn ,@body)))) + (requires (plist-get args* :requires)) + + (pre-compile-load + ;; When byte-compiling, load the package here so that all of its + ;; symbols are in scope. + (when (bound-and-true-p byte-compile-current-file) + `((eval-when-compile + ,@(mapcar #'(lambda (var) `(defvar ,var)) + (plist-get args* :defines)) + (with-demoted-errors + ,(format "Error in %s: %%S" name-string) + (message "Compiling package %s" ,name-string) + (require ',name-symbol nil t)))))) + + (body* + (use-package-cat-maybes + pre-compile-load + (list + (if (null requires) + expansion + `(if ,(if (listp requires) + `(not (member nil (mapcar #'featurep ',requires))) + `(featurep ',requires)) + ,expansion)))))) + + ;; If a dynamic test has been requested -- that certain other + ;; packages must be loaded first, before attempting to load and + ;; configure this package -- wrap that logic around the expansion. + (if (= (length body*) 1) + (car body*) + `(progn ,@body*)))))) + +(defun use-package-autoload-keymap (keymap-symbol package override) + "Loads PACKAGE and then binds the key sequence used to invoke +this function to KEYMAP-SYMBOL. It then simulates pressing the +same key sequence a again, so that the next key pressed is routed +to the newly loaded keymap. + +This function supports use-package's :bind-keymap keyword. It +works by binding the given key sequence to an invocation of this +function for a particular keymap. The keymap is expected to be +defined by the package. In this way, loading the package is +deferred until the prefix key sequence is pressed." + (if (not (require package nil t)) + (error "Could not load package %s" package) + (if (and (boundp keymap-symbol) + (keymapp (symbol-value keymap-symbol))) + (let ((key (key-description (this-command-keys-vector))) + (keymap (symbol-value keymap-symbol))) + (if override + ;; eval form is necessary to avoid compiler error + `(eval `(bind-key* ,key ,keymap)) + (bind-key key keymap)) + (setq unread-command-events + (listify-key-sequence (this-command-keys-vector)))) + (error "use-package: package %s failed to define keymap %s" + package keymap-symbol)))) + +(defconst use-package-font-lock-keywords + '(("(\\(use-package\\(?:-with-elapsed-timer\\)?\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" + (1 font-lock-keyword-face) + (2 font-lock-constant-face nil t)))) + +(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :idle support +;; + +(defcustom use-package-idle-interval 3 + "Time to wait when using :idle in a `use-package' specification." + :type 'number + :group 'use-package) (defvar use-package-idle-timer nil) (defvar use-package-idle-forms (make-hash-table)) @@ -141,11 +593,12 @@ Return nil when the queue is empty." (if next (progn (when use-package-verbose - (message "use-package idle:%s" next)) + (message "use-package idle: %s" next)) (condition-case e (funcall next) - (error "Failure on use-package idle. Form: %s, Error: %s" - next e)) + (error + (error "Failure on use-package idle. Form: %s, Error: %s" + next e))) ;; recurse after a bit (when (sit-for use-package-idle-interval) (use-package-idle-eval))) @@ -153,6 +606,11 @@ Return nil when the queue is empty." (cancel-timer use-package-idle-timer) (setq use-package-idle-timer nil)))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :pin and :ensure support +;; + (eval-when-compile (defvar package-pinned-packages) (defvar package-archives)) @@ -191,344 +649,11 @@ manually updated package." (when (not (package-installed-p package)) (package-install package))) -(defvar use-package-keywords - '(:bind - :bind* - :commands - :config - :defer - :defines - :demand - :diminish - :disabled - :ensure - :idle - :idle-priority - :if - :init - :interpreter - :load-path - :mode - :pin - :pre-init - :pre-load - :requires - :bind-keymap - :bind-keymap*) - "Keywords recognized by `use-package'.") - -(defun use-package-mplist-get (plist prop) - "Get the values associated to PROP in PLIST, a modified plist. - -A modified plist is one where keys are keywords and values are -all non-keywords elements that follow it. - -As a special case : if the first occurrence of the keyword PROP -is followed by another keyword or is the last element in the -list, the function returns t. - -Currently this function infloops when the list is circular." - (let ((tail plist) found result) - (while (and (consp tail) - (not (eq prop (car tail)))) - (pop tail)) - (when (eq prop (pop tail)) - (setq found t)) - (while (and (consp tail) - (not (keywordp (car tail)))) - (push (pop tail) result)) - (or (nreverse result) found))) - -(defun use-package-plist-get (plist prop &optional eval-backquote no-progn) - "Compatibility layer between classical and modified plists. - -If `use-package-mplist-get' returns exactly one value, that is -returned ; otherwise the list is returned wrapped in a `progn' -unless NO-PROGN is non-nil. - -When EVAL-BACKQUOTE is non-nil, the value is first evaluated as -if it were backquoted." - (let ((values (use-package-mplist-get plist prop))) - (when eval-backquote - (setq values (eval (list 'backquote values)))) - (when values - (cond ((not (listp values)) - values) - ((eq 1 (length values)) - (car values)) - (t (if no-progn - values - (cons 'progn values))))))) - -(defun use-package-mplist-keys (plist) - "Get the keys in PLIST, a modified plist. - -A modified plist is one where properties are keywords and values -are all non-keywords elements that follow it." - (let ((result)) - (mapc #'(lambda (elt) - (when (keywordp elt) - (push elt result))) - plist) - (nreverse result))) - -(defun use-package-validate-keywords (args) - "Error if any keyword given in ARGS is not recognized. -Return the list of recognized keywords." - (mapc #'(lambda (keyword) - (unless (memq keyword use-package-keywords) - (error "Unrecognized keyword: %s" keyword))) - (use-package-mplist-keys args))) - -(defsubst use-package-maybe-list (sym-or-list) - "If SYM-OR-LIST is just (a . b), return ((a . b))" - (if (and (consp sym-or-list) - (stringp (car sym-or-list))) - (list sym-or-list) - sym-or-list)) - -(defmacro use-package (name &rest args) - "Use a package with configuration options. - -For full documentation. please see commentary. - - (use-package package-name - :keyword option) - -:init Code to run when `use-package' form evals. -:bind Perform key bindings, and define autoload for bound - commands. -:bind* Perform key bindings, and define autoload for bound - commands, overriding all minor mode bindings. -:bind-keymap Bind key prefix to an auto-loaded keymap that - is defined in the package. Like bind but for keymaps - instead of commands. -:bind-keymap* like bind-keymap, but overrides all minor mode bindings -:commands Define autoloads for given commands. -:pre-load Code to run when `use-package' form evals and before - anything else. Unlike :init this form runs before the - package is required or autoloads added. -:mode Form to be added to `auto-mode-alist'. -:interpreter Form to be added to `interpreter-mode-alist'. -:defer Defer loading of package -- automatic - if :commands, :bind, :bind*, :mode or :interpreter are used. -:demand Prevent deferred loading in all cases. -:config Runs if and when package loads. -:if Conditional loading. -:disabled Ignore everything. -:defines Define vars to silence byte-compiler. -:load-path Add to `load-path' before loading. -:diminish Support for diminish package (if it's installed). -:idle adds a form to run on an idle timer -:idle-priority schedules the :idle form to run with the given - priority (lower priorities run first). Default priority - is 5; forms with the same priority are run in the order in - which they are evaluated. -:ensure loads package using package.el if necessary. -:pin pin package to archive." - (use-package-validate-keywords args) ; error if any bad keyword, ignore result - ;; force this immediately -- one off cost - (unless (use-package-plist-get args :disabled) - (let* ((commands (use-package-plist-get args :commands t t)) - (pre-init-body (use-package-plist-get args :pre-init)) - (pre-load-body (use-package-plist-get args :pre-load)) - init-body - (config-body (use-package-plist-get args :config)) - (diminish-var (use-package-plist-get args :diminish t)) - (defines (use-package-plist-get args :defines t t)) - (idle-body (use-package-plist-get args :idle)) - (idle-priority (use-package-plist-get args :idle-priority)) - (keybindings-alist (use-package-plist-get args :bind t t)) - (overriding-keybindings-alist (use-package-plist-get args :bind* t t)) - (keymap-alist (use-package-plist-get args :bind-keymap t t)) - (overriding-keymap-alist - (use-package-plist-get args :bind-keymap* t t)) - (mode (use-package-plist-get args :mode t t)) - (mode-alist - (if (stringp mode) (cons mode name) mode)) - (interpreter (use-package-plist-get args :interpreter t t)) - (interpreter-alist - (if (stringp interpreter) (cons interpreter name) interpreter)) - (predicate (use-package-plist-get args :if)) - (pkg-load-path (use-package-plist-get args :load-path t t)) - (archive-name (use-package-plist-get args :pin)) - (defines-eval (if (null defines) - nil - (if (listp defines) - (mapcar #'(lambda (var) `(defvar ,var)) defines) - `((defvar ,defines))))) - (requires (use-package-plist-get args :requires t)) - (requires-test (if (null requires) - t - (if (listp requires) - `(not (member nil (mapcar #'featurep - (quote ,requires)))) - `(featurep (quote ,requires))))) - (name-string (if (stringp name) name (symbol-name name))) - (name-symbol (if (stringp name) (intern name) name))) - - (when archive-name - (use-package-pin-package name archive-name)) - - (let* ((ensure (use-package-plist-get args :ensure)) - (package-name (or (and (eq ensure t) name) ensure))) - (when package-name - (require 'package) - (use-package-ensure-elpa package-name))) - - (if diminish-var - (setq - config-body - `(progn - ,config-body - (ignore-errors - ,@(cond - ((stringp diminish-var) - `((diminish (quote ,(intern (concat name-string "-mode"))) - ,diminish-var))) - ((symbolp diminish-var) - `((diminish (quote ,diminish-var)))) - ((and (consp diminish-var) (stringp (cdr diminish-var))) - `((diminish (quote ,(car diminish-var)) - ,(cdr diminish-var)))) - (t ; list of symbols or (symbol . "string") pairs - (mapcar #'(lambda (var) - (if (listp var) - `(diminish (quote ,(car var)) ,(cdr var)) - `(diminish (quote ,var)))) - diminish-var))))))) - - (if (and commands (symbolp commands)) - (setq commands (list commands))) - - (setq - init-body - (append - (mapcar #'(lambda (mode) - (push (cdr mode) commands) - `(add-to-list 'auto-mode-alist ',mode)) - (use-package-maybe-list mode-alist)) - - (mapcar #'(lambda (interpreter) - (push (cdr interpreter) commands) - `(add-to-list 'interpreter-mode-alist ',interpreter)) - (use-package-maybe-list interpreter-alist)) - - (mapcar #'(lambda (binding) - (push (cdr binding) commands) - `(bind-key ,(car binding) #',(cdr binding))) - (use-package-maybe-list keybindings-alist)) - - (mapcar #'(lambda (binding) - (push (cdr binding) commands) - `(bind-key* ,(car binding) #',(cdr binding))) - (use-package-maybe-list overriding-keybindings-alist)) - - (mapcar #'(lambda (binding) - `(bind-key ,(car binding) - #'(lambda () (interactive) - (use-package-autoload-keymap - ',(cdr binding) ,name-symbol nil)))) - (use-package-maybe-list keymap-alist)) - - (mapcar #'(lambda (binding) - `(bind-key ,(car binding) - #'(lambda () (interactive) - (use-package-autoload-keymap - ',(cdr binding) ,name-symbol t)))) - (use-package-maybe-list overriding-keymap-alist)) - - ;; First, execute the user's initializations - (list (use-package-plist-get args :init)) - - (when idle-body - (when (null idle-priority) - (setq idle-priority 5)) - (list - `(progn - (require 'use-package) - (use-package-init-on-idle #'(lambda () ,idle-body) - ,idle-priority)))))) - - `(progn - ,pre-load-body - ,@(mapcar - #'(lambda (path) - `(add-to-list 'load-path - ,(if (file-name-absolute-p path) - path - (expand-file-name path user-emacs-directory)))) - (cond ((stringp pkg-load-path) - (list pkg-load-path)) - ((functionp pkg-load-path) - (funcall pkg-load-path)) - (t pkg-load-path))) - - (eval-when-compile - (when (bound-and-true-p byte-compile-current-file) - ,@defines-eval - (with-demoted-errors - ,(format "Error in %s: %%S" name) - (require ',name-symbol nil t)))) - - ,(if (and (or commands (use-package-plist-get args :defer)) - (not (use-package-plist-get args :demand))) - `(when ,(or predicate t) - ,pre-init-body - ,@(mapcar #'(lambda (command) - `(autoload #',command ,name-string nil t)) - commands) - ,@init-body - ,(if (and config-body requires-test) - `(eval-after-load ,name-string - '(use-package-with-elapsed-timer - ,(format "Configuring package %s" name-string) - ,config-body))) - t) - `(when (and ,(or predicate t) ,requires-test) - (use-package-with-elapsed-timer - ,(format "Loading package %s" name-string) - (if (not (require ',name-symbol nil t)) - (message "Could not load package %s" ,name-string) - ,pre-init-body - ,@init-body - ,config-body - t)))))))) - -(defun use-package-autoload-keymap (keymap-symbol package override) - "Loads PACKAGE and then binds the key sequence used to invoke -this function to KEYMAP-SYMBOL. It then simulates pressing the -same key sequence a again, so that the next key pressed is routed -to the newly loaded keymap. - -This function supports use-package's :bind-keymap keyword. It -works by binding the given key sequence to an invocation of this -function for a particular keymap. The keymap is expected to be -defined by the package. In this way, loading the package is -deferred until the prefix key sequence is pressed." - (if (not (require package nil t)) - (error "Could not load package %s" package) - (if (and (boundp keymap-symbol) - (keymapp (symbol-value keymap-symbol))) - (let ((key (key-description (this-command-keys-vector))) - (keymap (symbol-value keymap-symbol))) - (if override - ;; eval form is necessary to avoid compiler error - `(eval `(bind-key* ,key ,keymap)) - (bind-key key keymap)) - (setq unread-command-events - (listify-key-sequence (this-command-keys-vector)))) - (error "use-package: package %s failed to define keymap %s" - package keymap-symbol)))) - (put 'use-package 'lisp-indent-function 'defun) - -(defconst use-package-font-lock-keywords - '(("(\\(use-package\\(?:-with-elapsed-timer\\)?\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" - (1 font-lock-keyword-face) - (2 font-lock-constant-face nil t)))) - -(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords) +(put 'use-package-expand 'lisp-indent-function 'defun) +(put 'use-package-only-one 'lisp-indent-function 'defun) +(put 'use-package-as-one 'lisp-indent-function 'defun) +(put 'use-package-with-elapsed-timer 'lisp-indent-function 'defun) (provide 'use-package) From 27cba067ee6c6aa93af4914d06db6e6ea876ed3d Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 14 Mar 2015 11:33:12 -0400 Subject: [PATCH 124/606] use-package-expand: use display-warning instead of with-demoted-errors. This prevents errors from getting lost in the *Messages* buffer. --- lisp/use-package/use-package.el | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 75d5ee6187c..0d295d192bb 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -282,9 +282,12 @@ then the expanded macros do their job silently." (defsubst use-package-expand (name label form) (declare (indent 1)) (and form - `(with-demoted-errors - ,(format "Failure in %s of %s: %%S" label name) - ,form))) + (let ((err (make-symbol "err")) + (fmt (format "Failure in %s of %s: %%S" label name))) + `(condition-case-unless-debug ,err + ,form + (error (display-warning 'use-package (format ,fmt ,err) :error) + nil))))) (defun use--package (name-symbol name-string args) "See docstring for `use-package'." From e68d00d525934fbadc0cde3f5150f79b366e36db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Fr=C3=B6ssman?= Date: Sat, 14 Mar 2015 17:53:02 +0100 Subject: [PATCH 125/606] Fix :ensure value interpretation --- lisp/use-package/use-package.el | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 75d5ee6187c..e0a19f0dde4 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -234,12 +234,22 @@ then the expanded macros do their job silently." (use-package-as-one (symbol-name head) args #'use-package-normalize-symbols)) - ((or :defer :demand :disabled :ensure) + ((or :defer :demand :disabled) (if (null args) t (use-package-only-one (symbol-name head) args #'use-package-normalize-value))) + (:ensure + (use-package-only-one (symbol-name head) args + (if (null args) + t + (lambda (label arg) + (if (symbolp arg) + arg + (use-package-error + ":ensure wants an optional package name (a unquoted symbol name)")))))) + ((or :if :when :unless) (use-package-only-one (symbol-name head) args #'use-package-normalize-value)) From 71f894fe78dc5ddb369ab387ece3d2255e11f07c Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 15 Mar 2015 02:21:40 -0500 Subject: [PATCH 126/606] Fix to :ensure normalization --- lisp/use-package/use-package.el | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 72550d0d35d..7cdd01d07b8 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -241,14 +241,15 @@ then the expanded macros do their job silently." #'use-package-normalize-value))) (:ensure - (use-package-only-one (symbol-name head) args - (if (null args) - t + (if (null args) + t + (use-package-only-one (symbol-name head) args (lambda (label arg) (if (symbolp arg) arg (use-package-error - ":ensure wants an optional package name (a unquoted symbol name)")))))) + (concat ":ensure wants an optional package name " + "(an unquoted symbol name)"))))))) ((or :if :when :unless) (use-package-only-one (symbol-name head) args From b4a00d2eb56abf89dc076dc92d9f14cca6972fd1 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 15 Mar 2015 02:21:53 -0500 Subject: [PATCH 127/606] Some minor code reformatting --- lisp/use-package/use-package.el | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 7cdd01d07b8..b3bf871576f 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -292,13 +292,14 @@ then the expanded macros do their job silently." (defsubst use-package-expand (name label form) (declare (indent 1)) - (and form - (let ((err (make-symbol "err")) - (fmt (format "Failure in %s of %s: %%S" label name))) - `(condition-case-unless-debug ,err - ,form - (error (display-warning 'use-package (format ,fmt ,err) :error) - nil))))) + (when form + (let ((err (make-symbol "err")) + (fmt (format "Failure in %s of %s: %%S" label name))) + `(condition-case-unless-debug ,err + ,form + (error + (ignore + (display-warning 'use-package (format ,fmt ,err) :error))))))) (defun use--package (name-symbol name-string args) "See docstring for `use-package'." From f637380fed23637dca2fe3bfe75cd629c2b0d0b9 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 15 Mar 2015 02:22:17 -0500 Subject: [PATCH 128/606] Add :preface, occurring before everything except :disabled This can be used to establish function and variable definitions that will 1) make the byte-compiler happy (it won't complain about functions whose definitions are unknown because you have them within a guard block), and 2) allow you to define code that can be used in an `:if` test. --- lisp/use-package/use-package.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index b3bf871576f..56c8a4c2e6d 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -259,7 +259,7 @@ then the expanded macros do their job silently." (use-package-as-one (symbol-name head) args (apply-partially #'use-package-normalize-diminish name-symbol))) - ((or :init :config :idle) + ((or :preface :init :config :idle) (use-package-normalize-form (symbol-name head) args)) (:idle-priority @@ -363,6 +363,8 @@ then the expanded macros do their job silently." ;; Return the main body of the macro (use-package-cat-maybes + (list (plist-get args :preface)) + ;; Setup the load-path (mapcar #'(lambda (path) `(add-to-list 'load-path ,path)) (plist-get args :load-path)) From 81f5e48d328e209631c6ec2588fe8d29e3c7053b Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 15 Mar 2015 03:49:16 -0500 Subject: [PATCH 129/606] Support optional injection of hooks, for Spacemacs --- lisp/use-package/use-package.el | 49 +++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 56c8a4c2e6d..e4ef0048e59 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -72,6 +72,41 @@ then the expanded macros do their job silently." :type 'number :group 'use-package) +(defcustom use-package-inject-hooks nil + "If non-nil, add hooks to the `:init' and `:config' sections for a package. +In particular, for a given package `foo', the following hooks +will become available: + + `use-package--foo--pre-init' + `use-package--foo--post-init' + `use-package--foo--pre-config' + `use-package--foo--post-config' + +This way, you can add to these hooks before evalaution of a +`use-package` declaration, and exercise some control over what +happens. + +Note that if either `pre-init' hooks returns a nil value, that +block's user-supplied configuration is not evaluated, so be +certain to return `t' if you only wish to add behavior to what +the user specified.") + +(defun use-package-hook-injector (name-string keyword args) + "Wrap pre/post hook injections around a given keyword form." + (let ((keyword-name (substring (format "%s" keyword) 1)) + (block (plist-get args keyword))) + (when block + `(when ,(use-package-expand name-string (format "pre-%s hook" keyword) + `(run-hook-with-args-until-failure + ',(intern (concat "use-package--" name-string + "--pre-" keyword-name)))) + ,(use-package-expand name-string (format "%s" keyword) + (plist-get args keyword)) + ,(use-package-expand name-string (format "post-%s hook" keyword) + `(run-hooks + ',(intern (concat "use-package--" name-string + "--post-" keyword-name)))))))) + (defmacro use-package-with-elapsed-timer (text &rest body) (declare (indent 1)) (let ((nowvar (make-symbol "now"))) @@ -352,8 +387,10 @@ then the expanded macros do their job silently." ;; loaded. (config-body (use-package-cat-maybes - (list (use-package-expand name-string ":config" - (plist-get args :config))) + (list (if use-package-inject-hooks + (use-package-hook-injector name-string :config args) + (use-package-expand name-string ":config" + (plist-get args :config)))) (mapcar #'(lambda (var) (if (listp var) @@ -377,11 +414,13 @@ then the expanded macros do their job silently." (when (bound-and-true-p byte-compile-current-file) (mapcar #'(lambda (fn) `(declare-function ,fn ,name-string)) - (append (plist-get args* :functions) commands))) + (append (plist-get args :functions) commands))) ;; The user's initializations - (list (use-package-expand name-string ":init" - (plist-get args :init))) + (list (if use-package-inject-hooks + (use-package-hook-injector name-string :init args) + (use-package-expand name-string ":init" + (plist-get args :init)))) (if defer-loading (use-package-cat-maybes From 1f20acfd57e93fd749c536dc24f5dcfdbe43e417 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sun, 15 Mar 2015 15:14:04 -0400 Subject: [PATCH 130/606] use--package: eval-after-load name instead of name-string. This prevents triggering by config file names that have the same name as the package. Reprise of c6d79d2cb40bd141f62eaca6dca47fb2e8e6943f --- lisp/use-package/use-package.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index e4ef0048e59..36021b4d520 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -336,7 +336,7 @@ the user specified.") (ignore (display-warning 'use-package (format ,fmt ,err) :error))))))) -(defun use--package (name-symbol name-string args) +(defun use--package (name name-symbol name-string args) "See docstring for `use-package'." (let* ((commands (plist-get args :commands)) @@ -431,7 +431,7 @@ the user specified.") ,(format "Configuring package %s" name-string) ,@config-body))) - (list `(eval-after-load ,name-string + (list `(eval-after-load ',name ',body))))) `((use-package-with-elapsed-timer ,(format "Loading package %s" name-string) @@ -522,7 +522,7 @@ this file. Usage: ;; At this point, we can expand the macro using the helper function. ;; `use--package'. (let* - ((body (use--package name-symbol name-string args*)) + ((body (use--package name name-symbol name-symbol args*)) (pred (plist-get args* :if)) (expansion (if pred `(when ,pred ,@body) From 9385ab417af21653b5b62219dd19ac95a0df3b0a Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 15 Mar 2015 18:07:37 -0500 Subject: [PATCH 131/606] BREAKING CHANGE: Remove :idle and :idle-priority I am removing this feature for now because it can result in a nasty inconsistency. Consider the following definition: (use-package vkill :commands vkill :idle (some-important-configuration-here) :bind ("C-x L" . vkill-and-helm-occur) :init (defun vkill-and-helm-occur () (interactive) (vkill) (call-interactively #'helm-occur)) :config (setq vkill-show-all-processes t)) If I load my Emacs and wait until the idle timer fires, then this is the sequence of events: :init :idle :config But if I load Emacs and immediately type C-x L without waiting for the idle timer to fire, this is the sequence of events: :init :config :idle It's possible that the user could use `featurep` in their idle to test for this case, but that's a subtlety I'd rather avoid. What I would consider is this: `:idle [N]` is a keyword that simply implies `:defer`, with an option number of N to specify a second count. After that many seconds, if the package has not yet been loaded by autoloading, it will be loaded via the idle timer. This approach has the benefit of complete consistency for both the idle and the autoloaded cases. Although, the fact that it implies `:defer` means we don't have to consider what it means to add `:idle` behavior to a demand-loaded configuration. --- lisp/use-package/use-package.el | 102 +++----------------------------- 1 file changed, 9 insertions(+), 93 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index e4ef0048e59..ce96a701ebc 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -294,19 +294,9 @@ the user specified.") (use-package-as-one (symbol-name head) args (apply-partially #'use-package-normalize-diminish name-symbol))) - ((or :preface :init :config :idle) + ((or :preface :init :config) (use-package-normalize-form (symbol-name head) args)) - (:idle-priority - (if (null args) - 5 - (use-package-only-one (symbol-name head) args - (lambda (label arg) - (if (numberp arg) - arg - (use-package-error - ":idle-priority wants an optional number")))))) - (:load-path (use-package-as-one (symbol-name head) args #'use-package-normalize-paths)) @@ -408,8 +398,14 @@ the user specified.") ;; Setup any required autoloads (if defer-loading - (mapcar #'(lambda (command) `(autoload #',command ,name-string nil t)) - commands)) + (delete nil + (mapcar #'(lambda (command) + ;; (unless (and (fboundp command) + ;; (not (autoloadp command))) + ;; `(autoload #',command ,name-string nil t)) + `(autoload #',command ,name-string nil t) + ) + commands))) (when (bound-and-true-p byte-compile-current-file) (mapcar #'(lambda (fn) @@ -442,14 +438,6 @@ the user specified.") config-body) t)))) - ;; Any :idle form that should be executed later - (let ((idle-body (plist-get args :idle))) - (when idle-body - `((require 'use-package) - (use-package-init-on-idle - #'(lambda () ,(use-package-expand name-string ":idle" idle-body)) - ,(plist-get args :idle-priority))))) - (list t)))) (defmacro use-package (name &rest args) @@ -491,10 +479,6 @@ this file. Usage: :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). -:idle Adds a form to be run on an idle timer after initialization. -:idle-priority Schedules the :idle form to run with the given priority (lower - priorities run first). Default priority is 5; forms with the - same priority are run in the order in which they are evaluated. :ensure Loads the package using package.el if necessary. :pin Pin the package to an archive." (declare (indent 1)) @@ -594,74 +578,6 @@ deferred until the prefix key sequence is pressed." (font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; :idle support -;; - -(defcustom use-package-idle-interval 3 - "Time to wait when using :idle in a `use-package' specification." - :type 'number - :group 'use-package) - -(defvar use-package-idle-timer nil) -(defvar use-package-idle-forms (make-hash-table)) - -(defun use-package-start-idle-timer () - "Ensure that the idle timer is running." - (unless use-package-idle-timer - (setq use-package-idle-timer - (run-with-idle-timer use-package-idle-interval t - 'use-package-idle-eval)))) - -(defun use-package-init-on-idle (form priority) - "Add a new form to the idle queue." - (use-package-start-idle-timer) - (puthash priority - (append (gethash priority use-package-idle-forms) - (list form)) - use-package-idle-forms)) - -(defun use-package-idle-priorities () - "Get a list of all priorities in the idle queue. -The list is sorted in the order forms should be run." - (let ((priorities nil)) - (maphash #'(lambda (priority forms) - (setq priorities (cons priority priorities))) - use-package-idle-forms) - (sort priorities '<))) - -(defun use-package-idle-pop () - "Pop the top-priority task from the idle queue. -Return nil when the queue is empty." - (let* ((priority (car (use-package-idle-priorities))) - (forms (gethash priority use-package-idle-forms)) - (first-form (car forms)) - (forms-remaining (cdr forms))) - (if forms-remaining - (puthash priority forms-remaining use-package-idle-forms) - (remhash priority use-package-idle-forms)) - first-form)) - -(defun use-package-idle-eval () - "Start to eval idle-commands from the idle queue." - (let ((next (use-package-idle-pop))) - (if next - (progn - (when use-package-verbose - (message "use-package idle: %s" next)) - (condition-case e - (funcall next) - (error - (error "Failure on use-package idle. Form: %s, Error: %s" - next e))) - ;; recurse after a bit - (when (sit-for use-package-idle-interval) - (use-package-idle-eval))) - ;; finished (so far!) - (cancel-timer use-package-idle-timer) - (setq use-package-idle-timer nil)))) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; :pin and :ensure support From 03ea5d6dbf58597525afd2e8cd8f321af18feba9 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 15 Mar 2015 18:45:41 -0500 Subject: [PATCH 132/606] Restore an earlier fix to Fixes https://github.com/jwiegley/use-package/issues/167 GitHub-reference: https://github.com/jwiegley/use-package/issues/53 --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index ce96a701ebc..1693698b5ef 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -427,7 +427,7 @@ the user specified.") ,(format "Configuring package %s" name-string) ,@config-body))) - (list `(eval-after-load ,name-string + (list `(eval-after-load ,(if (stringp name) name `',name) ',body))))) `((use-package-with-elapsed-timer ,(format "Loading package %s" name-string) From 199399e552561b99b0232ae65f7208be5141d87c Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 15 Mar 2015 18:49:08 -0500 Subject: [PATCH 133/606] Add -hook to the injected hooks Fixes https://github.com/jwiegley/use-package/issues/161 --- lisp/use-package/use-package.el | 47 +++++++++++++++------------------ 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 1693698b5ef..c63929cc0f2 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -77,10 +77,10 @@ then the expanded macros do their job silently." In particular, for a given package `foo', the following hooks will become available: - `use-package--foo--pre-init' - `use-package--foo--post-init' - `use-package--foo--pre-config' - `use-package--foo--post-config' + `use-package--foo--pre-init-hook' + `use-package--foo--post-init-hook' + `use-package--foo--pre-config-hook' + `use-package--foo--post-config-hook' This way, you can add to these hooks before evalaution of a `use-package` declaration, and exercise some control over what @@ -93,19 +93,22 @@ the user specified.") (defun use-package-hook-injector (name-string keyword args) "Wrap pre/post hook injections around a given keyword form." - (let ((keyword-name (substring (format "%s" keyword) 1)) - (block (plist-get args keyword))) - (when block - `(when ,(use-package-expand name-string (format "pre-%s hook" keyword) - `(run-hook-with-args-until-failure - ',(intern (concat "use-package--" name-string - "--pre-" keyword-name)))) - ,(use-package-expand name-string (format "%s" keyword) - (plist-get args keyword)) - ,(use-package-expand name-string (format "post-%s hook" keyword) - `(run-hooks - ',(intern (concat "use-package--" name-string - "--post-" keyword-name)))))))) + (if (not use-package-inject-hooks) + (use-package-expand name-string (format "%s" keyword) + (plist-get args keyword)) + (let ((keyword-name (substring (format "%s" keyword) 1)) + (block (plist-get args keyword))) + (when block + `(when ,(use-package-expand name-string (format "pre-%s hook" keyword) + `(run-hook-with-args-until-failure + ',(intern (concat "use-package--" name-string + "--pre-" keyword-name "-hook")))) + ,(use-package-expand name-string (format "%s" keyword) + (plist-get args keyword)) + ,(use-package-expand name-string (format "post-%s hook" keyword) + `(run-hooks + ',(intern (concat "use-package--" name-string + "--post-" keyword-name "-hook"))))))))) (defmacro use-package-with-elapsed-timer (text &rest body) (declare (indent 1)) @@ -377,10 +380,7 @@ the user specified.") ;; loaded. (config-body (use-package-cat-maybes - (list (if use-package-inject-hooks - (use-package-hook-injector name-string :config args) - (use-package-expand name-string ":config" - (plist-get args :config)))) + (list (use-package-hook-injector name-string :config args)) (mapcar #'(lambda (var) (if (listp var) @@ -413,10 +413,7 @@ the user specified.") (append (plist-get args :functions) commands))) ;; The user's initializations - (list (if use-package-inject-hooks - (use-package-hook-injector name-string :init args) - (use-package-expand name-string ":init" - (plist-get args :init)))) + (list (use-package-hook-injector name-string :init args)) (if defer-loading (use-package-cat-maybes From 98b642b794dfbeb7476b9ad1202809c1c5dce789 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 15 Mar 2015 19:07:03 -0500 Subject: [PATCH 134/606] Undo an erroneous change --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index c63929cc0f2..50b1431759e 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -424,7 +424,7 @@ the user specified.") ,(format "Configuring package %s" name-string) ,@config-body))) - (list `(eval-after-load ,(if (stringp name) name `',name) + (list `(eval-after-load ,name-string ',body))))) `((use-package-with-elapsed-timer ,(format "Loading package %s" name-string) From a66d1952e3ca688d89bf997e50624e1e1896f9ad Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 15 Mar 2015 20:39:19 -0500 Subject: [PATCH 135/606] Update docstring for :disabled --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 17543e3e734..6febf6af698 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -471,7 +471,7 @@ this file. Usage: :demand Prevent deferred loading in all cases. :if EXPR Initialize and load only if EXPR evaluates to a non-nil value. -:disabled The package is ignored completely, the same as `:if nil'. +: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. From a2030288716a2aa315482fa265cc970b5a208703 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 15 Mar 2015 21:21:11 -0500 Subject: [PATCH 136/606] Correct an erroneous symbol reference --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 6febf6af698..be4b0cd7c09 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -503,7 +503,7 @@ this file. Usage: ;; At this point, we can expand the macro using the helper function. ;; `use--package'. (let* - ((body (use--package name name-symbol name-symbol args*)) + ((body (use--package name name-symbol name-string args*)) (pred (plist-get args* :if)) (expansion (if pred `(when ,pred ,@body) From 5c85433fac3d51f6df0a82d670b3c3a147d09164 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 15 Mar 2015 21:23:40 -0500 Subject: [PATCH 137/606] Relax a path normalization check --- lisp/use-package/use-package.el | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index be4b0cd7c09..b843725eccb 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -228,10 +228,7 @@ the user specified.") (let ((path (if (file-name-absolute-p arg) arg (expand-file-name arg user-emacs-directory)))) - (if (file-directory-p path) - (list path) - (use-package-error - (concat label " wants a directory path, or list of paths"))))) + (list path))) ((and (not recursed) (listp arg) (listp (cdr arg))) (mapcar #'(lambda (x) (car (use-package-normalize-paths label x t))) arg)) From b75c1cb47e7ca8bc37536eab6b9534f2c8ecbea4 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 16 Mar 2015 02:48:13 -0500 Subject: [PATCH 138/606] Allow :pin to accept a symbol --- lisp/use-package/use-package.el | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index b843725eccb..638a16ee992 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -304,9 +304,12 @@ the user specified.") (:pin (use-package-only-one (symbol-name head) args (lambda (label arg) - (if (stringp arg) - arg - (use-package-error ":pin wants an archive name (a string)"))))) + (cond + ((stringp arg) arg) + ((symbolp arg) (symbol-name arg)) + (t + (use-package-error + ":pin wants an archive name (a string)")))))) (_ (use-package-error (format "Unrecognized keyword: %s" head))))) (use-package-normalize-plist name-symbol tail))))) From 4029030eb564ef553d9135a6ec576786b0a0ea2a Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 16 Mar 2015 02:48:55 -0500 Subject: [PATCH 139/606] Output Compiling message only if verbose is enabled --- lisp/use-package/use-package.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 638a16ee992..c1e5c36fb88 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -521,7 +521,8 @@ this file. Usage: (plist-get args* :defines)) (with-demoted-errors ,(format "Error in %s: %%S" name-string) - (message "Compiling package %s" ,name-string) + (if use-package-verbose + (message "Compiling package %s" ,name-string)) (require ',name-symbol nil t)))))) (body* From 55d6bb00cac8bab2be81e16ca62fca28fc83af6b Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 16 Mar 2015 02:54:43 -0500 Subject: [PATCH 140/606] Add code to workaround an inefficiency with eval-after-load This is currently disabled, as it leads to strange byte-compilation errors that need to be tracked down. --- lisp/use-package/use-package.el | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index c1e5c36fb88..a619ded7727 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -386,7 +386,11 @@ the user specified.") (if (listp var) `(diminish (quote ,(car var)) ,(cdr var)) `(diminish (quote ,var)))) - (plist-get args :diminish))))) + (plist-get args :diminish)))) + + (config-defun (make-symbol (concat name-string "-config")))) + + (setq commands (delete-dups commands)) ;; Return the main body of the macro (use-package-cat-maybes @@ -412,6 +416,12 @@ the user specified.") `(declare-function ,fn ,name-string)) (append (plist-get args :functions) commands))) + ;; (if (and defer-loading config-body) + ;; `((defun ,config-defun () + ;; (use-package-with-elapsed-timer + ;; ,(format "Configuring package %s" name-string) + ;; ,@config-body)))) + ;; The user's initializations (list (use-package-hook-injector name-string :init args)) @@ -419,17 +429,16 @@ the user specified.") (use-package-cat-maybes bindings (if config-body - (let ((body - `(use-package-with-elapsed-timer - ,(format "Configuring package %s" - name-string) - ,@config-body))) - (list `(eval-after-load ',name - ',body))))) + `((eval-after-load ',name + '(use-package-with-elapsed-timer + ,(format "Configuring package %s" name-string) + ,@config-body))))) `((use-package-with-elapsed-timer ,(format "Loading package %s" name-string) (if (not (require ',name-symbol nil t)) - (message "Could not load package %s" ,name-string) + (display-warning + 'use-package + (format "Could not load package %s" ,name-string) :error) ,@(use-package-cat-maybes bindings config-body) @@ -485,7 +494,9 @@ this file. Usage: (args* (condition-case-unless-debug err (use-package-normalize-plist name-symbol args) - (error (message (error-message-string err)))))) + (error + (display-warning 'use-package + (error-message-string err) :error))))) ;; Pin any packages that have been marked with `:pin'. (let ((archive-name (plist-get args* :pin))) From 05c02aee865762ef7b5dd1a3a39df7b3c4f29606 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 16 Mar 2015 03:19:28 -0500 Subject: [PATCH 141/606] Allow vectors to be passed to :bind again Fixes https://github.com/jwiegley/use-package/issues/166 --- lisp/use-package/use-package.el | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index a619ded7727..b7ef29aae0e 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -187,22 +187,24 @@ the user specified.") (use-package-error (concat label " wants a list")))) -(defsubst use-package-is-sympair (x) +(defsubst use-package-is-sympair (x &optional allow-vector) "Return t if X has the type (STRING . SYMBOL)." (and (consp x) - (stringp (car x)) + (or (stringp (car x)) + (and allow-vector (vectorp (car x)))) (symbolp (cdr x)))) -(defun use-package-normalize-pairs (name-symbol label arg &optional recursed) +(defun use-package-normalize-pairs + (name-symbol label arg &optional recursed allow-vector) "Normalize a list of string/symbol pairs." (cond - ((stringp arg) + ((or (stringp arg) (and allow-vector (vectorp arg))) (list (cons arg name-symbol))) - ((use-package-is-sympair arg) + ((use-package-is-sympair arg allow-vector) (list arg)) ((and (not recursed) (listp arg) (listp (cdr arg))) (mapcar #'(lambda (x) (car (use-package-normalize-pairs - name-symbol label x t))) arg)) + name-symbol label x t allow-vector))) arg)) (t (use-package-error (concat label " wants a string, (string . symbol) or list of these"))))) @@ -261,7 +263,12 @@ the user specified.") (cond ((memq head '(:when :unless)) :if) (t head)) (pcase head - ((or :bind :bind* :bind-keymap :bind-keymap* :interpreter :mode) + ((or :bind :bind* :bind-keymap :bind-keymap*) + (use-package-as-one (symbol-name head) args + (lambda (label arg) + (use-package-normalize-pairs name-symbol label arg nil t)))) + + ((or :interpreter :mode) (use-package-as-one (symbol-name head) args (apply-partially #'use-package-normalize-pairs name-symbol))) From 21a091f17a49175339b45efa422a1ab2e2cf8a45 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 16 Mar 2015 03:25:21 -0500 Subject: [PATCH 142/606] Collapse some whitespace --- lisp/use-package/use-package.el | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index b7ef29aae0e..3f51372f055 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -607,12 +607,8 @@ deferred until the prefix key sequence is pressed." "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)))) + (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)) From 302c008b456374e7a0ddd5858617f53681675d3b Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 16 Mar 2015 10:39:37 -0500 Subject: [PATCH 143/606] Permit minimal expansion of macro bodies, and other fixes --- lisp/use-package/use-package.el | 262 ++++++++++++++++++-------------- 1 file changed, 144 insertions(+), 118 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 3f51372f055..96f36e40939 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -89,43 +89,83 @@ happens. Note that if either `pre-init' hooks returns a nil value, that block's user-supplied configuration is not evaluated, so be certain to return `t' if you only wish to add behavior to what -the user specified.") +the user 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 + - Capture of load errors (normally redisplayed as warnings) + - Conditional loading of packages (load failures become errors) +The only real advantage is that, if you know your configuration +works, then your byte-compiled init file is as minimal as +possible." + :type 'boolean + :group 'use-package) + +(defmacro use-package-expand (name label form) + (declare (indent 1)) + (when form + (if use-package-expand-minimally + form + (let ((err (make-symbol "err"))) + `(condition-case-unless-debug ,err + ,form + (error + (ignore + (display-warning 'use-package (error-message-string ,err) + :error)))))))) + +(put 'use-package-expand 'lisp-indent-function 'defun) (defun use-package-hook-injector (name-string keyword args) "Wrap pre/post hook injections around a given keyword form." (if (not use-package-inject-hooks) - (use-package-expand name-string (format "%s" keyword) - (plist-get args keyword)) + (macroexpand-all + `(use-package-expand name-string ,(format "%s" keyword) + ,(plist-get args keyword))) (let ((keyword-name (substring (format "%s" keyword) 1)) (block (plist-get args keyword))) (when block - `(when ,(use-package-expand name-string (format "pre-%s hook" keyword) - `(run-hook-with-args-until-failure - ',(intern (concat "use-package--" name-string - "--pre-" keyword-name "-hook")))) - ,(use-package-expand name-string (format "%s" keyword) - (plist-get args keyword)) - ,(use-package-expand name-string (format "post-%s hook" keyword) - `(run-hooks - ',(intern (concat "use-package--" name-string - "--post-" keyword-name "-hook"))))))))) + (macroexpand-all + `(when (use-package-expand name-string ,(format "pre-%s hook" keyword) + (run-hook-with-args-until-failure + ',(intern (concat "use-package--" name-string + "--pre-" keyword-name "-hook")))) + (use-package-expand name-string ,(format "%s" keyword) + ,(plist-get args keyword)) + (use-package-expand name-string ,(format "post-%s hook" keyword) + (run-hooks + ',(intern (concat "use-package--" name-string + "--post-" keyword-name "-hook")))))))))) + +(defun use-package-progn (body) + (if (= (length body) 1) + (car body) + `(progn ,@body))) (defmacro use-package-with-elapsed-timer (text &rest body) (declare (indent 1)) - (let ((nowvar (make-symbol "now"))) - (if (bound-and-true-p use-package-verbose) - `(let ((,nowvar (current-time))) - (message "%s..." ,text) - (prog1 - (progn ,@body) - (let ((elapsed - (float-time (time-subtract (current-time) ,nowvar)))) - (if (> elapsed - (or (bound-and-true-p use-package-minimum-reported-time) - "0.01")) - (message "%s...done (%.3fs)" ,text elapsed) - (message "%s...done" ,text))))) - `(progn ,@body)))) + (if use-package-expand-minimally + (use-package-progn body) + (let ((nowvar (make-symbol "now"))) + (if (bound-and-true-p use-package-verbose) + `(let ((,nowvar (current-time))) + (message "%s..." ,text) + (prog1 + ,(use-package-progn body) + (let ((elapsed + (float-time (time-subtract (current-time) ,nowvar)))) + (if (> elapsed + (or (bound-and-true-p use-package-minimum-reported-time) + "0.01")) + (message "%s...done (%.3fs)" ,text elapsed) + (message "%s...done" ,text))))) + (use-package-progn body))))) + +(put 'use-package-with-elapsed-timer 'lisp-indent-function 'defun) (defsubst use-package-error (msg) "Report MSG as an error, so the user knows it came from this package." @@ -177,6 +217,8 @@ the user specified.") (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) "Call F on the first element of ARGS if it has one element, or all of ARGS." (declare (indent 1)) @@ -187,6 +229,8 @@ the user specified.") (use-package-error (concat label " wants a list")))) +(put 'use-package-as-one 'lisp-indent-function 'defun) + (defsubst use-package-is-sympair (x &optional allow-vector) "Return t if X has the type (STRING . SYMBOL)." (and (consp x) @@ -325,17 +369,6 @@ the user specified.") "Delete all empty lists from ELEMS (nil or (list nil)), and append them." (apply #'nconc (delete nil (delete (list nil) elems)))) -(defsubst use-package-expand (name label form) - (declare (indent 1)) - (when form - (let ((err (make-symbol "err")) - (fmt (format "Failure in %s of %s: %%S" label name))) - `(condition-case-unless-debug ,err - ,form - (error - (ignore - (display-warning 'use-package (format ,fmt ,err) :error))))))) - (defun use--package (name name-symbol name-string args) "See docstring for `use-package'." (let* @@ -414,8 +447,7 @@ the user specified.") ;; (unless (and (fboundp command) ;; (not (autoloadp command))) ;; `(autoload #',command ,name-string nil t)) - `(autoload #',command ,name-string nil t) - ) + `(autoload #',command ,name-string nil t)) commands))) (when (bound-and-true-p byte-compile-current-file) @@ -437,21 +469,24 @@ the user specified.") bindings (if config-body `((eval-after-load ',name - '(use-package-with-elapsed-timer - ,(format "Configuring package %s" name-string) - ,@config-body))))) - `((use-package-with-elapsed-timer - ,(format "Loading package %s" name-string) - (if (not (require ',name-symbol nil t)) - (display-warning - 'use-package - (format "Could not load package %s" ,name-string) :error) - ,@(use-package-cat-maybes - bindings - config-body) - t)))) - - (list t)))) + ',(macroexpand + `(use-package-with-elapsed-timer + ,(format "Configuring package %s" name-string) + ,@config-body)))))) + `(,(macroexpand + `(use-package-with-elapsed-timer + ,(format "Loading package %s" name-string) + ,(if use-package-expand-minimally + (use-package-progn + (use-package-cat-maybes + (list `(require ',name-symbol nil t)) + bindings + config-body)) + `(if (not (require ',name-symbol nil t)) + (error "Could not load package %s" ,name-string) + ,@(use-package-cat-maybes + bindings + config-body)))))))))) (defmacro use-package (name &rest args) "Declare an Emacs package by specifying a group of configuration options. @@ -496,70 +531,67 @@ this file. Usage: :pin Pin the package to an archive." (declare (indent 1)) (unless (member :disabled args) - (let* ((name-string (if (stringp name) name (symbol-name name))) - (name-symbol (if (stringp name) (intern name) name)) - (args* - (condition-case-unless-debug err - (use-package-normalize-plist name-symbol args) - (error - (display-warning 'use-package - (error-message-string err) :error))))) - - ;; Pin any packages that have been marked with `:pin'. - (let ((archive-name (plist-get args* :pin))) - (when archive-name - (use-package-pin-package name archive-name))) - - ;; Ensure that the package has been installed, if marked with - ;; `:ensure'. - (let* ((ensure (plist-get args* :ensure)) + (use-package-expand "use-package" "expansion" + (let* ((name-string (if (stringp name) name (symbol-name name))) + (name-symbol (if (stringp name) (intern name) name)) + (args* (use-package-normalize-plist name-symbol args)) + (archive-name (plist-get args* :pin)) + (ensure (plist-get args* :ensure)) (package-name (or (and (eq ensure t) name) ensure))) + ;; Pin any packages that have been marked with `:pin'. + (when archive-name + (use-package-pin-package name-symbol archive-name)) + + ;; Ensure that the package has been installed, if marked with + ;; `:ensure'. (when package-name (require 'package) - (use-package-ensure-elpa package-name))) + (use-package-ensure-elpa package-name)) - ;; At this point, we can expand the macro using the helper function. - ;; `use--package'. - (let* - ((body (use--package name name-symbol name-string args*)) - (pred (plist-get args* :if)) - (expansion (if pred - `(when ,pred ,@body) - (if (= (length body) 1) - (car body) - `(progn ,@body)))) - (requires (plist-get args* :requires)) + ;; At this point, we can expand the macro using the helper function. + ;; `use--package'. + (let* + ((body (use-package-cat-maybes + (use--package name name-symbol name-string args*) + (when archive-name + `((add-to-list 'package-pinned-packages + '(,name-symbol . ,archive-name)))))) + (pred (plist-get args* :if)) + (expansion (if pred + `(when ,pred ,@body) + (use-package-progn body))) + (requires (plist-get args* :requires)) - (pre-compile-load - ;; When byte-compiling, load the package here so that all of its - ;; symbols are in scope. - (when (bound-and-true-p byte-compile-current-file) - `((eval-when-compile - ,@(mapcar #'(lambda (var) `(defvar ,var)) - (plist-get args* :defines)) - (with-demoted-errors - ,(format "Error in %s: %%S" name-string) - (if use-package-verbose - (message "Compiling package %s" ,name-string)) - (require ',name-symbol nil t)))))) + (pre-compile-load + ;; When byte-compiling, load the package here so that all of its + ;; symbols are in scope. + (when (bound-and-true-p byte-compile-current-file) + `((eval-when-compile + ,@(mapcar #'(lambda (var) `(defvar ,var)) + (plist-get args* :defines)) + (with-demoted-errors + ,(format "Error in %s: %%S" name-string) + (if use-package-verbose + (message "Compiling package %s" ,name-string)) + (require ',name-symbol nil t)))))) - (body* - (use-package-cat-maybes - pre-compile-load - (list - (if (null requires) - expansion - `(if ,(if (listp requires) - `(not (member nil (mapcar #'featurep ',requires))) - `(featurep ',requires)) - ,expansion)))))) + (body* + (use-package-cat-maybes + pre-compile-load + (list + (if (null requires) + expansion + `(if ,(if (listp requires) + `(not (member nil (mapcar #'featurep ',requires))) + `(featurep ',requires)) + ,expansion)))))) - ;; If a dynamic test has been requested -- that certain other - ;; packages must be loaded first, before attempting to load and - ;; configure this package -- wrap that logic around the expansion. - (if (= (length body*) 1) - (car body*) - `(progn ,@body*)))))) + ;; If a dynamic test has been requested -- that certain other + ;; packages must be loaded first, before attempting to load and + ;; configure this package -- wrap that logic around the expansion. + (use-package-progn body*)))))) + +(put 'use-package 'lisp-indent-function 'defun) (defun use-package-autoload-keymap (keymap-symbol package override) "Loads PACKAGE and then binds the key sequence used to invoke @@ -633,12 +665,6 @@ manually updated package." (when (not (package-installed-p package)) (package-install package))) -(put 'use-package 'lisp-indent-function 'defun) -(put 'use-package-expand 'lisp-indent-function 'defun) -(put 'use-package-only-one 'lisp-indent-function 'defun) -(put 'use-package-as-one 'lisp-indent-function 'defun) -(put 'use-package-with-elapsed-timer 'lisp-indent-function 'defun) - (provide 'use-package) ;; Local Variables: From 1fe2c1c05658dea858c1000f0f5081f32d7be849 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 16 Mar 2015 10:46:25 -0500 Subject: [PATCH 144/606] :defer now accepts an optional number of seconds --- lisp/use-package/use-package.el | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 96f36e40939..c31314cd05e 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -373,6 +373,7 @@ possible." "See docstring for `use-package'." (let* ((commands (plist-get args :commands)) + (deferral (plist-get args :defer)) ;; Note: evaluation of this forms possibly extends the value of ;; `commands'. @@ -414,7 +415,7 @@ possible." ;; Should we defer loading of the package lazily? (defer-loading (and (not (plist-get args :demand)) - (or commands (plist-get args :defer)))) + (or commands deferral))) ;; These are all the configurations to be made after the package has ;; loaded. @@ -450,6 +451,10 @@ possible." `(autoload #',command ,name-string nil t)) commands))) + (if (numberp deferral) + `((run-with-idle-timer ,deferral nil + #'require ',name-symbol nil t))) + (when (bound-and-true-p byte-compile-current-file) (mapcar #'(lambda (fn) `(declare-function ,fn ,name-string)) @@ -479,7 +484,7 @@ possible." ,(if use-package-expand-minimally (use-package-progn (use-package-cat-maybes - (list `(require ',name-symbol nil t)) + (list `(require ',name-symbol)) bindings config-body)) `(if (not (require ',name-symbol nil t)) @@ -501,6 +506,9 @@ this file. Usage: :config Code to run after PACKAGE-NAME has been loaded. Note that if loading is deferred for any reason, this code does not execute until the lazy load has occurred. +:preface Code to be run before everything except `:disabled'; this can + be used to define functions for use in `:if', or that should be + seen by the byte-compiler. :mode Form to be added to `auto-mode-alist'. :interpreter Form to be added to `interpreter-mode-alist'. @@ -519,6 +527,8 @@ this file. Usage: :defer Defer loading of a package -- this is implied when using `:commands', `:bind', `:bind*', `:mode' or `:interpreter'. + This can be an integer, to force loading after N seconds of + idle time, if the package has not already been loaded. :demand Prevent deferred loading in all cases. :if EXPR Initialize and load only if EXPR evaluates to a non-nil value. From 34bc31e1d4a83a2a8ae9d13439de1a59e1e21d56 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 16 Mar 2015 11:50:32 -0500 Subject: [PATCH 145/606] A few changes for byte-compilation --- lisp/use-package/use-package.el | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index c31314cd05e..d81d7e4e77e 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -158,9 +158,7 @@ possible." ,(use-package-progn body) (let ((elapsed (float-time (time-subtract (current-time) ,nowvar)))) - (if (> elapsed - (or (bound-and-true-p use-package-minimum-reported-time) - "0.01")) + (if (> elapsed ,use-package-minimum-reported-time) (message "%s...done (%.3fs)" ,text elapsed) (message "%s...done" ,text))))) (use-package-progn body))))) @@ -429,7 +427,8 @@ possible." `(diminish (quote ,var)))) (plist-get args :diminish)))) - (config-defun (make-symbol (concat name-string "-config")))) + (config-defun + (make-symbol (concat "use-package--" name-string "--config")))) (setq commands (delete-dups commands)) @@ -438,7 +437,8 @@ possible." (list (plist-get args :preface)) ;; Setup the load-path - (mapcar #'(lambda (path) `(add-to-list 'load-path ,path)) + (mapcar #'(lambda (path) + `(eval-and-compile (add-to-list 'load-path ,path))) (plist-get args :load-path)) ;; Setup any required autoloads From 9e35dd95d95ef3006cfd8d87d3e2099ec03ba021 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 16 Mar 2015 11:58:37 -0500 Subject: [PATCH 146/606] More fixes related to byte-compilation --- lisp/use-package/use-package.el | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index d81d7e4e77e..e77ff96dc5e 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -427,6 +427,13 @@ possible." `(diminish (quote ,var)))) (plist-get args :diminish)))) + (config-body* + (and config-body + (macroexpand + `(use-package-with-elapsed-timer + ,(format "Configuring package %s" name-string) + ,@config-body)))) + (config-defun (make-symbol (concat "use-package--" name-string "--config")))) @@ -437,8 +444,7 @@ possible." (list (plist-get args :preface)) ;; Setup the load-path - (mapcar #'(lambda (path) - `(eval-and-compile (add-to-list 'load-path ,path))) + (mapcar #'(lambda (path) `(add-to-list 'load-path ,path)) (plist-get args :load-path)) ;; Setup any required autoloads @@ -461,10 +467,7 @@ possible." (append (plist-get args :functions) commands))) ;; (if (and defer-loading config-body) - ;; `((defun ,config-defun () - ;; (use-package-with-elapsed-timer - ;; ,(format "Configuring package %s" name-string) - ;; ,@config-body)))) + ;; `((defalias ',config-defun #'(lambda () ,config-body*)))) ;; The user's initializations (list (use-package-hook-injector name-string :init args)) @@ -474,10 +477,8 @@ possible." bindings (if config-body `((eval-after-load ',name - ',(macroexpand - `(use-package-with-elapsed-timer - ,(format "Configuring package %s" name-string) - ,@config-body)))))) + ;; '(,config-defun) + ',config-body*)))) `(,(macroexpand `(use-package-with-elapsed-timer ,(format "Loading package %s" name-string) @@ -486,12 +487,15 @@ possible." (use-package-cat-maybes (list `(require ',name-symbol)) bindings - config-body)) + (list config-body*))) `(if (not (require ',name-symbol nil t)) - (error "Could not load package %s" ,name-string) + (display-warning + 'use-package + (format "Could not load package %s" ,name-string) + :error) ,@(use-package-cat-maybes bindings - config-body)))))))))) + (list config-body*))))))))))) (defmacro use-package (name &rest args) "Declare an Emacs package by specifying a group of configuration options. From db69a3f81c0158cf9615dc3f19a6412d2b61446a Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 16 Mar 2015 12:19:14 -0500 Subject: [PATCH 147/606] Add to the load-path before the :preface Fixes https://github.com/jwiegley/use-package/issues/172 --- lisp/use-package/use-package.el | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index e77ff96dc5e..224eb375028 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -441,12 +441,13 @@ possible." ;; Return the main body of the macro (use-package-cat-maybes - (list (plist-get args :preface)) - ;; Setup the load-path - (mapcar #'(lambda (path) `(add-to-list 'load-path ,path)) + (mapcar #'(lambda (path) + `(eval-and-compile (add-to-list 'load-path ,path))) (plist-get args :load-path)) + (list (plist-get args :preface)) + ;; Setup any required autoloads (if defer-loading (delete nil From 771f2edc83a2d48e9d46975c6433c4f16f449a7b Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 16 Mar 2015 22:12:52 -0500 Subject: [PATCH 148/606] Always return t on a successful init-time load Fixes https://github.com/jwiegley/use-package/issues/174 --- lisp/use-package/use-package.el | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 224eb375028..561b12d74a5 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -105,6 +105,9 @@ possible." :type 'boolean :group 'use-package) +(eval-when-compile + (defvar use-package-expand-minimally)) + (defmacro use-package-expand (name label form) (declare (indent 1)) (when form @@ -479,7 +482,8 @@ possible." (if config-body `((eval-after-load ',name ;; '(,config-defun) - ',config-body*)))) + ',config-body*))) + (list t)) `(,(macroexpand `(use-package-with-elapsed-timer ,(format "Loading package %s" name-string) @@ -488,15 +492,18 @@ possible." (use-package-cat-maybes (list `(require ',name-symbol)) bindings - (list config-body*))) + config-body + (list t))) `(if (not (require ',name-symbol nil t)) - (display-warning - 'use-package - (format "Could not load package %s" ,name-string) - :error) + (ignore + (display-warning + 'use-package + (format "Could not load package %s" ,name-string) + :error)) ,@(use-package-cat-maybes bindings - (list config-body*))))))))))) + config-body + (list t))))))))))) (defmacro use-package (name &rest args) "Declare an Emacs package by specifying a group of configuration options. From 8d7a0c21852db1a0ef97204786b90b6e77a70c37 Mon Sep 17 00:00:00 2001 From: Russell Black Date: Mon, 16 Mar 2015 22:55:48 -0600 Subject: [PATCH 149/606] minor fixes to get bind-keymap working in 2.0 --- lisp/use-package/use-package.el | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 561b12d74a5..2fae2a2f3ec 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -384,14 +384,14 @@ possible." `(bind-key ,(car binding) #'(lambda () (interactive) (use-package-autoload-keymap - ',(cdr binding) ,name-symbol nil)))) + ',(cdr binding) (quote ,name-symbol) nil)))) (plist-get args :bind-keymap)) (mapcar #'(lambda (binding) `(bind-key ,(car binding) #'(lambda () (interactive) (use-package-autoload-keymap - ',(cdr binding) ,name-symbol t)))) + ',(cdr binding) (quote ,name-symbol) t)))) (plist-get args :bind-keymap*)) (mapcar #'(lambda (mode) @@ -416,7 +416,9 @@ possible." ;; Should we defer loading of the package lazily? (defer-loading (and (not (plist-get args :demand)) - (or commands deferral))) + (or commands deferral + (plist-get args :bind-keymap) + (plist-get args :bind-keymap*)))) ;; These are all the configurations to be made after the package has ;; loaded. From eda8246fc66c2a6dcc8d8300794122309f1f2e6d Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 17 Mar 2015 10:21:34 -0500 Subject: [PATCH 150/606] Change some code for consistency's sake --- lisp/use-package/use-package.el | 48 ++++++++++++++++----------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 2fae2a2f3ec..4bef7964760 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -384,14 +384,14 @@ possible." `(bind-key ,(car binding) #'(lambda () (interactive) (use-package-autoload-keymap - ',(cdr binding) (quote ,name-symbol) nil)))) + ',(cdr binding) ',name-symbol nil)))) (plist-get args :bind-keymap)) (mapcar #'(lambda (binding) `(bind-key ,(car binding) #'(lambda () (interactive) (use-package-autoload-keymap - ',(cdr binding) (quote ,name-symbol) t)))) + ',(cdr binding) ',name-symbol t)))) (plist-get args :bind-keymap*)) (mapcar #'(lambda (mode) @@ -428,16 +428,16 @@ possible." (mapcar #'(lambda (var) (if (listp var) - `(diminish (quote ,(car var)) ,(cdr var)) - `(diminish (quote ,var)))) + `(diminish ',(car var) ,(cdr var)) + `(diminish ',var))) (plist-get args :diminish)))) (config-body* (and config-body (macroexpand `(use-package-with-elapsed-timer - ,(format "Configuring package %s" name-string) - ,@config-body)))) + ,(format "Configuring package %s" name-string) + ,@config-body)))) (config-defun (make-symbol (concat "use-package--" name-string "--config")))) @@ -488,24 +488,24 @@ possible." (list t)) `(,(macroexpand `(use-package-with-elapsed-timer - ,(format "Loading package %s" name-string) - ,(if use-package-expand-minimally - (use-package-progn - (use-package-cat-maybes - (list `(require ',name-symbol)) - bindings - config-body - (list t))) - `(if (not (require ',name-symbol nil t)) - (ignore - (display-warning - 'use-package - (format "Could not load package %s" ,name-string) - :error)) - ,@(use-package-cat-maybes - bindings - config-body - (list t))))))))))) + ,(format "Loading package %s" name-string) + ,(if use-package-expand-minimally + (use-package-progn + (use-package-cat-maybes + (list `(require ',name-symbol)) + bindings + config-body + (list t))) + `(if (not (require ',name-symbol nil t)) + (ignore + (display-warning + 'use-package + (format "Could not load package %s" ,name-string) + :error)) + ,@(use-package-cat-maybes + bindings + config-body + (list t))))))))))) (defmacro use-package (name &rest args) "Declare an Emacs package by specifying a group of configuration options. From d2679595faffa8a2d452a24ee7add828deb91212 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 17 Mar 2015 11:42:04 -0500 Subject: [PATCH 151/606] Several minor improvements and fixes --- lisp/use-package/use-package.el | 301 +++++++++++++++----------------- 1 file changed, 145 insertions(+), 156 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 4bef7964760..10ae493b635 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -108,65 +108,70 @@ possible." (eval-when-compile (defvar use-package-expand-minimally)) -(defmacro use-package-expand (name label form) - (declare (indent 1)) - (when form - (if use-package-expand-minimally - form - (let ((err (make-symbol "err"))) - `(condition-case-unless-debug ,err - ,form - (error - (ignore - (display-warning 'use-package (error-message-string ,err) - :error)))))))) - -(put 'use-package-expand 'lisp-indent-function 'defun) - -(defun use-package-hook-injector (name-string keyword args) - "Wrap pre/post hook injections around a given keyword form." - (if (not use-package-inject-hooks) - (macroexpand-all - `(use-package-expand name-string ,(format "%s" keyword) - ,(plist-get args keyword))) - (let ((keyword-name (substring (format "%s" keyword) 1)) - (block (plist-get args keyword))) - (when block - (macroexpand-all - `(when (use-package-expand name-string ,(format "pre-%s hook" keyword) - (run-hook-with-args-until-failure - ',(intern (concat "use-package--" name-string - "--pre-" keyword-name "-hook")))) - (use-package-expand name-string ,(format "%s" keyword) - ,(plist-get args keyword)) - (use-package-expand name-string ,(format "post-%s hook" keyword) - (run-hooks - ',(intern (concat "use-package--" name-string - "--post-" keyword-name "-hook")))))))))) - (defun use-package-progn (body) (if (= (length body) 1) (car body) `(progn ,@body))) -(defmacro use-package-with-elapsed-timer (text &rest body) +(defun use-package-expand (name label form) + "FORM is a list of forms, so `((foo))' if only `foo' is being called." + (declare (indent 1)) + (when form + (if use-package-expand-minimally + form + (let ((err (make-symbol "err"))) + (list + `(condition-case-unless-debug ,err + ,(use-package-progn form) + (error + (ignore + (display-warning 'use-package (error-message-string ,err) + :error))))))))) + +(put 'use-package-expand 'lisp-indent-function 'defun) + +(defun use-package-hook-injector (name-string keyword args) + "Wrap pre/post hook injections around a given keyword form. +ARGS is a list of forms, so `((foo))' if only `foo' is being called." + (if (not use-package-inject-hooks) + (use-package-expand name-string (format "%s" keyword) + (plist-get args keyword)) + (let ((keyword-name (substring (format "%s" keyword) 1)) + (block (plist-get args keyword))) + (when block + `((when ,(use-package-progn + (use-package-expand name-string (format "pre-%s hook" keyword) + `(run-hook-with-args-until-failure + ',(intern (concat "use-package--" name-string + "--pre-" keyword-name "-hook"))))) + ,(use-package-progn + (use-package-expand name-string (format "%s" keyword) + (plist-get args keyword))) + ,(use-package-progn + (use-package-expand name-string (format "post-%s hook" keyword) + `(run-hooks + ',(intern (concat "use-package--" name-string + "--post-" keyword-name "-hook"))))))))))) + +(defun use-package-with-elapsed-timer (text body) + "BODY is a list of forms, so `((foo))' if only `foo' is being called." (declare (indent 1)) (if use-package-expand-minimally - (use-package-progn body) + body (let ((nowvar (make-symbol "now"))) (if (bound-and-true-p use-package-verbose) - `(let ((,nowvar (current-time))) - (message "%s..." ,text) - (prog1 - ,(use-package-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))))) - (use-package-progn body))))) + `((let ((,nowvar (current-time))) + (message "%s..." ,text) + (prog1 + ,(use-package-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 'defun) +(put 'use-package-with-elapsed-timer 'lisp-indent-function 1) (defsubst use-package-error (msg) "Report MSG as an error, so the user knows it came from this package." @@ -176,9 +181,7 @@ possible." "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"))) - (if (= (length args) 1) - (car args) - (cons 'progn args))) + (mapcar #'macroexpand args)) (defsubst use-package-normalize-value (label arg) "Normalize a value." @@ -321,7 +324,7 @@ possible." (use-package-as-one (symbol-name head) args #'use-package-normalize-symbols)) - ((or :defer :demand :disabled) + ((or :defer :demand :disabled :no-require) (if (null args) t (use-package-only-one (symbol-name head) args @@ -417,27 +420,37 @@ possible." ;; Should we defer loading of the package lazily? (defer-loading (and (not (plist-get args :demand)) (or commands deferral + (plist-get args :no-require) (plist-get args :bind-keymap) (plist-get args :bind-keymap*)))) + (pre-compile-load + ;; When byte-compiling, load the package here so that all of its + ;; symbols are in scope. + (when (bound-and-true-p byte-compile-current-file) + `((eval-when-compile + ,@(mapcar #'(lambda (var) `(defvar ,var)) + (plist-get args* :defines)) + (with-demoted-errors + ,(format "Error in %s: %%S" name-string) + ,(if use-package-verbose + `(message "Compiling package %s" ,name-string)) + ,(unless (plist-get args* :no-require) + `(require ',name-symbol nil t))))))) + ;; These are all the configurations to be made after the package has ;; loaded. (config-body - (use-package-cat-maybes - (list (use-package-hook-injector name-string :config args)) + (use-package-with-elapsed-timer + (format "Configuring package %s" name-string) + (use-package-cat-maybes + (use-package-hook-injector name-string :config args) - (mapcar #'(lambda (var) - (if (listp var) - `(diminish ',(car var) ,(cdr var)) - `(diminish ',var))) - (plist-get args :diminish)))) - - (config-body* - (and config-body - (macroexpand - `(use-package-with-elapsed-timer - ,(format "Configuring package %s" name-string) - ,@config-body)))) + (mapcar #'(lambda (var) + (if (listp var) + `(diminish ',(car var) ,(cdr var)) + `(diminish ',var))) + (plist-get args :diminish))))) (config-defun (make-symbol (concat "use-package--" name-string "--config")))) @@ -451,32 +464,29 @@ possible." `(eval-and-compile (add-to-list 'load-path ,path))) (plist-get args :load-path)) - (list (plist-get args :preface)) + pre-compile-load + + (plist-get args :preface) ;; Setup any required autoloads (if defer-loading - (delete nil - (mapcar #'(lambda (command) - ;; (unless (and (fboundp command) - ;; (not (autoloadp command))) - ;; `(autoload #',command ,name-string nil t)) - `(autoload #',command ,name-string nil t)) - commands))) + (mapcar #'(lambda (command) + `(unless (fboundp ',command) + (autoload #',command ,name-string nil t))) + commands)) (if (numberp deferral) - `((run-with-idle-timer ,deferral nil - #'require ',name-symbol nil t))) + `((run-with-idle-timer ,deferral nil #'require ',name-symbol nil t))) (when (bound-and-true-p byte-compile-current-file) - (mapcar #'(lambda (fn) - `(declare-function ,fn ,name-string)) + (mapcar #'(lambda (fn) `(declare-function ,fn ,name-string)) (append (plist-get args :functions) commands))) ;; (if (and defer-loading config-body) ;; `((defalias ',config-defun #'(lambda () ,config-body*)))) ;; The user's initializations - (list (use-package-hook-injector name-string :init args)) + (use-package-hook-injector name-string :init args) (if defer-loading (use-package-cat-maybes @@ -484,28 +494,26 @@ possible." (if config-body `((eval-after-load ',name ;; '(,config-defun) - ',config-body*))) + ',(use-package-progn config-body)))) (list t)) - `(,(macroexpand - `(use-package-with-elapsed-timer - ,(format "Loading package %s" name-string) - ,(if use-package-expand-minimally - (use-package-progn - (use-package-cat-maybes - (list `(require ',name-symbol)) - bindings - config-body - (list t))) - `(if (not (require ',name-symbol nil t)) - (ignore - (display-warning - 'use-package - (format "Could not load package %s" ,name-string) - :error)) - ,@(use-package-cat-maybes - bindings - config-body - (list t))))))))))) + (use-package-with-elapsed-timer + (format "Loading package %s" name-string) + (if use-package-expand-minimally + (use-package-cat-maybes + (list `(require ',name-symbol)) + bindings + config-body + (list t)) + `((if (not (require ',name-symbol nil t)) + (ignore + (display-warning + 'use-package + (format "Could not load package %s" ,name-string) + :error)) + ,@(use-package-cat-maybes + bindings + config-body + (list t)))))))))) (defmacro use-package (name &rest args) "Declare an Emacs package by specifying a group of configuration options. @@ -555,65 +563,46 @@ this file. Usage: :pin Pin the package to an archive." (declare (indent 1)) (unless (member :disabled args) - (use-package-expand "use-package" "expansion" - (let* ((name-string (if (stringp name) name (symbol-name name))) - (name-symbol (if (stringp name) (intern name) name)) - (args* (use-package-normalize-plist name-symbol args)) - (archive-name (plist-get args* :pin)) - (ensure (plist-get args* :ensure)) - (package-name (or (and (eq ensure t) name) ensure))) - ;; Pin any packages that have been marked with `:pin'. - (when archive-name - (use-package-pin-package name-symbol archive-name)) + (let* ((name-string (if (stringp name) name (symbol-name name))) + (name-symbol (if (stringp name) (intern name) name)) + (args* (use-package-normalize-plist name-symbol args)) + (archive-name (plist-get args* :pin)) + (ensure (plist-get args* :ensure)) + (package-name (or (and (eq ensure t) name) ensure))) + ;; Pin any packages that have been marked with `:pin'. + (when archive-name + (use-package-pin-package name-symbol archive-name)) - ;; Ensure that the package has been installed, if marked with - ;; `:ensure'. - (when package-name - (require 'package) - (use-package-ensure-elpa package-name)) + ;; Ensure that the package has been installed, if marked with + ;; `:ensure'. + (when package-name + (require 'package) + (use-package-ensure-elpa package-name)) - ;; At this point, we can expand the macro using the helper function. - ;; `use--package'. - (let* - ((body (use-package-cat-maybes - (use--package name name-symbol name-string args*) - (when archive-name - `((add-to-list 'package-pinned-packages - '(,name-symbol . ,archive-name)))))) - (pred (plist-get args* :if)) - (expansion (if pred - `(when ,pred ,@body) - (use-package-progn body))) - (requires (plist-get args* :requires)) - - (pre-compile-load - ;; When byte-compiling, load the package here so that all of its - ;; symbols are in scope. - (when (bound-and-true-p byte-compile-current-file) - `((eval-when-compile - ,@(mapcar #'(lambda (var) `(defvar ,var)) - (plist-get args* :defines)) - (with-demoted-errors - ,(format "Error in %s: %%S" name-string) - (if use-package-verbose - (message "Compiling package %s" ,name-string)) - (require ',name-symbol nil t)))))) - - (body* - (use-package-cat-maybes - pre-compile-load - (list - (if (null requires) - expansion - `(if ,(if (listp requires) + ;; At this point, we can expand the macro using the helper function. + ;; `use--package'. + (let* + ((body (use-package-cat-maybes + (use--package name name-symbol name-string args*) + (when archive-name + `((add-to-list 'package-pinned-packages + '(,name-symbol . ,archive-name)))))) + (pred (plist-get args* :if)) + (expansion (if pred + `((when ,pred ,@body)) + body)) + (requires (plist-get args* :requires)) + (body* + (use-package-progn + (use-package-expand "use-package" "expansion" + (if (null requires) + expansion + `((if ,(if (listp requires) `(not (member nil (mapcar #'featurep ',requires))) `(featurep ',requires)) - ,expansion)))))) - - ;; If a dynamic test has been requested -- that certain other - ;; packages must be loaded first, before attempting to load and - ;; configure this package -- wrap that logic around the expansion. - (use-package-progn body*)))))) + ,@expansion))))))) + ;; (message "Expanded: %s" (pp-to-string body*)) + body*)))) (put 'use-package 'lisp-indent-function 'defun) From 46435d7b84b0ca7b8829c2928f74e5a82b12464d Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 17 Mar 2015 11:50:25 -0500 Subject: [PATCH 152/606] Other minor improvements for byte-compiling --- lisp/use-package/use-package.el | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 10ae493b635..ab77fd2baf1 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -480,7 +480,7 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." (when (bound-and-true-p byte-compile-current-file) (mapcar #'(lambda (fn) `(declare-function ,fn ,name-string)) - (append (plist-get args :functions) commands))) + (plist-get args :functions))) ;; (if (and defer-loading config-body) ;; `((defalias ',config-defun #'(lambda () ,config-body*)))) @@ -594,13 +594,12 @@ this file. Usage: (requires (plist-get args* :requires)) (body* (use-package-progn - (use-package-expand "use-package" "expansion" - (if (null requires) - expansion - `((if ,(if (listp requires) - `(not (member nil (mapcar #'featurep ',requires))) - `(featurep ',requires)) - ,@expansion))))))) + (if (null requires) + expansion + `((if ,(if (listp requires) + `(not (member nil (mapcar #'featurep ',requires))) + `(featurep ',requires)) + ,@expansion)))))) ;; (message "Expanded: %s" (pp-to-string body*)) body*)))) From 5787ff074cbfbe7589c688f6fbeac1c89c79dfdd Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 18 Mar 2015 03:10:36 -0500 Subject: [PATCH 153/606] More work to silence the byte-compiler --- lisp/use-package/use-package.el | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index ab77fd2baf1..ade669be483 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -40,6 +40,7 @@ (require 'bind-key) (require 'bytecomp) (require 'diminish nil t) +(require 'bytecomp) (declare-function package-installed-p 'package) @@ -470,10 +471,13 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." ;; Setup any required autoloads (if defer-loading - (mapcar #'(lambda (command) - `(unless (fboundp ',command) - (autoload #',command ,name-string nil t))) - commands)) + (apply + #'nconc + (mapcar #'(lambda (command) + `((unless (fboundp ',command) + (autoload #',command ,name-string nil t)) + (declare-function ,command ,name-string))) + commands))) (if (numberp deferral) `((run-with-idle-timer ,deferral nil #'require ',name-symbol nil t))) @@ -601,7 +605,9 @@ this file. Usage: `(featurep ',requires)) ,@expansion)))))) ;; (message "Expanded: %s" (pp-to-string body*)) - body*)))) + `(let ((byte-compile-warnings byte-compile-warnings)) + (byte-compile-disable-warning 'redefined) + ,body*))))) (put 'use-package 'lisp-indent-function 'defun) From 658d103b70c63ba50b7f5438e7c42f1af0770090 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 18 Mar 2015 03:25:21 -0500 Subject: [PATCH 154/606] Make a warning more specific --- lisp/use-package/use-package.el | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index ade669be483..2bbc01b2593 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -126,7 +126,9 @@ possible." ,(use-package-progn form) (error (ignore - (display-warning 'use-package (error-message-string ,err) + (display-warning 'use-package + (format "use-package: Error in %s: %s" ,name + (error-message-string ,err)) :error))))))))) (put 'use-package-expand 'lisp-indent-function 'defun) @@ -431,12 +433,12 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." (when (bound-and-true-p byte-compile-current-file) `((eval-when-compile ,@(mapcar #'(lambda (var) `(defvar ,var)) - (plist-get args* :defines)) + (plist-get args :defines)) (with-demoted-errors ,(format "Error in %s: %%S" name-string) ,(if use-package-verbose `(message "Compiling package %s" ,name-string)) - ,(unless (plist-get args* :no-require) + ,(unless (plist-get args :no-require) `(require ',name-symbol nil t))))))) ;; These are all the configurations to be made after the package has From 8769309fbf1e5f59e37a08a949603ae3662e547d Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 18 Mar 2015 05:46:25 -0500 Subject: [PATCH 155/606] Remove a use of macroexpand --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 2bbc01b2593..e2054d11978 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -184,7 +184,7 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." "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 #'macroexpand args)) + args) (defsubst use-package-normalize-value (label arg) "Normalize a value." From 19ab94cf39809dc1aebce053962930b6c6ab6c4d Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 18 Mar 2015 20:53:55 -0500 Subject: [PATCH 156/606] Wrap the :preface in an eval-and-compile block --- lisp/use-package/use-package.el | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index e2054d11978..4d30ffe3ca3 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -74,9 +74,9 @@ then the expanded macros do their job silently." :group 'use-package) (defcustom use-package-inject-hooks nil - "If non-nil, add hooks to the `:init' and `:config' sections for a package. + "If non-nil, add hooks to the `:init' and `:config' sections. In particular, for a given package `foo', the following hooks -will become available: +become available: `use-package--foo--pre-init-hook' `use-package--foo--post-init-hook' @@ -100,9 +100,8 @@ This disables: - Printing to the *Messages* buffer of slowly-evaluating forms - Capture of load errors (normally redisplayed as warnings) - Conditional loading of packages (load failures become errors) -The only real advantage is that, if you know your configuration -works, then your byte-compiled init file is as minimal as -possible." +The only advantage is that, if you know your configuration works, +then your byte-compiled init file is as minimal as possible." :type 'boolean :group 'use-package) @@ -469,7 +468,9 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." pre-compile-load - (plist-get args :preface) + (mapcar #'(lambda (form) + `(eval-and-compile ,form)) + (plist-get args :preface)) ;; Setup any required autoloads (if defer-loading @@ -606,7 +607,7 @@ this file. Usage: `(not (member nil (mapcar #'featurep ',requires))) `(featurep ',requires)) ,@expansion)))))) - ;; (message "Expanded: %s" (pp-to-string body*)) + ;; (message "Expanded:\n%s" (pp-to-string body*)) `(let ((byte-compile-warnings byte-compile-warnings)) (byte-compile-disable-warning 'redefined) ,body*))))) From 2778e85a39bd111ac884fd11bf1b41fd80288a06 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 18 Mar 2015 20:56:45 -0500 Subject: [PATCH 157/606] macroexpand nested uses of use-package in :init and :config --- lisp/use-package/use-package.el | 45 ++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 4d30ffe3ca3..d352afd7581 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -105,8 +105,43 @@ then your byte-compiled init file is as minimal as possible." :type 'boolean :group 'use-package) -(eval-when-compile - (defvar use-package-expand-minimally)) +(defvar use-package-extra-keywords nil + "A list of extra keywords to be accepted in the use-package form.") + +(defconst use-package-phases + '(setup-load-path + pre-compile-load + preface + setup-autoloads + register-load-on-idle + declare-functions + init + register-eval-after-load + deferred-config + package-load + config + wrapup) + "A list of phases that capture the sequence of `use-package'. +This is used by `use-package-add-keywords' in order to register +new keywords, and to specify when their handler should be +called. +Each phase registers a `before-' and `after-' counterpart, so +that you can register new keywords as follows: + + (use-package-add-keywords :ensure 'after-preface) + +Which is identical to saying: + + (use-package-add-keywords :ensure 'before-setup-autoloads) + +The reason for duplicating the sequence points with redundant +before and after monikers is to make keyword-adding resilient to +the creation of new phases in future.") + +(defun use-package-add-keywords (&rest args) + (let ((keywords (cl-remove-if #'(lambda (x) (not (keywordp args))))) + (phases (cl-remove-if #'(lambda (x) (keywordp args)))))) + ) (defun use-package-progn (body) (if (= (length body) 1) @@ -183,7 +218,11 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." "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"))) - args) + (mapcar #'(lambda (form) + (if (and (consp form) + (eq (car form) 'use-package)) + (macroexpand form) + form)) args)) (defsubst use-package-normalize-value (label arg) "Normalize a value." From 38f907cc5d75fe514b6b721b95d186d55f720eed Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 19 Mar 2015 04:39:07 -0500 Subject: [PATCH 158/606] Remove a hack that is not needed anymore --- lisp/use-package/use-package.el | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index d352afd7581..7e11d33bb67 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -647,9 +647,7 @@ this file. Usage: `(featurep ',requires)) ,@expansion)))))) ;; (message "Expanded:\n%s" (pp-to-string body*)) - `(let ((byte-compile-warnings byte-compile-warnings)) - (byte-compile-disable-warning 'redefined) - ,body*))))) + body*)))) (put 'use-package 'lisp-indent-function 'defun) From 1b6605652c0ecc20ed2ba30873f2c92721e999fd Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 19 Mar 2015 04:42:22 -0500 Subject: [PATCH 159/606] Use push instead of add-to-list --- lisp/use-package/use-package.el | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 7e11d33bb67..7fa4a62d115 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -245,7 +245,7 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." (list arg)) ((and (not recursed) (listp arg) (listp (cdr arg))) (mapcar #'(lambda (x) (car (use-package-normalize-diminish - name-symbol label x t))) arg)) + name-symbol label x t))) arg)) (t (use-package-error (concat label " wants a string, symbol, " @@ -293,7 +293,7 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." (list arg)) ((and (not recursed) (listp arg) (listp (cdr arg))) (mapcar #'(lambda (x) (car (use-package-normalize-pairs - name-symbol label x t allow-vector))) arg)) + name-symbol label x t allow-vector))) arg)) (t (use-package-error (concat label " wants a string, (string . symbol) or list of these"))))) @@ -440,12 +440,12 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." (mapcar #'(lambda (mode) (push (cdr mode) commands) - `(add-to-list 'auto-mode-alist ',mode)) + `(push ',mode auto-mode-alist)) (plist-get args :mode)) (mapcar #'(lambda (interpreter) (push (cdr interpreter) commands) - `(add-to-list 'interpreter-mode-alist ',interpreter)) + `(push ',interpreter interpreter-mode-alist)) (plist-get args :interpreter)) (mapcar #'(lambda (binding) @@ -502,7 +502,7 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." (use-package-cat-maybes ;; Setup the load-path (mapcar #'(lambda (path) - `(eval-and-compile (add-to-list 'load-path ,path))) + `(eval-and-compile (push ,path load-path))) (plist-get args :load-path)) pre-compile-load @@ -631,8 +631,8 @@ this file. Usage: ((body (use-package-cat-maybes (use--package name name-symbol name-string args*) (when archive-name - `((add-to-list 'package-pinned-packages - '(,name-symbol . ,archive-name)))))) + `((push '(,name-symbol . ,archive-name) + package-pinned-packages))))) (pred (plist-get args* :if)) (expansion (if pred `((when ,pred ,@body)) @@ -700,8 +700,7 @@ deferred until the prefix key sequence is pressed." (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)) + (push (cons package archive-name) package-pinned-packages) (error "Archive '%s' requested for package '%s' is not available." archive-name package)) (package-initialize t))) From f5f4102ca18916786169935ea05a3a486599ab77 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Thu, 19 Mar 2015 11:25:18 -0400 Subject: [PATCH 160/606] get-binding-description: return keymap symbol instead of "#". --- lisp/use-package/bind-key.el | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index fd143888d5d..bf4e13b2189 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -234,12 +234,9 @@ function symbol (unquoted)." "#") (t elem))) - ((keymapp elem) - (if (and bind-key-describe-special-forms - (symbolp elem) - (get elem 'variable-documentation)) - (format "%s" (get elem 'variable-documentation)) - "#")) + ;; must be a symbol, non-symbol keymap case covered above + ((and bind-key-describe-special-forms (keymapp elem)) + (get elem 'variable-documentation)) ((symbolp elem) elem) (t From 3467e4eaa6b67f34d5ef31561d04a643c35e06e9 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Thu, 19 Mar 2015 17:40:41 -0400 Subject: [PATCH 161/606] use-package-progn: replace with macroexp-progn --- lisp/use-package/use-package.el | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 7fa4a62d115..b7726ea47cb 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -143,11 +143,6 @@ the creation of new phases in future.") (phases (cl-remove-if #'(lambda (x) (keywordp args)))))) ) -(defun use-package-progn (body) - (if (= (length body) 1) - (car body) - `(progn ,@body))) - (defun use-package-expand (name label form) "FORM is a list of forms, so `((foo))' if only `foo' is being called." (declare (indent 1)) @@ -157,7 +152,7 @@ the creation of new phases in future.") (let ((err (make-symbol "err"))) (list `(condition-case-unless-debug ,err - ,(use-package-progn form) + ,(macroexp-progn form) (error (ignore (display-warning 'use-package @@ -176,15 +171,15 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." (let ((keyword-name (substring (format "%s" keyword) 1)) (block (plist-get args keyword))) (when block - `((when ,(use-package-progn + `((when ,(macroexp-progn (use-package-expand name-string (format "pre-%s hook" keyword) `(run-hook-with-args-until-failure ',(intern (concat "use-package--" name-string "--pre-" keyword-name "-hook"))))) - ,(use-package-progn + ,(macroexp-progn (use-package-expand name-string (format "%s" keyword) (plist-get args keyword))) - ,(use-package-progn + ,(macroexp-progn (use-package-expand name-string (format "post-%s hook" keyword) `(run-hooks ',(intern (concat "use-package--" name-string @@ -200,7 +195,7 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." `((let ((,nowvar (current-time))) (message "%s..." ,text) (prog1 - ,(use-package-progn body) + ,(macroexp-progn body) (let ((elapsed (float-time (time-subtract (current-time) ,nowvar)))) (if (> elapsed ,use-package-minimum-reported-time) @@ -540,7 +535,7 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." (if config-body `((eval-after-load ',name ;; '(,config-defun) - ',(use-package-progn config-body)))) + ',(macroexp-progn config-body)))) (list t)) (use-package-with-elapsed-timer (format "Loading package %s" name-string) @@ -639,7 +634,7 @@ this file. Usage: body)) (requires (plist-get args* :requires)) (body* - (use-package-progn + (macroexp-progn (if (null requires) expansion `((if ,(if (listp requires) From c2f5b2479dc7d1a67f9d9da3e7fb128a7255287e Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 19 Mar 2015 18:45:30 -0500 Subject: [PATCH 162/606] Fix some docstrings --- lisp/use-package/use-package.el | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 7fa4a62d115..3860230d3f5 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -52,8 +52,7 @@ "Whether to report about loading and configuration details. If you customize this, then you should require the `use-package' -feature in files that use one of the macros `use-package' or -`use-package-with-elapsed-timer', even if these files only +feature in files that use `use-package', even if these files only contain compiled expansions of the macros. If you don't do so, then the expanded macros do their job silently." :type 'boolean @@ -66,8 +65,7 @@ Note that `use-package-verbose' has to be set to t, for anything to be reported at all. If you customize this, then you should require the `use-package' -feature in files that use one of the macros `use-package' or -`use-package-with-elapsed-timer', even if these files only +feature in files that use `use-package', even if these files only contain compiled expansions of the macros. If you don't do so, then the expanded macros do their job silently." :type 'number From b30b279a99e118e7896a0236489ef9953341e710 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 19 Mar 2015 18:47:15 -0500 Subject: [PATCH 163/606] Remove code I did not intend to commit --- lisp/use-package/use-package.el | 38 --------------------------------- 1 file changed, 38 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index d7da85b2c64..13fe760d90c 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -103,44 +103,6 @@ then your byte-compiled init file is as minimal as possible." :type 'boolean :group 'use-package) -(defvar use-package-extra-keywords nil - "A list of extra keywords to be accepted in the use-package form.") - -(defconst use-package-phases - '(setup-load-path - pre-compile-load - preface - setup-autoloads - register-load-on-idle - declare-functions - init - register-eval-after-load - deferred-config - package-load - config - wrapup) - "A list of phases that capture the sequence of `use-package'. -This is used by `use-package-add-keywords' in order to register -new keywords, and to specify when their handler should be -called. -Each phase registers a `before-' and `after-' counterpart, so -that you can register new keywords as follows: - - (use-package-add-keywords :ensure 'after-preface) - -Which is identical to saying: - - (use-package-add-keywords :ensure 'before-setup-autoloads) - -The reason for duplicating the sequence points with redundant -before and after monikers is to make keyword-adding resilient to -the creation of new phases in future.") - -(defun use-package-add-keywords (&rest args) - (let ((keywords (cl-remove-if #'(lambda (x) (not (keywordp args))))) - (phases (cl-remove-if #'(lambda (x) (keywordp args)))))) - ) - (defun use-package-expand (name label form) "FORM is a list of forms, so `((foo))' if only `foo' is being called." (declare (indent 1)) From 94ad68330da0b7bc92e2d45a5172bf9e936fa281 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 19 Mar 2015 18:48:14 -0500 Subject: [PATCH 164/606] Rename use-package-with-elapsed-timer at an internal name See https://github.com/jwiegley/use-package/issues/185 --- lisp/use-package/use-package.el | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 13fe760d90c..d584f4b5636 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -145,7 +145,7 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." ',(intern (concat "use-package--" name-string "--post-" keyword-name "-hook"))))))))))) -(defun use-package-with-elapsed-timer (text body) +(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 @@ -163,7 +163,7 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." (message "%s...done" ,text)))))) body)))) -(put 'use-package-with-elapsed-timer 'lisp-indent-function 1) +(put 'use-package--with-elapsed-timer 'lisp-indent-function 1) (defsubst use-package-error (msg) "Report MSG as an error, so the user knows it came from this package." @@ -437,7 +437,7 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." ;; These are all the configurations to be made after the package has ;; loaded. (config-body - (use-package-with-elapsed-timer + (use-package--with-elapsed-timer (format "Configuring package %s" name-string) (use-package-cat-maybes (use-package-hook-injector name-string :config args) @@ -497,7 +497,7 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." ;; '(,config-defun) ',(macroexp-progn config-body)))) (list t)) - (use-package-with-elapsed-timer + (use-package--with-elapsed-timer (format "Loading package %s" name-string) (if use-package-expand-minimally (use-package-cat-maybes @@ -633,7 +633,7 @@ deferred until the prefix key sequence is pressed." package keymap-symbol)))) (defconst use-package-font-lock-keywords - '(("(\\(use-package\\(?:-with-elapsed-timer\\)?\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" + '(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" (1 font-lock-keyword-face) (2 font-lock-constant-face nil t)))) From f1ab3291f6584eb6dd9a6a627ef4b8182a0ab9bb Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 19 Mar 2015 22:26:53 -0500 Subject: [PATCH 165/606] Began work on modular handling of keywords --- lisp/use-package/use-package.el | 432 ++++++++++++++++++++++---------- 1 file changed, 294 insertions(+), 138 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index d584f4b5636..82ee738ebf3 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -41,6 +41,7 @@ (require 'bytecomp) (require 'diminish nil t) (require 'bytecomp) +(eval-when-compile (require 'cl)) (declare-function package-installed-p 'package) @@ -92,6 +93,35 @@ the user specified." :type 'boolean :group 'use-package) +(defcustom use-package-keywords + '(:disabled + :pin + :ensure + :if + :when + :unless + :requires + :load-path + :no-require + :preface + :bind + :bind* + :bind-keymap + :bind-keymap* + :interpreter + :mode + :commands + :defines + :functions + :defer + :demand + :init + :config + :diminish) + "Establish which keywords are valid, and the order they are processed in." + :type '(repeat symbol) + :group 'use-package) + (defcustom use-package-expand-minimally nil "If non-nil, make the expanded code as minimal as possible. This disables: @@ -103,6 +133,11 @@ then your byte-compiled init file is as minimal as possible." :type 'boolean :group 'use-package) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Utility functions +;; + (defun use-package-expand (name label form) "FORM is a list of forms, so `((foo))' if only `foo' is being called." (declare (indent 1)) @@ -169,15 +204,62 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." "Report MSG as an error, so the user knows it came from this package." (error "use-package: %s" msg)) -(defun use-package-normalize-form (label args) - "Given a list of forms, return it wrapped in `progn'." - (unless (listp (car args)) - (use-package-error (concat label " wants a sexp or list of sexps"))) - (mapcar #'(lambda (form) - (if (and (consp form) - (eq (car form) 'use-package)) - (macroexpand form) - form)) args)) +(defun use-package-plist-delete (plist property) + "Delete PROPERTY from PLIST. +This is in contrast to merely setting it to 0." + (let (p) + (while plist + (if (not (eq property (car plist))) + (setq p (plist-put p (car plist) (nth 1 plist)))) + (setq plist (cddr plist))) + p)) + +(defun use-package-split-list (pred xs) + (let ((ys (list nil)) (zs (list nil)) flip) + (dolist (x xs) + (if flip + (nconc zs (list x)) + (if (funcall pred x) + (progn + (setq flip t) + (nconc zs (list x))) + (nconc ys (list x))))) + (cons (cdr ys) (cdr zs)))) + +(defun use-package-keyword-index (keyword) + (loop named outer + with index = 0 + for k in use-package-keywords do + (if (eq k keyword) + (return-from outer index)) + (incf index))) + +(defun use-package-sort-keywords (plist) + (let (plist-grouped) + (while plist + (push (cons (car plist) (cadr plist)) + plist-grouped) + (setq plist (cddr plist))) + (append + (sort plist-grouped + #'(lambda (l r) (< (use-package-keyword-index (car l)) + (use-package-keyword-index (car r)))))))) + +(defsubst use-package-cat-maybes (&rest elems) + "Delete all empty lists from ELEMS (nil or (list nil)), and append them." + (apply #'nconc (delete nil (delete (list nil) elems)))) + +(defconst use-package-font-lock-keywords + '(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" + (1 font-lock-keyword-face) + (2 font-lock-constant-face nil t)))) + +(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Normalization functions +;; (defsubst use-package-normalize-value (label arg) "Normalize a value." @@ -187,37 +269,23 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." `(funcall #',arg)) (t arg))) -(defun use-package-normalize-diminish (name-symbol label arg &optional recursed) - "Normalize the arguments to diminish down to a list of one of two forms: - SYMBOL - (SYMBOL . STRING)" +(defun use-package-normalize-paths (label arg &optional recursed) + "Normalize a list of filesystem paths." (cond - ((symbolp arg) - (list arg)) + ((or (symbolp arg) (functionp arg)) + (let ((value (use-package-normalize-value label arg))) + (use-package-normalize-paths label (eval value)))) ((stringp arg) - (list (cons (intern (concat (symbol-name name-symbol) "-mode")) arg))) - ((and (consp arg) (stringp (cdr arg))) - (list 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-diminish - name-symbol label x t))) arg)) + (mapcar #'(lambda (x) + (car (use-package-normalize-paths label x t))) arg)) (t (use-package-error - (concat label " wants a string, symbol, " - "(symbol . string) or list of these"))))) - -(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) + (concat label " wants a directory path, or list of paths"))))) (defun use-package-as-one (label args f) "Call F on the first element of ARGS if it has one element, or all of ARGS." @@ -253,6 +321,23 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." (use-package-error (concat label " wants a string, (string . symbol) or list of these"))))) +(defun use-package-normalize-binder (name-symbol keyword args) + (use-package-as-one (symbol-name keyword) args + (lambda (label arg) + (use-package-normalize-pairs name-symbol label arg nil t)))) + +(defalias 'use-package-normalize/:bind 'use-package-normalize-binder) +(defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) +(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder) +(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder) + +(defun use-package-normalize-mode (name-symbol keyword args) + (use-package-as-one (symbol-name keyword) args + (apply-partially #'use-package-normalize-pairs name-symbol))) + +(defalias 'use-package-normalize/:mode 'use-package-normalize-mode) +(defalias 'use-package-normalize/:interpreter 'use-package-normalize-mode) + (defun use-package-normalize-symbols (label arg &optional recursed) "Normalize a list of symbols." (cond @@ -264,110 +349,179 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." (use-package-error (concat label " wants a symbol, or list of symbols"))))) -(defun use-package-normalize-paths (label arg &optional recursed) - "Normalize a list of filesystem paths." +(defun use-package-normalize-symlist (name-symbol keyword args) + (use-package-as-one (symbol-name keyword) args + #'use-package-normalize-symbols)) + +(defalias 'use-package-normalize/:commands 'use-package-normalize-symlist) +(defalias 'use-package-normalize/:defines 'use-package-normalize-symlist) +(defalias 'use-package-normalize/:functions 'use-package-normalize-symlist) +(defalias 'use-package-normalize/:requires 'use-package-normalize-symlist) + +(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 - ((or (symbolp arg) (functionp arg)) - (let ((value (use-package-normalize-value label arg))) - (use-package-normalize-paths label (eval value)))) - ((stringp arg) - (let ((path (if (file-name-absolute-p arg) - arg - (expand-file-name arg user-emacs-directory)))) - (list path))) - ((and (not recursed) (listp arg) (listp (cdr arg))) - (mapcar #'(lambda (x) - (car (use-package-normalize-paths label x t))) arg)) + ((and (listp args) (listp (cdr args)) + (= (length args) 1)) + (funcall f label (car args))) (t (use-package-error - (concat label " wants a directory path, or list of paths"))))) + (concat label " wants exactly one argument"))))) -(defun use-package-split-list (pred xs) - (let ((ys (list nil)) (zs (list nil)) flip) - (dolist (x xs) - (if flip - (nconc zs (list x)) - (if (funcall pred x) - (progn - (setq flip t) - (nconc zs (list x))) - (nconc ys (list x))))) - (cons (cdr ys) (cdr zs)))) +(put 'use-package-only-one 'lisp-indent-function 'defun) + +(defun use-package-normalize-predicate (name-symbol keyword args) + (if (null args) + t + (use-package-only-one (symbol-name keyword) args + #'use-package-normalize-value))) + +(defalias 'use-package-normalize/:defer 'use-package-normalize-predicate) +(defalias 'use-package-normalize/:demand 'use-package-normalize-predicate) +(defalias 'use-package-normalize/:disabled 'use-package-normalize-predicate) +(defalias 'use-package-normalize/:no-require 'use-package-normalize-predicate) + +(defun use-package-normalize/:ensure (name-symbol keyword args) + (if (null args) + t + (use-package-only-one (symbol-name keyword) args + (lambda (label arg) + (if (symbolp arg) + arg + (use-package-error + (concat ":ensure wants an optional package name " + "(an unquoted symbol name)"))))))) + +(defun use-package-normalize-test (name-symbol keyword args) + (use-package-only-one (symbol-name keyword) args + #'use-package-normalize-value)) + +(defalias 'use-package-normalize/:if 'use-package-normalize-test) +(defalias 'use-package-normalize/:when 'use-package-normalize-test) + +(defun use-package-normalize/:unless (name-symbol keyword args) + (not (use-package-only-one (symbol-name keyword) args + #'use-package-normalize-value))) + +(defun use-package-normalize-diminish (name-symbol label arg &optional recursed) + "Normalize the arguments to diminish down to a list of one of two forms: + SYMBOL + (SYMBOL . STRING)" + (cond + ((symbolp arg) + (list arg)) + ((stringp arg) + (list (cons (intern (concat (symbol-name name-symbol) "-mode")) arg))) + ((and (consp arg) (stringp (cdr arg))) + (list arg)) + ((and (not recursed) (listp arg) (listp (cdr arg))) + (mapcar #'(lambda (x) (car (use-package-normalize-diminish + name-symbol label x t))) arg)) + (t + (use-package-error + (concat label " wants a string, symbol, " + "(symbol . string) or list of these"))))) + +(defun use-package-normalize/:diminish (name-symbol keyword args) + (use-package-as-one (symbol-name keyword) args + (apply-partially #'use-package-normalize-diminish name-symbol))) + +(defun use-package-normalize-form (label args) + "Given a list of forms, return it wrapped in `progn'." + (unless (listp (car args)) + (use-package-error (concat label " wants a sexp or list of sexps"))) + (mapcar #'(lambda (form) + (if (and (consp form) + (eq (car form) 'use-package)) + (macroexpand form) + form)) args)) + +(defun use-package-normalize-forms (name-symbol keyword args) + (use-package-normalize-form (symbol-name keyword) args)) + +(defalias 'use-package-normalize/:preface 'use-package-normalize-forms) +(defalias 'use-package-normalize/:init 'use-package-normalize-forms) +(defalias 'use-package-normalize/:config 'use-package-normalize-forms) + +(defun use-package-normalize/:load-path (name-symbol keyword args) + (use-package-as-one (symbol-name keyword) args + #'use-package-normalize-paths)) + +(defun use-package-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)")))))) (defun use-package-normalize-plist (name-symbol input) "Given a pseudo-plist, normalize it to a regular plist." - (if (null input) - nil - (let* ((head (car input)) + (unless (null input) + (let* ((keyword (car input)) (xs (use-package-split-list #'keywordp (cdr input))) (args (car xs)) - (tail (cdr xs))) - (append - (list - (cond ((memq head '(:when :unless)) :if) - (t head)) - (pcase head - ((or :bind :bind* :bind-keymap :bind-keymap*) - (use-package-as-one (symbol-name head) args - (lambda (label arg) - (use-package-normalize-pairs name-symbol label arg nil t)))) + (tail (cdr xs)) + (normalizer (intern (concat "use-package-normalize/" + (symbol-name keyword)))) + (arg + (cond + ((functionp normalizer) + (funcall normalizer name-symbol keyword args)) + ((= (length args) 1) + (car args)) + (t + args)))) + (if (memq keyword use-package-keywords) + (cons keyword + (cons arg (use-package-normalize-plist name-symbol tail))) + (use-package-error (format "Unrecognized keyword: %s" keyword)))))) - ((or :interpreter :mode) - (use-package-as-one (symbol-name head) args - (apply-partially #'use-package-normalize-pairs name-symbol))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Keyword processing +;; - ((or :commands :defines :functions :requires) - (use-package-as-one (symbol-name head) args - #'use-package-normalize-symbols)) +(defun use-package-process-keywords (name-symbol plist 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). - ((or :defer :demand :disabled :no-require) - (if (null args) - t - (use-package-only-one (symbol-name head) args - #'use-package-normalize-value))) +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. - (:ensure - (if (null args) - t - (use-package-only-one (symbol-name head) args - (lambda (label arg) - (if (symbolp arg) - arg - (use-package-error - (concat ":ensure wants an optional package name " - "(an unquoted symbol name)"))))))) +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." + (let ((plist* (use-package-sort-keywords + (use-package-normalize-plist name-symbol plist)))) + (unless (null plist*) + (let* ((keyword (car plist*)) + (arg (cadr plist*)) + (rest (cddr plist*))) + (unless (keywordp keyword) + (use-package-error (format "%s is not a keyword" keyword))) + (let* ((handler (concat "use-package-handler/" + (symbol-name keyword))) + (handler-sym (intern handler))) + (if (functionp handler-sym) + (funcall handler-sym name-symbol keyword arg rest state) + (use-package-error + (format "Keyword handler not defined: %s" handler)))))))) - ((or :if :when :unless) - (use-package-only-one (symbol-name head) args - #'use-package-normalize-value)) +(defun use-package-handler/:if (name-symbol keyword pred rest state) + `((when ,pred + ,@(use-package-process-keywords name-symbol rest state)))) - (:diminish - (use-package-as-one (symbol-name head) args - (apply-partially #'use-package-normalize-diminish name-symbol))) - - ((or :preface :init :config) - (use-package-normalize-form (symbol-name head) args)) - - (:load-path - (use-package-as-one (symbol-name head) args - #'use-package-normalize-paths)) - - (:pin - (use-package-only-one (symbol-name head) args - (lambda (label arg) - (cond - ((stringp arg) arg) - ((symbolp arg) (symbol-name arg)) - (t - (use-package-error - ":pin wants an archive name (a string)")))))) - - (_ (use-package-error (format "Unrecognized keyword: %s" head))))) - (use-package-normalize-plist name-symbol tail))))) - -(defsubst use-package-cat-maybes (&rest elems) - "Delete all empty lists from ELEMS (nil or (list nil)), and append them." - (apply #'nconc (delete nil (delete (list nil) elems)))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; The main macro +;; (defun use--package (name name-symbol name-string args) "See docstring for `use-package'." @@ -471,18 +625,22 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." (apply #'nconc (mapcar #'(lambda (command) - `((unless (fboundp ',command) - (autoload #',command ,name-string nil t)) - (declare-function ,command ,name-string))) + (append + `((unless (fboundp ',command) + (autoload #',command ,name-string nil t))) + (when (bound-and-true-p byte-compile-current-file) + `((eval-when-compile + (declare-function ,command ,name-string)))))) commands))) + (when (bound-and-true-p byte-compile-current-file) + (mapcar #'(lambda (fn) `(eval-when-compile + (declare-function ,fn ,name-string))) + (plist-get args :functions))) + (if (numberp deferral) `((run-with-idle-timer ,deferral nil #'require ',name-symbol nil t))) - (when (bound-and-true-p byte-compile-current-file) - (mapcar #'(lambda (fn) `(declare-function ,fn ,name-string)) - (plist-get args :functions))) - ;; (if (and defer-loading config-body) ;; `((defalias ',config-defun #'(lambda () ,config-body*)))) @@ -606,6 +764,11 @@ this file. Usage: (put 'use-package 'lisp-indent-function 'defun) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Special support for autoloading keymaps +;; + (defun use-package-autoload-keymap (keymap-symbol package override) "Loads PACKAGE and then binds the key sequence used to invoke this function to KEYMAP-SYMBOL. It then simulates pressing the @@ -632,13 +795,6 @@ deferred until the prefix key sequence is pressed." (error "use-package: package %s failed to define keymap %s" package keymap-symbol)))) -(defconst use-package-font-lock-keywords - '(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" - (1 font-lock-keyword-face) - (2 font-lock-constant-face nil t)))) - -(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; :pin and :ensure support From e7f3f97a7159f8816e757b864e63d7ad95242d29 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 21 Mar 2015 02:57:18 -0500 Subject: [PATCH 166/606] Modular support appears to be working --- lisp/use-package/use-package.el | 1034 ++++++++++++++++++------------- 1 file changed, 608 insertions(+), 426 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 82ee738ebf3..4f6241fc37a 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -59,6 +59,11 @@ then the expanded macros do their job silently." :type 'boolean :group 'use-package) +(defcustom use-package-debug nil + "Whether to display use-package expansions in a *use-package* buffer." + :type 'boolean + :group 'use-package) + (defcustom use-package-minimum-reported-time 0.1 "Minimal load time that will be reported. @@ -102,8 +107,8 @@ the user specified." :unless :requires :load-path - :no-require :preface + :no-require :bind :bind* :bind-keymap @@ -118,7 +123,10 @@ the user specified." :init :config :diminish) - "Establish which keywords are valid, and the order they are processed in." + "Establish which keywords are valid, and the order they are processed in. + +Note that `:disabled' is special, in that it causes nothing at all to happen, +even if the rest of the use-package declaration is incorrect." :type '(repeat symbol) :group 'use-package) @@ -151,29 +159,26 @@ then your byte-compiled init file is as minimal as possible." (error (ignore (display-warning 'use-package - (format "use-package: Error in %s: %s" ,name - (error-message-string ,err)) + (format "%s %s: %s" + ,name ,label (error-message-string ,err)) :error))))))))) (put 'use-package-expand 'lisp-indent-function 'defun) -(defun use-package-hook-injector (name-string keyword args) +(defun use-package-hook-injector (name-string keyword body) "Wrap pre/post hook injections around a given keyword form. ARGS is a list of forms, so `((foo))' if only `foo' is being called." (if (not use-package-inject-hooks) - (use-package-expand name-string (format "%s" keyword) - (plist-get args keyword)) - (let ((keyword-name (substring (format "%s" keyword) 1)) - (block (plist-get args keyword))) - (when block + (use-package-expand name-string (format "%s" keyword) body) + (let ((keyword-name (substring (format "%s" keyword) 1))) + (when body `((when ,(macroexp-progn (use-package-expand name-string (format "pre-%s hook" keyword) `(run-hook-with-args-until-failure ',(intern (concat "use-package--" name-string "--pre-" keyword-name "-hook"))))) ,(macroexp-progn - (use-package-expand name-string (format "%s" keyword) - (plist-get args keyword))) + (use-package-expand name-string (format "%s" keyword) body)) ,(macroexp-progn (use-package-expand name-string (format "post-%s hook" keyword) `(run-hooks @@ -204,6 +209,20 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." "Report MSG as an error, so the user knows it came from this package." (error "use-package: %s" msg)) +(defsubst use-package-plist-maybe-put (plist property value) + "Add a VALUE for PROPERTY to PLIST, if it does not already exist." + (if (plist-member plist property) + plist + (plist-put plist property value))) + +(defsubst use-package-plist-cons (plist property value) + "Cons VALUE onto the head of the list at PROPERTY in PLIST." + (plist-put plist property (cons value (plist-get plist property)))) + +(defsubst use-package-plist-append (plist property value) + "Append VALUE onto the front of the list at PROPERTY in PLIST." + (plist-put plist property (append value (plist-get plist property)))) + (defun use-package-plist-delete (plist property) "Delete PROPERTY from PLIST. This is in contrast to merely setting it to 0." @@ -240,12 +259,16 @@ This is in contrast to merely setting it to 0." (push (cons (car plist) (cadr plist)) plist-grouped) (setq plist (cddr plist))) - (append - (sort plist-grouped - #'(lambda (l r) (< (use-package-keyword-index (car l)) - (use-package-keyword-index (car r)))))))) + (let (result) + (dolist (x + (nreverse + (sort plist-grouped + #'(lambda (l r) (< (use-package-keyword-index (car l)) + (use-package-keyword-index (car r))))))) + (setq result (cons (car x) (cons (cdr x) result)))) + result))) -(defsubst use-package-cat-maybes (&rest elems) +(defsubst use-package-concat (&rest elems) "Delete all empty lists from ELEMS (nil or (list nil)), and append them." (apply #'nconc (delete nil (delete (list nil) elems)))) @@ -256,11 +279,172 @@ This is in contrast to merely setting it to 0." (font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Keyword processing +;; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Normalization functions ;; +(defun use-package-normalize-plist (name-symbol input) + "Given a pseudo-plist, normalize it to a regular plist." + (unless (null input) + (let* ((keyword (car input)) + (xs (use-package-split-list #'keywordp (cdr input))) + (args (car xs)) + (tail (cdr xs)) + (normalizer (intern (concat "use-package-normalize/" + (symbol-name keyword)))) + (arg + (cond + ((eq keyword :disabled) + (use-package-normalize-plist name-symbol tail)) + ((functionp normalizer) + (funcall normalizer name-symbol keyword args)) + ((= (length args) 1) + (car args)) + (t + args)))) + (if (memq keyword use-package-keywords) + (cons keyword + (cons arg (use-package-normalize-plist name-symbol tail))) + (use-package-error (format "Unrecognized keyword: %s" keyword)))))) + +(defun use-package-process-keywords (name-symbol plist &optional state) + "Process the next keyword in the free-form property list PLIST. +The values in the PLIST have each been normalized by the function +use-package-normalize/KEYWORD (minus the colon). + +STATE is a property list that the function may modify and/or +query. This is useful if a package defines multiple keywords and +wishes them to have some kind of stateful interaction. + +Unless the KEYWORD being processed intends to ignore remaining +keywords, it must call this function recursively, passing in the +plist with its keyword and argument removed, and passing in the +next value for the STATE." + (unless (null plist) + (let* ((keyword (car plist)) + (arg (cadr plist)) + (rest (cddr plist))) + (unless (keywordp keyword) + (use-package-error (format "%s is not a keyword" keyword))) + (let* ((handler (concat "use-package-handler/" (symbol-name keyword))) + (handler-sym (intern handler))) + (if (functionp handler-sym) + (funcall handler-sym name-symbol keyword arg rest state) + (use-package-error + (format "Keyword handler not defined: %s" handler))))))) + +(put 'use-package-process-keywords 'lisp-indent-function 'defun) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :pin +;; + +(defun use-package-only-one (label args f) + "Call F on the first member of ARGS if it has exactly one element." + (declare (indent 1)) + (cond + ((and (listp args) (listp (cdr args)) + (= (length args) 1)) + (funcall f label (car args))) + (t + (use-package-error + (concat label " wants exactly one argument"))))) + +(put 'use-package-only-one 'lisp-indent-function 'defun) + +(defun use-package-normalize/:pin (name-symbol keyword args) + (use-package-only-one (symbol-name keyword) args + (lambda (label arg) + (cond + ((stringp arg) arg) + ((symbolp arg) (symbol-name arg)) + (t + (use-package-error + ":pin wants an archive name (a string)")))))) + +(eval-when-compile + (defvar package-pinned-packages) + (defvar package-archives)) + +(defun use-package--archive-exists-p (archive) + "Check if a given ARCHIVE is enabled. + +ARCHIVE can be a string or a symbol or 'manual to indicate a +manually updated package." + (if (member archive '(manual "manual")) + 't + (let ((valid nil)) + (dolist (pa package-archives) + (when (member archive (list (car pa) (intern (car pa)))) + (setq valid 't))) + valid))) + +(defun use-package-pin-package (package archive) + "Pin PACKAGE to ARCHIVE." + (unless (boundp 'package-pinned-packages) + (setq package-pinned-packages ())) + (let ((archive-symbol (if (symbolp archive) archive (intern archive))) + (archive-name (if (stringp archive) archive (symbol-name archive)))) + (if (use-package--archive-exists-p archive-symbol) + (push (cons package archive-name) package-pinned-packages) + (error "Archive '%s' requested for package '%s' is not available." + archive-name package)) + (package-initialize t))) + +(defun use-package-handler/:pin (name-symbol keyword archive-name rest state) + (let ((body (use-package-process-keywords name-symbol rest state))) + ;; This happens at macro expansion time, not when the expanded code is + ;; compiled or evaluated. + (if (null archive-name) + body + (use-package-pin-package name-symbol archive-name) + (use-package-concat + body + `((push '(,name-symbol . ,archive-name) + package-pinned-packages)))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :ensure +;; + +(defun use-package-normalize/:ensure (name-symbol keyword args) + (if (null args) + t + (use-package-only-one (symbol-name keyword) args + (lambda (label arg) + (if (symbolp arg) + arg + (use-package-error + (concat ":ensure wants an optional package name " + "(an unquoted symbol name)"))))))) + +(defun use-package-ensure-elpa (package) + (when (not (package-installed-p package)) + (package-install package))) + +(defun use-package-handler/:ensure (name-symbol keyword ensure rest state) + (let ((body (use-package-process-keywords name-symbol rest state))) + ;; This happens at macro expansion time, not when the expanded code is + ;; compiled or evaluated. + (let ((package-name (or (and (eq ensure t) name-symbol) ensure))) + (when package-name + (require 'package) + (use-package-ensure-elpa package-name))) + body)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :if, :when and :unless +;; + (defsubst use-package-normalize-value (label arg) "Normalize a value." (cond ((symbolp arg) @@ -269,6 +453,75 @@ This is in contrast to merely setting it to 0." `(funcall #',arg)) (t arg))) +(defun use-package-normalize-test (name-symbol keyword args) + (use-package-only-one (symbol-name keyword) args + #'use-package-normalize-value)) + +(defalias 'use-package-normalize/:if 'use-package-normalize-test) +(defalias 'use-package-normalize/:when 'use-package-normalize-test) + +(defun use-package-normalize/:unless (name-symbol keyword args) + (not (use-package-only-one (symbol-name keyword) args + #'use-package-normalize-value))) + +(defun use-package-handler/:if (name-symbol keyword pred rest state) + (let ((body (use-package-process-keywords name-symbol rest state))) + `((when ,pred ,@body)))) + +(defalias 'use-package-handler/:when 'use-package-handler/:if) + +(defun use-package-handler/:unless (name-symbol keyword pred rest state) + (let ((body (use-package-process-keywords name-symbol rest state))) + `((unless ,pred ,@body)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :requires +;; + +(defun use-package-as-one (label args f) + "Call F on the first element of ARGS if it has one element, or all of ARGS." + (declare (indent 1)) + (if (and (listp args) (listp (cdr args))) + (if (= (length args) 1) + (funcall f label (car args)) + (funcall f label args)) + (use-package-error + (concat label " wants a list")))) + +(put 'use-package-as-one 'lisp-indent-function 'defun) + +(defun use-package-normalize-symbols (label arg &optional recursed) + "Normalize a list of symbols." + (cond + ((symbolp arg) + (list arg)) + ((and (not recursed) (listp arg) (listp (cdr arg))) + (mapcar #'(lambda (x) (car (use-package-normalize-symbols label x t))) arg)) + (t + (use-package-error + (concat label " wants a symbol, or list of symbols"))))) + +(defun use-package-normalize-symlist (name-symbol keyword args) + (use-package-as-one (symbol-name keyword) args + #'use-package-normalize-symbols)) + +(defalias 'use-package-normalize/:requires 'use-package-normalize-symlist) + +(defun use-package-handler/:requires (name-symbol keyword requires rest state) + (let ((body (use-package-process-keywords name-symbol rest state))) + (if (null requires) + body + `((when ,(if (listp requires) + `(not (member nil (mapcar #'featurep ',requires))) + `(featurep ',requires)) + ,@body))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :load-path +;; + (defun use-package-normalize-paths (label arg &optional recursed) "Normalize a list of filesystem paths." (cond @@ -287,17 +540,65 @@ This is in contrast to merely setting it to 0." (use-package-error (concat label " wants a directory path, or list of paths"))))) -(defun use-package-as-one (label args f) - "Call F on the first element of ARGS if it has one element, or all of ARGS." - (declare (indent 1)) - (if (and (listp args) (listp (cdr args))) - (if (= (length args) 1) - (funcall f label (car args)) - (funcall f label args)) - (use-package-error - (concat label " wants a list")))) +(defun use-package-normalize/:load-path (name-symbol keyword args) + (use-package-as-one (symbol-name keyword) args + #'use-package-normalize-paths)) -(put 'use-package-as-one 'lisp-indent-function 'defun) +(defun use-package-handler/:load-path (name-symbol keyword arg rest state) + (let ((body (use-package-process-keywords name-symbol rest state))) + (use-package-concat + (mapcar #'(lambda (path) + `(eval-and-compile (push ,path load-path))) arg) + body))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :no-require +;; + +(defun use-package-normalize-predicate (name-symbol keyword args) + (if (null args) + t + (use-package-only-one (symbol-name keyword) args + #'use-package-normalize-value))) + +(defalias 'use-package-normalize/:no-require 'use-package-normalize-predicate) + +(defun use-package-handler/:no-require (name-symbol keyword arg rest state) + ;; This keyword has no functional meaning. + (use-package-process-keywords name-symbol rest state)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :preface +;; + +(defun use-package-normalize-form (label args) + "Given a list of forms, return it wrapped in `progn'." + (unless (listp (car args)) + (use-package-error (concat label " wants a sexp or list of sexps"))) + (mapcar #'(lambda (form) + (if (and (consp form) + (eq (car form) 'use-package)) + (macroexpand form) + form)) args)) + +(defun use-package-normalize-forms (name-symbol keyword args) + (use-package-normalize-form (symbol-name keyword) args)) + +(defalias 'use-package-normalize/:preface 'use-package-normalize-forms) + +(defun use-package-handler/:preface (name-symbol keyword arg rest state) + (let ((body (use-package-process-keywords name-symbol rest state))) + (use-package-concat + (unless (null arg) + `((eval-and-compile ,@arg))) + body))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :bind, :bind* +;; (defsubst use-package-is-sympair (x &optional allow-vector) "Return t if X has the type (STRING . SYMBOL)." @@ -328,81 +629,266 @@ This is in contrast to merely setting it to 0." (defalias 'use-package-normalize/:bind 'use-package-normalize-binder) (defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) + +(defun use-package-handler/:bind + (name-symbol keyword arg rest state &optional override) + (let* (commands + (form (mapcar + #'(lambda (binding) + (push (cdr binding) commands) + `(,(if override + 'bind-key* + 'bind-key) ,(car binding) #',(cdr binding))) arg))) + (use-package-concat + (use-package-process-keywords name-symbol + (use-package-sort-keywords + (use-package-plist-maybe-put rest :defer t)) + (use-package-plist-append state :commands commands)) + `((ignore ,@form))))) + +(defun use-package-handler/:bind* (name-symbol keyword arg rest state) + (use-package-handler/:bind name-symbol keyword arg rest state t)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :bind-keymap, :bind-keymap* +;; + (defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder) (defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder) +(defun use-package-autoload-keymap (keymap-symbol package override) + "Loads PACKAGE and then binds the key sequence used to invoke +this function to KEYMAP-SYMBOL. It then simulates pressing the +same key sequence a again, so that the next key pressed is routed +to the newly loaded keymap. + +This function supports use-package's :bind-keymap keyword. It +works by binding the given key sequence to an invocation of this +function for a particular keymap. The keymap is expected to be +defined by the package. In this way, loading the package is +deferred until the prefix key sequence is pressed." + (if (not (require package nil t)) + (error "Could not load package %s" package) + (if (and (boundp keymap-symbol) + (keymapp (symbol-value keymap-symbol))) + (let ((key (key-description (this-command-keys-vector))) + (keymap (symbol-value keymap-symbol))) + (if override + ;; eval form is necessary to avoid compiler error + `(eval `(bind-key* ,key ,keymap)) + (bind-key key keymap)) + (setq unread-command-events + (listify-key-sequence (this-command-keys-vector)))) + (error "use-package: package %s failed to define keymap %s" + package keymap-symbol)))) + +(defun use-package-handler/:bind-keymap + (name-symbol keyword arg rest state &optional override) + (let* (commands + (form (mapcar + #'(lambda (binding) + (push (cdr binding) commands) + `(,(if override + 'bind-key* + 'bind-key) + ,(car binding) + #'(lambda () + (use-package-autoload-keymap + ',(cdr binding) ',name-symbol nil)))) arg))) + (use-package-concat + (use-package-process-keywords name-symbol + (use-package-sort-keywords + (use-package-plist-maybe-put rest :defer t)) + (use-package-plist-append state :commands commands)) + `((ignore ,@form))))) + +(defun use-package-handler/:bind-keymap* (name-symbol keyword arg rest state) + (use-package-handler/:bind-keymap name-symbol keyword arg rest state t)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :interpreter +;; + (defun use-package-normalize-mode (name-symbol keyword args) (use-package-as-one (symbol-name keyword) args (apply-partially #'use-package-normalize-pairs name-symbol))) -(defalias 'use-package-normalize/:mode 'use-package-normalize-mode) (defalias 'use-package-normalize/:interpreter 'use-package-normalize-mode) -(defun use-package-normalize-symbols (label arg &optional recursed) - "Normalize a list of symbols." - (cond - ((symbolp arg) - (list arg)) - ((and (not recursed) (listp arg) (listp (cdr arg))) - (mapcar #'(lambda (x) (car (use-package-normalize-symbols label x t))) arg)) - (t - (use-package-error - (concat label " wants a symbol, or list of symbols"))))) +(defun use-package-handler/:interpreter (name-symbol keyword arg rest state) + (let* (commands + (form (mapcar #'(lambda (interpreter) + (push (cdr interpreter) commands) + `(push ',interpreter interpreter-mode-alist)) arg))) + (use-package-concat + (use-package-process-keywords name-symbol + (use-package-sort-keywords + (use-package-plist-maybe-put rest :defer t)) + (use-package-plist-append state :commands commands)) + `((ignore ,@form))))) -(defun use-package-normalize-symlist (name-symbol keyword args) - (use-package-as-one (symbol-name keyword) args - #'use-package-normalize-symbols)) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :mode +;; + +(defalias 'use-package-normalize/:mode 'use-package-normalize-mode) + +(defun use-package-handler/:mode (name-symbol keyword arg rest state) + (let* (commands + (form (mapcar #'(lambda (mode) + (push (cdr mode) commands) + `(push ',mode auto-mode-alist)) arg))) + (use-package-concat + (use-package-process-keywords name-symbol + (use-package-sort-keywords + (use-package-plist-maybe-put rest :defer t)) + (use-package-plist-append state :commands commands)) + `((ignore ,@form))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :commands +;; (defalias 'use-package-normalize/:commands 'use-package-normalize-symlist) + +(defun use-package-handler/:commands (name-symbol keyword arg rest state) + ;; The actual processing for commands is done in :defer + (use-package-process-keywords name-symbol + (use-package-sort-keywords + (use-package-plist-maybe-put rest :defer t)) + (use-package-plist-append state :commands arg))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :defines +;; + (defalias 'use-package-normalize/:defines 'use-package-normalize-symlist) + +(defun use-package-handler/:defines (name-symbol keyword arg rest state) + (let ((body (use-package-process-keywords name-symbol rest state))) + body)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :functions +;; + (defalias 'use-package-normalize/:functions 'use-package-normalize-symlist) -(defalias 'use-package-normalize/:requires 'use-package-normalize-symlist) -(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"))))) +(defun use-package-handler/:functions (name-symbol keyword arg rest state) + (let ((body (use-package-process-keywords name-symbol rest state))) + (if (not (bound-and-true-p byte-compile-current-file)) + body + (use-package-concat + (unless (null arg) + `((eval-when-compile + ,@(mapcar + #'(lambda (fn) + `(declare-function ,fn ,(symbol-name name-symbol))) arg)))) + body)))) -(put 'use-package-only-one 'lisp-indent-function 'defun) - -(defun use-package-normalize-predicate (name-symbol keyword args) - (if (null args) - t - (use-package-only-one (symbol-name keyword) args - #'use-package-normalize-value))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :defer +;; (defalias 'use-package-normalize/:defer 'use-package-normalize-predicate) + +(defun use-package-handler/:defer (name-symbol keyword arg rest state) + (let ((body (use-package-process-keywords name-symbol rest + (plist-put state :deferred t))) + (name-string (symbol-name name-symbol))) + (use-package-concat + ;; Load the package after a set amount of idle time, if the argument to + ;; `:defer' was a number. + (when (numberp arg) + `((run-with-idle-timer ,arg nil #'require ',name-symbol nil t))) + + ;; Since we deferring load, establish any necessary autoloads, and also + ;; keep the byte-compiler happy. + (apply + #'nconc + (mapcar #'(lambda (command) + (append + `((unless (fboundp ',command) + (autoload #',command ,name-string nil t))) + (when (bound-and-true-p byte-compile-current-file) + `((eval-when-compile + (declare-function ,command ,name-string)))))) + (delete-dups (plist-get state :commands)))) + + body))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :demand +;; + (defalias 'use-package-normalize/:demand 'use-package-normalize-predicate) -(defalias 'use-package-normalize/:disabled 'use-package-normalize-predicate) -(defalias 'use-package-normalize/:no-require 'use-package-normalize-predicate) -(defun use-package-normalize/:ensure (name-symbol keyword args) - (if (null args) - t - (use-package-only-one (symbol-name keyword) args - (lambda (label arg) - (if (symbolp arg) - arg - (use-package-error - (concat ":ensure wants an optional package name " - "(an unquoted symbol name)"))))))) +(defun use-package-handler/:demand (name-symbol keyword arg rest state) + (use-package-process-keywords name-symbol rest + (use-package-plist-delete state :deferred))) -(defun use-package-normalize-test (name-symbol keyword args) - (use-package-only-one (symbol-name keyword) args - #'use-package-normalize-value)) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :init +;; -(defalias 'use-package-normalize/:if 'use-package-normalize-test) -(defalias 'use-package-normalize/:when 'use-package-normalize-test) +(defalias 'use-package-normalize/:init 'use-package-normalize-forms) -(defun use-package-normalize/:unless (name-symbol keyword args) - (not (use-package-only-one (symbol-name keyword) args - #'use-package-normalize-value))) +(defun use-package-handler/:init (name-symbol keyword arg rest state) + (let ((body (use-package-process-keywords name-symbol rest state))) + (use-package-concat + ;; The user's initializations + (use-package-hook-injector (symbol-name name-symbol) :init arg) + body))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :config +;; + +(defalias 'use-package-normalize/:config 'use-package-normalize-forms) + +(defun use-package-handler/:config (name-symbol keyword arg rest state) + (let* ((body (use-package-process-keywords name-symbol rest state)) + (config-body + (if (equal arg '(t)) + body + (use-package--with-elapsed-timer + (format "Configuring package %s" name-symbol) + (use-package-concat + (use-package-hook-injector (symbol-name name-symbol) + :config arg) + body + (list t)))))) + (if (plist-get state :deferred) + (unless (equal config-body '(t)) + `((eval-after-load ',name-symbol + ',(macroexp-progn config-body)))) + (use-package--with-elapsed-timer + (format "Loading package %s" name-symbol) + (if use-package-expand-minimally + (use-package-concat + (list `(require ',name-symbol)) + config-body) + `((if (not (require ',name-symbol nil t)) + (ignore + (display-warning + 'use-package + (format "Could not load %s" ',name-symbol) + :error)) + ,@config-body))))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :diminish (defun use-package-normalize-diminish (name-symbol label arg &optional recursed) "Normalize the arguments to diminish down to a list of one of two forms: @@ -427,253 +913,21 @@ This is in contrast to merely setting it to 0." (use-package-as-one (symbol-name keyword) args (apply-partially #'use-package-normalize-diminish name-symbol))) -(defun use-package-normalize-form (label args) - "Given a list of forms, return it wrapped in `progn'." - (unless (listp (car args)) - (use-package-error (concat label " wants a sexp or list of sexps"))) - (mapcar #'(lambda (form) - (if (and (consp form) - (eq (car form) 'use-package)) - (macroexpand form) - form)) args)) - -(defun use-package-normalize-forms (name-symbol keyword args) - (use-package-normalize-form (symbol-name keyword) args)) - -(defalias 'use-package-normalize/:preface 'use-package-normalize-forms) -(defalias 'use-package-normalize/:init 'use-package-normalize-forms) -(defalias 'use-package-normalize/:config 'use-package-normalize-forms) - -(defun use-package-normalize/:load-path (name-symbol keyword args) - (use-package-as-one (symbol-name keyword) args - #'use-package-normalize-paths)) - -(defun use-package-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)")))))) - -(defun use-package-normalize-plist (name-symbol input) - "Given a pseudo-plist, normalize it to a regular plist." - (unless (null input) - (let* ((keyword (car input)) - (xs (use-package-split-list #'keywordp (cdr input))) - (args (car xs)) - (tail (cdr xs)) - (normalizer (intern (concat "use-package-normalize/" - (symbol-name keyword)))) - (arg - (cond - ((functionp normalizer) - (funcall normalizer name-symbol keyword args)) - ((= (length args) 1) - (car args)) - (t - args)))) - (if (memq keyword use-package-keywords) - (cons keyword - (cons arg (use-package-normalize-plist name-symbol tail))) - (use-package-error (format "Unrecognized keyword: %s" keyword)))))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; Keyword processing -;; - -(defun use-package-process-keywords (name-symbol plist 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." - (let ((plist* (use-package-sort-keywords - (use-package-normalize-plist name-symbol plist)))) - (unless (null plist*) - (let* ((keyword (car plist*)) - (arg (cadr plist*)) - (rest (cddr plist*))) - (unless (keywordp keyword) - (use-package-error (format "%s is not a keyword" keyword))) - (let* ((handler (concat "use-package-handler/" - (symbol-name keyword))) - (handler-sym (intern handler))) - (if (functionp handler-sym) - (funcall handler-sym name-symbol keyword arg rest state) - (use-package-error - (format "Keyword handler not defined: %s" handler)))))))) - -(defun use-package-handler/:if (name-symbol keyword pred rest state) - `((when ,pred - ,@(use-package-process-keywords name-symbol rest state)))) +(defun use-package-handler/:diminish (name-symbol keyword arg rest state) + (let ((body (use-package-process-keywords name-symbol rest state))) + (use-package-concat + (mapcar #'(lambda (var) + (if (consp var) + `(diminish ',(car var) ,(cdr var)) + `(diminish ',var))) + arg) + body))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; The main macro ;; -(defun use--package (name name-symbol name-string args) - "See docstring for `use-package'." - (let* - ((commands (plist-get args :commands)) - (deferral (plist-get args :defer)) - - ;; Note: evaluation of this forms possibly extends the value of - ;; `commands'. - (bindings - (append - (mapcar #'(lambda (binding) - `(bind-key ,(car binding) - #'(lambda () (interactive) - (use-package-autoload-keymap - ',(cdr binding) ',name-symbol nil)))) - (plist-get args :bind-keymap)) - - (mapcar #'(lambda (binding) - `(bind-key ,(car binding) - #'(lambda () (interactive) - (use-package-autoload-keymap - ',(cdr binding) ',name-symbol t)))) - (plist-get args :bind-keymap*)) - - (mapcar #'(lambda (mode) - (push (cdr mode) commands) - `(push ',mode auto-mode-alist)) - (plist-get args :mode)) - - (mapcar #'(lambda (interpreter) - (push (cdr interpreter) commands) - `(push ',interpreter interpreter-mode-alist)) - (plist-get args :interpreter)) - - (mapcar #'(lambda (binding) - (push (cdr binding) commands) - `(bind-key ,(car binding) #',(cdr binding))) - (plist-get args :bind)) - - (mapcar #'(lambda (binding) - (push (cdr binding) commands) - `(bind-key* ,(car binding) #',(cdr binding))) - (plist-get args :bind*)))) - - ;; Should we defer loading of the package lazily? - (defer-loading (and (not (plist-get args :demand)) - (or commands deferral - (plist-get args :no-require) - (plist-get args :bind-keymap) - (plist-get args :bind-keymap*)))) - - (pre-compile-load - ;; When byte-compiling, load the package here so that all of its - ;; symbols are in scope. - (when (bound-and-true-p byte-compile-current-file) - `((eval-when-compile - ,@(mapcar #'(lambda (var) `(defvar ,var)) - (plist-get args :defines)) - (with-demoted-errors - ,(format "Error in %s: %%S" name-string) - ,(if use-package-verbose - `(message "Compiling package %s" ,name-string)) - ,(unless (plist-get args :no-require) - `(require ',name-symbol nil t))))))) - - ;; These are all the configurations to be made after the package has - ;; loaded. - (config-body - (use-package--with-elapsed-timer - (format "Configuring package %s" name-string) - (use-package-cat-maybes - (use-package-hook-injector name-string :config args) - - (mapcar #'(lambda (var) - (if (listp var) - `(diminish ',(car var) ,(cdr var)) - `(diminish ',var))) - (plist-get args :diminish))))) - - (config-defun - (make-symbol (concat "use-package--" name-string "--config")))) - - (setq commands (delete-dups commands)) - - ;; Return the main body of the macro - (use-package-cat-maybes - ;; Setup the load-path - (mapcar #'(lambda (path) - `(eval-and-compile (push ,path load-path))) - (plist-get args :load-path)) - - pre-compile-load - - (mapcar #'(lambda (form) - `(eval-and-compile ,form)) - (plist-get args :preface)) - - ;; Setup any required autoloads - (if defer-loading - (apply - #'nconc - (mapcar #'(lambda (command) - (append - `((unless (fboundp ',command) - (autoload #',command ,name-string nil t))) - (when (bound-and-true-p byte-compile-current-file) - `((eval-when-compile - (declare-function ,command ,name-string)))))) - commands))) - - (when (bound-and-true-p byte-compile-current-file) - (mapcar #'(lambda (fn) `(eval-when-compile - (declare-function ,fn ,name-string))) - (plist-get args :functions))) - - (if (numberp deferral) - `((run-with-idle-timer ,deferral nil #'require ',name-symbol nil t))) - - ;; (if (and defer-loading config-body) - ;; `((defalias ',config-defun #'(lambda () ,config-body*)))) - - ;; The user's initializations - (use-package-hook-injector name-string :init args) - - (if defer-loading - (use-package-cat-maybes - bindings - (if config-body - `((eval-after-load ',name - ;; '(,config-defun) - ',(macroexp-progn config-body)))) - (list t)) - (use-package--with-elapsed-timer - (format "Loading package %s" name-string) - (if use-package-expand-minimally - (use-package-cat-maybes - (list `(require ',name-symbol)) - bindings - config-body - (list t)) - `((if (not (require ',name-symbol nil t)) - (ignore - (display-warning - 'use-package - (format "Could not load package %s" ,name-string) - :error)) - ,@(use-package-cat-maybes - bindings - config-body - (list t)))))))))) - (defmacro use-package (name &rest args) "Declare an Emacs package by specifying a group of configuration options. @@ -722,117 +976,45 @@ this file. Usage: :pin Pin the package to an archive." (declare (indent 1)) (unless (member :disabled args) - (let* ((name-string (if (stringp name) name (symbol-name name))) - (name-symbol (if (stringp name) (intern name) name)) - (args* (use-package-normalize-plist name-symbol args)) - (archive-name (plist-get args* :pin)) - (ensure (plist-get args* :ensure)) - (package-name (or (and (eq ensure t) name) ensure))) - ;; Pin any packages that have been marked with `:pin'. - (when archive-name - (use-package-pin-package name-symbol archive-name)) + (let* ((name-symbol (if (stringp name) (intern name) name)) + (args* (use-package-sort-keywords + (use-package-plist-maybe-put + (use-package-normalize-plist name-symbol args) + :config '(t))))) - ;; Ensure that the package has been installed, if marked with - ;; `:ensure'. - (when package-name - (require 'package) - (use-package-ensure-elpa package-name)) + ;; When byte-compiling, pre-load the package so all its symbols are in + ;; scope. + (if (bound-and-true-p byte-compile-current-file) + (setq args* + (use-package-plist-cons + args* :preface + `(eval-when-compile + ,@(mapcar #'(lambda (var) `(defvar ,var)) + (plist-get args* :defines)) + (with-demoted-errors + ,(format "Error loading %s: %%S" name-symbol) + ,(if use-package-verbose + `(message "Compiling package %s" ',name-symbol)) + ,(unless (plist-get args* :no-require) + `(require ',name-symbol nil t))))))) + + (let ((body + (macroexp-progn + (use-package-process-keywords name-symbol args*)))) + (if use-package-debug + (display-buffer + (save-current-buffer + (let ((buf (get-buffer-create "*use-package*"))) + (with-current-buffer buf + (delete-region (point-min) (point-max)) + (emacs-lisp-mode) + (insert (pp-to-string body))) + buf)))) + body)))) - ;; At this point, we can expand the macro using the helper function. - ;; `use--package'. - (let* - ((body (use-package-cat-maybes - (use--package name name-symbol name-string args*) - (when archive-name - `((push '(,name-symbol . ,archive-name) - package-pinned-packages))))) - (pred (plist-get args* :if)) - (expansion (if pred - `((when ,pred ,@body)) - body)) - (requires (plist-get args* :requires)) - (body* - (macroexp-progn - (if (null requires) - expansion - `((if ,(if (listp requires) - `(not (member nil (mapcar #'featurep ',requires))) - `(featurep ',requires)) - ,@expansion)))))) - ;; (message "Expanded:\n%s" (pp-to-string body*)) - body*)))) (put 'use-package 'lisp-indent-function 'defun) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; Special support for autoloading keymaps -;; - -(defun use-package-autoload-keymap (keymap-symbol package override) - "Loads PACKAGE and then binds the key sequence used to invoke -this function to KEYMAP-SYMBOL. It then simulates pressing the -same key sequence a again, so that the next key pressed is routed -to the newly loaded keymap. - -This function supports use-package's :bind-keymap keyword. It -works by binding the given key sequence to an invocation of this -function for a particular keymap. The keymap is expected to be -defined by the package. In this way, loading the package is -deferred until the prefix key sequence is pressed." - (if (not (require package nil t)) - (error "Could not load package %s" package) - (if (and (boundp keymap-symbol) - (keymapp (symbol-value keymap-symbol))) - (let ((key (key-description (this-command-keys-vector))) - (keymap (symbol-value keymap-symbol))) - (if override - ;; eval form is necessary to avoid compiler error - `(eval `(bind-key* ,key ,keymap)) - (bind-key key keymap)) - (setq unread-command-events - (listify-key-sequence (this-command-keys-vector)))) - (error "use-package: package %s failed to define keymap %s" - package keymap-symbol)))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; :pin and :ensure support -;; - -(eval-when-compile - (defvar package-pinned-packages) - (defvar package-archives)) - -(defun use-package-pin-package (package archive) - "Pin PACKAGE to ARCHIVE." - (unless (boundp 'package-pinned-packages) - (setq package-pinned-packages ())) - (let ((archive-symbol (if (symbolp archive) archive (intern archive))) - (archive-name (if (stringp archive) archive (symbol-name archive)))) - (if (use-package--archive-exists-p archive-symbol) - (push (cons package archive-name) package-pinned-packages) - (error "Archive '%s' requested for package '%s' is not available." - archive-name package)) - (package-initialize t))) - -(defun use-package--archive-exists-p (archive) - "Check if a given ARCHIVE is enabled. - -ARCHIVE can be a string or a symbol or 'manual to indicate a -manually updated package." - (if (member archive '(manual "manual")) - 't - (let ((valid nil)) - (dolist (pa package-archives) - (when (member archive (list (car pa) (intern (car pa)))) - (setq valid 't))) - valid))) - -(defun use-package-ensure-elpa (package) - (when (not (package-installed-p package)) - (package-install package))) - (provide 'use-package) ;; Local Variables: From 2abf565af2f6bf27c854467ef1b1dca584128861 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 21 Mar 2015 03:12:32 -0500 Subject: [PATCH 167/606] :pin should return `t' --- lisp/use-package/use-package.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 4f6241fc37a..4c1433d66d9 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -408,7 +408,8 @@ manually updated package." (use-package-concat body `((push '(,name-symbol . ,archive-name) - package-pinned-packages)))))) + package-pinned-packages) + t))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; From eb6b81dfecbb1f0a79ec94388b8474c3871e79b2 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 21 Mar 2015 03:30:04 -0500 Subject: [PATCH 168/606] Allow :map in bind-keys to accept multiple maps Fixes https://github.com/jwiegley/use-package/issues/129 --- lisp/use-package/bind-key.el | 116 +++++++++++++++++++---------------- 1 file changed, 62 insertions(+), 54 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index bf4e13b2189..4cf6cf8708b 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -1,77 +1,77 @@ -;;; bind-key.el --- A simple way to manage personal keybindings +;;; bind-key.el --- a simple way to manage personal keybindings -;; Copyright (C) 2012 John Wiegley +;; copyright (c) 2012 john wiegley -;; Author: John Wiegley -;; Created: 16 Jun 2012 -;; Version: 1.0 -;; Keywords: keys keybinding config dotemacs -;; URL: https://github.com/jwiegley/use-package +;; author: john wiegley +;; created: 16 jun 2012 +;; version: 1.0 +;; keywords: keys keybinding config dotemacs +;; url: https://github.com/jwiegley/use-package -;; This program is free software; you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 2, or (at +;; this program is free software; you can redistribute it and/or +;; modify it under the terms of the gnu general public license as +;; published by the free software foundation; either version 2, or (at ;; your option) any later version. -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. +;; 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. +;; 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: +;;; commentary: -;; If you have lots of keybindings set in your .emacs file, it can be hard to +;; if you have lots of keybindings set in your .emacs file, it can be hard to ;; know which ones you haven't set yet, and which may now be overriding some -;; new default in a new Emacs version. This module aims to solve that +;; new default in a new emacs version. this module aims to solve that ;; problem. ;; -;; Bind keys as follows in your .emacs: +;; bind keys as follows in your .emacs: ;; ;; (require 'bind-key) ;; -;; (bind-key "C-c x" 'my-ctrl-c-x-command) +;; (bind-key "c-c x" 'my-ctrl-c-x-command) ;; -;; If you want the keybinding to override all minor modes that may also bind +;; if you want the keybinding to override all minor modes that may also bind ;; the same key, use the `bind-key*' form: ;; -;; (bind-key* "" 'other-window) +;; (bind-key* "" 'other-window) ;; -;; If you want to rebind a key only in a particular keymap, use: +;; if you want to rebind a key only in a particular keymap, use: ;; -;; (bind-key "C-c x" 'my-ctrl-c-x-command some-other-mode-map) +;; (bind-key "c-c x" 'my-ctrl-c-x-command some-other-mode-map) ;; -;; To unbind a key within a keymap (for example, to stop your favorite major +;; to unbind a key within a keymap (for example, to stop your favorite major ;; mode from changing a binding that you don't want to override everywhere), ;; use `unbind-key': ;; -;; (unbind-key "C-c x" some-other-mode-map) +;; (unbind-key "c-c x" some-other-mode-map) ;; -;; To bind multiple keys at once, or set up a prefix map, a -;; `bind-keys' macro is provided. It accepts keyword arguments, see -;; its documentation for detailed description. +;; to bind multiple keys at once, or set up a prefix map, a `bind-keys' macro +;; is provided. it accepts keyword arguments, see its documentation for +;; detailed description. ;; -;; To add keys into a specific map, use :map argument +;; 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) +;; to set up a prefix map, use `:prefix-map' and `:prefix' arguments (both are +;; required) ;; ;; (bind-keys :prefix-map my-customize-prefix-map ;; :prefix "C-c c" ;; ("f" . customize-face) ;; ("v" . customize-variable)) ;; -;; You can combine all the keywords together. -;; Additionally, :prefix-docstring can be specified to set -;; documentation of created :prefix-map variable. +;; You can combine all the keywords together. Additionally, +;; `:prefix-docstring' can be specified to set documentation of created +;; `:prefix-map' variable. ;; ;; To bind multiple keys in a `bind-key*' way (to be sure that your bindings ;; will not be overridden by other modes), you may use `bind-keys*' macro: @@ -182,16 +182,17 @@ Accepts keyword arguments: The rest of the arguments are conses of keybinding string and a function symbol (unquoted)." - (let ((map (plist-get args :map)) - (doc (plist-get args :prefix-docstring)) - (prefix-map (plist-get args :prefix-map)) - (prefix (plist-get args :prefix)) - (menu-name (plist-get args :menu-name)) - (key-bindings (progn - (while (keywordp (car args)) - (pop args) - (pop args)) - args))) + (let* ((map (plist-get args :map)) + (maps (if (listp map) map (list map))) + (doc (plist-get args :prefix-docstring)) + (prefix-map (plist-get args :prefix-map)) + (prefix (plist-get args :prefix)) + (menu-name (plist-get args :menu-name)) + (key-bindings (progn + (while (keywordp (car args)) + (pop args) + (pop args)) + args))) (when (or (and prefix-map (not prefix)) (and prefix @@ -205,12 +206,19 @@ function symbol (unquoted)." ,@(when doc `((put ',prefix-map 'variable-documentation ,doc))) ,@(if menu-name `((define-prefix-command ',prefix-map nil ,menu-name)) - `((define-prefix-command ',prefix-map))) - (bind-key ,prefix ',prefix-map ,map))) - ,@(mapcar (lambda (form) - `(bind-key ,(car form) ',(cdr form) - ,(or prefix-map map))) - key-bindings)))) + `((define-prefix-command ',prefix-map))) + ,@(mapcar + #'(lambda (m) + `(bind-key ,prefix ',prefix-map ,m)) maps))) + ,@(apply + #'nconc + (mapcar (lambda (form) + (if prefix-map + `((bind-key ,(car form) ',(cdr form) ,prefix-map)) + (mapcar + #'(lambda (m) + `(bind-key ,(car form) ',(cdr form) ,m)) maps))) + key-bindings))))) (defmacro bind-keys* (&rest args) `(bind-keys :map override-global-map From 029e46a8743e8b6a0d63f449b90d233e1fd800b5 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 21 Mar 2015 03:30:52 -0500 Subject: [PATCH 169/606] Whitespace cleanups --- lisp/use-package/bind-key.el | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 4cf6cf8708b..083c8b1c0a6 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -221,8 +221,7 @@ function symbol (unquoted)." key-bindings))))) (defmacro bind-keys* (&rest args) - `(bind-keys :map override-global-map - ,@args)) + `(bind-keys :map override-global-map ,@args)) (defun get-binding-description (elem) (cond @@ -292,7 +291,7 @@ function symbol (unquoted)." (sort personal-keybindings (lambda (l r) (car (compare-keybindings l r)))))) - + (if (not (eq (cdar last-binding) (cdar binding))) (princ (format "\n\n%s\n%s\n\n" (cdar binding) @@ -300,7 +299,7 @@ function symbol (unquoted)." (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)) @@ -325,7 +324,7 @@ function symbol (unquoted)." (princ (if (string-match "[ \t]+\n" line) (replace-match "\n" t t line) line)))) - + (setq last-binding binding))))) (provide 'bind-key) From 012c37d722f779747abdb747db196eeb552aaf4c Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 21 Mar 2015 03:31:59 -0500 Subject: [PATCH 170/606] Change bind-key* behavior to mimic bind-keys* Fixes https://github.com/jwiegley/use-package/issues/148 --- lisp/use-package/bind-key.el | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 083c8b1c0a6..12502c07c38 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -165,9 +165,7 @@ spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of `(bind-key ,key-name nil ,keymap)) (defmacro bind-key* (key-name command) - `(progn - (bind-key ,key-name ,command) - (define-key override-global-map ,(read-kbd-macro key-name) ,command))) + `(bind-key ,key-name ,command override-global-map)) (defmacro bind-keys (&rest args) "Bind multiple keys at once. From 8c00f108bfa31bae6dfde16a29e7744f8c8ffc96 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 21 Mar 2015 03:46:26 -0500 Subject: [PATCH 171/606] Change use-package to use bind-keys and bind-keys* Fixes https://github.com/jwiegley/use-package/issues/129 --- lisp/use-package/bind-key.el | 49 +++++++++++++++++---------------- lisp/use-package/use-package.el | 10 ++----- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 12502c07c38..28b5dbb572b 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -191,32 +191,35 @@ function symbol (unquoted)." (pop args) (pop args)) args))) - (when (or (and prefix-map - (not prefix)) - (and prefix - (not prefix-map))) + (when (or (and prefix-map (not prefix)) + (and prefix (not prefix-map))) (error "Both :prefix-map and :prefix must be supplied")) (when (and menu-name (not prefix)) (error "If :menu-name is supplied, :prefix must be too")) - `(progn - ,@(when prefix-map - `((defvar ,prefix-map) - ,@(when doc `((put ',prefix-map 'variable-documentation ,doc))) - ,@(if menu-name - `((define-prefix-command ',prefix-map nil ,menu-name)) - `((define-prefix-command ',prefix-map))) - ,@(mapcar - #'(lambda (m) - `(bind-key ,prefix ',prefix-map ,m)) maps))) - ,@(apply - #'nconc - (mapcar (lambda (form) - (if prefix-map - `((bind-key ,(car form) ',(cdr form) ,prefix-map)) - (mapcar - #'(lambda (m) - `(bind-key ,(car form) ',(cdr form) ,m)) maps))) - key-bindings))))) + (macroexp-progn + (append + (when prefix-map + `((defvar ,prefix-map) + ,@(when doc `((put ',prefix-map 'variable-documentation ,doc))) + ,@(if menu-name + `((define-prefix-command ',prefix-map nil ,menu-name)) + `((define-prefix-command ',prefix-map))) + ,@(if maps + (mapcar + #'(lambda (m) + `(bind-key ,prefix ',prefix-map ,m)) maps) + `((bind-key ,prefix ',prefix-map))))) + (apply + #'nconc + (mapcar (lambda (form) + (if prefix-map + `((bind-key ,(car form) ',(cdr form) ,prefix-map)) + (if maps + (mapcar + #'(lambda (m) + `(bind-key ,(car form) ',(cdr form) ,m)) maps) + `((bind-key ,(car form) ',(cdr form)))))) + key-bindings)))))) (defmacro bind-keys* (&rest args) `(bind-keys :map override-global-map ,@args)) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 4c1433d66d9..5f911e3b718 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -633,19 +633,13 @@ manually updated package." (defun use-package-handler/:bind (name-symbol keyword arg rest state &optional override) - (let* (commands - (form (mapcar - #'(lambda (binding) - (push (cdr binding) commands) - `(,(if override - 'bind-key* - 'bind-key) ,(car binding) #',(cdr binding))) arg))) + (let ((commands (mapcar #'cdr arg))) (use-package-concat (use-package-process-keywords name-symbol (use-package-sort-keywords (use-package-plist-maybe-put rest :defer t)) (use-package-plist-append state :commands commands)) - `((ignore ,@form))))) + `((ignore (,(if override 'bind-keys* 'bind-keys) ,@arg)))))) (defun use-package-handler/:bind* (name-symbol keyword arg rest state) (use-package-handler/:bind name-symbol keyword arg rest state t)) From d70d70843a3c1b1fbb12267368ae24409d8e950e Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 21 Mar 2015 03:49:08 -0500 Subject: [PATCH 172/606] Correction to an eval-after-load expansion --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 5f911e3b718..4c8aad9f57a 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -864,7 +864,7 @@ deferred until the prefix key sequence is pressed." body (list t)))))) (if (plist-get state :deferred) - (unless (equal config-body '(t)) + (unless (or (null config-body) (equal config-body '(t))) `((eval-after-load ',name-symbol ',(macroexp-progn config-body)))) (use-package--with-elapsed-timer From 53bb14cfb7a4d51b4bf077955cba08e346a06720 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 21 Mar 2015 03:50:51 -0500 Subject: [PATCH 173/606] Add autoload stanzas to bind-key Fixes https://github.com/jwiegley/use-package/issues/33 --- lisp/use-package/bind-key.el | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 28b5dbb572b..5ae00396c27 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -132,6 +132,7 @@ Elements have the form ((KEY . [MAP]) CMD ORIGINAL-CMD)") +;;;###autoload (defmacro bind-key (key-name command &optional keymap) "Bind KEY-NAME to COMMAND in KEYMAP (`global-map' if not passed). @@ -161,12 +162,15 @@ spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of personal-keybindings) (define-key (or ,keymap global-map) ,keyvar ,command)))) +;;;###autoload (defmacro unbind-key (key-name &optional keymap) `(bind-key ,key-name nil ,keymap)) +;;;###autoload (defmacro bind-key* (key-name command) `(bind-key ,key-name ,command override-global-map)) +;;;###autoload (defmacro bind-keys (&rest args) "Bind multiple keys at once. @@ -221,6 +225,7 @@ function symbol (unquoted)." `((bind-key ,(car form) ',(cdr form)))))) key-bindings)))))) +;;;###autoload (defmacro bind-keys* (&rest args) `(bind-keys :map override-global-map ,@args)) @@ -277,6 +282,7 @@ function symbol (unquoted)." (t (cons (string< (caar l) (caar r)) nil))))) +;;;###autoload (defun describe-personal-keybindings () "Display all the personal keybindings defined by `bind-key'." (interactive) @@ -329,7 +335,9 @@ function symbol (unquoted)." (setq last-binding binding))))) (provide 'bind-key) + ;; Local Variables: ;; indent-tabs-mode: nil ;; End: + ;;; bind-key.el ends here From 47586c714e2b2ab56fd925f0671317fa474f803b Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 21 Mar 2015 03:57:09 -0500 Subject: [PATCH 174/606] Fix file headers --- lisp/use-package/bind-key.el | 45 +++++++++++++++++---------------- lisp/use-package/use-package.el | 3 ++- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 5ae00396c27..e41c858b2ee 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -1,67 +1,68 @@ -;;; bind-key.el --- a simple way to manage personal keybindings +;;; bind-key.el --- A simple way to manage personal keybindings -;; copyright (c) 2012 john wiegley +;; Copyright (c) 2012-2015 john wiegley -;; author: john wiegley -;; created: 16 jun 2012 -;; version: 1.0 -;; keywords: keys keybinding config dotemacs -;; url: https://github.com/jwiegley/use-package +;; Author: John Wiegley +;; Maintainer: John Wiegley +;; Created: 16 Jun 2012 +;; Version: 1.0 +;; Keywords: keys keybinding config dotemacs +;; URL: https://github.com/jwiegley/use-package -;; this program is free software; you can redistribute it and/or +;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the gnu general public license as ;; published by the free software foundation; either version 2, or (at ;; your option) any later version. -;; this program is distributed in the hope that it will be useful, but +;; 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 +;; 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: +;;; Commentary: -;; if you have lots of keybindings set in your .emacs file, it can be hard to +;; If you have lots of keybindings set in your .emacs file, it can be hard to ;; know which ones you haven't set yet, and which may now be overriding some -;; new default in a new emacs version. this module aims to solve that +;; new default in a new emacs version. This module aims to solve that ;; problem. ;; -;; bind keys as follows in your .emacs: +;; Bind keys as follows in your .emacs: ;; ;; (require 'bind-key) ;; ;; (bind-key "c-c x" 'my-ctrl-c-x-command) ;; -;; if you want the keybinding to override all minor modes that may also bind +;; If you want the keybinding to override all minor modes that may also bind ;; the same key, use the `bind-key*' form: ;; ;; (bind-key* "" 'other-window) ;; -;; if you want to rebind a key only in a particular keymap, use: +;; If you want to rebind a key only in a particular keymap, use: ;; ;; (bind-key "c-c x" 'my-ctrl-c-x-command some-other-mode-map) ;; -;; to unbind a key within a keymap (for example, to stop your favorite major +;; 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, see its documentation for -;; detailed description. +;; To bind multiple keys at once, or set up a prefix map, a `bind-keys' macro +;; is provided. It accepts keyword arguments, please see its documentation +;; for a detailed description. ;; -;; to add keys into a specific map, use :map argument +;; 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 +;; To set up a prefix map, use `:prefix-map' and `:prefix' arguments (both are ;; required) ;; ;; (bind-keys :prefix-map my-customize-prefix-map diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 4c8aad9f57a..c4959ce48da 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -3,11 +3,12 @@ ;; Copyright (C) 2012 John Wiegley ;; Author: John Wiegley +;; Maintainer: John Wiegley ;; Created: 17 Jun 2012 ;; Version: 2.0 ;; Package-Requires: ((bind-key "1.0") (diminish "0.44")) ;; Keywords: dotemacs startup speed config package -;; X-URL: https://github.com/jwiegley/use-package +;; URL: https://github.com/jwiegley/use-package ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as From 348bc571418d4659598965d5eea77da7d0a5acc9 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 21 Mar 2015 04:13:02 -0500 Subject: [PATCH 175/606] unbind-key now removes key from personal-keybindings Fixes https://github.com/jwiegley/use-package/issues/74 --- lisp/use-package/bind-key.el | 37 ++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index e41c858b2ee..5cace724196 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -91,6 +91,7 @@ ;; what the default was. Also, it will tell you if the key was rebound after ;; your binding it with `bind-key', and what it was rebound it to. +(require 'cl-lib) (require 'easy-mmode) (defgroup bind-key nil @@ -144,8 +145,7 @@ spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of (let ((namevar (make-symbol "name")) (keyvar (make-symbol "key")) (kdescvar (make-symbol "kdesc")) - (bindingvar (make-symbol "binding")) - (entryvar (make-symbol "entry"))) + (bindingvar (make-symbol "binding"))) `(let* ((,namevar ,key-name) (,keyvar (if (vectorp ,namevar) ,namevar (read-kbd-macro ,namevar))) @@ -153,19 +153,25 @@ spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of (key-description ,namevar)) (quote ,keymap))) (,bindingvar (lookup-key (or ,keymap global-map) - ,keyvar)) - (,entryvar (assoc ,kdescvar personal-keybindings))) - (when ,entryvar - (setq personal-keybindings - (delq ,entryvar personal-keybindings))) - (push (list ,kdescvar ,command - (unless (numberp ,bindingvar) ,bindingvar)) - personal-keybindings) + ,keyvar))) + (add-to-list 'personal-keybindings + (list ,kdescvar ,command + (unless (numberp ,bindingvar) ,bindingvar))) (define-key (or ,keymap global-map) ,keyvar ,command)))) ;;;###autoload (defmacro unbind-key (key-name &optional keymap) - `(bind-key ,key-name nil ,keymap)) + `(progn + (bind-key ,key-name nil ,keymap) + (setq personal-keybindings + (cl-delete-if #'(lambda (k) + ,(if keymap + `(and (consp (car k)) + (string= (caar k) ,key-name) + (eq (cdar k) ',keymap)) + `(and (stringp (car k)) + (string= (car k) ,key-name)))) + personal-keybindings)))) ;;;###autoload (defmacro bind-key* (key-name command) @@ -288,7 +294,8 @@ function symbol (unquoted)." "Display all the personal keybindings defined by `bind-key'." (interactive) (with-output-to-temp-buffer "*Personal Keybindings*" - (princ (format "Key name%s Command%s Comments\n%s %s ---------------------\n" + (princ (format (concat "Key name%s Command%s Comments\n%s %s " + "---------------------\n") (make-string (- (car bind-key-column-widths) 9) ? ) (make-string (- (cdr bind-key-column-widths) 8) ? ) (make-string (1- (car bind-key-column-widths)) ?-) @@ -303,7 +310,8 @@ function symbol (unquoted)." (if (not (eq (cdar last-binding) (cdar binding))) (princ (format "\n\n%s\n%s\n\n" (cdar binding) - (make-string (+ 21 (car bind-key-column-widths) (cdr bind-key-column-widths)) ?-))) + (make-string (+ 21 (car bind-key-column-widths) + (cdr bind-key-column-widths)) ?-))) (if (and last-binding (cdr (compare-keybindings last-binding binding))) (princ "\n"))) @@ -321,7 +329,8 @@ function symbol (unquoted)." ) (let ((line (format - (format "%%-%ds%%-%ds%%s\n" (car bind-key-column-widths) (cdr bind-key-column-widths)) + (format "%%-%ds%%-%ds%%s\n" (car bind-key-column-widths) + (cdr bind-key-column-widths)) key-name (format "`%s\'" command-desc) (if (string= command-desc at-present-desc) (if (or (null was-command) From 80aad34a39f72d5cf0e5a1bc4bc50f0c3c340eb9 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 21 Mar 2015 04:19:33 -0500 Subject: [PATCH 176/606] Add new customization use-package-always-ensure Fixes https://github.com/jwiegley/use-package/issues/27 --- lisp/use-package/use-package.el | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index c4959ce48da..78f1281dbb3 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -65,6 +65,11 @@ then the expanded macros do their job silently." :type 'boolean :group 'use-package) +(defcustom use-package-always-ensure nil + "Treat every package as though it had specified `:ensure SEXP`." + :type 'sexp + :group 'use-package) + (defcustom use-package-minimum-reported-time 0.1 "Minimal load time that will be reported. @@ -973,10 +978,14 @@ this file. Usage: (declare (indent 1)) (unless (member :disabled args) (let* ((name-symbol (if (stringp name) (intern name) name)) + (args0 (use-package-plist-maybe-put + (use-package-normalize-plist name-symbol args) + :config '(t))) (args* (use-package-sort-keywords - (use-package-plist-maybe-put - (use-package-normalize-plist name-symbol args) - :config '(t))))) + (if use-package-always-ensure + (use-package-plist-maybe-put + args0 :ensure use-package-always-ensure) + args0)))) ;; When byte-compiling, pre-load the package so all its symbols are in ;; scope. From 800669d9dac14c370b3f7d5b2966799d677f3dc8 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 21 Mar 2015 23:35:58 -0500 Subject: [PATCH 177/606] Add :delight support, thanks to darkfeline on GitHub Fixes https://github.com/jwiegley/use-package/issues/189 --- lisp/use-package/use-package.el | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 78f1281dbb3..7396677ac0a 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -128,7 +128,8 @@ the user specified." :demand :init :config - :diminish) + :diminish + :delight) "Establish which keywords are valid, and the order they are processed in. Note that `:disabled' is special, in that it causes nothing at all to happen, @@ -924,6 +925,36 @@ deferred until the prefix key sequence is pressed." arg) body))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :delight +;; + +(defun use-package-normalize/:delight (name-symbol keyword args) + "Normalize arguments to delight." + (cond + ((and (= (length args) 1) + (symbolp (cdr args))) + (list (car args) nil name-symbol)) + ((and (= (length args) 2) + (symbolp (cdr args))) + (list (car args) (cadr args) name-symbol)) + ((and (= (length args) 3) + (symbolp (cdr args))) + args) + (t + (use-package-error ":delight expects same args as delight function")))) + +(defun use-package-handler/:delight (name-symbol keyword args rest state) + (let ((body (use-package-process-keywords name-symbol rest state))) + (use-package-concat + body + `((delight + (quote ,(nth 0 args)) + ,(nth 1 args) + (quote ,(nth 2 args))) + t)))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; The main macro From c3a4b03b5f198be2743a8bf80c405dc2e8014fb5 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 23 Mar 2015 00:38:51 -0500 Subject: [PATCH 178/606] Fix a bug in the :delight support --- lisp/use-package/use-package.el | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 7396677ac0a..093188e141f 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -934,13 +934,13 @@ deferred until the prefix key sequence is pressed." "Normalize arguments to delight." (cond ((and (= (length args) 1) - (symbolp (cdr args))) + (symbolp (car args))) (list (car args) nil name-symbol)) ((and (= (length args) 2) - (symbolp (cdr args))) + (symbolp (car args))) (list (car args) (cadr args) name-symbol)) ((and (= (length args) 3) - (symbolp (cdr args))) + (symbolp (car args))) args) (t (use-package-error ":delight expects same args as delight function")))) @@ -949,11 +949,7 @@ deferred until the prefix key sequence is pressed." (let ((body (use-package-process-keywords name-symbol rest state))) (use-package-concat body - `((delight - (quote ,(nth 0 args)) - ,(nth 1 args) - (quote ,(nth 2 args))) - t)))) + `((delight (quote ,(nth 0 args)) ,(nth 1 args) (quote ,(nth 2 args))) t)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; From d1e91745b37aea1559667a4453abd8b083c1b9cf Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 24 Mar 2015 21:59:10 -0500 Subject: [PATCH 179/606] Minor fix to :diminish --- lisp/use-package/use-package.el | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 093188e141f..82b782bfe09 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -919,9 +919,10 @@ deferred until the prefix key sequence is pressed." (let ((body (use-package-process-keywords name-symbol rest state))) (use-package-concat (mapcar #'(lambda (var) - (if (consp var) - `(diminish ',(car var) ,(cdr var)) - `(diminish ',var))) + `(if (fboundp 'diminish) + ,(if (consp var) + `(diminish ',(car var) ,(cdr var)) + `(diminish ',var)))) arg) body))) @@ -1024,11 +1025,11 @@ this file. Usage: ,@(mapcar #'(lambda (var) `(defvar ,var)) (plist-get args* :defines)) (with-demoted-errors - ,(format "Error loading %s: %%S" name-symbol) + ,(format "Cannot load %s: %%S" name-symbol) ,(if use-package-verbose `(message "Compiling package %s" ',name-symbol)) ,(unless (plist-get args* :no-require) - `(require ',name-symbol nil t))))))) + `(require ',name-symbol))))))) (let ((body (macroexp-progn From c850481d069c0b799edb3039ec1950dc7c06125f Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 24 Mar 2015 22:30:48 -0500 Subject: [PATCH 180/606] Failed to require a package is just a message --- lisp/use-package/use-package.el | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 82b782bfe09..0d6325c4f0f 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -671,7 +671,7 @@ 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)) - (error "Could not load package %s" package) + (use-package-error (format "Could not load package.el: %s" package)) (if (and (boundp keymap-symbol) (keymapp (symbol-value keymap-symbol))) (let ((key (key-description (this-command-keys-vector))) @@ -682,8 +682,9 @@ deferred until the prefix key sequence is pressed." (bind-key key keymap)) (setq unread-command-events (listify-key-sequence (this-command-keys-vector)))) - (error "use-package: package %s failed to define keymap %s" - package keymap-symbol)))) + (use-package-error + (format "use-package: package.el %s failed to define keymap %s" + package keymap-symbol))))) (defun use-package-handler/:bind-keymap (name-symbol keyword arg rest state &optional override) @@ -882,10 +883,7 @@ deferred until the prefix key sequence is pressed." config-body) `((if (not (require ',name-symbol nil t)) (ignore - (display-warning - 'use-package - (format "Could not load %s" ',name-symbol) - :error)) + (message (format "Could not load %s" ',name-symbol))) ,@config-body))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; From f1a00054b13f77f9d8f7c58de7978ff3b6d4b683 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 25 Mar 2015 18:14:49 -0500 Subject: [PATCH 181/606] Keymap bindings must be interactive --- lisp/use-package/use-package.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 0d6325c4f0f..6feb0d84a5c 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -697,6 +697,7 @@ deferred until the prefix key sequence is pressed." 'bind-key) ,(car binding) #'(lambda () + (interactive) (use-package-autoload-keymap ',(cdr binding) ',name-symbol nil)))) arg))) (use-package-concat From a53b5062c4c275bde5b86b5065bbc34a72a09ef7 Mon Sep 17 00:00:00 2001 From: Russell Black Date: Sat, 11 Apr 2015 18:08:58 -0600 Subject: [PATCH 182/606] bind-keymap fixes Override argument no longer ignored. Not adding keymap to list of commands. `eval' no longer appears to be necessary, using direct invocation of bind-key*. --- lisp/use-package/use-package.el | 34 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 6feb0d84a5c..400616d3b5e 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -674,37 +674,35 @@ deferred until the prefix key sequence is pressed." (use-package-error (format "Could not load package.el: %s" package)) (if (and (boundp keymap-symbol) (keymapp (symbol-value keymap-symbol))) - (let ((key (key-description (this-command-keys-vector))) - (keymap (symbol-value keymap-symbol))) + (let* ((kv (this-command-keys-vector)) + (key (key-description kv)) + (keymap (symbol-value keymap-symbol))) (if override - ;; eval form is necessary to avoid compiler error - `(eval `(bind-key* ,key ,keymap)) + (bind-key* key keymap) (bind-key key keymap)) (setq unread-command-events - (listify-key-sequence (this-command-keys-vector)))) + (listify-key-sequence kv))) (use-package-error (format "use-package: package.el %s failed to define keymap %s" package keymap-symbol))))) (defun use-package-handler/:bind-keymap (name-symbol keyword arg rest state &optional override) - (let* (commands - (form (mapcar - #'(lambda (binding) - (push (cdr binding) commands) - `(,(if override - 'bind-key* - 'bind-key) - ,(car binding) - #'(lambda () - (interactive) - (use-package-autoload-keymap - ',(cdr binding) ',name-symbol nil)))) arg))) + (let ((form (mapcar + #'(lambda (binding) + `(,(if override + 'bind-key* + 'bind-key) + ,(car binding) + #'(lambda () + (interactive) + (use-package-autoload-keymap + ',(cdr binding) ',name-symbol ,override)))) arg))) (use-package-concat (use-package-process-keywords name-symbol (use-package-sort-keywords (use-package-plist-maybe-put rest :defer t)) - (use-package-plist-append state :commands commands)) + state) `((ignore ,@form))))) (defun use-package-handler/:bind-keymap* (name-symbol keyword arg rest state) From 6f0586ef52be9f9fa4491211101a84e35260d8ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Fr=C3=B6ssman?= Date: Fri, 8 May 2015 12:19:35 +0200 Subject: [PATCH 183/606] Refresh package.el archives if package is missing --- lisp/use-package/use-package.el | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 6feb0d84a5c..0eaa1ac3371 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -434,9 +434,14 @@ manually updated package." (concat ":ensure wants an optional package name " "(an unquoted symbol name)"))))))) -(defun use-package-ensure-elpa (package) - (when (not (package-installed-p package)) - (package-install package))) +(defun use-package-ensure-elpa (package &optional no-refresh) + (if (package-installed-p package) + t + (if (or (assoc package package-archive-contents) no-refresh) + (package-install package) + (progn + (package-refresh-contents) + (use-package-ensure-elpa package t))))) (defun use-package-handler/:ensure (name-symbol keyword ensure rest state) (let ((body (use-package-process-keywords name-symbol rest state))) From 90e3f4811144c0dcef05162892e8117e9577bb12 Mon Sep 17 00:00:00 2001 From: Sylvain Benner Date: Tue, 19 May 2015 21:07:30 -0400 Subject: [PATCH 184/606] Fix calls to run-hooks for :init and :config injected hooks --- lisp/use-package/use-package.el | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 6feb0d84a5c..444a48ca511 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -181,16 +181,16 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." (when body `((when ,(macroexp-progn (use-package-expand name-string (format "pre-%s hook" keyword) - `(run-hook-with-args-until-failure - ',(intern (concat "use-package--" name-string - "--pre-" keyword-name "-hook"))))) + `((run-hook-with-args-until-failure + ',(intern (concat "use-package--" name-string + "--pre-" keyword-name "-hook")))))) ,(macroexp-progn (use-package-expand name-string (format "%s" keyword) body)) ,(macroexp-progn (use-package-expand name-string (format "post-%s hook" keyword) - `(run-hooks - ',(intern (concat "use-package--" name-string - "--post-" keyword-name "-hook"))))))))))) + `((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." From d81390f6de016d939f2a95a31ce9c5a1e55bebcf Mon Sep 17 00:00:00 2001 From: Alex Kost Date: Mon, 22 Jun 2015 19:43:55 +0300 Subject: [PATCH 185/606] Handle the case when keymap has a broken documentation --- lisp/use-package/bind-key.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 5cace724196..ad0bf5c2df5 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -256,7 +256,8 @@ function symbol (unquoted)." elem))) ;; must be a symbol, non-symbol keymap case covered above ((and bind-key-describe-special-forms (keymapp elem)) - (get elem 'variable-documentation)) + (let ((doc (get elem 'variable-documentation))) + (if (stringp doc) doc elem))) ((symbolp elem) elem) (t From 1cbcd66ebe98f7fab83aa3b4239bcb073029e74e Mon Sep 17 00:00:00 2001 From: Nick Alcock Date: Thu, 30 Jul 2015 23:42:59 +0100 Subject: [PATCH 186/606] Support :bind (:map '(...)) We transform it into (:map foo (...) (...)) in the normalizer, and no longer warn about unknown sorts of arg. --- lisp/use-package/use-package.el | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 78abd9f776f..36360632813 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -629,11 +629,13 @@ manually updated package." ((use-package-is-sympair arg allow-vector) (list arg)) ((and (not recursed) (listp arg) (listp (cdr arg))) - (mapcar #'(lambda (x) (car (use-package-normalize-pairs - name-symbol label x t allow-vector))) arg)) - (t - (use-package-error - (concat label " wants a string, (string . symbol) or list of these"))))) + (mapcar #'(lambda (x) + (let ((ret (use-package-normalize-pairs + name-symbol label x t allow-vector))) + (if (listp ret) + (car ret) + ret))) arg)) + (t arg))) (defun use-package-normalize-binder (name-symbol keyword args) (use-package-as-one (symbol-name keyword) args @@ -645,7 +647,10 @@ manually updated package." (defun use-package-handler/:bind (name-symbol keyword arg rest state &optional override) - (let ((commands (mapcar #'cdr arg))) + (let ((commands (remq nil (mapcar #'(lambda (arg) + (if (listp arg) + (cdr arg) + nil)) arg)))) (use-package-concat (use-package-process-keywords name-symbol (use-package-sort-keywords From 3cdc6c39bfbfd1625b8bbc59f423cd48b0f22376 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Wed, 17 Jun 2015 13:33:09 -0400 Subject: [PATCH 187/606] Re-add support for string package names e.g. (use-package "isearch") rather than (use-package isearch) --- lisp/use-package/use-package.el | 202 +++++++++++++++++--------------- 1 file changed, 110 insertions(+), 92 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 36360632813..87bda97cd32 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -153,6 +153,23 @@ then your byte-compiled init file is as minimal as possible." ;; Utility functions ;; +(defun use-package-as-symbol (string-or-symbol) + "If STRING-OR-SYMBOL is already a symbol, return it. Otherwise +convert it to a symbol and return that." + (if (symbolp string-or-symbol) string-or-symbol + (intern string-or-symbol))) + +(defun use-package-as-string (string-or-symbol) + "If STRING-OR-SYMBOL is already a string, return it. Otherwise +convert it to a string and return that." + (if (stringp string-or-symbol) string-or-symbol + (symbol-name string-or-symbol))) + +(defun use-package-load-name (name &optional noerror) + "Return a form which will load or require NAME depending on +whether it's a string or symbol." + (if (stringp name) `(load ,name 'noerror) `(require ',name nil 'noerror))) + (defun use-package-expand (name label form) "FORM is a list of forms, so `((foo))' if only `foo' is being called." (declare (indent 1)) @@ -296,7 +313,7 @@ This is in contrast to merely setting it to 0." ;; Normalization functions ;; -(defun use-package-normalize-plist (name-symbol input) +(defun use-package-normalize-plist (name input) "Given a pseudo-plist, normalize it to a regular plist." (unless (null input) (let* ((keyword (car input)) @@ -308,19 +325,19 @@ This is in contrast to merely setting it to 0." (arg (cond ((eq keyword :disabled) - (use-package-normalize-plist name-symbol tail)) + (use-package-normalize-plist name tail)) ((functionp normalizer) - (funcall normalizer name-symbol keyword args)) + (funcall normalizer name keyword args)) ((= (length args) 1) (car args)) (t args)))) (if (memq keyword use-package-keywords) (cons keyword - (cons arg (use-package-normalize-plist name-symbol tail))) + (cons arg (use-package-normalize-plist name tail))) (use-package-error (format "Unrecognized keyword: %s" keyword)))))) -(defun use-package-process-keywords (name-symbol plist &optional state) +(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). @@ -342,7 +359,7 @@ next value for the STATE." (let* ((handler (concat "use-package-handler/" (symbol-name keyword))) (handler-sym (intern handler))) (if (functionp handler-sym) - (funcall handler-sym name-symbol keyword arg rest state) + (funcall handler-sym name keyword arg rest state) (use-package-error (format "Keyword handler not defined: %s" handler))))))) @@ -366,7 +383,7 @@ next value for the STATE." (put 'use-package-only-one 'lisp-indent-function 'defun) -(defun use-package-normalize/:pin (name-symbol keyword args) +(defun use-package-normalize/:pin (name keyword args) (use-package-only-one (symbol-name keyword) args (lambda (label arg) (cond @@ -405,16 +422,16 @@ manually updated package." archive-name package)) (package-initialize t))) -(defun use-package-handler/:pin (name-symbol keyword archive-name rest state) - (let ((body (use-package-process-keywords name-symbol rest state))) +(defun use-package-handler/:pin (name keyword archive-name rest state) + (let ((body (use-package-process-keywords name 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-pin-package name archive-name) (use-package-concat body - `((push '(,name-symbol . ,archive-name) + `((push '(,(use-package-as-symbol name) . ,archive-name) package-pinned-packages) t))))) @@ -423,7 +440,7 @@ manually updated package." ;; :ensure ;; -(defun use-package-normalize/:ensure (name-symbol keyword args) +(defun use-package-normalize/:ensure (name keyword args) (if (null args) t (use-package-only-one (symbol-name keyword) args @@ -443,11 +460,11 @@ manually updated package." (package-refresh-contents) (use-package-ensure-elpa package t))))) -(defun use-package-handler/:ensure (name-symbol keyword ensure rest state) - (let ((body (use-package-process-keywords name-symbol rest state))) +(defun use-package-handler/:ensure (name keyword ensure rest state) + (let ((body (use-package-process-keywords name rest state))) ;; This happens at macro expansion time, not when the expanded code is ;; compiled or evaluated. - (let ((package-name (or (and (eq ensure t) name-symbol) ensure))) + (let ((package-name (or (and (eq ensure t) (use-package-as-symbol name)) ensure))) (when package-name (require 'package) (use-package-ensure-elpa package-name))) @@ -466,25 +483,25 @@ manually updated package." `(funcall #',arg)) (t arg))) -(defun use-package-normalize-test (name-symbol keyword args) +(defun use-package-normalize-test (name keyword args) (use-package-only-one (symbol-name keyword) args #'use-package-normalize-value)) (defalias 'use-package-normalize/:if 'use-package-normalize-test) (defalias 'use-package-normalize/:when 'use-package-normalize-test) -(defun use-package-normalize/:unless (name-symbol keyword args) +(defun use-package-normalize/:unless (name keyword args) (not (use-package-only-one (symbol-name keyword) args #'use-package-normalize-value))) -(defun use-package-handler/:if (name-symbol keyword pred rest state) - (let ((body (use-package-process-keywords name-symbol rest state))) +(defun use-package-handler/:if (name keyword pred rest state) + (let ((body (use-package-process-keywords name rest state))) `((when ,pred ,@body)))) (defalias 'use-package-handler/:when 'use-package-handler/:if) -(defun use-package-handler/:unless (name-symbol keyword pred rest state) - (let ((body (use-package-process-keywords name-symbol rest state))) +(defun use-package-handler/:unless (name keyword pred rest state) + (let ((body (use-package-process-keywords name rest state))) `((unless ,pred ,@body)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -515,14 +532,14 @@ manually updated package." (use-package-error (concat label " wants a symbol, or list of symbols"))))) -(defun use-package-normalize-symlist (name-symbol keyword args) +(defun use-package-normalize-symlist (name keyword args) (use-package-as-one (symbol-name keyword) args #'use-package-normalize-symbols)) (defalias 'use-package-normalize/:requires 'use-package-normalize-symlist) -(defun use-package-handler/:requires (name-symbol keyword requires rest state) - (let ((body (use-package-process-keywords name-symbol rest state))) +(defun use-package-handler/:requires (name keyword requires rest state) + (let ((body (use-package-process-keywords name rest state))) (if (null requires) body `((when ,(if (listp requires) @@ -553,12 +570,12 @@ manually updated package." (use-package-error (concat label " wants a directory path, or list of paths"))))) -(defun use-package-normalize/:load-path (name-symbol keyword args) +(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-symbol keyword arg rest state) - (let ((body (use-package-process-keywords name-symbol rest state))) +(defun use-package-handler/:load-path (name keyword arg rest state) + (let ((body (use-package-process-keywords name rest state))) (use-package-concat (mapcar #'(lambda (path) `(eval-and-compile (push ,path load-path))) arg) @@ -569,7 +586,7 @@ manually updated package." ;; :no-require ;; -(defun use-package-normalize-predicate (name-symbol keyword args) +(defun use-package-normalize-predicate (name keyword args) (if (null args) t (use-package-only-one (symbol-name keyword) args @@ -577,9 +594,9 @@ manually updated package." (defalias 'use-package-normalize/:no-require 'use-package-normalize-predicate) -(defun use-package-handler/:no-require (name-symbol keyword arg rest state) +(defun use-package-handler/:no-require (name keyword arg rest state) ;; This keyword has no functional meaning. - (use-package-process-keywords name-symbol rest state)) + (use-package-process-keywords name rest state)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -596,13 +613,13 @@ manually updated package." (macroexpand form) form)) args)) -(defun use-package-normalize-forms (name-symbol keyword args) +(defun use-package-normalize-forms (name keyword args) (use-package-normalize-form (symbol-name keyword) args)) (defalias 'use-package-normalize/:preface 'use-package-normalize-forms) -(defun use-package-handler/:preface (name-symbol keyword arg rest state) - (let ((body (use-package-process-keywords name-symbol rest state))) +(defun use-package-handler/:preface (name keyword arg rest state) + (let ((body (use-package-process-keywords name rest state))) (use-package-concat (unless (null arg) `((eval-and-compile ,@arg))) @@ -621,45 +638,45 @@ manually updated package." (symbolp (cdr x)))) (defun use-package-normalize-pairs - (name-symbol label arg &optional recursed allow-vector) + (name label arg &optional recursed allow-vector) "Normalize a list of string/symbol pairs." (cond ((or (stringp arg) (and allow-vector (vectorp arg))) - (list (cons arg name-symbol))) + (list (cons arg (use-package-as-symbol name)))) ((use-package-is-sympair arg allow-vector) (list arg)) ((and (not recursed) (listp arg) (listp (cdr arg))) (mapcar #'(lambda (x) (let ((ret (use-package-normalize-pairs - name-symbol label x t allow-vector))) + name label x t allow-vector))) (if (listp ret) (car ret) ret))) arg)) (t arg))) -(defun use-package-normalize-binder (name-symbol keyword args) +(defun use-package-normalize-binder (name keyword args) (use-package-as-one (symbol-name keyword) args (lambda (label arg) - (use-package-normalize-pairs name-symbol label arg nil t)))) + (use-package-normalize-pairs name label arg nil t)))) (defalias 'use-package-normalize/:bind 'use-package-normalize-binder) (defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) (defun use-package-handler/:bind - (name-symbol keyword arg rest state &optional override) + (name keyword arg rest state &optional override) (let ((commands (remq nil (mapcar #'(lambda (arg) (if (listp arg) (cdr arg) nil)) arg)))) (use-package-concat - (use-package-process-keywords name-symbol + (use-package-process-keywords name (use-package-sort-keywords (use-package-plist-maybe-put rest :defer t)) (use-package-plist-append state :commands commands)) `((ignore (,(if override 'bind-keys* 'bind-keys) ,@arg)))))) -(defun use-package-handler/:bind* (name-symbol keyword arg rest state) - (use-package-handler/:bind name-symbol keyword arg rest state t)) +(defun use-package-handler/:bind* (name keyword arg rest state) + (use-package-handler/:bind name keyword arg rest state t)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -697,7 +714,7 @@ deferred until the prefix key sequence is pressed." package keymap-symbol))))) (defun use-package-handler/:bind-keymap - (name-symbol keyword arg rest state &optional override) + (name keyword arg rest state &optional override) (let ((form (mapcar #'(lambda (binding) `(,(if override @@ -707,35 +724,35 @@ deferred until the prefix key sequence is pressed." #'(lambda () (interactive) (use-package-autoload-keymap - ',(cdr binding) ',name-symbol ,override)))) arg))) + ',(cdr binding) ',(use-package-as-symbol name) ,override)))) arg))) (use-package-concat - (use-package-process-keywords name-symbol + (use-package-process-keywords name (use-package-sort-keywords (use-package-plist-maybe-put rest :defer t)) state) `((ignore ,@form))))) -(defun use-package-handler/:bind-keymap* (name-symbol keyword arg rest state) - (use-package-handler/:bind-keymap name-symbol keyword arg rest state t)) +(defun use-package-handler/:bind-keymap* (name keyword arg rest state) + (use-package-handler/:bind-keymap name keyword arg rest state t)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; :interpreter ;; -(defun use-package-normalize-mode (name-symbol keyword args) +(defun use-package-normalize-mode (name keyword args) (use-package-as-one (symbol-name keyword) args - (apply-partially #'use-package-normalize-pairs name-symbol))) + (apply-partially #'use-package-normalize-pairs name))) (defalias 'use-package-normalize/:interpreter 'use-package-normalize-mode) -(defun use-package-handler/:interpreter (name-symbol keyword arg rest state) +(defun use-package-handler/:interpreter (name keyword arg rest state) (let* (commands (form (mapcar #'(lambda (interpreter) (push (cdr interpreter) commands) `(push ',interpreter interpreter-mode-alist)) arg))) (use-package-concat - (use-package-process-keywords name-symbol + (use-package-process-keywords name (use-package-sort-keywords (use-package-plist-maybe-put rest :defer t)) (use-package-plist-append state :commands commands)) @@ -748,13 +765,13 @@ deferred until the prefix key sequence is pressed." (defalias 'use-package-normalize/:mode 'use-package-normalize-mode) -(defun use-package-handler/:mode (name-symbol keyword arg rest state) +(defun use-package-handler/:mode (name keyword arg rest state) (let* (commands (form (mapcar #'(lambda (mode) (push (cdr mode) commands) `(push ',mode auto-mode-alist)) arg))) (use-package-concat - (use-package-process-keywords name-symbol + (use-package-process-keywords name (use-package-sort-keywords (use-package-plist-maybe-put rest :defer t)) (use-package-plist-append state :commands commands)) @@ -767,9 +784,9 @@ deferred until the prefix key sequence is pressed." (defalias 'use-package-normalize/:commands 'use-package-normalize-symlist) -(defun use-package-handler/:commands (name-symbol keyword arg rest state) +(defun use-package-handler/:commands (name keyword arg rest state) ;; The actual processing for commands is done in :defer - (use-package-process-keywords name-symbol + (use-package-process-keywords name (use-package-sort-keywords (use-package-plist-maybe-put rest :defer t)) (use-package-plist-append state :commands arg))) @@ -781,8 +798,8 @@ deferred until the prefix key sequence is pressed." (defalias 'use-package-normalize/:defines 'use-package-normalize-symlist) -(defun use-package-handler/:defines (name-symbol keyword arg rest state) - (let ((body (use-package-process-keywords name-symbol rest state))) +(defun use-package-handler/:defines (name keyword arg rest state) + (let ((body (use-package-process-keywords name rest state))) body)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -792,8 +809,8 @@ deferred until the prefix key sequence is pressed." (defalias 'use-package-normalize/:functions 'use-package-normalize-symlist) -(defun use-package-handler/:functions (name-symbol keyword arg rest state) - (let ((body (use-package-process-keywords name-symbol rest state))) +(defun use-package-handler/:functions (name keyword arg rest state) + (let ((body (use-package-process-keywords name rest state))) (if (not (bound-and-true-p byte-compile-current-file)) body (use-package-concat @@ -801,7 +818,7 @@ deferred until the prefix key sequence is pressed." `((eval-when-compile ,@(mapcar #'(lambda (fn) - `(declare-function ,fn ,(symbol-name name-symbol))) arg)))) + `(declare-function ,fn ,(use-package-as-string name))) arg)))) body)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -811,15 +828,15 @@ deferred until the prefix key sequence is pressed." (defalias 'use-package-normalize/:defer 'use-package-normalize-predicate) -(defun use-package-handler/:defer (name-symbol keyword arg rest state) - (let ((body (use-package-process-keywords name-symbol rest +(defun use-package-handler/:defer (name keyword arg rest state) + (let ((body (use-package-process-keywords name rest (plist-put state :deferred t))) - (name-string (symbol-name name-symbol))) + (name-string (use-package-as-string name))) (use-package-concat ;; Load the package after a set amount of idle time, if the argument to ;; `:defer' was a number. (when (numberp arg) - `((run-with-idle-timer ,arg nil #'require ',name-symbol nil t))) + `((run-with-idle-timer ,arg nil #'require ',(use-package-as-symbol name) nil t))) ;; Since we deferring load, establish any necessary autoloads, and also ;; keep the byte-compiler happy. @@ -843,8 +860,8 @@ deferred until the prefix key sequence is pressed." (defalias 'use-package-normalize/:demand 'use-package-normalize-predicate) -(defun use-package-handler/:demand (name-symbol keyword arg rest state) - (use-package-process-keywords name-symbol rest +(defun use-package-handler/:demand (name keyword arg rest state) + (use-package-process-keywords name rest (use-package-plist-delete state :deferred))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -854,11 +871,11 @@ deferred until the prefix key sequence is pressed." (defalias 'use-package-normalize/:init 'use-package-normalize-forms) -(defun use-package-handler/:init (name-symbol keyword arg rest state) - (let ((body (use-package-process-keywords name-symbol rest state))) +(defun use-package-handler/:init (name keyword arg rest state) + (let ((body (use-package-process-keywords name rest state))) (use-package-concat ;; The user's initializations - (use-package-hook-injector (symbol-name name-symbol) :init arg) + (use-package-hook-injector (use-package-as-string name) :init arg) body))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -868,8 +885,9 @@ deferred until the prefix key sequence is pressed." (defalias 'use-package-normalize/:config 'use-package-normalize-forms) -(defun use-package-handler/:config (name-symbol keyword arg rest state) - (let* ((body (use-package-process-keywords name-symbol rest state)) +(defun use-package-handler/:config (name keyword arg rest state) + (let* ((body (use-package-process-keywords name rest state)) + (name-symbol (use-package-as-symbol name)) (config-body (if (equal arg '(t)) body @@ -882,24 +900,24 @@ deferred until the prefix key sequence is pressed." (list t)))))) (if (plist-get state :deferred) (unless (or (null config-body) (equal config-body '(t))) - `((eval-after-load ',name-symbol + `((eval-after-load ,(if (symbolp name) `',name name) ',(macroexp-progn config-body)))) (use-package--with-elapsed-timer - (format "Loading package %s" name-symbol) + (format "Loading package %s" name) (if use-package-expand-minimally (use-package-concat - (list `(require ',name-symbol)) + (list (use-package-load-name name)) config-body) - `((if (not (require ',name-symbol nil t)) + `((if (not ,(use-package-load-name name t)) (ignore - (message (format "Could not load %s" ',name-symbol))) + (message (format "Could not load %s" name))) ,@config-body))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; :diminish -(defun use-package-normalize-diminish (name-symbol label arg &optional recursed) +(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)" @@ -907,23 +925,23 @@ deferred until the prefix key sequence is pressed." ((symbolp arg) (list arg)) ((stringp arg) - (list (cons (intern (concat (symbol-name name-symbol) "-mode")) arg))) + (list (cons (intern (concat (use-package-as-string name) "-mode")) arg))) ((and (consp arg) (stringp (cdr arg))) (list arg)) ((and (not recursed) (listp arg) (listp (cdr arg))) (mapcar #'(lambda (x) (car (use-package-normalize-diminish - name-symbol label x t))) arg)) + name label x t))) arg)) (t (use-package-error (concat label " wants a string, symbol, " "(symbol . string) or list of these"))))) -(defun use-package-normalize/:diminish (name-symbol keyword args) +(defun use-package-normalize/:diminish (name keyword args) (use-package-as-one (symbol-name keyword) args - (apply-partially #'use-package-normalize-diminish name-symbol))) + (apply-partially #'use-package-normalize-diminish name))) -(defun use-package-handler/:diminish (name-symbol keyword arg rest state) - (let ((body (use-package-process-keywords name-symbol rest state))) +(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) @@ -938,23 +956,23 @@ deferred until the prefix key sequence is pressed." ;; :delight ;; -(defun use-package-normalize/:delight (name-symbol keyword args) +(defun use-package-normalize/:delight (name keyword args) "Normalize arguments to delight." (cond ((and (= (length args) 1) (symbolp (car args))) - (list (car args) nil name-symbol)) + (list (car args) nil name)) ((and (= (length args) 2) (symbolp (car args))) - (list (car args) (cadr args) name-symbol)) + (list (car args) (cadr args) (use-package-as-symbol name))) ((and (= (length args) 3) (symbolp (car args))) args) (t (use-package-error ":delight expects same args as delight function")))) -(defun use-package-handler/:delight (name-symbol keyword args rest state) - (let ((body (use-package-process-keywords name-symbol rest state))) +(defun use-package-handler/:delight (name keyword args rest state) + (let ((body (use-package-process-keywords name rest state))) (use-package-concat body `((delight (quote ,(nth 0 args)) ,(nth 1 args) (quote ,(nth 2 args))) t)))) @@ -1014,7 +1032,7 @@ this file. Usage: (unless (member :disabled args) (let* ((name-symbol (if (stringp name) (intern name) name)) (args0 (use-package-plist-maybe-put - (use-package-normalize-plist name-symbol args) + (use-package-normalize-plist name args) :config '(t))) (args* (use-package-sort-keywords (if use-package-always-ensure @@ -1032,15 +1050,15 @@ this file. Usage: ,@(mapcar #'(lambda (var) `(defvar ,var)) (plist-get args* :defines)) (with-demoted-errors - ,(format "Cannot load %s: %%S" name-symbol) + ,(format "Cannot load %s: %%S" name) ,(if use-package-verbose `(message "Compiling package %s" ',name-symbol)) ,(unless (plist-get args* :no-require) - `(require ',name-symbol))))))) + (use-package-load-name name))))))) (let ((body (macroexp-progn - (use-package-process-keywords name-symbol args*)))) + (use-package-process-keywords name args*)))) (if use-package-debug (display-buffer (save-current-buffer From d5145927462c8ff9da08879a73c1af11536dc121 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 17 Aug 2015 23:41:28 +0300 Subject: [PATCH 188/606] fix quotation error --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 87bda97cd32..97b6ab30351 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -910,7 +910,7 @@ deferred until the prefix key sequence is pressed." config-body) `((if (not ,(use-package-load-name name t)) (ignore - (message (format "Could not load %s" name))) + (message (format "Could not load %s" ',name))) ,@config-body))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; From 9c1156dbf8593b37bbbc8f8e6d987b1ce748bd6d Mon Sep 17 00:00:00 2001 From: Edward Knyshov Date: Sun, 30 Aug 2015 11:23:49 +0300 Subject: [PATCH 189/606] error handling for use-package GitHub-reference: https://github.com/jwiegley/use-package/issues/246 --- lisp/use-package/use-package.el | 59 +++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 97b6ab30351..2b52054fd59 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -165,10 +165,10 @@ convert it to a string and return that." (if (stringp string-or-symbol) string-or-symbol (symbol-name string-or-symbol))) -(defun use-package-load-name (name &optional noerror) +(defun use-package-load-name (name) "Return a form which will load or require NAME depending on whether it's a string or symbol." - (if (stringp name) `(load ,name 'noerror) `(require ',name nil 'noerror))) + (if (stringp name) `(use-package-load ,name) `(use-package-require ',name))) (defun use-package-expand (name label form) "FORM is a list of forms, so `((foo))' if only `foo' is being called." @@ -292,6 +292,24 @@ This is in contrast to merely setting it to 0." (setq result (cons (car x) (cons (cdr x) result)))) result))) +(defun use-package-require (package) + "Require a package and handle any error from it." + (condition-case e + (require package) + (error (progn (use-package-require-error-handler package e) + nil)))) + +(defun use-package-load (name) + "Load a file and handle any error from it." + (condition-case e + (load name) + (error (progn (use-package-require-error-handler name e) + nil)))) + +(defun use-package-require-error-handler (package error) + "Main use package error handler for package loading." + (use-package-error (format "Could not load package.el: %s error: %s" package error))) + (defsubst use-package-concat (&rest elems) "Delete all empty lists from ELEMS (nil or (list nil)), and append them." (apply #'nconc (delete nil (delete (list nil) elems)))) @@ -697,21 +715,20 @@ works by binding the given key sequence to an invocation of this function for a particular keymap. The keymap is expected to be defined by the package. In this way, loading the package is deferred until the prefix key sequence is pressed." - (if (not (require package nil t)) - (use-package-error (format "Could not load package.el: %s" package)) - (if (and (boundp keymap-symbol) - (keymapp (symbol-value keymap-symbol))) - (let* ((kv (this-command-keys-vector)) - (key (key-description kv)) - (keymap (symbol-value keymap-symbol))) - (if override - (bind-key* key keymap) - (bind-key key keymap)) - (setq unread-command-events - (listify-key-sequence kv))) - (use-package-error - (format "use-package: package.el %s failed to define keymap %s" - package keymap-symbol))))) + (if (use-package-require package) + (if (and (boundp keymap-symbol) + (keymapp (symbol-value keymap-symbol))) + (let* ((kv (this-command-keys-vector)) + (key (key-description kv)) + (keymap (symbol-value keymap-symbol))) + (if override + (bind-key* key keymap) + (bind-key key keymap)) + (setq unread-command-events + (listify-key-sequence kv))) + (use-package-error + (format "use-package: package.el %s failed to define keymap %s" + package keymap-symbol))))) (defun use-package-handler/:bind-keymap (name keyword arg rest state &optional override) @@ -836,7 +853,7 @@ deferred until the prefix key sequence is pressed." ;; 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))) + `((run-with-idle-timer ,arg nil #'use-package-require ',(use-package-as-symbol name)))) ;; Since we deferring load, establish any necessary autoloads, and also ;; keep the byte-compiler happy. @@ -908,10 +925,8 @@ deferred until the prefix key sequence is pressed." (use-package-concat (list (use-package-load-name name)) config-body) - `((if (not ,(use-package-load-name name t)) - (ignore - (message (format "Could not load %s" ',name))) - ,@config-body))))))) + `((if (not (null ,(use-package-load-name name))) + ,@config-body))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; From 3e2747f17465e5c26196c54bfbd5ab68d547d060 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 6 Sep 2015 20:51:31 -0700 Subject: [PATCH 190/606] Revert "Merge pull request from edvorg/master" This reverts commit 38b213c6c382f87b7f6e60d0c97d37f2951c2482, reversing changes made to 7d34df4f5dd26b6d8b0899e6508c9af5dedf2dc4. GitHub-reference: https://github.com/jwiegley/use-package/issues/247 --- lisp/use-package/use-package.el | 59 ++++++++++++--------------------- 1 file changed, 22 insertions(+), 37 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 2b52054fd59..97b6ab30351 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -165,10 +165,10 @@ convert it to a string and return that." (if (stringp string-or-symbol) string-or-symbol (symbol-name string-or-symbol))) -(defun use-package-load-name (name) +(defun use-package-load-name (name &optional noerror) "Return a form which will load or require NAME depending on whether it's a string or symbol." - (if (stringp name) `(use-package-load ,name) `(use-package-require ',name))) + (if (stringp name) `(load ,name 'noerror) `(require ',name nil 'noerror))) (defun use-package-expand (name label form) "FORM is a list of forms, so `((foo))' if only `foo' is being called." @@ -292,24 +292,6 @@ This is in contrast to merely setting it to 0." (setq result (cons (car x) (cons (cdr x) result)))) result))) -(defun use-package-require (package) - "Require a package and handle any error from it." - (condition-case e - (require package) - (error (progn (use-package-require-error-handler package e) - nil)))) - -(defun use-package-load (name) - "Load a file and handle any error from it." - (condition-case e - (load name) - (error (progn (use-package-require-error-handler name e) - nil)))) - -(defun use-package-require-error-handler (package error) - "Main use package error handler for package loading." - (use-package-error (format "Could not load package.el: %s error: %s" package error))) - (defsubst use-package-concat (&rest elems) "Delete all empty lists from ELEMS (nil or (list nil)), and append them." (apply #'nconc (delete nil (delete (list nil) elems)))) @@ -715,20 +697,21 @@ 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 (use-package-require package) - (if (and (boundp keymap-symbol) - (keymapp (symbol-value keymap-symbol))) - (let* ((kv (this-command-keys-vector)) - (key (key-description kv)) - (keymap (symbol-value keymap-symbol))) - (if override - (bind-key* key keymap) - (bind-key key keymap)) - (setq unread-command-events - (listify-key-sequence kv))) - (use-package-error - (format "use-package: package.el %s failed to define keymap %s" - package keymap-symbol))))) + (if (not (require package nil t)) + (use-package-error (format "Could not load package.el: %s" package)) + (if (and (boundp keymap-symbol) + (keymapp (symbol-value keymap-symbol))) + (let* ((kv (this-command-keys-vector)) + (key (key-description kv)) + (keymap (symbol-value keymap-symbol))) + (if override + (bind-key* key keymap) + (bind-key key keymap)) + (setq unread-command-events + (listify-key-sequence kv))) + (use-package-error + (format "use-package: package.el %s failed to define keymap %s" + package keymap-symbol))))) (defun use-package-handler/:bind-keymap (name keyword arg rest state &optional override) @@ -853,7 +836,7 @@ deferred until the prefix key sequence is pressed." ;; 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 #'use-package-require ',(use-package-as-symbol name)))) + `((run-with-idle-timer ,arg nil #'require ',(use-package-as-symbol name) nil t))) ;; Since we deferring load, establish any necessary autoloads, and also ;; keep the byte-compiler happy. @@ -925,8 +908,10 @@ deferred until the prefix key sequence is pressed." (use-package-concat (list (use-package-load-name name)) config-body) - `((if (not (null ,(use-package-load-name name))) - ,@config-body))))))) + `((if (not ,(use-package-load-name name t)) + (ignore + (message (format "Could not load %s" ',name))) + ,@config-body))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; From 6298e7e4775154fb1a48035293b60bb326ff54ea Mon Sep 17 00:00:00 2001 From: Justin Talbott Date: Wed, 23 Sep 2015 11:06:58 -0400 Subject: [PATCH 191/606] pass in symbol of bind macro, for more extensible re-use of same handler related to https://github.com/jwiegley/use-package/issues/258 --- lisp/use-package/use-package.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 97b6ab30351..d3ed84a4038 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -663,7 +663,7 @@ manually updated package." (defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) (defun use-package-handler/:bind - (name keyword arg rest state &optional override) + (name keyword arg rest state &optional bind-macro) (let ((commands (remq nil (mapcar #'(lambda (arg) (if (listp arg) (cdr arg) @@ -673,10 +673,10 @@ manually updated package." (use-package-sort-keywords (use-package-plist-maybe-put rest :defer t)) (use-package-plist-append state :commands commands)) - `((ignore (,(if override 'bind-keys* 'bind-keys) ,@arg)))))) + `((ignore (,(if bind-macro bind-macro 'bind-keys) ,@arg)))))) (defun use-package-handler/:bind* (name keyword arg rest state) - (use-package-handler/:bind name keyword arg rest state t)) + (use-package-handler/:bind name keyword arg rest state 'bind-keys*)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; From ff8bdfcdca1901e3920d1c1d12d753f855260ebe Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 26 Sep 2015 08:46:37 -0700 Subject: [PATCH 192/606] Bump version to 2.1 --- lisp/use-package/use-package.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index d3ed84a4038..0fb6734ab48 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -5,7 +5,8 @@ ;; Author: John Wiegley ;; Maintainer: John Wiegley ;; Created: 17 Jun 2012 -;; Version: 2.0 +;; Modified: 26 Sep 2015 +;; Version: 2.1 ;; Package-Requires: ((bind-key "1.0") (diminish "0.44")) ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package From ac47f783da34350eee19fe855d57469aa743d037 Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Tue, 3 Nov 2015 14:43:51 +1300 Subject: [PATCH 193/606] Move :ensure option from macro expansion phase to runtime phase --- lisp/use-package/use-package.el | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 0fb6734ab48..18d7031f272 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -463,13 +463,11 @@ manually updated package." (defun use-package-handler/:ensure (name keyword ensure rest state) (let ((body (use-package-process-keywords name rest state))) - ;; This happens at macro expansion time, not when the expanded code is - ;; compiled or evaluated. - (let ((package-name (or (and (eq ensure t) (use-package-as-symbol name)) ensure))) - (when package-name - (require 'package) - (use-package-ensure-elpa package-name))) - body)) + `((let ((package-name (or (and (eq ,ensure t) (use-package-as-symbol ',name)) ,ensure))) + (when package-name + (require 'package) + (use-package-ensure-elpa package-name))) + ,@body))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; From 564f9bb74b872ea7df534733c25ccc413cd6cab0 Mon Sep 17 00:00:00 2001 From: Phillip Lord Date: Wed, 4 Nov 2015 22:45:37 +0000 Subject: [PATCH 194/606] Support for after keyword After provides `eval-after-load' functionality for any number of features. This helps to avoid deeply nested `use-package' statements. Closes https://github.com/jwiegley/use-package/issues/274 --- lisp/use-package/use-package.el | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 0fb6734ab48..c398ebbef1e 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -126,6 +126,7 @@ the user specified." :defines :functions :defer + :after :demand :init :config @@ -854,6 +855,33 @@ deferred until the prefix key sequence is pressed." body))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :after +;; + +(defalias 'use-package-normalize/:after 'use-package-normalize-symlist) + +(defun use-package-require-after-load (features name) + "Return form for after any of FEATURES require NAME." + `(progn + ,@(mapcar + (lambda (feat) + `(eval-after-load + (quote ,feat) + (quote (require (quote ,name))))) + features))) + +(defun use-package-handler/:after (name keyword arg rest state) + (let ((body (use-package-process-keywords name rest + (plist-put state :deferred t))) + (name-string (use-package-as-string name))) + (use-package-concat + (when arg + (list (use-package-require-after-load arg name))) + body))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; :demand @@ -1019,6 +1047,10 @@ this file. Usage: `:commands', `:bind', `:bind*', `:mode' or `:interpreter'. This can be an integer, to force loading after N seconds of idle time, if the package has not already been loaded. + +:after Defer loading of a package until after any of the named + features are loaded. + :demand Prevent deferred loading in all cases. :if EXPR Initialize and load only if EXPR evaluates to a non-nil value. From b1f442c15bc6f8ac54c81e8c9b80c263b99d4ccc Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 9 Nov 2015 17:33:05 -0800 Subject: [PATCH 195/606] Apply a fix from npostavs relating to GitHub-reference: https://github.com/jwiegley/use-package/issues/279 --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index afb306fc764..6027c9f3aee 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -464,7 +464,7 @@ manually updated package." (defun use-package-handler/:ensure (name keyword ensure rest state) (let ((body (use-package-process-keywords name rest state))) - `((let ((package-name (or (and (eq ,ensure t) (use-package-as-symbol ',name)) ,ensure))) + `((let ((package-name (or (and (eq ',ensure t) (use-package-as-symbol ',name)) ',ensure))) (when package-name (require 'package) (use-package-ensure-elpa package-name))) From d9f37b4f0c1abff2e3e9122403b6a578acbaba99 Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Fri, 13 Nov 2015 11:08:02 +1300 Subject: [PATCH 196/606] Install packages when byte-compiling (fix by @npostavs) --- lisp/use-package/use-package.el | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 6027c9f3aee..b88749d357b 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -463,12 +463,19 @@ manually updated package." (use-package-ensure-elpa package t))))) (defun use-package-handler/:ensure (name keyword ensure rest state) - (let ((body (use-package-process-keywords name rest state))) - `((let ((package-name (or (and (eq ',ensure t) (use-package-as-symbol ',name)) ',ensure))) - (when package-name - (require 'package) - (use-package-ensure-elpa package-name))) - ,@body))) + (let* ((body (use-package-process-keywords name rest state)) + (package-name (or (and (eq ensure t) (use-package-as-symbol name)) ensure)) + (ensure-form (if package-name + `(progn (require 'package) + (use-package-ensure-elpa ',package-name))))) + ;; We want to avoid installing packages when the `use-package' + ;; macro is being macro-expanded by elisp completion (see + ;; `lisp--local-variables'), but still do install packages when + ;; byte-compiling to avoid requiring `package' at runtime. + (if (bound-and-true-p byte-compile-current-file) + (eval ensure-form) ; Eval when byte-compiling, + (push ensure-form body)) ; or else wait until runtime. + body)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; From ed2e85e4a74e760ca4d4219f2b37628ca5fce9f7 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 20 Dec 2015 14:39:33 -0800 Subject: [PATCH 197/606] Use cl-mapcan rather than apply 'nconc; thanks wasamasa --- lisp/use-package/bind-key.el | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 5cace724196..5ea5ab37b56 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -220,17 +220,15 @@ function symbol (unquoted)." #'(lambda (m) `(bind-key ,prefix ',prefix-map ,m)) maps) `((bind-key ,prefix ',prefix-map))))) - (apply - #'nconc - (mapcar (lambda (form) - (if prefix-map - `((bind-key ,(car form) ',(cdr form) ,prefix-map)) - (if maps - (mapcar - #'(lambda (m) - `(bind-key ,(car form) ',(cdr form) ,m)) maps) - `((bind-key ,(car form) ',(cdr form)))))) - key-bindings)))))) + (cl-mapcan (lambda (form) + (if prefix-map + `((bind-key ,(car form) ',(cdr form) ,prefix-map)) + (if maps + (mapcar + #'(lambda (m) + `(bind-key ,(car form) ',(cdr form) ,m)) maps) + `((bind-key ,(car form) ',(cdr form)))))) + key-bindings))))) ;;;###autoload (defmacro bind-keys* (&rest args) From 308e4e3f2cac8868b79ee181433c776fc029434a Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Wed, 6 Jan 2016 11:15:22 +1300 Subject: [PATCH 198/606] Move :pin out of macro expansion phase --- lisp/use-package/use-package.el | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index b88749d357b..d5226e3a9d3 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -419,23 +419,23 @@ manually updated package." (let ((archive-symbol (if (symbolp archive) archive (intern archive))) (archive-name (if (stringp archive) archive (symbol-name archive)))) (if (use-package--archive-exists-p archive-symbol) - (push (cons package archive-name) package-pinned-packages) + (add-to-list 'package-pinned-packages (cons package archive-name) t) (error "Archive '%s' requested for package '%s' is not available." archive-name package)) (package-initialize t))) (defun use-package-handler/:pin (name keyword archive-name rest state) - (let ((body (use-package-process-keywords name 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 archive-name) - (use-package-concat - body - `((push '(,(use-package-as-symbol name) . ,archive-name) - package-pinned-packages) - t))))) + (let ((body (use-package-process-keywords name rest state)) + (pin-form (if archive-name + `(use-package-pin-package ',name ,archive-name)))) + ;; We want to avoid pinning packages when the `use-package' + ;; macro is being macro-expanded by elisp completion (see + ;; `lisp--local-variables'), but still do pin packages when + ;; byte-compiling to avoid requiring `package' at runtime. + (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)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; From d1c78a646cdf08cc0aa9c8664f69ce23e3e8cb83 Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Wed, 6 Jan 2016 12:56:54 +1300 Subject: [PATCH 199/606] Move :pin out of macro expansion phase fixes --- lisp/use-package/use-package.el | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index d5226e3a9d3..a225d99810f 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -419,7 +419,7 @@ manually updated package." (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) t) + (add-to-list 'package-pinned-packages (cons package archive-name)) (error "Archive '%s' requested for package '%s' is not available." archive-name package)) (package-initialize t))) @@ -427,11 +427,10 @@ manually updated package." (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 ',name ,archive-name)))) - ;; We want to avoid pinning packages when the `use-package' - ;; macro is being macro-expanded by elisp completion (see - ;; `lisp--local-variables'), but still do pin packages when - ;; byte-compiling to avoid requiring `package' at runtime. + `(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. From 95038f96f1e715022a5ca5ffbb12fc9a4fa8a252 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 6 Jan 2016 15:50:43 -0800 Subject: [PATCH 200/606] Guard against a case where :load-paths is nil --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index b88749d357b..fecd37bc121 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -562,7 +562,7 @@ manually updated package." (defun use-package-normalize-paths (label arg &optional recursed) "Normalize a list of filesystem paths." (cond - ((or (symbolp arg) (functionp arg)) + ((and arg (or (symbolp arg) (functionp arg))) (let ((value (use-package-normalize-value label arg))) (use-package-normalize-paths label (eval value)))) ((stringp arg) From cd867dfe2f21aa1397016d7c441a3d6c90f36672 Mon Sep 17 00:00:00 2001 From: Justin Talbott Date: Fri, 8 Jan 2016 14:35:17 -0500 Subject: [PATCH 201/606] allow string values in cons for :bind keywords MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is possible with `bind-key` and `define-key` (and also `bind-chord` and `key-chord-define`) to define a binding to a string's value, i.e: ``` elisp (bind-key "C-;" "the ") (bind-chord "^^" "λ") ``` This adds an option for `(use-package-normalize-pairs)` that allows string values to be given with the `:bind` (and also `:chord`) keywords to expand into these definitions. --- lisp/use-package/use-package.el | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index fecd37bc121..36a2540f7e0 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -644,8 +644,14 @@ manually updated package." (and allow-vector (vectorp (car x)))) (symbolp (cdr x)))) +(defsubst use-package-is-string-pair (x) + "Return t if X has the type (STRING . STRING)." + (and (consp x) + (stringp (car x)) + (stringp (cdr x)))) + (defun use-package-normalize-pairs - (name label arg &optional recursed allow-vector) + (name label arg &optional recursed allow-vector allow-string-cdrs) "Normalize a list of string/symbol pairs." (cond ((or (stringp arg) (and allow-vector (vectorp arg))) @@ -655,16 +661,18 @@ manually updated package." ((and (not recursed) (listp arg) (listp (cdr arg))) (mapcar #'(lambda (x) (let ((ret (use-package-normalize-pairs - name label x t allow-vector))) + name label x t allow-vector allow-string-cdrs))) (if (listp ret) (car ret) ret))) arg)) + ((and allow-string-cdrs (use-package-is-string-pair arg)) + (list arg)) (t arg))) (defun use-package-normalize-binder (name keyword args) (use-package-as-one (symbol-name keyword) args (lambda (label arg) - (use-package-normalize-pairs name label arg nil t)))) + (use-package-normalize-pairs name label arg nil t t)))) (defalias 'use-package-normalize/:bind 'use-package-normalize-binder) (defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) @@ -850,12 +858,13 @@ deferred until the prefix key sequence is pressed." (apply #'nconc (mapcar #'(lambda (command) - (append - `((unless (fboundp ',command) - (autoload #',command ,name-string nil t))) - (when (bound-and-true-p byte-compile-current-file) - `((eval-when-compile - (declare-function ,command ,name-string)))))) + (when (not (stringp command)) + (append + `((unless (fboundp ',command) + (autoload #',command ,name-string nil t))) + (when (bound-and-true-p byte-compile-current-file) + `((eval-when-compile + (declare-function ,command ,name-string))))))) (delete-dups (plist-get state :commands)))) body))) From b4ec5abad2b8b1e2585daa644c2b364da4b08546 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 11 Jan 2016 22:38:31 -0800 Subject: [PATCH 202/606] Add a PREDICATE option to bind-key, and :filter to `bind-keys' --- lisp/use-package/bind-key.el | 65 +++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 5ea5ab37b56..5c05486c815 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -135,13 +135,19 @@ Elements have the form ((KEY . [MAP]) CMD ORIGINAL-CMD)") ;;;###autoload -(defmacro bind-key (key-name command &optional keymap) +(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." +`edmacro-mode' for details. + +If PREDICATE is non-nil, it is a form evaluated to determine when +a key should be bound. It must return non-nil in such cases. +Emacs can evaluate this form at any time that it does redisplay +or operates on menu data structures, so you should write it so it +can safely be called at any time." (let ((namevar (make-symbol "name")) (keyvar (make-symbol "key")) (kdescvar (make-symbol "kdesc")) @@ -152,15 +158,21 @@ spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of (,kdescvar (cons (if (stringp ,namevar) ,namevar (key-description ,namevar)) (quote ,keymap))) - (,bindingvar (lookup-key (or ,keymap global-map) - ,keyvar))) + (,bindingvar (lookup-key (or ,keymap global-map) ,keyvar))) (add-to-list 'personal-keybindings (list ,kdescvar ,command (unless (numberp ,bindingvar) ,bindingvar))) - (define-key (or ,keymap global-map) ,keyvar ,command)))) + ,(if predicate + `(define-key (or ,keymap global-map) ,keyvar + '(menu-item "" nil :filter (lambda (&optional _) + (when ,predicate + ,command)))) + `(define-key (or ,keymap global-map) ,keyvar ,command))))) ;;;###autoload (defmacro unbind-key (key-name &optional keymap) + "Unbind the given KEY-NAME, within the KEYMAP (if specified). +See `bind-key' for more details." `(progn (bind-key ,key-name nil ,keymap) (setq personal-keybindings @@ -174,20 +186,23 @@ spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of personal-keybindings)))) ;;;###autoload -(defmacro bind-key* (key-name command) - `(bind-key ,key-name ,command override-global-map)) +(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)) ;;;###autoload (defmacro bind-keys (&rest args) "Bind multiple keys at once. Accepts keyword arguments: -:map - a keymap into which the keybindings should be added -:prefix-map - name of the prefix map that should be created for - these bindings -:prefix - prefix key for these bindings -:prefix-docstring - docstring for the prefix-map variable -:menu-name - optional menu string for prefix map +:map MAP - a keymap into which the keybindings should be + added +:prefix KEY - prefix key for these bindings +:prefix-map MAP - name of the prefix map that should be created + for these bindings +:prefix-docstring STR - docstring for the prefix-map variable +:menu-name NAME - optional menu string for prefix map +:filter FORM - optional form to determine when bindings apply The rest of the arguments are conses of keybinding string and a function symbol (unquoted)." @@ -196,6 +211,7 @@ function symbol (unquoted)." (doc (plist-get args :prefix-docstring)) (prefix-map (plist-get args :prefix-map)) (prefix (plist-get args :prefix)) + (filter (plist-get args :filter)) (menu-name (plist-get args :menu-name)) (key-bindings (progn (while (keywordp (car args)) @@ -218,17 +234,18 @@ function symbol (unquoted)." ,@(if maps (mapcar #'(lambda (m) - `(bind-key ,prefix ',prefix-map ,m)) maps) - `((bind-key ,prefix ',prefix-map))))) - (cl-mapcan (lambda (form) - (if prefix-map - `((bind-key ,(car form) ',(cdr form) ,prefix-map)) - (if maps - (mapcar - #'(lambda (m) - `(bind-key ,(car form) ',(cdr form) ,m)) maps) - `((bind-key ,(car form) ',(cdr form)))))) - key-bindings))))) + `(bind-key ,prefix ',prefix-map ,m ,filter)) maps) + `((bind-key ,prefix ',prefix-map nil ,filter))))) + (cl-mapcan + (lambda (form) + (if prefix-map + `((bind-key ,(car form) ',(cdr form) ,prefix-map ,filter)) + (if maps + (mapcar + #'(lambda (m) + `(bind-key ,(car form) ',(cdr form) ,m ,filter)) maps) + `((bind-key ,(car form) ',(cdr form) nil ,filter))))) + key-bindings))))) ;;;###autoload (defmacro bind-keys* (&rest args) From 3ce3b3a98c65f365d5e95258c28b9c9f751f41b0 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 12 Jan 2016 07:58:06 -0800 Subject: [PATCH 203/606] Add a missing comma --- lisp/use-package/bind-key.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 5c05486c815..ecd0ba1a157 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -188,7 +188,7 @@ See `bind-key' for more details." ;;;###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)) + `(bind-key ,key-name ,command override-global-map ,predicate)) ;;;###autoload (defmacro bind-keys (&rest args) From 19474a17116737bc821041f2e1b339b32512c518 Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Mon, 18 Jan 2016 14:41:27 +1300 Subject: [PATCH 204/606] Do not package-initialize on each :pin --- lisp/use-package/use-package.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index a359e946378..9eab03dedc3 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -422,7 +422,9 @@ manually updated package." (add-to-list 'package-pinned-packages (cons package archive-name)) (error "Archive '%s' requested for package '%s' is not available." archive-name package)) - (package-initialize t))) + (when (and (boundp 'package--initialized) + (not 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)) From c42e3f5669482b46936fe391e5b73e8e27dc8438 Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Wed, 20 Jan 2016 10:49:27 +1300 Subject: [PATCH 205/606] Change condition that checks if package has been initialized --- lisp/use-package/use-package.el | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 9eab03dedc3..8a0921aebd0 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -422,8 +422,7 @@ manually updated package." (add-to-list 'package-pinned-packages (cons package archive-name)) (error "Archive '%s' requested for package '%s' is not available." archive-name package)) - (when (and (boundp 'package--initialized) - (not package--initialized)) + (unless (bound-and-true-p package--initialized) (package-initialize t)))) (defun use-package-handler/:pin (name keyword archive-name rest state) From f4a01f3e009112e8991df849b0cbea2f3317bc4b Mon Sep 17 00:00:00 2001 From: Phillip Lord Date: Wed, 20 Jan 2016 22:02:26 +0000 Subject: [PATCH 206/606] Add new option `-always-pin' `use-package-always-pin' allows a default archive (or manual) to be specified for all use-package statements, unless explicitly overridden. --- lisp/use-package/use-package.el | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index a359e946378..a76b0473d7e 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -71,6 +71,11 @@ then the expanded macros do their job silently." :type 'sexp :group 'use-package) +(defcustom use-package-always-pin nil + "Treat every package as though it had specified `:pin SYM." + :type 'symbol + :group 'use-package) + (defcustom use-package-minimum-reported-time 0.1 "Minimal load time that will be reported. @@ -1075,6 +1080,11 @@ this file. Usage: (if use-package-always-ensure (use-package-plist-maybe-put args0 :ensure use-package-always-ensure) + args0))) + (args* (use-package-sort-keywords + (if use-package-always-pin + (use-package-plist-maybe-put + args* :pin use-package-always-pin) args0)))) ;; When byte-compiling, pre-load the package so all its symbols are in From ba4aeb600d6b4a662220561e8d980abeffe07f3f Mon Sep 17 00:00:00 2001 From: Phillip Lord Date: Thu, 21 Jan 2016 09:06:28 +0000 Subject: [PATCH 207/606] Fix errant variable name --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index a76b0473d7e..bfb5002965d 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1085,7 +1085,7 @@ this file. Usage: (if use-package-always-pin (use-package-plist-maybe-put args* :pin use-package-always-pin) - args0)))) + args*)))) ;; When byte-compiling, pre-load the package so all its symbols are in ;; scope. From 5cbfd926c5e4035fc46c17d4188015cb54204225 Mon Sep 17 00:00:00 2001 From: Thierry Volpiatto Date: Thu, 4 Feb 2016 10:20:55 +0100 Subject: [PATCH 208/606] When :ensure is used install package as a selected package Also shutup bytecompiler about package-archive-contents. * use-package.el (use-package-ensure-elpa): Add package to selected package by using second arg of package install. --- lisp/use-package/use-package.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index dcc8842b6e9..05dbf651498 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -446,7 +446,7 @@ manually updated package." ;; ;; :ensure ;; - +(defvar package-archive-contents) (defun use-package-normalize/:ensure (name keyword args) (if (null args) t @@ -462,7 +462,7 @@ manually updated package." (if (package-installed-p package) t (if (or (assoc package package-archive-contents) no-refresh) - (package-install package) + (package-install package t) (progn (package-refresh-contents) (use-package-ensure-elpa package t))))) From c5e98d87dae831d3ed8527bd806f6c4814db8f9b Mon Sep 17 00:00:00 2001 From: Thierry Volpiatto Date: Thu, 4 Feb 2016 11:19:23 +0100 Subject: [PATCH 209/606] Ensure package-install support a second argument * use-package.el (use-package-ensure-elpa): Do it. --- lisp/use-package/use-package.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 05dbf651498..98bbc417e65 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -462,7 +462,9 @@ manually updated package." (if (package-installed-p package) t (if (or (assoc package package-archive-contents) no-refresh) - (package-install package t) + (if (boundp 'package-selected-packages) + (package-install package t) + (package-install package)) (progn (package-refresh-contents) (use-package-ensure-elpa package t))))) From 32748d06571a93928043c73910a65ca64d989467 Mon Sep 17 00:00:00 2001 From: Nicolas Dudebout Date: Fri, 5 Feb 2016 21:40:34 -0500 Subject: [PATCH 210/606] Upper casing Cs corresponding to Ctrl A number of Cs corresponding to Ctrl have been lower cased in comments in eb6b81dfe. --- lisp/use-package/bind-key.el | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index ecd0ba1a157..0e2d843a09a 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -35,22 +35,22 @@ ;; ;; (require 'bind-key) ;; -;; (bind-key "c-c x" 'my-ctrl-c-x-command) +;; (bind-key "C-c x" 'my-ctrl-c-x-command) ;; ;; If you want the keybinding to override all minor modes that may also bind ;; the same key, use the `bind-key*' form: ;; -;; (bind-key* "" 'other-window) +;; (bind-key* "" '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) +;; (bind-key "C-c x" 'my-ctrl-c-x-command some-other-mode-map) ;; ;; To unbind a key within a keymap (for example, to stop your favorite major ;; mode from changing a binding that you don't want to override everywhere), ;; use `unbind-key': ;; -;; (unbind-key "c-c x" some-other-mode-map) +;; (unbind-key "C-c x" some-other-mode-map) ;; ;; To bind multiple keys at once, or set up a prefix map, a `bind-keys' macro ;; is provided. It accepts keyword arguments, please see its documentation From ee8ac83641e35d87bc9d476e15db313041686627 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 6 Feb 2016 14:55:35 -0500 Subject: [PATCH 211/606] Add an autoload cookie for `use-package' --- lisp/use-package/use-package.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 98bbc417e65..1bd6a929d1f 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1023,6 +1023,7 @@ deferred until the prefix key sequence is pressed." ;; The main macro ;; +;;;###autoload (defmacro use-package (name &rest args) "Declare an Emacs package by specifying a group of configuration options. From 543935482f1d7a6dddcff9fc6da5b930c3b976e7 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 9 Feb 2016 19:33:09 -0500 Subject: [PATCH 212/606] Add a comment about a recent change --- lisp/use-package/use-package.el | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index d106ef2e20b..cf5b2814d45 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -659,7 +659,12 @@ manually updated package." (defun use-package-normalize-pairs (name label arg &optional recursed allow-vector allow-string-cdrs) - "Normalize a list of string/symbol pairs." + "Normalize a list of string/symbol pairs. +If RECURSED is non-nil, recurse into sublists. +If ALLOW-VECTOR is non-nil, then the key to bind may specify a +vector of keys, as accepted by `define-key'. +If ALLOW-STRING-CDRS is non-nil, then the command name to bind to +may also be a string, as accepted by `define-key'." (cond ((or (stringp arg) (and allow-vector (vectorp arg))) (list (cons arg (use-package-as-symbol name)))) From c65a33427650a20b77138ee3cdfaeeb174dda35d Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 25 Feb 2016 15:08:32 -0800 Subject: [PATCH 213/606] Handle :unless correctly GitHub-reference: fixes https://github.com/jwiegley/use-package/issues/197 --- lisp/use-package/use-package.el | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index cf5b2814d45..67486194169 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -503,10 +503,7 @@ manually updated package." (defalias 'use-package-normalize/:if 'use-package-normalize-test) (defalias 'use-package-normalize/:when 'use-package-normalize-test) - -(defun use-package-normalize/:unless (name keyword args) - (not (use-package-only-one (symbol-name keyword) args - #'use-package-normalize-value))) +(defalias 'use-package-normalize/:unless 'use-package-normalize-test) (defun use-package-handler/:if (name keyword pred rest state) (let ((body (use-package-process-keywords name rest state))) From 947345028e7ba1a50b902ed8f94bb31eba898cd8 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 25 Feb 2016 15:16:04 -0800 Subject: [PATCH 214/606] Add another `declare' --- lisp/use-package/use-package.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 67486194169..baa50b0270f 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -357,6 +357,7 @@ 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)) From 23a61c8f6b97afd1c6f3aaf0b3a8f9460828e240 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 25 Feb 2016 15:21:49 -0800 Subject: [PATCH 215/606] Add some variable settings to use-package-tests.el, thanks tarsius --- test/lisp/use-package/use-package-tests.el | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 869b818e54b..0644a5ee493 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -46,5 +46,7 @@ ;; Local Variables: ;; indent-tabs-mode: nil +;; no-byte-compile: t +;; no-update-autoloads: t ;; End: ;;; use-package-tests.el ends here From 856e8ee2459de8843b1c0efc0d05b576fccd3d2d Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 25 Feb 2016 15:57:50 -0800 Subject: [PATCH 216/606] Support multiples uses of :map with :bind GitHub-reference: fixes https://github.com/jwiegley/use-package/issues/121 --- lisp/use-package/bind-key.el | 78 +++++++++++++++++++++++---------- lisp/use-package/use-package.el | 4 +- 2 files changed, 57 insertions(+), 25 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 65f40f7901a..c74e7b6a753 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -190,8 +190,7 @@ See `bind-key' for more details." "Similar to `bind-key', but overrides any mode-specific bindings." `(bind-key ,key-name ,command override-global-map ,predicate)) -;;;###autoload -(defmacro bind-keys (&rest args) +(defun bind-keys-form (args) "Bind multiple keys at once. Accepts keyword arguments: @@ -223,33 +222,64 @@ function symbol (unquoted)." (error "Both :prefix-map and :prefix must be supplied")) (when (and menu-name (not prefix)) (error "If :menu-name is supplied, :prefix must be too")) - (macroexp-progn - (append - (when prefix-map - `((defvar ,prefix-map) - ,@(when doc `((put ',prefix-map 'variable-documentation ,doc))) - ,@(if menu-name - `((define-prefix-command ',prefix-map nil ,menu-name)) - `((define-prefix-command ',prefix-map))) - ,@(if maps + (let ((args key-bindings) + 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)))) + (append + (when prefix-map + `((defvar ,prefix-map) + ,@(when doc `((put ',prefix-map 'variable-documentation ,doc))) + ,@(if menu-name + `((define-prefix-command ',prefix-map nil ,menu-name)) + `((define-prefix-command ',prefix-map))) + ,@(if maps + (mapcar + #'(lambda (m) + `(bind-key ,prefix ',prefix-map ,m ,filter)) maps) + `((bind-key ,prefix ',prefix-map nil ,filter))))) + (cl-mapcan + (lambda (form) + (if prefix-map + `((bind-key ,(car form) ',(cdr form) ,prefix-map ,filter)) + (if maps (mapcar #'(lambda (m) - `(bind-key ,prefix ',prefix-map ,m ,filter)) maps) - `((bind-key ,prefix ',prefix-map nil ,filter))))) - (cl-mapcan - (lambda (form) - (if prefix-map - `((bind-key ,(car form) ',(cdr form) ,prefix-map ,filter)) - (if maps - (mapcar - #'(lambda (m) - `(bind-key ,(car form) ',(cdr form) ,m ,filter)) maps) - `((bind-key ,(car form) ',(cdr form) nil ,filter))))) - key-bindings))))) + `(bind-key ,(car form) ',(cdr form) ,m ,filter)) maps) + `((bind-key ,(car form) ',(cdr form) nil ,filter))))) + first) + (when next + (bind-keys-form next)))))) + +;;;###autoload +(defmacro bind-keys (&rest args) + "Bind multiple keys at once. + +Accepts keyword arguments: +:map MAP - a keymap into which the keybindings should be + added +:prefix KEY - prefix key for these bindings +:prefix-map MAP - name of the prefix map that should be created + for these bindings +:prefix-docstring STR - docstring for the prefix-map variable +:menu-name NAME - optional menu string for prefix map +:filter FORM - optional form to determine when bindings apply + +The rest of the arguments are conses of keybinding string and a +function symbol (unquoted)." + (macroexp-progn (bind-keys-form args))) ;;;###autoload (defmacro bind-keys* (&rest args) - `(bind-keys :map override-global-map ,@args)) + (macroexp-progn + (bind-keys-form (cons :map (cons override-global-map args))))) (defun get-binding-description (elem) (cond diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index baa50b0270f..15da2452f1a 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -698,7 +698,9 @@ may also be a string, as accepted by `define-key'." (use-package-sort-keywords (use-package-plist-maybe-put rest :defer t)) (use-package-plist-append state :commands commands)) - `((ignore (,(if bind-macro bind-macro 'bind-keys) ,@arg)))))) + `((ignore + ,(macroexpand + `(,(if bind-macro bind-macro 'bind-keys) ,@arg))))))) (defun use-package-handler/:bind* (name keyword arg rest state) (use-package-handler/:bind name keyword arg rest state 'bind-keys*)) From 828563a7563bc99a468fd1b7b82797ec335475fa Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 25 Feb 2016 16:37:34 -0800 Subject: [PATCH 217/606] Remove :bind-keymaps, and only apply :map bindings after load --- lisp/use-package/bind-key.el | 62 +++++++++++++++++------------ lisp/use-package/use-package.el | 69 +++------------------------------ 2 files changed, 43 insertions(+), 88 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index c74e7b6a753..023ab794316 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -212,6 +212,7 @@ function symbol (unquoted)." (prefix (plist-get args :prefix)) (filter (plist-get args :filter)) (menu-name (plist-get args :menu-name)) + (pkg (plist-get args :package)) (key-bindings (progn (while (keywordp (car args)) (pop args) @@ -233,30 +234,43 @@ function symbol (unquoted)." (nconc first (list (car args))) (setq first (list (car args)))) (setq args (cdr args)))) - (append - (when prefix-map - `((defvar ,prefix-map) - ,@(when doc `((put ',prefix-map 'variable-documentation ,doc))) - ,@(if menu-name - `((define-prefix-command ',prefix-map nil ,menu-name)) - `((define-prefix-command ',prefix-map))) - ,@(if maps - (mapcar - #'(lambda (m) - `(bind-key ,prefix ',prefix-map ,m ,filter)) maps) - `((bind-key ,prefix ',prefix-map nil ,filter))))) - (cl-mapcan - (lambda (form) - (if prefix-map - `((bind-key ,(car form) ',(cdr form) ,prefix-map ,filter)) - (if maps - (mapcar - #'(lambda (m) - `(bind-key ,(car form) ',(cdr form) ,m ,filter)) maps) - `((bind-key ,(car form) ',(cdr form) nil ,filter))))) - first) - (when next - (bind-keys-form next)))))) + (cl-flet ((wrap (maps bindings) + (if (and maps pkg) + `((eval-after-load + ,(if (symbolp pkg) `',pkg pkg) + '(progn ,@bindings))) + bindings))) + (append + (when prefix-map + `((defvar ,prefix-map) + ,@(when doc `((put ',prefix-map 'variable-documentation ,doc))) + ,@(if menu-name + `((define-prefix-command ',prefix-map nil ,menu-name)) + `((define-prefix-command ',prefix-map))) + ,@(if maps + (wrap maps + (mapcar + #'(lambda (m) + `(bind-key ,prefix ',prefix-map ,m ,filter)) + maps)) + `((bind-key ,prefix ',prefix-map nil ,filter))))) + (wrap maps + (cl-mapcan + (lambda (form) + (if prefix-map + `((bind-key ,(car form) ',(cdr form) ,prefix-map ,filter)) + (if maps + (mapcar + #'(lambda (m) + `(bind-key ,(car form) ',(cdr form) ,m ,filter)) + maps) + `((bind-key ,(car form) ',(cdr form) nil ,filter))))) + first)) + (when next + (bind-keys-form + (if pkg + (cons :package (cons pkg next)) + next)))))))) ;;;###autoload (defmacro bind-keys (&rest args) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 15da2452f1a..e0233c8479d 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -123,8 +123,6 @@ the user specified." :no-require :bind :bind* - :bind-keymap - :bind-keymap* :interpreter :mode :commands @@ -175,7 +173,9 @@ convert it to a string and return that." (defun use-package-load-name (name &optional noerror) "Return a form which will load or require NAME depending on whether it's a string or symbol." - (if (stringp name) `(load ,name 'noerror) `(require ',name nil 'noerror))) + (if (stringp name) + `(load ,name 'noerror) + `(require ',name nil 'noerror))) (defun use-package-expand (name label form) "FORM is a list of forms, so `((foo))' if only `foo' is being called." @@ -700,68 +700,12 @@ may also be a string, as accepted by `define-key'." (use-package-plist-append state :commands commands)) `((ignore ,(macroexpand - `(,(if bind-macro bind-macro 'bind-keys) ,@arg))))))) + `(,(if bind-macro bind-macro 'bind-keys) + :package ,name ,@arg))))))) (defun use-package-handler/:bind* (name keyword arg rest state) (use-package-handler/:bind name keyword arg rest state 'bind-keys*)) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; :bind-keymap, :bind-keymap* -;; - -(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder) -(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder) - -(defun use-package-autoload-keymap (keymap-symbol package override) - "Loads PACKAGE and then binds the key sequence used to invoke -this function to KEYMAP-SYMBOL. It then simulates pressing the -same key sequence a again, so that the next key pressed is routed -to the newly loaded keymap. - -This function supports use-package's :bind-keymap keyword. It -works by binding the given key sequence to an invocation of this -function for a particular keymap. The keymap is expected to be -defined by the package. In this way, loading the package is -deferred until the prefix key sequence is pressed." - (if (not (require package nil t)) - (use-package-error (format "Could not load package.el: %s" package)) - (if (and (boundp keymap-symbol) - (keymapp (symbol-value keymap-symbol))) - (let* ((kv (this-command-keys-vector)) - (key (key-description kv)) - (keymap (symbol-value keymap-symbol))) - (if override - (bind-key* key keymap) - (bind-key key keymap)) - (setq unread-command-events - (listify-key-sequence kv))) - (use-package-error - (format "use-package: package.el %s failed to define keymap %s" - package keymap-symbol))))) - -(defun use-package-handler/:bind-keymap - (name keyword arg rest state &optional override) - (let ((form (mapcar - #'(lambda (binding) - `(,(if override - 'bind-key* - 'bind-key) - ,(car binding) - #'(lambda () - (interactive) - (use-package-autoload-keymap - ',(cdr binding) ',(use-package-as-symbol name) ,override)))) arg))) - (use-package-concat - (use-package-process-keywords name - (use-package-sort-keywords - (use-package-plist-maybe-put rest :defer t)) - state) - `((ignore ,@form))))) - -(defun use-package-handler/:bind-keymap* (name keyword arg rest state) - (use-package-handler/:bind-keymap name keyword arg rest state t)) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; :interpreter @@ -1066,9 +1010,6 @@ this file. Usage: :bind Bind keys, and define autoloads for the bound commands. :bind* Bind keys, and define autoloads for the bound commands, *overriding all minor mode bindings*. -:bind-keymap Bind a key prefix to an auto-loaded keymap defined in the - package. This is like `:bind', but for keymaps. -:bind-keymap* Like `:bind-keymap', but overrides all minor mode bindings :defer Defer loading of a package -- this is implied when using `:commands', `:bind', `:bind*', `:mode' or `:interpreter'. From eeba14ef079544edeb33d2505e69e51f16359960 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 25 Feb 2016 16:41:09 -0800 Subject: [PATCH 218/606] Restore :bind-keymap, it does something special still --- lisp/use-package/use-package.el | 62 +++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index e0233c8479d..48611720a9c 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -123,6 +123,8 @@ the user specified." :no-require :bind :bind* + :bind-keymap + :bind-keymap* :interpreter :mode :commands @@ -706,6 +708,63 @@ may also be a string, as accepted by `define-key'." (defun use-package-handler/:bind* (name keyword arg rest state) (use-package-handler/:bind name keyword arg rest state 'bind-keys*)) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :bind-keymap, :bind-keymap* +;; + +(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder) +(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder) + +(defun use-package-autoload-keymap (keymap-symbol package override) + "Loads PACKAGE and then binds the key sequence used to invoke +this function to KEYMAP-SYMBOL. It then simulates pressing the +same key sequence a again, so that the next key pressed is routed +to the newly loaded keymap. + +This function supports use-package's :bind-keymap keyword. It +works by binding the given key sequence to an invocation of this +function for a particular keymap. The keymap is expected to be +defined by the package. In this way, loading the package is +deferred until the prefix key sequence is pressed." + (if (not (require package nil t)) + (use-package-error (format "Could not load package.el: %s" package)) + (if (and (boundp keymap-symbol) + (keymapp (symbol-value keymap-symbol))) + (let* ((kv (this-command-keys-vector)) + (key (key-description kv)) + (keymap (symbol-value keymap-symbol))) + (if override + (bind-key* key keymap) + (bind-key key keymap)) + (setq unread-command-events + (listify-key-sequence kv))) + (use-package-error + (format "use-package: package.el %s failed to define keymap %s" + package keymap-symbol))))) + +(defun use-package-handler/:bind-keymap + (name keyword arg rest state &optional override) + (let ((form (mapcar + #'(lambda (binding) + `(,(if override + 'bind-key* + 'bind-key) + ,(car binding) + #'(lambda () + (interactive) + (use-package-autoload-keymap + ',(cdr binding) ',(use-package-as-symbol name) ,override)))) arg))) + (use-package-concat + (use-package-process-keywords name + (use-package-sort-keywords + (use-package-plist-maybe-put rest :defer t)) + state) + `((ignore ,@form))))) + +(defun use-package-handler/:bind-keymap* (name keyword arg rest state) + (use-package-handler/:bind-keymap name keyword arg rest state t)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; :interpreter @@ -1010,6 +1069,9 @@ this file. Usage: :bind Bind keys, and define autoloads for the bound commands. :bind* Bind keys, and define autoloads for the bound commands, *overriding all minor mode bindings*. +:bind-keymap Bind a key prefix to an auto-loaded keymap defined in the + package. This is like `:bind', but for keymaps. +:bind-keymap* Like `:bind-keymap', but overrides all minor mode bindings :defer Defer loading of a package -- this is implied when using `:commands', `:bind', `:bind*', `:mode' or `:interpreter'. From 6da4e0ce9d9841d64a07f991fc8de39149d3a737 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 25 Feb 2016 17:04:17 -0800 Subject: [PATCH 219/606] Add variable `use-package-always-defer' GitHub-reference: fixes https://github.com/jwiegley/use-package/issues/202 --- lisp/use-package/use-package.el | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 48611720a9c..45ef410be88 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -66,6 +66,11 @@ then the expanded macros do their job silently." :type 'boolean :group 'use-package) +(defcustom use-package-always-defer nil + "If non-nil, assume `:defer t` unless `:demand t` is given." + :type 'sexp + :group 'use-package) + (defcustom use-package-always-ensure nil "Treat every package as though it had specified `:ensure SEXP`." :type 'sexp @@ -1126,7 +1131,8 @@ this file. Usage: (let ((body (macroexp-progn - (use-package-process-keywords name args*)))) + (use-package-process-keywords name args* + (and use-package-always-defer '(:deferred t)))))) (if use-package-debug (display-buffer (save-current-buffer From ce51ea2055cc5c713f52342ceac79bc36631c8fe Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 25 Feb 2016 17:13:02 -0800 Subject: [PATCH 220/606] Use `add-to-list' defensively instead of `push' GitHub-reference: fixes https://github.com/jwiegley/use-package/issues/293 --- lisp/use-package/use-package.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 45ef410be88..619c6c3b3f3 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -597,7 +597,7 @@ manually updated package." (let ((body (use-package-process-keywords name rest state))) (use-package-concat (mapcar #'(lambda (path) - `(eval-and-compile (push ,path load-path))) arg) + `(eval-and-compile (add-to-list 'load-path ,path))) arg) body))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -785,7 +785,7 @@ deferred until the prefix key sequence is pressed." (let* (commands (form (mapcar #'(lambda (interpreter) (push (cdr interpreter) commands) - `(push ',interpreter interpreter-mode-alist)) arg))) + `(add-to-list 'interpreter-mode-alist ',interpreter)) arg))) (use-package-concat (use-package-process-keywords name (use-package-sort-keywords @@ -804,7 +804,7 @@ deferred until the prefix key sequence is pressed." (let* (commands (form (mapcar #'(lambda (mode) (push (cdr mode) commands) - `(push ',mode auto-mode-alist)) arg))) + `(add-to-list 'auto-mode-alist ',mode)) arg))) (use-package-concat (use-package-process-keywords name (use-package-sort-keywords From 6a90a9f16d0d31dd414139ea089dce3d80f1049b Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 25 Feb 2016 17:24:59 -0800 Subject: [PATCH 221/606] Add configuration variable `use-package-check-before-init' Fixes https://github.com/jwiegley/use-package/issues/306 --- lisp/use-package/use-package.el | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 619c6c3b3f3..617c523f8ff 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -66,9 +66,15 @@ then the expanded macros do their job silently." :type 'boolean :group 'use-package) +(defcustom use-package-check-before-init nil + "If non-nil, check that package exists before executing its `:init' block. +The check is performed by looking for the module using `locate-library'." + :type 'boolean + :group 'use-package) + (defcustom use-package-always-defer nil "If non-nil, assume `:defer t` unless `:demand t` is given." - :type 'sexp + :type 'boolean :group 'use-package) (defcustom use-package-always-ensure nil @@ -938,7 +944,13 @@ deferred until the prefix key sequence is pressed." (let ((body (use-package-process-keywords name rest state))) (use-package-concat ;; The user's initializations - (use-package-hook-injector (use-package-as-string name) :init arg) + (let ((init-body + (use-package-hook-injector (use-package-as-string name) + :init arg))) + (if use-package-check-before-init + `((if (locate-library ,(use-package-as-string name)) + ,(macroexp-progn init-body))) + init-body)) body))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; From b0b5cfbfb26bbc18d36d7ea8cd90bd665f521d9b Mon Sep 17 00:00:00 2001 From: Bjarte Johansen Date: Fri, 26 Feb 2016 15:19:24 +0000 Subject: [PATCH 222/606] Quote variable in `bind-keys*' * bind-key.el (bind-keys*): `override-global-map' needs to be quoted so the symbol is passed to `bind-keys-form' and not the value. GitHub-reference: fixes https://github.com/jwiegley/use-package/issues/323 --- lisp/use-package/bind-key.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 023ab794316..2333433e509 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -293,7 +293,7 @@ function symbol (unquoted)." ;;;###autoload (defmacro bind-keys* (&rest args) (macroexp-progn - (bind-keys-form (cons :map (cons override-global-map args))))) + (bind-keys-form `(:map override-global-map ,@args)))) (defun get-binding-description (elem) (cond From 6ca19531bbfecab5aca380ba80b15896d39bc173 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 26 Feb 2016 16:06:58 -0800 Subject: [PATCH 223/606] Repair :map handling in bind-key.el GitHub-reference: fixes https://github.com/jwiegley/use-package/issues/324 --- lisp/use-package/bind-key.el | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 023ab794316..7d702bc6f9c 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -205,6 +205,11 @@ Accepts keyword arguments: The rest of the arguments are conses of keybinding string and a function symbol (unquoted)." + ;; jww (2016-02-26): This is a hack; this whole function needs to be + ;; rewritten to normalize arguments the way that use-package.el does. + (if (and (eq (car args) :package) + (not (eq (car (cdr (cdr args))) :map))) + (setq args (cons :map (cons 'global-map args)))) (let* ((map (plist-get args :map)) (maps (if (listp map) map (list map))) (doc (plist-get args :prefix-docstring)) @@ -224,7 +229,7 @@ function symbol (unquoted)." (when (and menu-name (not prefix)) (error "If :menu-name is supplied, :prefix must be too")) (let ((args key-bindings) - first next) + saw-map first next) (while args (if (keywordp (car args)) (progn @@ -235,7 +240,8 @@ function symbol (unquoted)." (setq first (list (car args)))) (setq args (cdr args)))) (cl-flet ((wrap (maps bindings) - (if (and maps pkg) + (if (and maps pkg + (not (equal maps '(global-map)))) `((eval-after-load ,(if (symbolp pkg) `',pkg pkg) '(progn ,@bindings))) @@ -247,7 +253,7 @@ function symbol (unquoted)." ,@(if menu-name `((define-prefix-command ',prefix-map nil ,menu-name)) `((define-prefix-command ',prefix-map))) - ,@(if maps + ,@(if (and maps (not (equal maps '(global-map)))) (wrap maps (mapcar #'(lambda (m) @@ -259,7 +265,7 @@ function symbol (unquoted)." (lambda (form) (if prefix-map `((bind-key ,(car form) ',(cdr form) ,prefix-map ,filter)) - (if maps + (if (and maps (not (equal maps '(global-map)))) (mapcar #'(lambda (m) `(bind-key ,(car form) ',(cdr form) ,m ,filter)) From f150691c7808aabb3d1206bab6b1d28a7b127e74 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 26 Feb 2016 16:14:51 -0800 Subject: [PATCH 224/606] Only printing debug messages if use-package-verbose is `debug' Fixes https://github.com/jwiegley/use-package/issues/271 --- lisp/use-package/use-package.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 617c523f8ff..0767d8e7fb0 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -58,7 +58,8 @@ If you customize this, then you should require the `use-package' feature in files that use `use-package', even if these files only contain compiled expansions of the macros. If you don't do so, then the expanded macros do their job silently." - :type 'boolean + :type '(choice (const :tag "Quiet" nil) (const :tag "Verbose" t) + (const :tag "Debug" debug)) :group 'use-package) (defcustom use-package-debug nil @@ -1136,7 +1137,7 @@ this file. Usage: (plist-get args* :defines)) (with-demoted-errors ,(format "Cannot load %s: %%S" name) - ,(if use-package-verbose + ,(if (eq use-package-verbose 'debug) `(message "Compiling package %s" ',name-symbol)) ,(unless (plist-get args* :no-require) (use-package-load-name name))))))) From a1c4e6d0aba966aec122e396376995c28dd81098 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 26 Feb 2016 16:18:21 -0800 Subject: [PATCH 225/606] Normalize some error text --- lisp/use-package/use-package.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 0767d8e7fb0..9437c217353 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -740,7 +740,7 @@ function for a particular keymap. The keymap is expected to be defined by the package. In this way, loading the package is deferred until the prefix key sequence is pressed." (if (not (require package nil t)) - (use-package-error (format "Could not load package.el: %s" package)) + (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)) @@ -986,7 +986,7 @@ deferred until the prefix key sequence is pressed." config-body) `((if (not ,(use-package-load-name name t)) (ignore - (message (format "Could not load %s" ',name))) + (message (format "Cannot load %s" ',name))) ,@config-body))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; From af65fbea63f42e2cacb83bd513144f900bab4605 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 27 Feb 2016 00:48:29 -0800 Subject: [PATCH 226/606] :map no longer accepts lists; only eval-after-load if necessary Fixes https://github.com/jwiegley/use-package/issues/324 --- lisp/use-package/bind-key.el | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index b63c34a1976..995e4816ff4 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -211,7 +211,6 @@ function symbol (unquoted)." (not (eq (car (cdr (cdr args))) :map))) (setq args (cons :map (cons 'global-map args)))) (let* ((map (plist-get args :map)) - (maps (if (listp map) map (list map))) (doc (plist-get args :prefix-docstring)) (prefix-map (plist-get args :prefix-map)) (prefix (plist-get args :prefix)) @@ -239,13 +238,15 @@ function symbol (unquoted)." (nconc first (list (car args))) (setq first (list (car args)))) (setq args (cdr args)))) - (cl-flet ((wrap (maps bindings) - (if (and maps pkg - (not (equal maps '(global-map)))) - `((eval-after-load - ,(if (symbolp pkg) `',pkg pkg) - '(progn ,@bindings))) - bindings))) + (cl-flet + ((wrap (map bindings) + (if (and map pkg (not (eq map 'global-map))) + (if (boundp map) + bindings + `((eval-after-load + ,(if (symbolp pkg) `',pkg pkg) + '(progn ,@bindings)))) + bindings))) (append (when prefix-map `((defvar ,prefix-map) @@ -253,23 +254,16 @@ function symbol (unquoted)." ,@(if menu-name `((define-prefix-command ',prefix-map nil ,menu-name)) `((define-prefix-command ',prefix-map))) - ,@(if (and maps (not (equal maps '(global-map)))) - (wrap maps - (mapcar - #'(lambda (m) - `(bind-key ,prefix ',prefix-map ,m ,filter)) - maps)) + ,@(if (and map (not (eq map 'global-map))) + (wrap map `((bind-key ,prefix ',prefix-map ,map ,filter))) `((bind-key ,prefix ',prefix-map nil ,filter))))) - (wrap maps + (wrap map (cl-mapcan (lambda (form) (if prefix-map `((bind-key ,(car form) ',(cdr form) ,prefix-map ,filter)) - (if (and maps (not (equal maps '(global-map)))) - (mapcar - #'(lambda (m) - `(bind-key ,(car form) ',(cdr form) ,m ,filter)) - maps) + (if (and map (not (eq map 'global-map))) + `((bind-key ,(car form) ',(cdr form) ,map ,filter)) `((bind-key ,(car form) ',(cdr form) nil ,filter))))) first)) (when next From 3aa6aecb7f26f79ee23bc1984bbb34c91502cb52 Mon Sep 17 00:00:00 2001 From: Chunyang Xu Date: Thu, 31 Mar 2016 19:25:48 +0800 Subject: [PATCH 227/606] Mark package as selected with package-install Fixes https://github.com/jwiegley/use-package/issues/327 --- lisp/use-package/use-package.el | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 9437c217353..7dba2b5dcf0 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -477,9 +477,7 @@ manually updated package." (if (package-installed-p package) t (if (or (assoc package package-archive-contents) no-refresh) - (if (boundp 'package-selected-packages) - (package-install package t) - (package-install package)) + (package-install package) (progn (package-refresh-contents) (use-package-ensure-elpa package t))))) From 858a7f9b7c242251843c859810ae72e6c9387fc6 Mon Sep 17 00:00:00 2001 From: robario Date: Sun, 5 Jun 2016 14:58:40 +0900 Subject: [PATCH 228/606] Fix to ignore load error caused via :after Copyright-paperwork-exempt: yes --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 7dba2b5dcf0..c3b4e431d12 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -909,7 +909,7 @@ deferred until the prefix key sequence is pressed." (lambda (feat) `(eval-after-load (quote ,feat) - (quote (require (quote ,name))))) + (quote (require (quote ,name) nil t)))) features))) (defun use-package-handler/:after (name keyword arg rest state) From d34fb2bdc9ad3c4d8e98d55ff677405b7b6f1d4d Mon Sep 17 00:00:00 2001 From: Justin Burkett Date: Mon, 13 Jun 2016 09:45:27 -0400 Subject: [PATCH 229/606] Add imenu support for use-package forms Also add require forms and group both under menu "Package". --- lisp/use-package/use-package.el | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 7dba2b5dcf0..2076d5858fa 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -44,6 +44,7 @@ (require 'diminish nil t) (require 'bytecomp) (eval-when-compile (require 'cl)) +(eval-when-compile (require 'regexp-opt)) (declare-function package-installed-p 'package) @@ -167,6 +168,26 @@ then your byte-compiled init file is as minimal as possible." :type 'boolean :group 'use-package) +(defcustom use-package-enable-imenu-support nil + "If non-nil, adjust `lisp-imenu-generic-expression' to include +support for finding `use-package' and `require' forms. + +Must be set before loading use-package." + :type 'boolean + :group 'use-package) + +(when use-package-enable-imenu-support + (add-to-list + 'lisp-imenu-generic-expression + (list "Package" + (purecopy (concat "^\\s-*(" + (eval-when-compile + (regexp-opt + '("use-package" "require") + t)) + "\\s-+\\(" lisp-mode-symbol-regexp "\\)")) + 2))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Utility functions From da08a04652a8a1955d7d7e8eece3882fd531842a Mon Sep 17 00:00:00 2001 From: Justin Burkett Date: Mon, 13 Jun 2016 21:02:14 -0400 Subject: [PATCH 230/606] Fix imenu support for older versions lisp-mode-symbol-regexp was not defined in Emacs 24.5. --- lisp/use-package/use-package.el | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index f2c4b8a734d..8c47678117d 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -177,6 +177,9 @@ Must be set before loading use-package." :group 'use-package) (when use-package-enable-imenu-support + ;; Not defined in Emacs 24 + (defvar lisp-mode-symbol-regexp + "\\(?:\\sw\\|\\s_\\|\\\\.\\)+") (add-to-list 'lisp-imenu-generic-expression (list "Package" From 75bdb87833625ec33dec6be103bfaee4617511e3 Mon Sep 17 00:00:00 2001 From: Justin Burkett Date: Tue, 14 Jun 2016 22:37:56 -0400 Subject: [PATCH 231/606] Improve imenu support Instead of using defvar for lisp-mode-symbol-regexp, wait until lisp-mode is loaded and check for its existence to avoid making use-package the place where this variable is declared. --- lisp/use-package/use-package.el | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 8c47678117d..59f26158740 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -177,19 +177,17 @@ Must be set before loading use-package." :group 'use-package) (when use-package-enable-imenu-support - ;; Not defined in Emacs 24 - (defvar lisp-mode-symbol-regexp - "\\(?:\\sw\\|\\s_\\|\\\\.\\)+") - (add-to-list - 'lisp-imenu-generic-expression - (list "Package" - (purecopy (concat "^\\s-*(" - (eval-when-compile - (regexp-opt - '("use-package" "require") - t)) - "\\s-+\\(" lisp-mode-symbol-regexp "\\)")) - 2))) + (eval-after-load 'lisp-mode + `(let ((sym-regexp (or (bound-and-true-p lisp-mode-symbol-regexp) + "\\(?:\\sw\\|\\s_\\|\\\\.\\)+"))) + (add-to-list + 'lisp-imenu-generic-expression + (list "Packages" + (concat "^\\s-*(" + ,(eval-when-compile + (regexp-opt '("use-package" "require") t)) + "\\s-+\\(" sym-regexp "\\)") + 2))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; From c13ca927c201c53f2107d54ba2dad8beb15d84ba Mon Sep 17 00:00:00 2001 From: Justin Burkett Date: Wed, 22 Jun 2016 22:46:32 -0400 Subject: [PATCH 232/606] Add function use-package-jump-to-package-form This is an attempt at resolving https://github.com/jwiegley/use-package/issues/329. The new interactive function use-package-jump-to-package-form will prompt with a completing read of all known packages. After selecting a package, use-package-find-require searches load-history to see where the package was required and then I attempt to find the correct use-package form using use-package-form-regexp. It will fail if the use-package form you are looking for did not actually load the package. For example it could be something that is a dependency of a library that was already loaded. In some sense this is a feature because it is helpful to know that the library was already loaded when your use-package form was encountered. It will also fail if your use-package declaration doesn't match the regexp used, but this is easily adjusted. --- lisp/use-package/use-package.el | 41 +++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 8c47678117d..a5195146df8 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -191,6 +191,47 @@ Must be set before loading use-package." "\\s-+\\(" lisp-mode-symbol-regexp "\\)")) 2))) +(defvar use-package-form-regexp "^\\s-*(\\s-*use-package\\s-+\\_<%s\\_>" + "Regexp used in `use-package-jump-to-package-form' to find use +package forms in user files.") + +(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))))))) + +(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 orginally 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 that requires this feature.") + (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 use-package-form-regexp package) nil t))) + (if (null location) + (message "No use-package form found.") + (goto-char location) + (beginning-of-line)))))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Utility functions From 59d34cf9ce738f92f6574449b43676b6f2bb6478 Mon Sep 17 00:00:00 2001 From: Justin Burkett Date: Thu, 23 Jun 2016 10:01:33 -0400 Subject: [PATCH 233/606] Move :init forms before :after and :demand The docstring of use-package says that :init should run before the package is loaded but using :after moves the require statement ahead of :init when any package specified in :after is already loaded. In the following example, in the first case bar-x might get set before or after bar is loaded depending on if foo is already loaded at the time, while the second case always sets bar-x first. (use-package bar :after (foo) :init (setq bar-x 2) :config (bar-mode)) (use-package bar :init (setq bar-x 2) :config (bar-mode)) This commit fixes the issue and makes sure that bar-x is set before bar is loaded by use-package. Fixes https://github.com/jwiegley/use-package/issues/352. --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 8c47678117d..aeea5ea9244 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -144,9 +144,9 @@ the user specified." :defines :functions :defer + :init :after :demand - :init :config :diminish :delight) From 758739e6dbf82c6ad4ee0f1fa93bc2093be50956 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 6 Jul 2016 15:20:41 -0700 Subject: [PATCH 234/606] Version 2.2 --- lisp/use-package/use-package.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index aeea5ea9244..cdff6ce772e 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -5,8 +5,8 @@ ;; Author: John Wiegley ;; Maintainer: John Wiegley ;; Created: 17 Jun 2012 -;; Modified: 26 Sep 2015 -;; Version: 2.1 +;; Modified: 6 Jul 2016 +;; Version: 2.2 ;; Package-Requires: ((bind-key "1.0") (diminish "0.44")) ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package From be7a0e46495b336ce3019e6d1dc6e602d703494a Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sun, 24 Apr 2016 10:31:23 -0400 Subject: [PATCH 235/606] Don't pass a constant as the state for use-package-process-keywords, because the function may modify the list object. Modifying a quoted constant can lead to unexpected side effects (e.g. values from previous use-package forms end up in subsequent ones). --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index cdff6ce772e..ffe2dac3e46 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1167,7 +1167,7 @@ this file. Usage: (let ((body (macroexp-progn (use-package-process-keywords name args* - (and use-package-always-defer '(:deferred t)))))) + (and use-package-always-defer (list :deferred t)))))) (if use-package-debug (display-buffer (save-current-buffer From 71057bc20f2170f2a1250caa949201297dfa8dde Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sun, 6 Sep 2015 22:28:50 -0400 Subject: [PATCH 236/606] use-package-as-string: use noerror parameter --- lisp/use-package/use-package.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index ffe2dac3e46..dd1e3426993 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -212,8 +212,8 @@ convert it to a string and return that." "Return a form which will load or require NAME depending on whether it's a string or symbol." (if (stringp name) - `(load ,name 'noerror) - `(require ',name nil 'noerror))) + `(load ,name ',noerror) + `(require ',name nil ',noerror))) (defun use-package-expand (name label form) "FORM is a list of forms, so `((foo))' if only `foo' is being called." From 79c38c5184e174c11922ed59568e1070201112f7 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sun, 17 Jul 2016 22:28:25 -0400 Subject: [PATCH 237/606] Fix declare-function call: FILE must be a string --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index dd1e3426993..f81b64a02c7 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -46,7 +46,7 @@ (eval-when-compile (require 'cl)) (eval-when-compile (require 'regexp-opt)) -(declare-function package-installed-p 'package) +(declare-function package-installed-p "package") (defgroup use-package nil "A use-package declaration for simplifying your `.emacs'." From 5053f75e0080b1e56d2e8a913f1621e48d684a0d Mon Sep 17 00:00:00 2001 From: Matthew Feinberg Date: Thu, 21 Jul 2016 08:38:30 -0400 Subject: [PATCH 238/606] Make pin and ensure compatible `:pin` does not work with `:ensure`, because it doesn't add the package to package-pinned-packages until after reading the package archive contents. This change causes the package archive contents to be reread if the package is pinned and `:ensure` is being used. Copyright-paperwork-exempt: yes --- lisp/use-package/use-package.el | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index f81b64a02c7..92c35a42950 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -500,6 +500,8 @@ manually updated package." (defun use-package-ensure-elpa (package &optional no-refresh) (if (package-installed-p package) t + (if (and (not no-refresh) (assoc package package-pinned-packages)) + (package-read-all-archive-contents)) (if (or (assoc package package-archive-contents) no-refresh) (package-install package) (progn From 4629e86240a7494df77009a8925752c9a90e8a10 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 22 Jul 2016 11:23:10 -0700 Subject: [PATCH 239/606] Remove the use of a tab --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 92c35a42950..a2f9883a110 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -298,7 +298,7 @@ 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 p (plist-put p (car plist) (nth 1 plist)))) (setq plist (cddr plist))) p)) From ef0cbfdc7332708587827f5fc7181e24d4f5af4d Mon Sep 17 00:00:00 2001 From: Mike Appleby Date: Sun, 14 Aug 2016 22:43:36 -0500 Subject: [PATCH 240/606] Ensure package-pinned-packages is bound before referencing it Add a bound-and-true-p guard to package-pinned-packages before referencing it in use-package-ensure-elpa. Package pinning was introduced in Emacs 24.4, and hence package-pinned-packages in unbound by default in earlier versions. Relevant commits: 72452b5 Merge pull request https://github.com/jwiegley/use-package/issues/367 from ketbra/master 5053f75 Make pin and ensure compatible Fixes https://github.com/jwiegley/use-package/issues/375 Copyright-paperwork-exempt: yes --- lisp/use-package/use-package.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index a2f9883a110..427945ff5b0 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -500,7 +500,8 @@ manually updated package." (defun use-package-ensure-elpa (package &optional no-refresh) (if (package-installed-p package) t - (if (and (not no-refresh) (assoc package package-pinned-packages)) + (if (and (not no-refresh) + (assoc package (bound-and-true-p package-pinned-packages))) (package-read-all-archive-contents)) (if (or (assoc package package-archive-contents) no-refresh) (package-install package) From fc7fc42f13549fa78c1829c2e3ce05dea5019a6c Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 17 Oct 2016 16:40:29 -0700 Subject: [PATCH 241/606] Bump version to 2.3 --- lisp/use-package/use-package.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 427945ff5b0..4928ece0b0d 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -5,8 +5,8 @@ ;; Author: John Wiegley ;; Maintainer: John Wiegley ;; Created: 17 Jun 2012 -;; Modified: 6 Jul 2016 -;; Version: 2.2 +;; Modified: 17 Oct 2016 +;; Version: 2.3 ;; Package-Requires: ((bind-key "1.0") (diminish "0.44")) ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package From 5ed9a6b5a5dad3563a4aeab0fe3b79f92b3d59d8 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Thu, 26 May 2016 15:00:56 -0400 Subject: [PATCH 242/606] Remove obsolete mplist tests The mplist functions were removed in the 2.0 refactoring (4ae584f3ff0e9bda05420ec3b8598e59374b0899). --- test/lisp/use-package/use-package-tests.el | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 0644a5ee493..0cd389b20aa 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -25,24 +25,6 @@ (require 'ert) (require 'use-package) -(ert-deftest use-package-mplist-get () - (let ((mplist '(:foo bar baz bal :blob plap plup :blam)) - (tests '((:foo . (bar baz bal)) - (:blob . (plap plup)) - (:blam . t) - (:blow . nil)))) - (mapc (lambda (test) - (should - (equal - (use-package-mplist-get mplist - (car test)) - (cdr test)))) - tests))) - -(ert-deftest use-package-mplist-keys () - (should (equal (use-package-mplist-keys - '(:foo bar baz bal :blob plap plup :blam)) - '(:foo :blob :blam)))) ;; Local Variables: ;; indent-tabs-mode: nil From fc57b342991b94640d5ff565a47b5603adec0a6f Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Thu, 26 May 2016 15:08:32 -0400 Subject: [PATCH 243/606] Refactor pair normalizers; add tests for them This is not a pure refactoring, it also fixes a bug where :bind ([keysym] . "string") would actually bind keysym to nil (i.e., unbind it). It now binds to "string" as expected. --- lisp/use-package/use-package.el | 45 ++++++++++------------ test/lisp/use-package/use-package-tests.el | 21 ++++++++++ 2 files changed, 41 insertions(+), 25 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 4928ece0b0d..aeb39b4c343 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -681,47 +681,40 @@ manually updated package." ;; :bind, :bind* ;; -(defsubst use-package-is-sympair (x &optional allow-vector) - "Return t if X has the type (STRING . SYMBOL)." +(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) - (or (stringp (car x)) - (and allow-vector (vectorp (car x)))) - (symbolp (cdr x)))) - -(defsubst use-package-is-string-pair (x) - "Return t if X has the type (STRING . STRING)." - (and (consp x) - (stringp (car x)) - (stringp (cdr x)))) + (funcall car-pred (car x)) + (funcall cdr-pred (cdr x)))) (defun use-package-normalize-pairs - (name label arg &optional recursed allow-vector allow-string-cdrs) - "Normalize a list of string/symbol pairs. -If RECURSED is non-nil, recurse into sublists. -If ALLOW-VECTOR is non-nil, then the key to bind may specify a -vector of keys, as accepted by `define-key'. -If ALLOW-STRING-CDRS is non-nil, then the command name to bind to -may also be a string, as accepted by `define-key'." + (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 - ((or (stringp arg) (and allow-vector (vectorp arg))) + ((funcall key-pred arg) (list (cons arg (use-package-as-symbol name)))) - ((use-package-is-sympair arg allow-vector) + ((use-package-is-pair arg key-pred val-pred) (list arg)) ((and (not recursed) (listp arg) (listp (cdr arg))) (mapcar #'(lambda (x) (let ((ret (use-package-normalize-pairs - name label x t allow-vector allow-string-cdrs))) + key-pred val-pred name label x t))) (if (listp ret) (car ret) ret))) arg)) - ((and allow-string-cdrs (use-package-is-string-pair arg)) - (list arg)) (t arg))) (defun use-package-normalize-binder (name keyword args) (use-package-as-one (symbol-name keyword) args (lambda (label arg) - (use-package-normalize-pairs name label arg nil t t)))) + (use-package-normalize-pairs (lambda (k) (or (stringp k) (vectorp k))) + (lambda (b) (or (symbolp b) (stringp b))) + name label arg)))) (defalias 'use-package-normalize/:bind 'use-package-normalize-binder) (defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) @@ -809,7 +802,9 @@ deferred until the prefix key sequence is pressed." (defun use-package-normalize-mode (name keyword args) (use-package-as-one (symbol-name keyword) args - (apply-partially #'use-package-normalize-pairs name))) + (apply-partially #'use-package-normalize-pairs + #'stringp #'symbolp + name))) (defalias 'use-package-normalize/:interpreter 'use-package-normalize-mode) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 0cd389b20aa..aa9f542a803 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -25,6 +25,27 @@ (require 'ert) (require 'use-package) +(ert-deftest use-package-normalize-binder () + (let ((good-values '(:map map-sym + ("str" . sym) ("str" . "str") + ([vec] . sym) ([vec] . "str")))) + (should (equal (use-package-normalize-binder + 'foopkg :bind good-values) + good-values))) + (should-error (use-package-normalize-binder + 'foopkg :bind '("foo" . 99))) + (should-error (use-package-normalize-binder + 'foopkg :bind '(99 . sym)))) + +(ert-deftest use-package-normalize-mode () + (should (equal (use-package-normalize-mode 'foopkg :mode '(".foo")) + '((".foo" . foopkg)))) + (should (equal (use-package-normalize-mode 'foopkg :mode '(".foo" ".bar")) + '((".foo" . foopkg) (".bar" . foopkg)))) + (should (equal (use-package-normalize-mode 'foopkg :mode '((".foo" ".bar"))) + '((".foo" . foopkg) (".bar" . foopkg)))) + (should (equal (use-package-normalize-mode 'foopkg :mode '((".foo" . foo) (".bar" . bar))) + '((".foo" . foo) (".bar" . bar))))) ;; Local Variables: ;; indent-tabs-mode: nil From 65c7b42a14c5ad42d4b6c6e6547c793e0ccbfe80 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Thu, 26 May 2016 15:09:46 -0400 Subject: [PATCH 244/606] Don't allow nil as a mode function This means (use-package foopkg :mode (".foo")) will add (".foo" . foopkg) into auto-mode-alist instead of the broken (".foo" . nil), this is more consistent with the behaviour of (use-package foopkg :mode (".foo" ".bar")). --- lisp/use-package/use-package.el | 2 +- test/lisp/use-package/use-package-tests.el | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index aeb39b4c343..96137c3c78d 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -803,7 +803,7 @@ deferred until the prefix key sequence is pressed." (defun use-package-normalize-mode (name keyword args) (use-package-as-one (symbol-name keyword) args (apply-partially #'use-package-normalize-pairs - #'stringp #'symbolp + #'stringp (lambda (m) (and (not (null m)) (symbolp m))) name))) (defalias 'use-package-normalize/:interpreter 'use-package-normalize-mode) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index aa9f542a803..d3deef995b1 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -44,6 +44,8 @@ '((".foo" . foopkg) (".bar" . foopkg)))) (should (equal (use-package-normalize-mode 'foopkg :mode '((".foo" ".bar"))) '((".foo" . foopkg) (".bar" . foopkg)))) + (should (equal (use-package-normalize-mode 'foopkg :mode '((".foo"))) + '((".foo" . foopkg)))) (should (equal (use-package-normalize-mode 'foopkg :mode '((".foo" . foo) (".bar" . bar))) '((".foo" . foo) (".bar" . bar))))) From 9688d2f64bd01b86a98ccd87138e6fc0a345e62b Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Fri, 5 Aug 2016 18:43:34 -0400 Subject: [PATCH 245/606] Don't allow implicit package name arg for binders It's unlikely that (use-package foopkg :bind "") intendes to bind to 'foopkg command. --- lisp/use-package/use-package.el | 4 ++++ test/lisp/use-package/use-package-tests.el | 2 ++ 2 files changed, 6 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 96137c3c78d..f99a3767777 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -712,6 +712,10 @@ If RECURSED is non-nil, recurse into sublists." (defun use-package-normalize-binder (name keyword args) (use-package-as-one (symbol-name keyword) args (lambda (label arg) + (unless (consp arg) + (use-package-error + (concat label " a ( . )" + " or list of these"))) (use-package-normalize-pairs (lambda (k) (or (stringp k) (vectorp k))) (lambda (b) (or (symbolp b) (stringp b))) name label arg)))) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index d3deef995b1..00682e9e0fc 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -32,6 +32,8 @@ (should (equal (use-package-normalize-binder 'foopkg :bind good-values) good-values))) + (should-error (use-package-normalize-binder + 'foopkg :bind '("foo"))) (should-error (use-package-normalize-binder 'foopkg :bind '("foo" . 99))) (should-error (use-package-normalize-binder From c15c616eb16b572cfb4495bd71c2909be243c75c Mon Sep 17 00:00:00 2001 From: Philipp Stephani Date: Mon, 31 Oct 2016 18:16:50 +0100 Subject: [PATCH 246/606] =?UTF-8?q?Remove=20tests,=20which=20don=E2=80=99t?= =?UTF-8?q?=20work?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/jwiegley/use-package/issues/399 --- test/lisp/use-package/use-package-tests.el | 52 ---------------------- 1 file changed, 52 deletions(-) delete mode 100644 test/lisp/use-package/use-package-tests.el diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el deleted file mode 100644 index 0644a5ee493..00000000000 --- a/test/lisp/use-package/use-package-tests.el +++ /dev/null @@ -1,52 +0,0 @@ -;;; use-package-tests.el --- Tests for use-package.el - -;; This program is free software; you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 2, or (at -;; your option) any later version. - -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; - - -;;; Code: - -(require 'ert) -(require 'use-package) - -(ert-deftest use-package-mplist-get () - (let ((mplist '(:foo bar baz bal :blob plap plup :blam)) - (tests '((:foo . (bar baz bal)) - (:blob . (plap plup)) - (:blam . t) - (:blow . nil)))) - (mapc (lambda (test) - (should - (equal - (use-package-mplist-get mplist - (car test)) - (cdr test)))) - tests))) - -(ert-deftest use-package-mplist-keys () - (should (equal (use-package-mplist-keys - '(:foo bar baz bal :blob plap plup :blam)) - '(:foo :blob :blam)))) - -;; Local Variables: -;; indent-tabs-mode: nil -;; no-byte-compile: t -;; no-update-autoloads: t -;; End: -;;; use-package-tests.el ends here From baa9e25a6bbccf1a213e81beab76520b0d8d1e31 Mon Sep 17 00:00:00 2001 From: Philipp Stephani Date: Mon, 31 Oct 2016 18:22:03 +0100 Subject: [PATCH 247/606] Declare package-read-all-archive-contents Fixes https://github.com/jwiegley/use-package/issues/398 --- lisp/use-package/use-package.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 4928ece0b0d..fb92010eaa5 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -47,6 +47,7 @@ (eval-when-compile (require 'regexp-opt)) (declare-function package-installed-p "package") +(declare-function package-read-all-archive-contents "package" ()) (defgroup use-package nil "A use-package declaration for simplifying your `.emacs'." From aad07daa8d9507f216946e68858f31240afadb20 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" Date: Fri, 16 Dec 2016 08:50:05 +0000 Subject: [PATCH 248/606] Increase :preface priority Reconcile order of `use-package-keywords' with the README description of `:preface' as occurring before everything but `:disabled'. --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index fb92010eaa5..34d9e727c99 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -126,6 +126,7 @@ the user specified." (defcustom use-package-keywords '(:disabled + :preface :pin :ensure :if @@ -133,7 +134,6 @@ the user specified." :unless :requires :load-path - :preface :no-require :bind :bind* From 134ecb3c883c51e19564813bf6227e3686c30ee3 Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Sat, 17 Dec 2016 15:26:15 +0100 Subject: [PATCH 249/606] Support outline-minor-mode In "use-package.el" prefix headings with ";;;" instead of just ";;". In "bind-key.el" add the missing ";;; Code:" heading. In both libraries set `outline-regexp' to an appropriate value. --- lisp/use-package/bind-key.el | 3 ++ lisp/use-package/use-package.el | 52 +++++++++++++++++---------------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 995e4816ff4..6564a263929 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -91,6 +91,8 @@ ;; 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) @@ -407,6 +409,7 @@ function symbol (unquoted)." (provide 'bind-key) ;; Local Variables: +;; outline-regexp: ";;;\\(;* [^\s\t\n]\\|###autoload\\)\\|(" ;; indent-tabs-mode: nil ;; End: diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index fb92010eaa5..62b87cbc667 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -194,7 +194,7 @@ Must be set before loading use-package." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; Utility functions +;;; Utility functions ;; (defun use-package-as-symbol (string-or-symbol) @@ -351,12 +351,12 @@ This is in contrast to merely setting it to 0." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; Keyword processing +;;; Keyword processing ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; Normalization functions +;;; Normalization functions ;; (defun use-package-normalize-plist (name input) @@ -414,7 +414,7 @@ next value for the STATE." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :pin +;;; :pin ;; (defun use-package-only-one (label args f) @@ -484,7 +484,7 @@ manually updated package." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :ensure +;;; :ensure ;; (defvar package-archive-contents) (defun use-package-normalize/:ensure (name keyword args) @@ -527,7 +527,7 @@ manually updated package." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :if, :when and :unless +;;; :if, :when and :unless ;; (defsubst use-package-normalize-value (label arg) @@ -558,7 +558,7 @@ manually updated package." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :requires +;;; :requires ;; (defun use-package-as-one (label args f) @@ -601,7 +601,7 @@ manually updated package." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :load-path +;;; :load-path ;; (defun use-package-normalize-paths (label arg &optional recursed) @@ -635,7 +635,7 @@ manually updated package." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :no-require +;;; :no-require ;; (defun use-package-normalize-predicate (name keyword args) @@ -652,7 +652,7 @@ manually updated package." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :preface +;;; :preface ;; (defun use-package-normalize-form (label args) @@ -679,7 +679,7 @@ manually updated package." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :bind, :bind* +;;; :bind, :bind* ;; (defsubst use-package-is-sympair (x &optional allow-vector) @@ -748,7 +748,7 @@ may also be a string, as accepted by `define-key'." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :bind-keymap, :bind-keymap* +;;; :bind-keymap, :bind-keymap* ;; (defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder) @@ -805,7 +805,7 @@ deferred until the prefix key sequence is pressed." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :interpreter +;;; :interpreter ;; (defun use-package-normalize-mode (name keyword args) @@ -828,7 +828,7 @@ deferred until the prefix key sequence is pressed." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :mode +;;; :mode ;; (defalias 'use-package-normalize/:mode 'use-package-normalize-mode) @@ -847,7 +847,7 @@ deferred until the prefix key sequence is pressed." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :commands +;;; :commands ;; (defalias 'use-package-normalize/:commands 'use-package-normalize-symlist) @@ -861,7 +861,7 @@ deferred until the prefix key sequence is pressed." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :defines +;;; :defines ;; (defalias 'use-package-normalize/:defines 'use-package-normalize-symlist) @@ -872,7 +872,7 @@ deferred until the prefix key sequence is pressed." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :functions +;;; :functions ;; (defalias 'use-package-normalize/:functions 'use-package-normalize-symlist) @@ -891,7 +891,7 @@ deferred until the prefix key sequence is pressed." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :defer +;;; :defer ;; (defalias 'use-package-normalize/:defer 'use-package-normalize-predicate) @@ -925,7 +925,7 @@ deferred until the prefix key sequence is pressed." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :after +;;; :after ;; (defalias 'use-package-normalize/:after 'use-package-normalize-symlist) @@ -951,7 +951,7 @@ deferred until the prefix key sequence is pressed." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :demand +;;; :demand ;; (defalias 'use-package-normalize/:demand 'use-package-normalize-predicate) @@ -962,7 +962,7 @@ deferred until the prefix key sequence is pressed." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :init +;;; :init ;; (defalias 'use-package-normalize/:init 'use-package-normalize-forms) @@ -982,7 +982,7 @@ deferred until the prefix key sequence is pressed." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :config +;;; :config ;; (defalias 'use-package-normalize/:config 'use-package-normalize-forms) @@ -1017,7 +1017,8 @@ deferred until the prefix key sequence is pressed." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :diminish +;;; :diminish +;; (defun use-package-normalize-diminish (name label arg &optional recursed) "Normalize the arguments to diminish down to a list of one of two forms: @@ -1055,7 +1056,7 @@ deferred until the prefix key sequence is pressed." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; :delight +;;; :delight ;; (defun use-package-normalize/:delight (name keyword args) @@ -1081,7 +1082,7 @@ deferred until the prefix key sequence is pressed." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; The main macro +;;; The main macro ;; ;;;###autoload @@ -1189,6 +1190,7 @@ this file. Usage: (provide 'use-package) ;; Local Variables: +;; outline-regexp: ";;;\\(;* [^\s\t\n]\\|###autoload\\)\\|(" ;; indent-tabs-mode: nil ;; End: From 75e0cd93c53beff2abe81b8e2f0bd25d9098f078 Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Sun, 18 Dec 2016 15:47:36 +0100 Subject: [PATCH 250/606] Delay decision whether to use eval-after-load until run-time Just because a keymap variable is bound at macro-expansion-time doesn't mean that it must be bound at run-time too. Change `bind-keys-form', which is used by `bind-keys' and other macros, to return a form which delays the decision on whether to wrap the binding forms with `eval-after-load' until run-time. Fixes https://github.com/jwiegley/use-package/issues/378. --- lisp/use-package/bind-key.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 995e4816ff4..35a4e3c6655 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -241,9 +241,9 @@ function symbol (unquoted)." (cl-flet ((wrap (map bindings) (if (and map pkg (not (eq map 'global-map))) - (if (boundp map) - bindings - `((eval-after-load + `((if (boundp ',map) + (progn ,@bindings) + (eval-after-load ,(if (symbolp pkg) `',pkg pkg) '(progn ,@bindings)))) bindings))) From ad8094c22d9a1bfbc1ad19bbbe3c164d1dae6850 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 22 Dec 2016 09:02:52 -0800 Subject: [PATCH 251/606] Add new customization option `use-package-always-demand` This is equivalent to adding `:demand t` to all `use-package` declarations, and has the same semantics as doing so (meaning it can be overridden locally using `:defer t` in a declaration). Fixes https://github.com/jwiegley/use-package/issues/423 --- lisp/use-package/use-package.el | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 29855044241..cfff54579bc 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -80,6 +80,11 @@ The check is performed by looking for the module using `locate-library'." :type 'boolean :group 'use-package) +(defcustom use-package-always-demand nil + "If non-nil, assume `:demand t` unless `:defer t` is given." + :type 'boolean + :group 'use-package) + (defcustom use-package-always-ensure nil "Treat every package as though it had specified `:ensure SEXP`." :type 'sexp @@ -1171,7 +1176,10 @@ this file. Usage: (let ((body (macroexp-progn - (use-package-process-keywords name args* + (use-package-process-keywords name + (if use-package-always-demand + (append args* '(:demand t)) + args*) (and use-package-always-defer (list :deferred t)))))) (if use-package-debug (display-buffer From e853355714254d76691f97ec51c4980eff85c49a Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 15 Jan 2017 09:03:05 -0700 Subject: [PATCH 252/606] Add use-package-ensure-function This allows the user to customize the :ensure keyword by using a different package manager than package.el. --- lisp/use-package/use-package.el | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index cfff54579bc..469872b94db 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -182,6 +182,16 @@ Must be set before loading use-package." :type 'boolean :group 'use-package) +(defcustom use-package-ensure-function 'use-package-ensure-elpa + "Function that ensures a package is installed. +This function is called with one argument, the package name as a +symbol, by the `:ensure' keyword. + +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) + (when use-package-enable-imenu-support ;; Not defined in Emacs 24 (defvar lisp-mode-symbol-regexp @@ -504,6 +514,7 @@ manually updated package." "(an unquoted symbol name)"))))))) (defun use-package-ensure-elpa (package &optional no-refresh) + (require 'package) (if (package-installed-p package) t (if (and (not no-refresh) @@ -518,9 +529,8 @@ manually updated package." (defun use-package-handler/:ensure (name keyword ensure rest state) (let* ((body (use-package-process-keywords name rest state)) (package-name (or (and (eq ensure t) (use-package-as-symbol name)) ensure)) - (ensure-form (if package-name - `(progn (require 'package) - (use-package-ensure-elpa ',package-name))))) + (ensure-form (when package-name + `(,use-package-ensure-function ',package-name)))) ;; We want to avoid installing packages when the `use-package' ;; macro is being macro-expanded by elisp completion (see ;; `lisp--local-variables'), but still do install packages when From 3dec23c0860ad297436b9b71b221491ae3790cce Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 16 Jan 2017 13:47:31 -0800 Subject: [PATCH 253/606] Add use-package-defaults Previously, the :config, :ensure, and :pin keywords had default values (dependent on the values of the use-package-always-ensure and use-package-always-pin). This change allows the user to customize the default values used for those keywords, and add default values for their own keywords in a non-hacky way. This functionality would be useful for (as an example) the quelpa-use-package package, which needs to use an advice to override the functionality of :ensure. The same problem prevents adding a use-package-always-quelpa variable in any reasonable way, without a way to customize the default values of keywords. --- lisp/use-package/use-package.el | 52 ++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 469872b94db..4f5c3fa5100 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -192,6 +192,20 @@ The default value uses package.el to install the package." (function :tag "Custom")) :group 'use-package) +(defcustom use-package-defaults + '((:config '(t) t) + (:ensure use-package-always-ensure use-package-always-ensure) + (:pin use-package-always-pin use-package-always-pin)) + "Alist of default values for `use-package' keywords. +Each entry in the alist is a list of three elements. The first +element is the `use-package' keyword and the second is a form +that can be evaluated to get the default value. 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." + :type '(repeat (list symbol sexp sexp))) + (when use-package-enable-imenu-support ;; Not defined in Emacs 24 (defvar lisp-mode-symbol-regexp @@ -1153,43 +1167,41 @@ this file. Usage: :pin Pin the package to an archive." (declare (indent 1)) (unless (member :disabled args) - (let* ((name-symbol (if (stringp name) (intern name) name)) - (args0 (use-package-plist-maybe-put - (use-package-normalize-plist name args) - :config '(t))) - (args* (use-package-sort-keywords - (if use-package-always-ensure - (use-package-plist-maybe-put - args0 :ensure use-package-always-ensure) - args0))) - (args* (use-package-sort-keywords - (if use-package-always-pin - (use-package-plist-maybe-put - args* :pin use-package-always-pin) - args*)))) + (let ((name-symbol (if (stringp name) (intern name) name)) + (args (use-package-normalize-plist name args))) + (let ((first-spec (car use-package-defaults)) + (rest-specs (cdr use-package-defaults))) + (when (eval (nth 2 first-spec)) + (setq args (use-package-plist-maybe-put + args (nth 0 first-spec) (eval (nth 1 first-spec))))) + (dolist (spec rest-specs) + (when (eval (nth 2 spec)) + (setq args (use-package-sort-keywords + (use-package-plist-maybe-put + args (nth 0 spec) (eval (nth 1 spec)))))))) ;; When byte-compiling, pre-load the package so all its symbols are in ;; scope. (if (bound-and-true-p byte-compile-current-file) - (setq args* + (setq args (use-package-plist-cons - args* :preface + args :preface `(eval-when-compile ,@(mapcar #'(lambda (var) `(defvar ,var)) - (plist-get args* :defines)) + (plist-get args :defines)) (with-demoted-errors ,(format "Cannot load %s: %%S" name) ,(if (eq use-package-verbose 'debug) `(message "Compiling package %s" ',name-symbol)) - ,(unless (plist-get args* :no-require) + ,(unless (plist-get args :no-require) (use-package-load-name name))))))) (let ((body (macroexp-progn (use-package-process-keywords name (if use-package-always-demand - (append args* '(:demand t)) - args*) + (append args '(:demand t)) + args) (and use-package-always-defer (list :deferred t)))))) (if use-package-debug (display-buffer From 013425edeb1829f5d21514f77d41763347538b14 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 13 Feb 2017 10:33:11 -0800 Subject: [PATCH 254/606] Revert "Add use-package-defaults" This reverts commit 3dec23c0860ad297436b9b71b221491ae3790cce. --- lisp/use-package/use-package.el | 52 +++++++++++++-------------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 4f5c3fa5100..469872b94db 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -192,20 +192,6 @@ The default value uses package.el to install the package." (function :tag "Custom")) :group 'use-package) -(defcustom use-package-defaults - '((:config '(t) t) - (:ensure use-package-always-ensure use-package-always-ensure) - (:pin use-package-always-pin use-package-always-pin)) - "Alist of default values for `use-package' keywords. -Each entry in the alist is a list of three elements. The first -element is the `use-package' keyword and the second is a form -that can be evaluated to get the default value. 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." - :type '(repeat (list symbol sexp sexp))) - (when use-package-enable-imenu-support ;; Not defined in Emacs 24 (defvar lisp-mode-symbol-regexp @@ -1167,41 +1153,43 @@ this file. Usage: :pin Pin the package to an archive." (declare (indent 1)) (unless (member :disabled args) - (let ((name-symbol (if (stringp name) (intern name) name)) - (args (use-package-normalize-plist name args))) - (let ((first-spec (car use-package-defaults)) - (rest-specs (cdr use-package-defaults))) - (when (eval (nth 2 first-spec)) - (setq args (use-package-plist-maybe-put - args (nth 0 first-spec) (eval (nth 1 first-spec))))) - (dolist (spec rest-specs) - (when (eval (nth 2 spec)) - (setq args (use-package-sort-keywords - (use-package-plist-maybe-put - args (nth 0 spec) (eval (nth 1 spec)))))))) + (let* ((name-symbol (if (stringp name) (intern name) name)) + (args0 (use-package-plist-maybe-put + (use-package-normalize-plist name args) + :config '(t))) + (args* (use-package-sort-keywords + (if use-package-always-ensure + (use-package-plist-maybe-put + args0 :ensure use-package-always-ensure) + args0))) + (args* (use-package-sort-keywords + (if use-package-always-pin + (use-package-plist-maybe-put + args* :pin use-package-always-pin) + args*)))) ;; When byte-compiling, pre-load the package so all its symbols are in ;; scope. (if (bound-and-true-p byte-compile-current-file) - (setq args + (setq args* (use-package-plist-cons - args :preface + args* :preface `(eval-when-compile ,@(mapcar #'(lambda (var) `(defvar ,var)) - (plist-get args :defines)) + (plist-get args* :defines)) (with-demoted-errors ,(format "Cannot load %s: %%S" name) ,(if (eq use-package-verbose 'debug) `(message "Compiling package %s" ',name-symbol)) - ,(unless (plist-get args :no-require) + ,(unless (plist-get args* :no-require) (use-package-load-name name))))))) (let ((body (macroexp-progn (use-package-process-keywords name (if use-package-always-demand - (append args '(:demand t)) - args) + (append args* '(:demand t)) + args*) (and use-package-always-defer (list :deferred t)))))) (if use-package-debug (display-buffer From 8fa6e8823be90d605b46ab30f9242588cdeafeba Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 13 Feb 2017 12:48:24 -0800 Subject: [PATCH 255/606] Unrevert "Add use-package-defaults" This reverts commit 013425edeb1829f5d21514f77d41763347538b14. --- lisp/use-package/use-package.el | 52 ++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 469872b94db..4f5c3fa5100 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -192,6 +192,20 @@ The default value uses package.el to install the package." (function :tag "Custom")) :group 'use-package) +(defcustom use-package-defaults + '((:config '(t) t) + (:ensure use-package-always-ensure use-package-always-ensure) + (:pin use-package-always-pin use-package-always-pin)) + "Alist of default values for `use-package' keywords. +Each entry in the alist is a list of three elements. The first +element is the `use-package' keyword and the second is a form +that can be evaluated to get the default value. 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." + :type '(repeat (list symbol sexp sexp))) + (when use-package-enable-imenu-support ;; Not defined in Emacs 24 (defvar lisp-mode-symbol-regexp @@ -1153,43 +1167,41 @@ this file. Usage: :pin Pin the package to an archive." (declare (indent 1)) (unless (member :disabled args) - (let* ((name-symbol (if (stringp name) (intern name) name)) - (args0 (use-package-plist-maybe-put - (use-package-normalize-plist name args) - :config '(t))) - (args* (use-package-sort-keywords - (if use-package-always-ensure - (use-package-plist-maybe-put - args0 :ensure use-package-always-ensure) - args0))) - (args* (use-package-sort-keywords - (if use-package-always-pin - (use-package-plist-maybe-put - args* :pin use-package-always-pin) - args*)))) + (let ((name-symbol (if (stringp name) (intern name) name)) + (args (use-package-normalize-plist name args))) + (let ((first-spec (car use-package-defaults)) + (rest-specs (cdr use-package-defaults))) + (when (eval (nth 2 first-spec)) + (setq args (use-package-plist-maybe-put + args (nth 0 first-spec) (eval (nth 1 first-spec))))) + (dolist (spec rest-specs) + (when (eval (nth 2 spec)) + (setq args (use-package-sort-keywords + (use-package-plist-maybe-put + args (nth 0 spec) (eval (nth 1 spec)))))))) ;; When byte-compiling, pre-load the package so all its symbols are in ;; scope. (if (bound-and-true-p byte-compile-current-file) - (setq args* + (setq args (use-package-plist-cons - args* :preface + args :preface `(eval-when-compile ,@(mapcar #'(lambda (var) `(defvar ,var)) - (plist-get args* :defines)) + (plist-get args :defines)) (with-demoted-errors ,(format "Cannot load %s: %%S" name) ,(if (eq use-package-verbose 'debug) `(message "Compiling package %s" ',name-symbol)) - ,(unless (plist-get args* :no-require) + ,(unless (plist-get args :no-require) (use-package-load-name name))))))) (let ((body (macroexp-progn (use-package-process-keywords name (if use-package-always-demand - (append args* '(:demand t)) - args*) + (append args '(:demand t)) + args) (and use-package-always-defer (list :deferred t)))))) (if use-package-debug (display-buffer From 482c8e57289a1b465676fc5469d70856a5afda3c Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 13 Feb 2017 12:48:48 -0800 Subject: [PATCH 256/606] Fix use-package-defaults This patch should address issues https://github.com/jwiegley/use-package/issues/428 and https://github.com/jwiegley/use-package/issues/429. See https://github.com/jwiegley/use-package/issues/426 for discussion. In brief, the issue was that use-package-sort-keywords was not applied when the predicates in use-package-defaults did not return true, when it should have been applied unconditionally. --- lisp/use-package/use-package.el | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 4f5c3fa5100..bba24d923f5 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1169,16 +1169,12 @@ this file. Usage: (unless (member :disabled args) (let ((name-symbol (if (stringp name) (intern name) name)) (args (use-package-normalize-plist name args))) - (let ((first-spec (car use-package-defaults)) - (rest-specs (cdr use-package-defaults))) - (when (eval (nth 2 first-spec)) - (setq args (use-package-plist-maybe-put - args (nth 0 first-spec) (eval (nth 1 first-spec))))) - (dolist (spec rest-specs) - (when (eval (nth 2 spec)) - (setq args (use-package-sort-keywords + (dolist (spec use-package-defaults) + (setq args (use-package-sort-keywords + (if (eval (nth 2 spec)) (use-package-plist-maybe-put - args (nth 0 spec) (eval (nth 1 spec)))))))) + args (nth 0 spec) (eval (nth 1 spec))) + args)))) ;; When byte-compiling, pre-load the package so all its symbols are in ;; scope. From 61d6a8e449739e443f224e223c6187a37440ca6b Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 16 Feb 2017 11:33:29 -0800 Subject: [PATCH 257/606] Add autoload cookie for use-package-autoload-keymap Fixes https://github.com/jwiegley/use-package/issues/337 --- lisp/use-package/use-package.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index b20d149cb86..bb9fb4855ff 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -819,6 +819,7 @@ If RECURSED is non-nil, recurse into sublists." (defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder) (defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder) +;;;###autoload (defun use-package-autoload-keymap (keymap-symbol package override) "Loads PACKAGE and then binds the key sequence used to invoke this function to KEYMAP-SYMBOL. It then simulates pressing the From 87a8ff6d693f3cc79ea423ca8c8e0a60b0bc596c Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 16 Feb 2017 11:44:41 -0800 Subject: [PATCH 258/606] Return `t' after calling `eval-after-load' Fixes https://github.com/jwiegley/use-package/issues/174 --- lisp/use-package/use-package.el | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index bb9fb4855ff..733a6316647 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1070,8 +1070,10 @@ deferred until the prefix key sequence is pressed." (list t)))))) (if (plist-get state :deferred) (unless (or (null config-body) (equal config-body '(t))) - `((eval-after-load ,(if (symbolp name) `',name name) - ',(macroexp-progn config-body)))) + `((progn + (eval-after-load ,(if (symbolp name) `',name name) + ',(macroexp-progn config-body)) + t))) (use-package--with-elapsed-timer (format "Loading package %s" name) (if use-package-expand-minimally From f1fa65d7733ece85490d037775d73e1a3a4dae69 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 16 Feb 2017 12:03:59 -0800 Subject: [PATCH 259/606] :mode and :interpreter can now accept (rx ...) forms Fixes https://github.com/jwiegley/use-package/issues/204 --- lisp/use-package/use-package.el | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 733a6316647..c6387d7e1f1 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -427,6 +427,28 @@ This is in contrast to merely setting it to 0." ;;; Normalization functions ;; +(defun use-package-regex-p (re) + "Return t if RE is some regexp-like thing." + (cond + ((and (listp re) + (eq (car re) 'rx)) + t) + ((stringp re) + t) + (t + nil))) + +(defun use-package-normalize-regex (re) + "Given some regexp-like thing, resolve it down 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)))) + (defun use-package-normalize-plist (name input) "Given a pseudo-plist, normalize it to a regular plist." (unless (null input) @@ -877,7 +899,8 @@ deferred until the prefix key sequence is pressed." (defun use-package-normalize-mode (name keyword args) (use-package-as-one (symbol-name keyword) args (apply-partially #'use-package-normalize-pairs - #'stringp (lambda (m) (and (not (null m)) (symbolp m))) + #'use-package-regex-p + (lambda (m) (and (not (null m)) (symbolp m))) name))) (defalias 'use-package-normalize/:interpreter 'use-package-normalize-mode) @@ -886,6 +909,8 @@ deferred until the prefix key sequence is pressed." (let* (commands (form (mapcar #'(lambda (interpreter) (push (cdr interpreter) commands) + (setcar interpreter + (use-package-normalize-regex (car interpreter))) `(add-to-list 'interpreter-mode-alist ',interpreter)) arg))) (use-package-concat (use-package-process-keywords name @@ -905,6 +930,8 @@ deferred until the prefix key sequence is pressed." (let* (commands (form (mapcar #'(lambda (mode) (push (cdr mode) commands) + (setcar mode + (use-package-normalize-regex (car mode))) `(add-to-list 'auto-mode-alist ',mode)) arg))) (use-package-concat (use-package-process-keywords name From 0517689cf3bb55b034788d6427220bd42f8ca4b1 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 16 Feb 2017 13:48:05 -0800 Subject: [PATCH 260/606] Support multiple symbols passed to :after The following expressions are now permitted: foo ; load after foo is loaded foo bar ; load after both foo and bar are loaded :all foo bar ; same as previous :any foo bar ; load after either foo or bar is loaded :any (:all foo bar) baz ; more complex combinations... :any (:all foo bar) (:all baz wow) :all (:any foo bar) (:any baz wow) Fixes https://github.com/jwiegley/use-package/issues/283 --- lisp/use-package/use-package.el | 55 +++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index c6387d7e1f1..4b425242ed1 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -678,6 +678,22 @@ manually updated package." (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 + ((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)) + (defalias 'use-package-normalize/:requires 'use-package-normalize-symlist) (defun use-package-handler/:requires (name keyword requires rest state) @@ -1023,25 +1039,44 @@ deferred until the prefix key sequence is pressed." ;;; :after ;; -(defalias 'use-package-normalize/:after 'use-package-normalize-symlist) +(defalias 'use-package-normalize/:after 'use-package-normalize-recursive-symlist) -(defun use-package-require-after-load (features name) +(defun use-package-require-after-load (features) "Return form for after any of FEATURES require NAME." - `(progn - ,@(mapcar - (lambda (feat) - `(eval-after-load - (quote ,feat) - (quote (require (quote ,name) nil t)))) - features))) + (pcase features + ((and (pred symbolp) feat) + `(lambda (body) + (list 'eval-after-load (list 'quote ',feat) + (list 'quote body)))) + (`(,(or :or :any) . ,rest) + `(lambda (body) + (append (list 'progn) + (mapcar (lambda (form) + (funcall form body)) + (list ,@(use-package-require-after-load rest)))))) + (`(,(or :and :all) . ,rest) + `(lambda (body) + (let ((result body)) + (dolist (form (list ,@(use-package-require-after-load rest))) + (setq result (funcall form result))) + result))) + (`(,feat . ,rest) + (if rest + (cons (use-package-require-after-load feat) + (use-package-require-after-load rest)) + (list (use-package-require-after-load feat)))))) (defun use-package-handler/:after (name keyword arg rest state) (let ((body (use-package-process-keywords name rest (plist-put state :deferred t))) (name-string (use-package-as-string name))) + (if (and (consp arg) + (not (memq (car arg) '(:or :any :and :all)))) + (setq arg (cons :all arg))) (use-package-concat (when arg - (list (use-package-require-after-load arg name))) + (list (funcall (use-package-require-after-load arg) + `(require (quote ,name) nil t)))) body))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; From 45442561d3ec095b7fa244d3b2c80b9847baee99 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 18 Feb 2017 01:32:34 -0800 Subject: [PATCH 261/606] Revert "Return `t' after calling `eval-after-load'" This reverts commit 87a8ff6d693f3cc79ea423ca8c8e0a60b0bc596c. --- lisp/use-package/use-package.el | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 4b425242ed1..99646e2690a 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1132,10 +1132,8 @@ deferred until the prefix key sequence is pressed." (list t)))))) (if (plist-get state :deferred) (unless (or (null config-body) (equal config-body '(t))) - `((progn - (eval-after-load ,(if (symbolp name) `',name name) - ',(macroexp-progn config-body)) - t))) + `((eval-after-load ,(if (symbolp name) `',name name) + ',(macroexp-progn config-body)))) (use-package--with-elapsed-timer (format "Loading package %s" name) (if use-package-expand-minimally From 4e6115214b24b5e52fddcb53040045890d01f59a Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 8 Mar 2017 11:17:33 -0800 Subject: [PATCH 262/606] Extend capabilities of use-package-ensure-function Modify the expected API of `use-package-ensure-function' so that it is passed three arguments: the name of the package declared in the `use-package' form; the argument passed to `:ensure'; and the current `state' plist created by previous handlers. (Previously, it was only given a single argument, which was the argument passed to `:ensure', or the name of the package declared in the `use-package' form, if the former was `t'. This allows for more flexibility in the capabilities of the `use-package-ensure-function' implementation. For example, its behavior can change depending on the values of other keywords, if those keywords modify the `state' plist appropriately. --- lisp/use-package/use-package.el | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index f933ce2d936..2ef697201f8 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -566,24 +566,26 @@ manually updated package." (concat ":ensure wants an optional package name " "(an unquoted symbol name)"))))))) -(defun use-package-ensure-elpa (package &optional no-refresh) - (require 'package) - (if (package-installed-p package) - t - (if (and (not no-refresh) - (assoc package (bound-and-true-p package-pinned-packages))) - (package-read-all-archive-contents)) - (if (or (assoc package package-archive-contents) no-refresh) - (package-install package) - (progn - (package-refresh-contents) - (use-package-ensure-elpa package t))))) +(defun use-package-ensure-elpa (name ensure state &optional no-refresh) + (let ((package (or (and (eq ensure t) (use-package-as-symbol name)) + ensure))) + (when package + (require 'package) + (if (package-installed-p package) + t + (if (and (not no-refresh) + (assoc package (bound-and-true-p package-pinned-packages))) + (package-read-all-archive-contents)) + (if (or (assoc package package-archive-contents) no-refresh) + (package-install package) + (progn + (package-refresh-contents) + (use-package-ensure-elpa name ensure state t))))))) (defun use-package-handler/:ensure (name keyword ensure rest state) (let* ((body (use-package-process-keywords name rest state)) - (package-name (or (and (eq ensure t) (use-package-as-symbol name)) ensure)) - (ensure-form (when package-name - `(,use-package-ensure-function ',package-name)))) + (ensure-form `(,use-package-ensure-function + ',name ',ensure ',state))) ;; We want to avoid installing packages when the `use-package' ;; macro is being macro-expanded by elisp completion (see ;; `lisp--local-variables'), but still do install packages when From f6224b295622d5a7065a107b1323486fa9822387 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 8 Mar 2017 12:28:40 -0800 Subject: [PATCH 263/606] First cut at :defer-install keyword This new keyword, if provided along with a non-nil value, causes the action of :ensure to be deferred until "necessary". Package installation can be triggered by the user calling the new interactive function `use-package-install-deferred-package', or by the feature declared by the `use-package' form being required. This latter behavior seems to be the simplest way to make sure that package installation actually takes place when it needs to, but it requires that an advice be added to `require', which may be considered overly intrusive. (Also, it's generally considered bad practice for functions in Emacs to put advice on other functions in Emacs.) Thus it may make sense to add an option or function to explicitly enable this behavior, if there does not turn out to be a better way to accomplish deferred installation. Documentation has not been updated to reflect :defer-install yet. --- lisp/use-package/use-package.el | 85 +++++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 2ef697201f8..3d5c99919d6 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -133,6 +133,7 @@ the user specified." '(:disabled :preface :pin + :defer-install :ensure :if :when @@ -550,6 +551,75 @@ manually updated package." (push pin-form body)) ; or else wait until runtime. body)) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; :defer-install +;; + +(defvar use-package--deferred-packages (make-hash-table) + "Hash mapping packages to forms which install them. +If `use-package' needs to install one of the named packages, it +will evaluate the corresponding form to do so. + +The keys are not actually symbols naming packages, but rather +symbols naming the features which are the names of \"packages\" +required by `use-package' forms. Since +`use-package-ensure-function' could be set to anything, it is +actually impossible for `use-package' to determine what package +is supposed to provide the feature being ensured just based on +the value of `:ensure'. The values are unevaluated Lisp forms. ") + +(defun use-package-install-deferred-package + (name &optional no-prompt) + "Install a package whose installation has been deferred. +NAME should be a symbol naming a package (actually, a feature). +The user is prompted for confirmation first, unless NO-PROMPT is +non-nil." + (interactive + (let ((packages nil)) + (maphash (lambda (package info) + (push package packages)) + use-package--deferred-packages) + (if packages + (list + (completing-read + "Select package: " + packages + nil + 'require-match) + 'no-prompt) + (user-error "No packages with deferred installation")))) + (when (or no-prompt + (y-or-n-p (format "Install package %S? " name))) + (eval (gethash name use-package--deferred-packages)) + (let ((features nil)) + (maphash (lambda (feature package) + (when (eq package name) + (push feature features))) + use-package--deferred-features) + (dolist (feature features) + (remhash feature use-package--deferred-features))) + (remhash name use-package--deferred-packages))) + +(defun use-package--require-advice (require feature &optional + filename noerror) + "Advice for `require' to support `:defer-install'. +If there is a package with deferred installation enabled that is +expected to provide the requested feature, that package is +installed first (if the user confirms it) and then the `require' +proceeds." + (when (gethash feature use-package--deferred-packages) + (use-package-install-deferred-package feature)) + (funcall require feature filename noerror)) + +(advice-add #'require :around #'use-package--require-advice) + +(defalias 'use-package-normalize/:defer-install 'use-package-normalize-test) + +(defun use-package-handler/:defer-install (name keyword defer rest state) + (use-package-process-keywords name rest + (plist-put state :defer-install defer))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; :ensure @@ -585,14 +655,21 @@ manually updated package." (defun use-package-handler/:ensure (name keyword ensure rest state) (let* ((body (use-package-process-keywords name rest state)) (ensure-form `(,use-package-ensure-function - ',name ',ensure ',state))) + ',name ',ensure ',state)) + (defer-install (plist-get state :defer-install))) ;; We want to avoid installing packages when the `use-package' ;; macro is being macro-expanded by elisp completion (see ;; `lisp--local-variables'), but still do install packages when ;; byte-compiling to avoid requiring `package' at runtime. - (if (bound-and-true-p byte-compile-current-file) - (eval ensure-form) ; Eval when byte-compiling, - (push ensure-form body)) ; or else wait until runtime. + (cond + (defer-install + (push + `(puthash ',name ',ensure-form + use-package--deferred-packages) + body)) + ((bound-and-true-p byte-compile-current-file) + (eval ensure-form)) ; Eval when byte-compiling, + (t (push ensure-form body))) ; or else wait until runtime. body)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; From a233f01ff64a3cb4002c3913883035bb1b299208 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 8 Mar 2017 18:16:31 -0800 Subject: [PATCH 264/606] Update docstring for use-package-ensure-function Now it properly reflects the API changes recently made. --- lisp/use-package/use-package.el | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 2ef697201f8..13ba63446c1 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -184,8 +184,12 @@ Must be set before loading use-package." (defcustom use-package-ensure-function 'use-package-ensure-elpa "Function that ensures a package is installed. -This function is called with one argument, the package name as a -symbol, by the `:ensure' keyword. +This function is called with three arguments: the name of the +package declared in the `use-package' form; the argument passed +to `:ensure'; 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'. The default value uses package.el to install the package." :type '(choice (const :tag "package.el" use-package-ensure-elpa) From 855a2afbe3167fe6bb9f1993fb825fd180605dd3 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 8 Mar 2017 19:00:37 -0800 Subject: [PATCH 265/606] Improve deferred installation mechanism This time around, I've gotten rid of the advice on `require' (that was never going to work) and instead made `use-package' try to handle loading the package at the appropriate time. In particular, when deferred installation is active, all the autoloads generated by `use-package' are not regular autoloads, but regular functions that will install the relevant package, require the relevant feature, and only then call the newly defined (autoloaded) function. Some smarter logic has been added to make sure things like `:demand' play nicely with the autoloading system; see the extensive comment in `use-package-handler/:defer-install' for more information on how that works. There was a section in `use-package-install-deferred-package' which referred to a nonexistent variable `use-package--deferred-features'; that has been removed. There is now, in addition to `use-package-ensure-function', a new variable called `use-package-pre-ensure-function'. This is intended for use by package managers which, unlike package.el, activate autoloads package-by-package instead of all at once. Even if a package is marked for deferred installation, the user would likely want its autoloads activated immediately *if* it was already installed. The logic for doing that can now be put in `use-package-pre-ensure-function'. --- lisp/use-package/use-package.el | 108 ++++++++++++++++++++++---------- 1 file changed, 76 insertions(+), 32 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 6695c19af64..8902b406712 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -197,6 +197,22 @@ The default value uses package.el to install the package." (function :tag "Custom")) :group 'use-package) +(defcustom use-package-pre-ensure-function 'ignore + "Function that is called upon installation deferral. +It is called with the same arguments as +`use-package-ensure-function', but only if installation has been +deferred. It is intended for package managers other than +package.el which might want to activate the autoloads of a +package immediately, if it's installed, but otherwise defer +installation until later (if `:defer-install' is specified). The +reason it is set to `ignore' by default is that package.el +activates the autoloads for all known packages at initialization +time, rather than one by one when the packages are actually +requested." + :type '(choice (const :tag "None" ignore) + (function :tag "Custom")) + :group 'use-package) + (defcustom use-package-defaults '((:config '(t) t) (:ensure use-package-always-ensure use-package-always-ensure) @@ -596,33 +612,23 @@ non-nil." (when (or no-prompt (y-or-n-p (format "Install package %S? " name))) (eval (gethash name use-package--deferred-packages)) - (let ((features nil)) - (maphash (lambda (feature package) - (when (eq package name) - (push feature features))) - use-package--deferred-features) - (dolist (feature features) - (remhash feature use-package--deferred-features))) (remhash name use-package--deferred-packages))) -(defun use-package--require-advice (require feature &optional - filename noerror) - "Advice for `require' to support `:defer-install'. -If there is a package with deferred installation enabled that is -expected to provide the requested feature, that package is -installed first (if the user confirms it) and then the `require' -proceeds." - (when (gethash feature use-package--deferred-packages) - (use-package-install-deferred-package feature)) - (funcall require feature filename noerror)) - -(advice-add #'require :around #'use-package--require-advice) - (defalias 'use-package-normalize/:defer-install 'use-package-normalize-test) (defun use-package-handler/:defer-install (name keyword defer rest state) (use-package-process-keywords name rest - (plist-put state :defer-install defer))) + ;; Just specifying `:defer-install' does not do anything; this + ;; sets up a marker so that if `:ensure' is specified as well then + ;; it knows to set up deferred installation. But then later, when + ;; `:config' is processed, it might turn out that `:demand' was + ;; specified as well, and the deferred installation needs to be + ;; run immediately. For this we need to know if the deferred + ;; installation was actually set up or not, so we need to set one + ;; marker value in `:defer-install', and then change it to a + ;; different value in `:ensure', if the first one is present. (The + ;; first marker is `:ensure', and the second is `:defer'.) + (plist-put state :defer-install (when defer :defer-install)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -657,7 +663,17 @@ proceeds." (use-package-ensure-elpa name ensure state t))))))) (defun use-package-handler/:ensure (name keyword ensure rest state) - (let* ((body (use-package-process-keywords name rest state)) + (let* ((body (use-package-process-keywords name rest + ;; Here we are conditionally updating the marker + ;; value for deferred installation; this will be + ;; checked later by `:config'. For more information + ;; see `use-package-handler/:defer-install'. + (if (eq (plist-get state :defer-install) + :defer-install) + (plist-put state :defer-install :ensure) + state))) + (pre-ensure-form `(,use-package-pre-ensure-function + ',name ',ensure ',state)) (ensure-form `(,use-package-ensure-function ',name ',ensure ',state)) (defer-install (plist-get state :defer-install))) @@ -670,7 +686,8 @@ proceeds." (push `(puthash ',name ',ensure-form use-package--deferred-packages) - body)) + body) + (push pre-ensure-form body)) ((bound-and-true-p byte-compile-current-file) (eval ensure-form)) ; Eval when byte-compiling, (t (push ensure-form body))) ; or else wait until runtime. @@ -1047,6 +1064,19 @@ deferred until the prefix key sequence is pressed." (defalias 'use-package-normalize/:defer 'use-package-normalize-predicate) +(defun use-package--autoload-with-deferred-install + (command package-name) + "Return a form defining an autoload supporting deferred install." + `(defun ,command (&rest args) + (if (bound-and-true-p use-package--recursive-autoload) + (use-package-error + (format "Autoloading failed to define function %S" + command)) + (use-package-install-deferred-package ',package-name) + (require ',package-name) + (let ((use-package--recursive-autoload t)) + (funcall ',command args))))) + (defun use-package-handler/:defer (name keyword arg rest state) (let ((body (use-package-process-keywords name rest (plist-put state :deferred t))) @@ -1061,15 +1091,24 @@ deferred until the prefix key sequence is pressed." ;; keep the byte-compiler happy. (apply #'nconc - (mapcar #'(lambda (command) - (when (not (stringp command)) - (append - `((unless (fboundp ',command) - (autoload #',command ,name-string nil t))) - (when (bound-and-true-p byte-compile-current-file) - `((eval-when-compile - (declare-function ,command ,name-string))))))) - (delete-dups (plist-get state :commands)))) + (mapcar + #'(lambda (command) + (when (not (stringp command)) + (append + `((unless (fboundp ',command) + ;; Here we are checking the marker value set in + ;; `use-package-handler/:ensure' to see if deferred + ;; installation is actually happening. See + ;; `use-package-handler/:defer-install' for more + ;; information. + ,(if (eq (plist-get state :defer-install) :ensure) + (use-package--autoload-with-deferred-install + ',command ',name) + `(autoload #',command ,name-string nil t)))) + (when (bound-and-true-p byte-compile-current-file) + `((eval-when-compile + (declare-function ,command ,name-string))))))) + (delete-dups (plist-get state :commands)))) body))) @@ -1155,6 +1194,11 @@ deferred until the prefix key sequence is pressed." (unless (or (null config-body) (equal config-body '(t))) `((eval-after-load ,(if (symbolp name) `',name name) ',(macroexp-progn config-body)))) + ;; Here we are checking the marker value for deferred + ;; installation set in `use-package-handler/:ensure'. See also + ;; `use-package-handler/:defer-install'. + (when (eq (plist-get state :defer-install) :ensure) + (use-package-install-deferred-package name 'no-prompt)) (use-package--with-elapsed-timer (format "Loading package %s" name) (if use-package-expand-minimally From 57e38152e143ef9c447c015c09e7f375737f4b8e Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Wed, 8 Mar 2017 20:05:15 -0800 Subject: [PATCH 266/606] Get :defer-install completely working, in theory * A quoting error has been fixed in `use-package-handler/:defer'. * `use-package-install-deferred-package' has been updated to return t if the package was actually installed, and nil otherwise. * The fake autoloads generated during deferred installation are doctored so Emacs does not think they were defined in the user's init-file. * The docstrings of the fake autoloads have been improved. * Arguments and interactivity are now correctly passed to the autoloaded function. * The autoload now skips requiring the feature and calling the original function if the user declines to install the package. This prevents unprofessional errors. --- lisp/use-package/use-package.el | 40 +++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 8902b406712..94f5229eca8 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -594,7 +594,7 @@ the value of `:ensure'. The values are unevaluated Lisp forms. ") "Install a package whose installation has been deferred. NAME should be a symbol naming a package (actually, a feature). The user is prompted for confirmation first, unless NO-PROMPT is -non-nil." +non-nil. Return t if the package is installed, nil otherwise." (interactive (let ((packages nil)) (maphash (lambda (package info) @@ -612,7 +612,8 @@ non-nil." (when (or no-prompt (y-or-n-p (format "Install package %S? " name))) (eval (gethash name use-package--deferred-packages)) - (remhash name use-package--deferred-packages))) + (remhash name use-package--deferred-packages) + t)) (defalias 'use-package-normalize/:defer-install 'use-package-normalize-test) @@ -1067,15 +1068,30 @@ deferred until the prefix key sequence is pressed." (defun use-package--autoload-with-deferred-install (command package-name) "Return a form defining an autoload supporting deferred install." - `(defun ,command (&rest args) - (if (bound-and-true-p use-package--recursive-autoload) - (use-package-error - (format "Autoloading failed to define function %S" - command)) - (use-package-install-deferred-package ',package-name) - (require ',package-name) - (let ((use-package--recursive-autoload t)) - (funcall ',command args))))) + `(let* ((load-list-item '(defun . ,command)) + (already-loaded (member load-list-item current-load-list))) + (defun ,command (&rest args) + "[Arg list not available until function definition is loaded.] + +\(fn ...)" + (interactive) + (if (bound-and-true-p use-package--recursive-autoload) + (use-package-error + (format "Autoloading failed to define function %S" + command)) + (when (use-package-install-deferred-package ',package-name) + (require ',package-name) + (let ((use-package--recursive-autoload t)) + (if (called-interactively-p 'any) + (call-interactively ',command) + (apply ',command args)))))) + ;; This prevents the user's init-file from being recorded as the + ;; definition location for the function before it is actually + ;; loaded. (Our goal is to leave the `current-load-list' + ;; unchanged, so we only remove the entry for this function if it + ;; was not already present.) + (unless already-loaded + (setq current-load-list (remove load-list-item current-load-list))))) (defun use-package-handler/:defer (name keyword arg rest state) (let ((body (use-package-process-keywords name rest @@ -1103,7 +1119,7 @@ deferred until the prefix key sequence is pressed." ;; information. ,(if (eq (plist-get state :defer-install) :ensure) (use-package--autoload-with-deferred-install - ',command ',name) + command name) `(autoload #',command ,name-string nil t)))) (when (bound-and-true-p byte-compile-current-file) `((eval-when-compile From ecc5fddda43aa9163c65e4f1cfe2cd538198b07a Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 18 Mar 2017 19:34:28 -0700 Subject: [PATCH 267/606] Various improvements for deferred installation --- lisp/use-package/use-package.el | 161 +++++++++++++++++++++----------- 1 file changed, 109 insertions(+), 52 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 94f5229eca8..0c2ee5b8b5d 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -185,21 +185,43 @@ Must be set before loading use-package." (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 +This function is called with four arguments: the name of the package declared in the `use-package' form; the argument passed -to `:ensure'; 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'. +to `:ensure'; the current `state' plist created by previous +handlers; and a keyword indicating the context in which the +installation is occurring. -The default value uses package.el to install the package." +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. + +Possible values for the context keyword are: + +:byte-compile - package installed during byte-compilation +:ensure - package installed normally by :ensure +:autoload - deferred installation triggered by an autoloaded + function +:after - deferred installation triggered by the loading of a + feature listed in the :after declaration +:config - deferred installation was specified at the same time + as :demand, so the installation was triggered + immediately +:unknown - context not provided + +Note that third-party code can provide other values for the +context keyword by calling `use-package-install-deferred-package' +with the appropriate value." :type '(choice (const :tag "package.el" use-package-ensure-elpa) (function :tag "Custom")) :group 'use-package) (defcustom use-package-pre-ensure-function 'ignore "Function that is called upon installation deferral. -It is called with the same arguments as +It is called immediately with the same arguments as `use-package-ensure-function', but only if installation has been deferred. It is intended for package managers other than package.el which might want to activate the autoloads of a @@ -577,9 +599,7 @@ manually updated package." ;; (defvar use-package--deferred-packages (make-hash-table) - "Hash mapping packages to forms which install them. -If `use-package' needs to install one of the named packages, it -will evaluate the corresponding form to do so. + "Hash mapping packages to data about their installation. The keys are not actually symbols naming packages, but rather symbols naming the features which are the names of \"packages\" @@ -587,14 +607,29 @@ required by `use-package' forms. Since `use-package-ensure-function' could be set to anything, it is actually impossible for `use-package' to determine what package is supposed to provide the feature being ensured just based on -the value of `:ensure'. The values are unevaluated Lisp forms. ") +the value of `:ensure'. -(defun use-package-install-deferred-package - (name &optional no-prompt) +Each value is a cons, with the car being the the value passed to +`:ensure' and the cdr being the `state' plist. See +`use-package-install-deferred-package' for information about how +these values are used to call `use-package-ensure-function'.") + +(defun use-package-install-deferred-package (name &optional context) "Install a package whose installation has been deferred. NAME should be a symbol naming a package (actually, a feature). -The user is prompted for confirmation first, unless NO-PROMPT is -non-nil. Return t if the package is installed, nil otherwise." +This is done by calling `use-package-ensure-function' is called +with four arguments: the key (NAME) and the two elements of the +cons in `use-package--deferred-packages' (the value passed to +`:ensure', and the `state' plist), and a keyword providing +information about the context in which the installation is +happening. (This defaults to `:unknown' but can be overridden by +providing CONTEXT.) + +Return t if the package is installed, nil otherwise. (This is +determined by the return value of `use-package-ensure-function'.) +If the package is installed, its entry is removed from +`use-package--deferred-packages'. If the package has no entry in +`use-package--deferred-packages', do nothing and return t." (interactive (let ((packages nil)) (maphash (lambda (package info) @@ -607,13 +642,16 @@ non-nil. Return t if the package is installed, nil otherwise." packages nil 'require-match) - 'no-prompt) + :interactive) (user-error "No packages with deferred installation")))) - (when (or no-prompt - (y-or-n-p (format "Install package %S? " name))) - (eval (gethash name use-package--deferred-packages)) - (remhash name use-package--deferred-packages) - t)) + (let ((spec (gethash name use-package--deferred-packages))) + (if spec + (when (funcall use-package-ensure-function + name (car spec) (cdr spec) + (or context :unknown)) + (remhash name use-package--deferred-packages) + t) + t))) (defalias 'use-package-normalize/:defer-install 'use-package-normalize-test) @@ -628,7 +666,7 @@ non-nil. Return t if the package is installed, nil otherwise." ;; installation was actually set up or not, so we need to set one ;; marker value in `:defer-install', and then change it to a ;; different value in `:ensure', if the first one is present. (The - ;; first marker is `:ensure', and the second is `:defer'.) + ;; first marker is `:defer-install', and the second is `:ensure'.) (plist-put state :defer-install (when defer :defer-install)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -647,21 +685,28 @@ non-nil. Return t if the package is installed, nil otherwise." (concat ":ensure wants an optional package name " "(an unquoted symbol name)"))))))) -(defun use-package-ensure-elpa (name ensure state &optional no-refresh) - (let ((package (or (and (eq ensure t) (use-package-as-symbol name)) +(defun use-package-ensure-elpa (name ensure state context &optional no-refresh) + (let ((package (or (when (eq ensure t) (use-package-as-symbol name)) ensure))) (when package (require 'package) - (if (package-installed-p package) - t - (if (and (not no-refresh) - (assoc package (bound-and-true-p package-pinned-packages))) - (package-read-all-archive-contents)) - (if (or (assoc package package-archive-contents) no-refresh) - (package-install package) + (or (package-installed-p package) + (not (or + ;; Contexts in which the confirmation prompt is + ;; bypassed. + (member context '(:byte-compile :ensure :config)) + (y-or-n-p (format "Install package %S?" name)))) (progn - (package-refresh-contents) - (use-package-ensure-elpa name ensure state t))))))) + (when (assoc package (bound-and-true-p package-pinned-packages)) + (package-read-all-archive-contents)) + (if (assoc package package-archive-contents) + (progn (package-install package) t) + (progn + (package-refresh-contents) + (when (assoc package (bound-and-true-p + package-pinned-packages)) + (package-read-all-archive-contents)) + (package-install package)))))))) (defun use-package-handler/:ensure (name keyword ensure rest state) (let* ((body (use-package-process-keywords name rest @@ -672,26 +717,28 @@ non-nil. Return t if the package is installed, nil otherwise." (if (eq (plist-get state :defer-install) :defer-install) (plist-put state :defer-install :ensure) - state))) - (pre-ensure-form `(,use-package-pre-ensure-function - ',name ',ensure ',state)) - (ensure-form `(,use-package-ensure-function - ',name ',ensure ',state)) - (defer-install (plist-get state :defer-install))) + state)))) ;; We want to avoid installing packages when the `use-package' ;; macro is being macro-expanded by elisp completion (see ;; `lisp--local-variables'), but still do install packages when ;; byte-compiling to avoid requiring `package' at runtime. (cond - (defer-install - (push - `(puthash ',name ',ensure-form - use-package--deferred-packages) - body) - (push pre-ensure-form body)) + ((plist-get state :defer-install) + (push + `(puthash ',name '(,ensure . ,state) + use-package--deferred-packages) + body) + (push `(,use-package-pre-ensure-function + ',name ',ensure ',state) + body)) ((bound-and-true-p byte-compile-current-file) - (eval ensure-form)) ; Eval when byte-compiling, - (t (push ensure-form body))) ; or else wait until runtime. + ;; Eval when byte-compiling, + (funcall use-package-ensure-function + name ensure state :byte-compile)) + ;; or else wait until runtime. + (t (push `(,use-package-ensure-function + ',name ',ensure ',state :ensure) + body))) body)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1079,7 +1126,8 @@ deferred until the prefix key sequence is pressed." (use-package-error (format "Autoloading failed to define function %S" command)) - (when (use-package-install-deferred-package ',package-name) + (when (use-package-install-deferred-package + ',package-name :autoload) (require ',package-name) (let ((use-package--recursive-autoload t)) (if (called-interactively-p 'any) @@ -1136,14 +1184,19 @@ deferred until the prefix key sequence is pressed." (defalias 'use-package-normalize/:after 'use-package-normalize-symlist) -(defun use-package-require-after-load (features name) +(defun use-package-require-after-load + (features name &optional deferred-install) "Return form for after any of FEATURES require NAME." `(progn ,@(mapcar (lambda (feat) `(eval-after-load (quote ,feat) - (quote (require (quote ,name) nil t)))) + ,(macroexp-progn + `(,@(when deferred-install + `((use-package-install-deferred-package + ',name :after))) + '(require ',name nil t))))) features))) (defun use-package-handler/:after (name keyword arg rest state) @@ -1152,7 +1205,11 @@ deferred until the prefix key sequence is pressed." (name-string (use-package-as-string name))) (use-package-concat (when arg - (list (use-package-require-after-load arg name))) + (list (use-package-require-after-load + ;; Here we are checking the marker value for deferred + ;; installation set in `use-package-handler/:ensure'. + ;; See also `use-package-handler/:defer-install'. + arg name (eq (plist-get state :defer-install) :ensure)))) body))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1214,7 +1271,7 @@ deferred until the prefix key sequence is pressed." ;; installation set in `use-package-handler/:ensure'. See also ;; `use-package-handler/:defer-install'. (when (eq (plist-get state :defer-install) :ensure) - (use-package-install-deferred-package name 'no-prompt)) + (use-package-install-deferred-package name 'no-prompt :config)) (use-package--with-elapsed-timer (format "Loading package %s" name) (if use-package-expand-minimally From b2e674de0a30c5961e7e31a8658b3eba9a229ba1 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 18 Mar 2017 20:00:53 -0700 Subject: [PATCH 268/606] Update docstring, installation prompt message --- lisp/use-package/use-package.el | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 0c2ee5b8b5d..45215eccdaa 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -221,16 +221,16 @@ with the appropriate value." (defcustom use-package-pre-ensure-function 'ignore "Function that is called upon installation deferral. -It is called immediately with the same arguments as -`use-package-ensure-function', but only if installation has been -deferred. It is intended for package managers other than -package.el which might want to activate the autoloads of a -package immediately, if it's installed, but otherwise defer -installation until later (if `:defer-install' is specified). The -reason it is set to `ignore' by default is that package.el -activates the autoloads for all known packages at initialization -time, rather than one by one when the packages are actually -requested." +It is called immediately with the first three arguments that +would be passed to `use-package-ensure-function' (the context +keyword is omitted), but only if installation has been deferred. +It is intended for package managers other than package.el which +might want to activate the autoloads of a package immediately, if +it's installed, but otherwise defer installation until later (if +`:defer-install' is specified). The reason it is set to `ignore' +by default is that package.el activates the autoloads for all +known packages at initialization time, rather than one by one +when the packages are actually requested." :type '(choice (const :tag "None" ignore) (function :tag "Custom")) :group 'use-package) @@ -695,7 +695,7 @@ If the package is installed, its entry is removed from ;; Contexts in which the confirmation prompt is ;; bypassed. (member context '(:byte-compile :ensure :config)) - (y-or-n-p (format "Install package %S?" name)))) + (y-or-n-p (format "Install package %S?" package)))) (progn (when (assoc package (bound-and-true-p package-pinned-packages)) (package-read-all-archive-contents)) From 9ad6f2ef1a6ab40ba756b712fac976ecc0e5cb67 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 19 Mar 2017 08:33:30 -0700 Subject: [PATCH 269/606] Fix :after keyword Commit [1] broke the functionality of :after (see [2]) due to an extraneous quote being added. [1]: bd2afa53c7580d23ed8008267b80e1834b6e6600 [2]: https://github.com/jwiegley/use-package/pull/433#issuecomment-287606553 --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 2943dafe6b0..c7d472e2eb4 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1270,7 +1270,7 @@ deferred until the prefix key sequence is pressed." `(,@(when (eq (plist-get state :defer-install) :ensure) `((use-package-install-deferred-package 'name :after))) - '(require (quote ,name) nil t)))))) + (require (quote ,name) nil t)))))) body))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; From bca84ee71ab707e5452cb89c8148541a31619741 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 26 Mar 2017 14:40:17 -0700 Subject: [PATCH 270/606] Add use-package-always-defer-install See https://github.com/jwiegley/use-package/pull/433#issuecomment-289317875 --- lisp/use-package/use-package.el | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 2943dafe6b0..56e1e342d0a 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -85,13 +85,18 @@ The check is performed by looking for the module using `locate-library'." :type 'boolean :group 'use-package) +(defcustom use-package-always-defer-install nil + "If non-nil, assume `:defer-install t` unless `:defer-install nil` is given." + :type 'boolean + :group 'use-package) + (defcustom use-package-always-ensure nil "Treat every package as though it had specified `:ensure SEXP`." :type 'sexp :group 'use-package) (defcustom use-package-always-pin nil - "Treat every package as though it had specified `:pin SYM." + "Treat every package as though it had specified `:pin SYM`." :type 'symbol :group 'use-package) @@ -238,6 +243,9 @@ when the packages are actually requested." (defcustom use-package-defaults '((:config '(t) t) (:ensure use-package-always-ensure use-package-always-ensure) + (:defer-install + use-package-always-defer-install + use-package-always-defer-install) (:pin use-package-always-pin use-package-always-pin)) "Alist of default values for `use-package' keywords. Each entry in the alist is a list of three elements. The first From d5d320e607e5b043aca42b087acd91a8e14d2e2f Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 2 Apr 2017 21:03:47 -0700 Subject: [PATCH 271/606] Don't mutilate keyword arguments in :bind The parsing logic in `use-package-normalize-pairs' is not designed to deal with keyword arguments. However, `use-package-normalize-pairs' is used to process the arguments to :bind, which can include keyword arguments. These keyword arguments are supposed to be passed untouched to the underlying `bind-keys' function, but there is a clause in `use-package-normalize-pairs' that replaces lists with their first element. Thus an invocation like: (use-package company :bind (:map company-active-map :filter (company-explicit-action-p) ("RET" . company-complete-selection))) Generates code like this: (bind-keys :map company-active-map :filter company-explicit-action-p ("RET" . company-complete-selection)) Which generates an error since `company-explicit-action-p' is now being referenced as a variable rather than a function. The proper solution is to refactor the logic that goes into parsing uses of :bind, but this commit adds a temporary patch to eliminate the above problem, while trying to be as reverse-compatible as possible. In particular it just inhibits the list-to-first-element transformation when the previous element processed was a keyword. --- lisp/use-package/use-package.el | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 8515ce2f376..440ffa02065 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -964,12 +964,15 @@ If RECURSED is non-nil, recurse into sublists." ((use-package-is-pair arg key-pred val-pred) (list arg)) ((and (not recursed) (listp arg) (listp (cdr arg))) - (mapcar #'(lambda (x) - (let ((ret (use-package-normalize-pairs - key-pred val-pred name label x t))) - (if (listp ret) - (car ret) - ret))) arg)) + (let ((last-item nil)) + (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-normalize-binder (name keyword args) From e5e335424c3455b06d8942f7cda2d17f04612713 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 3 Apr 2017 10:40:46 -0700 Subject: [PATCH 272/606] Add comment explaining keyword-argument patch --- lisp/use-package/use-package.el | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 440ffa02065..02a358c7145 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -969,6 +969,25 @@ If RECURSED is non-nil, recurse into sublists." (prog1 (let ((ret (use-package-normalize-pairs key-pred val-pred name label x t))) + ;; Currently, the handling of keyword + ;; arguments by `use-package' and `bind-key' + ;; is non-uniform and undocumented. As a + ;; result, `use-package-normalize-pairs' (as + ;; it is currently implemented) does not + ;; correctly handle the keyword-argument + ;; syntax of `bind-keys'. A permanent solution + ;; to this problem will require a careful + ;; consideration of the desired + ;; keyword-argument interface for + ;; `use-package' and `bind-key'. However, in + ;; the meantime, we have a quick patch to fix + ;; a serious bug in the handling of keyword + ;; arguments. Namely, the code below would + ;; normally unwrap lists that were passed as + ;; keyword arguments (for example, the + ;; `:filter' argument in `:bind') without + ;; the (not (keywordp last-item)) clause. See + ;; #447 for further discussion. (if (and (listp ret) (not (keywordp last-item))) (car ret) ret)) From a9ffffcee5c8047db5b00625790ab9d1b1eccc4b Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 4 Apr 2017 21:16:06 -0700 Subject: [PATCH 273/606] Make use-package-normalize-value handle nil better The previous version of `use-package-normalize-value', when passed nil, would return the list (symbol-value (quote nil)). This meant that keywords which used `use-package-normalize-value' or the higher-level normalizer `use-package-normalize-test' would get a non-nil argument (i.e. the above list) even when the user specified nil to the package. This had the concrete impact of making it so that :defer-install nil was treated as :defer-install t. --- lisp/use-package/use-package.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 02a358c7145..74f1f309436 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -778,7 +778,8 @@ If the package is installed, its entry is removed from (defsubst use-package-normalize-value (label arg) "Normalize a value." - (cond ((symbolp arg) + (cond ((null arg) nil) + ((symbolp arg) `(symbol-value ',arg)) ((functionp arg) `(funcall #',arg)) From 3823a9059e9eead000f1b7b79de7226ccaee65c3 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 7 May 2017 15:23:50 -0700 Subject: [PATCH 274/606] Fix quoting error in failed autoload message --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 74f1f309436..b6fecb9fe33 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1199,7 +1199,7 @@ deferred until the prefix key sequence is pressed." (if (bound-and-true-p use-package--recursive-autoload) (use-package-error (format "Autoloading failed to define function %S" - command)) + ',command)) (when (use-package-install-deferred-package ',package-name :autoload) (require ',package-name) From ec088b747a370462a00d61f3d49af21125edf7e5 Mon Sep 17 00:00:00 2001 From: David Leatherman Date: Mon, 22 May 2017 18:23:26 -0700 Subject: [PATCH 275/606] Protect against errors during package install If the network is missing and there is a new use-package with :ensure, startup would fail part of the way through due package.el being unable to reach the package repo. This will catch that error and report it while allowing startup to continue. Copyright-paperwork-exempt: yes --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index b6fecb9fe33..066a365deb5 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -726,7 +726,7 @@ If the package is installed, its entry is removed from ;; bypassed. (member context '(:byte-compile :ensure :config)) (y-or-n-p (format "Install package %S?" package)))) - (progn + (with-demoted-errors (format "Cannot load %s: %%S" name) (when (assoc package (bound-and-true-p package-pinned-packages)) (package-read-all-archive-contents)) (if (assoc package package-archive-contents) From ac4a3a4aa819732aa21340c9ae501ca6e02f5003 Mon Sep 17 00:00:00 2001 From: Joe Wreschnig Date: Thu, 15 Jun 2017 20:44:11 +0200 Subject: [PATCH 276/606] Add `:magic` and `:magic-fallback` keywords (issue) These keywords work equivalently to `:mode` or `:interpreter`, but for `magic-mode-alist` and `magic-fallback-mode-alist`. The handler function implementation is now passed a list to add to, and shared by all four of them. GitHub-reference: https://github.com/jwiegley/use-package/issues/469 --- lisp/use-package/use-package.el | 128 ++++++++++++++++++-------------- 1 file changed, 74 insertions(+), 54 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 066a365deb5..68d38d19b8c 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -152,6 +152,8 @@ the user specified." :bind-keymap* :interpreter :mode + :magic + :magic-fallback :commands :defines :functions @@ -1092,21 +1094,21 @@ deferred until the prefix key sequence is pressed." ;; (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 (lambda (m) (and (not (null m)) (symbolp m))) name))) -(defalias 'use-package-normalize/:interpreter 'use-package-normalize-mode) - -(defun use-package-handler/:interpreter (name keyword arg rest state) +(defun use-package-handle-mode (name alist arg rest state) + "Handle keywords which add regexp/mode pairs to an alist." (let* (commands - (form (mapcar #'(lambda (interpreter) - (push (cdr interpreter) commands) - (setcar interpreter - (use-package-normalize-regex (car interpreter))) - `(add-to-list 'interpreter-mode-alist ',interpreter)) arg))) + (form (mapcar #'(lambda (thing) + (push (cdr thing) commands) + (setcar thing + (use-package-normalize-regex (car thing))) + `(add-to-list ',alist ',thing)) arg))) (use-package-concat (use-package-process-keywords name (use-package-sort-keywords @@ -1114,6 +1116,11 @@ deferred until the prefix key sequence is pressed." (use-package-plist-append state :commands commands)) `((ignore ,@form))))) +(defalias 'use-package-normalize/:interpreter 'use-package-normalize-mode) + +(defun use-package-handler/:interpreter (name keyword arg rest state) + (use-package-handle-mode name 'interpreter-mode-alist arg rest state)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; :mode @@ -1122,18 +1129,27 @@ deferred until the prefix key sequence is pressed." (defalias 'use-package-normalize/:mode 'use-package-normalize-mode) (defun use-package-handler/:mode (name keyword arg rest state) - (let* (commands - (form (mapcar #'(lambda (mode) - (push (cdr mode) commands) - (setcar mode - (use-package-normalize-regex (car mode))) - `(add-to-list 'auto-mode-alist ',mode)) arg))) - (use-package-concat - (use-package-process-keywords name - (use-package-sort-keywords - (use-package-plist-maybe-put rest :defer t)) - (use-package-plist-append state :commands commands)) - `((ignore ,@form))))) + (use-package-handle-mode name 'auto-mode-alist arg rest state)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; :magic +;; + +(defalias 'use-package-normalize/:magic 'use-package-normalize-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) + +(defun use-package-handler/:magic-fallback (name keyword arg rest state) + (use-package-handle-mode name 'magic-fallback-mode-alist arg rest state)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -1455,47 +1471,51 @@ this file. Usage: (use-package package-name [:keyword [option]]...) -:init Code to run before PACKAGE-NAME has been loaded. -:config Code to run after PACKAGE-NAME has been loaded. Note that if - loading is deferred for any reason, this code does not execute - until the lazy load has occurred. -:preface Code to be run before everything except `:disabled'; this can - be used to define functions for use in `:if', or that should be - seen by the byte-compiler. +:init Code to run before PACKAGE-NAME has been loaded. +:config Code to run after PACKAGE-NAME has been loaded. Note that + if loading is deferred for any reason, this code does not + execute until the lazy load has occurred. +:preface Code to be run before everything except `:disabled'; this + can be used to define functions for use in `:if', or that + should be seen by the byte-compiler. -:mode Form to be added to `auto-mode-alist'. -:interpreter Form to be added to `interpreter-mode-alist'. +: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'. +:mode Form to be added to `auto-mode-alist'. +:interpreter Form to be added to `interpreter-mode-alist'. -:commands Define autoloads for commands that will be defined by the - package. This is useful if the package is being lazily loaded, - and you wish to conditionally call functions in your `:init' - block that are defined in the package. +:commands Define autoloads for commands that will be defined by the + package. This is useful if the package is being lazily + loaded, and you wish to conditionally call functions in your + `:init' block that are defined in the package. -:bind Bind keys, and define autoloads for the bound commands. -:bind* Bind keys, and define autoloads for the bound commands, - *overriding all minor mode bindings*. -:bind-keymap Bind a key prefix to an auto-loaded keymap defined in the - package. This is like `:bind', but for keymaps. -:bind-keymap* Like `:bind-keymap', but overrides all minor mode bindings +:bind Bind keys, and define autoloads for the bound commands. +:bind* Bind keys, and define autoloads for the bound commands, + *overriding all minor mode bindings*. +:bind-keymap Bind a key prefix to an auto-loaded keymap defined in the + package. This is like `:bind', but for keymaps. +:bind-keymap* Like `:bind-keymap', but overrides all minor mode bindings -:defer Defer loading of a package -- this is implied when using - `:commands', `:bind', `:bind*', `:mode' or `:interpreter'. - This can be an integer, to force loading after N seconds of - idle time, if the package has not already been loaded. +:defer Defer loading of a package -- this is implied when using + `:commands', `:bind', `:bind*', `:mode', `:magic', + `: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. -:after Defer loading of a package until after any of the named - features are loaded. +:after Defer loading of a package until after any of the named + features are loaded. -:demand Prevent deferred loading in all cases. +:demand Prevent deferred loading in all cases. -:if EXPR Initialize and load only if EXPR evaluates to a non-nil value. -:disabled The package is ignored completely if this keyword is present. -:defines Declare certain variables to silence the byte-compiler. -:functions Declare certain functions to silence the byte-compiler. -:load-path Add to the `load-path' before attempting to load the package. -:diminish Support for diminish.el (if installed). -:ensure Loads the package using package.el if necessary. -:pin Pin the package to an archive." +:if EXPR Initialize and load only if EXPR evaluates to a non-nil value. +:disabled The package is ignored completely if this keyword is present. +:defines Declare certain variables to silence the byte-compiler. +:functions Declare certain functions to silence the byte-compiler. +:load-path Add to the `load-path' before attempting to load the package. +:diminish Support for diminish.el (if installed). +:ensure Loads the package using package.el if necessary. +:pin Pin the package to an archive." (declare (indent 1)) (unless (member :disabled args) (let ((name-symbol (if (stringp name) (intern name) name)) From 6e6b533aaf321cbca46e2efe6dc3e0d30e73e91e Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 30 Jun 2017 12:26:26 -0700 Subject: [PATCH 277/606] Fix bug in use-package-install-deferred-package Previously, deferred installation didn't work because I didn't convert the result of a `completing-read' back from a string to a symbol, which meant the hash-table lookup failed. --- lisp/use-package/use-package.el | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 68d38d19b8c..578e54cf076 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -669,11 +669,12 @@ If the package is installed, its entry is removed from use-package--deferred-packages) (if packages (list - (completing-read - "Select package: " - packages - nil - 'require-match) + (intern + (completing-read + "Select package: " + packages + nil + 'require-match)) :interactive) (user-error "No packages with deferred installation")))) (let ((spec (gethash name use-package--deferred-packages))) From 4b8b850cf0d814bda1e39d8ea276d8e93938d573 Mon Sep 17 00:00:00 2001 From: Joe Wreschnig Date: Sun, 2 Jul 2017 16:20:01 +0200 Subject: [PATCH 278/606] Allow multiple :delight arguments, or omitting the mode. () This allows using forms such as (use-package foo :delight) ;; => (delight 'foo-mode) (use-package foo :delight " f") ;; => (delight 'foo-mode " f") (use-package foo :delight (a-mode) (b-mode " b") ;; => (delight 'a-mode) (delight 'b-mode " b") This brings support for `:delight` in line with `:diminish`. GitHub-reference: https://github.com/jwiegley/use-package/issues/477 --- lisp/use-package/use-package.el | 51 ++++++++++++++++------ test/lisp/use-package/use-package-tests.el | 19 ++++++++ 2 files changed, 57 insertions(+), 13 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 68d38d19b8c..ce38a6e1a77 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -330,6 +330,14 @@ convert it to a string and return that." (if (stringp string-or-symbol) string-or-symbol (symbol-name string-or-symbol))) +(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"))))) + (defun use-package-load-name (name &optional noerror) "Return a form which will load or require NAME depending on whether it's a string or symbol." @@ -1435,26 +1443,43 @@ deferred until the prefix key sequence is pressed." ;;; :delight ;; +(defun use-package--normalize-delight-1 (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) (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")))) + (defun use-package-normalize/:delight (name keyword args) "Normalize arguments to delight." - (cond - ((and (= (length args) 1) - (symbolp (car args))) - (list (car args) nil name)) - ((and (= (length args) 2) - (symbolp (car args))) - (list (car args) (cadr args) (use-package-as-symbol name))) - ((and (= (length args) 3) - (symbolp (car args))) - args) - (t - (use-package-error ":delight expects same args as delight function")))) + (cond ((null args) + `((,(use-package-as-mode name) nil ,name))) + ((and (= (length args) 1) + (symbolp (car args))) + `((,(car args) nil ,name))) + ((and (= (length args) 1) + (or (not (listp (car args))) + (eq 'quote (caar args)))) + `((,(use-package-as-mode name) ,(car args) ,name))) + (t (mapcar + (apply-partially #'use-package--normalize-delight-1 name) + (if (symbolp (car args)) (list args) args))))) (defun use-package-handler/:delight (name keyword args rest state) (let ((body (use-package-process-keywords name rest state))) (use-package-concat body - `((delight (quote ,(nth 0 args)) ,(nth 1 args) (quote ,(nth 2 args))) t)))) + (mapcar (lambda (arg) + `(delight ',(nth 0 arg) ,(nth 1 arg) ',(nth 2 arg))) + args)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 00682e9e0fc..ababfe0d5b2 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -51,6 +51,25 @@ (should (equal (use-package-normalize-mode 'foopkg :mode '((".foo" . foo) (".bar" . bar))) '((".foo" . foo) (".bar" . bar))))) +(ert-deftest use-package-normalize-delight () + (should (equal `((foo-mode nil foo)) + (use-package-normalize/:delight 'foo :delight nil))) + (should (equal `((foo-mode nil foo-mode)) + (use-package-normalize/:delight 'foo-mode :delight nil))) + (should (equal `((bar-mode nil foo)) + (use-package-normalize/:delight 'foo :delight '(bar-mode)))) + (should (equal `((foo-mode "abc" foo)) + (use-package-normalize/:delight 'foo :delight '("abc")))) + (should (equal `((foo-mode '(:eval 1) foo)) + (use-package-normalize/:delight 'foo :delight '('(:eval 1))))) + (should (equal `((a-mode nil foo) + (b-mode " b" foo)) + (use-package-normalize/:delight 'foo :delight '((a-mode) + (b-mode " b"))))) + (should-error (use-package-normalize/:delight 'foo :delight '((:eval 1)))) + + ) + ;; Local Variables: ;; indent-tabs-mode: nil ;; no-byte-compile: t From 7eec86f5cd98cf9a40795b9607111d8671e63ae2 Mon Sep 17 00:00:00 2001 From: Joe Wreschnig Date: Sun, 2 Jul 2017 17:45:26 +0200 Subject: [PATCH 279/606] Allow :major as the third argument in :delight calls --- lisp/use-package/use-package.el | 15 ++++++++++----- test/lisp/use-package/use-package-tests.el | 4 +++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index ce38a6e1a77..593a680eee3 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1466,9 +1466,16 @@ deferred until the prefix key sequence is pressed." (symbolp (car args))) `((,(car args) nil ,name))) ((and (= (length args) 1) - (or (not (listp (car args))) - (eq 'quote (caar args)))) + (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-1 name) (if (symbolp (car args)) (list args) args))))) @@ -1477,9 +1484,7 @@ deferred until the prefix key sequence is pressed." (let ((body (use-package-process-keywords name rest state))) (use-package-concat body - (mapcar (lambda (arg) - `(delight ',(nth 0 arg) ,(nth 1 arg) ',(nth 2 arg))) - args)))) + `((delight '(,@args)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index ababfe0d5b2..625e95ca587 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -58,9 +58,11 @@ (use-package-normalize/:delight 'foo-mode :delight nil))) (should (equal `((bar-mode nil foo)) (use-package-normalize/:delight 'foo :delight '(bar-mode)))) + (should (equal `((bar-mode nil :major)) + (use-package-normalize/:delight 'foo :delight '((bar-mode nil :major))))) (should (equal `((foo-mode "abc" foo)) (use-package-normalize/:delight 'foo :delight '("abc")))) - (should (equal `((foo-mode '(:eval 1) foo)) + (should (equal `((foo-mode (:eval 1) foo)) (use-package-normalize/:delight 'foo :delight '('(:eval 1))))) (should (equal `((a-mode nil foo) (b-mode " b" foo)) From ca83649a324128fafa33fad2dc58f54eb1c0480c Mon Sep 17 00:00:00 2001 From: Joe Wreschnig Date: Wed, 14 Jun 2017 20:24:01 +0200 Subject: [PATCH 280/606] Allow `:diminish` with no arguments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When given no arguments, have :diminish assume it should diminish a mode named after the current package (the package’s name, with “-mode” appended, if it’s not already) to an empty string. When given only a string to diminish an implicit package name to, do not append “-mode” to the package name if it already ends with it. (This is a backwards-incompatible change if someone was diminishing a package named “foo-mode” implementing `foo-mode-mode`.) Add test cases for `use-package-normalize-diminish`. This addresses some of the redundancy mentioned in issue https://github.com/jwiegley/use-package/issues/288. --- lisp/use-package/use-package.el | 4 +++- test/lisp/use-package/use-package-tests.el | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 593a680eee3..d397e0e4072 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1409,10 +1409,12 @@ deferred until the prefix key sequence is pressed." SYMBOL (SYMBOL . STRING)" (cond + ((not arg) + (list (use-package-as-mode name))) ((symbolp arg) (list arg)) ((stringp arg) - (list (cons (intern (concat (use-package-as-string name) "-mode")) 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))) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 625e95ca587..c52c3810439 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -72,6 +72,18 @@ ) +(ert-deftest use-package-normalize-diminish () + (should (equal (use-package-normalize-diminish 'foopkg :diminish nil) + '(foopkg-mode))) + (should (equal (use-package-normalize-diminish 'foopkg :diminish 'bar) + '(bar))) + (should (equal (use-package-normalize-diminish 'foopkg :diminish "bar") + '((foopkg-mode . "bar")))) + (should (equal (use-package-normalize-diminish 'foopkg :diminish 'foo-mode) + '(foo-mode))) + (should (equal (use-package-normalize-diminish 'foopkg :diminish '(foo . "bar")) + '((foo . "bar"))))) + ;; Local Variables: ;; indent-tabs-mode: nil ;; no-byte-compile: t From d0dcd95d80b13172378b9b9f85312e5233234e4c Mon Sep 17 00:00:00 2001 From: Joe Wreschnig Date: Sun, 9 Jul 2017 22:23:38 +0200 Subject: [PATCH 281/606] Document :delight in the doc string and README --- lisp/use-package/use-package.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 593a680eee3..35b4231d9c4 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1544,6 +1544,7 @@ this file. Usage: :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). :ensure Loads the package using package.el if necessary. :pin Pin the package to an archive." (declare (indent 1)) From c3455b2a6788c3e9ea2a07d5488c06b1491cad08 Mon Sep 17 00:00:00 2001 From: Dror Levin Date: Mon, 31 Jul 2017 00:11:13 +0300 Subject: [PATCH 282/606] Remove duplicate documentation of :mode --- lisp/use-package/use-package.el | 1 - 1 file changed, 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 35b4231d9c4..7b4fa7152fa 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1512,7 +1512,6 @@ this file. Usage: :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'. -:mode Form to be added to `auto-mode-alist'. :interpreter Form to be added to `interpreter-mode-alist'. :commands Define autoloads for commands that will be defined by the From 68c9ee4bff308b4426c1de4b80f57d6f8eed683c Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Fri, 13 Oct 2017 14:08:06 +0200 Subject: [PATCH 283/606] Don't use with-demoted-errors in use-package-ensure-elpa It expects a literal string as argument at macro-expansion time, but we need to construct the message. --- lisp/use-package/use-package.el | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 78321621a07..4720c072ba6 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -737,17 +737,20 @@ If the package is installed, its entry is removed from ;; bypassed. (member context '(:byte-compile :ensure :config)) (y-or-n-p (format "Install package %S?" package)))) - (with-demoted-errors (format "Cannot load %s: %%S" name) - (when (assoc package (bound-and-true-p package-pinned-packages)) - (package-read-all-archive-contents)) - (if (assoc package package-archive-contents) - (progn (package-install package) t) + (condition-case-unless-debug err (progn - (package-refresh-contents) - (when (assoc package (bound-and-true-p - package-pinned-packages)) + (when (assoc package (bound-and-true-p package-pinned-packages)) (package-read-all-archive-contents)) - (package-install package)))))))) + (if (assoc package package-archive-contents) + (progn (package-install package) t) + (progn + (package-refresh-contents) + (when (assoc package (bound-and-true-p + package-pinned-packages)) + (package-read-all-archive-contents)) + (package-install package)))) + (error (message "Error: Cannot load %s: %S" name err) + nil)))))) (defun use-package-handler/:ensure (name keyword ensure rest state) (let* ((body (use-package-process-keywords name rest From 85643eaf18842b11032f2c919c7656ed00a5d6a5 Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Fri, 13 Oct 2017 14:09:13 +0200 Subject: [PATCH 284/606] Cosmetic changes to use-package-ensure-elpa --- lisp/use-package/use-package.el | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 4720c072ba6..969cd0beabf 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -741,14 +741,15 @@ If the package is installed, its entry is removed from (progn (when (assoc package (bound-and-true-p package-pinned-packages)) (package-read-all-archive-contents)) - (if (assoc package package-archive-contents) - (progn (package-install package) t) - (progn - (package-refresh-contents) - (when (assoc package (bound-and-true-p - package-pinned-packages)) - (package-read-all-archive-contents)) - (package-install package)))) + (cond ((assoc package package-archive-contents) + (package-install package) + t) + (t + (package-refresh-contents) + (when (assoc package + (bound-and-true-p package-pinned-packages)) + (package-read-all-archive-contents)) + (package-install package)))) (error (message "Error: Cannot load %s: %S" name err) nil)))))) From 5396491aecc88a51cd3ba058257e4a587bf927dc Mon Sep 17 00:00:00 2001 From: Carl Lieberman Date: Mon, 30 Oct 2017 16:03:35 -0400 Subject: [PATCH 285/606] Fix typos in docstring --- lisp/use-package/use-package.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 969cd0beabf..51f90958662 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -123,7 +123,7 @@ become available: `use-package--foo--pre-config-hook' `use-package--foo--post-config-hook' -This way, you can add to these hooks before evalaution of a +This way, you can add to these hooks before evaluation of a `use-package` declaration, and exercise some control over what happens. @@ -290,7 +290,7 @@ found." "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 orginally required PACKAGE +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)) From fcf219701b83697898e5e73f49e1b2d4536beaec Mon Sep 17 00:00:00 2001 From: Damien Merenne Date: Tue, 17 Oct 2017 19:35:19 +0200 Subject: [PATCH 286/606] Add support for variable customization Allows customization of variable using customize-set-variables. This makes it easier to manage customization in version control. Instead of having all the variables written in a custom.el, the variable can be customized where the rest of the package is configured. --- lisp/use-package/use-package.el | 40 +++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 969cd0beabf..7e36d6204a9 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -158,6 +158,7 @@ the user specified." :defines :functions :defer + :custom :init :after :demand @@ -1404,6 +1405,44 @@ deferred until the prefix key sequence is pressed." (message (format "Cannot load %s" ',name))) ,@config-body))))))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; :custom +;; + +(defun use-package-normalize/:custom (name-symbol keyword arg) + "Normalize use-package custom keyword." + (let ((error-msg (format "%s wants a (
) or list of these" name-symbol))) + (unless (listp arg) + (use-package-error error-msg)) + (dolist (def arg arg) + (unless (listp def) + (use-package-error error-msg)) + (let ((variable (nth 0 def)) + (value (nth 1 def)) + (comment (nth 2 def))) + (when (or (not variable) + (not value) + (> (length def) 3) + (and comment (not (stringp comment)))) + (use-package-error error-msg)))))) + +(defun use-package-handler/:custom (name keyword args rest state) + "Generate use-package custom keyword code." + (let ((body (use-package-process-keywords name rest state))) + (use-package-concat + (mapcar (lambda (def) + (let ((variable (nth 0 def)) + (value (nth 1 def)) + (comment (nth 2 def))) + (unless comment + (setq comment (format "Customized with use-package %s" name))) + `(customize-set-variable (quote ,variable) ,value ,comment))) + args) + body))) + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; :diminish @@ -1550,6 +1589,7 @@ this file. Usage: :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 `customize-set-variable' with each variable definition. :ensure Loads the package using package.el if necessary. :pin Pin the package to an archive." (declare (indent 1)) From d8bbc3a95d6d58a36e7a8c01e05f9b6388c52feb Mon Sep 17 00:00:00 2001 From: Damien Merenne Date: Tue, 17 Oct 2017 19:40:38 +0200 Subject: [PATCH 287/606] Add support for face customization Allows customization of faces using customize-set-faces. This makes it easier to manage customization in version control. Instead of having all the faces written in a custom.el, the faces can be customized where the rest of the package is configured. --- lisp/use-package/use-package.el | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 7e36d6204a9..711f4c7bfe4 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -159,6 +159,7 @@ the user specified." :functions :defer :custom + :custom-face :init :after :demand @@ -1441,7 +1442,34 @@ deferred until the prefix key sequence is pressed." args) body))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; :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 ( ) or list of these" name-symbol))) + (unless (listp arg) + (use-package-error error-msg)) + (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 arg) 2)) + (use-package-error error-msg)))))) + +(defun use-package-handler/:custom-face (name keyword args rest state) + "Generate use-package custom-face keyword code." + (let ((body (use-package-process-keywords name rest state))) + (use-package-concat + (mapcar (lambda (def) + `(custom-set-faces (quote ,def))) + args) + body))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -1590,6 +1618,7 @@ this file. Usage: :diminish Support for diminish.el (if installed). :delight Support for delight.el (if installed). :custom Call `customize-set-variable' with each variable definition. +:custom-face Call `customize-set-faces' with each face definition. :ensure Loads the package using package.el if necessary. :pin Pin the package to an archive." (declare (indent 1)) From 57ec21a0139a286d3a670a4aef6699e13b4ec963 Mon Sep 17 00:00:00 2001 From: Justin Talbott Date: Mon, 20 Nov 2017 23:33:34 -0500 Subject: [PATCH 288/606] allow customized values to be nil --- lisp/use-package/use-package.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 24c62339ea1..f36cebe70d1 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1423,7 +1423,8 @@ deferred until the prefix key sequence is pressed." (value (nth 1 def)) (comment (nth 2 def))) (when (or (not variable) - (not value) + (and (not value) + (not (eq value nil))) (> (length def) 3) (and comment (not (stringp comment)))) (use-package-error error-msg)))))) From c72d8567d2627a18b5d4da8184053644ccd576a3 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 28 Nov 2017 11:03:47 -0800 Subject: [PATCH 289/606] Corrections to the normalization of :custom --- lisp/use-package/use-package.el | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 5b732c12179..f38d883285c 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1411,23 +1411,20 @@ deferred until the prefix key sequence is pressed." ;;; :custom ;; -(defun use-package-normalize/:custom (name-symbol keyword arg) +(defun use-package-normalize/:custom (name-symbol keyword args) "Normalize use-package custom keyword." - (let ((error-msg (format "%s wants a ( ) or list of these" name-symbol))) - (unless (listp arg) - (use-package-error error-msg)) - (dolist (def arg arg) - (unless (listp def) - (use-package-error error-msg)) - (let ((variable (nth 0 def)) - (value (nth 1 def)) - (comment (nth 2 def))) - (when (or (not variable) - (and (not value) - (not (eq value nil))) - (> (length def) 3) - (and comment (not (stringp comment)))) - (use-package-error error-msg)))))) + (cond + ((and (= (length args) 1) + (listp (car args)) + (listp (car (car args)))) + (car args)) + ((and (= (length args) 1) + (listp (car args))) + args) + (t + (use-package-error + (concat label " a ( [comment])" + " or list of these"))))) (defun use-package-handler/:custom (name keyword args rest state) "Generate use-package custom keyword code." @@ -1437,7 +1434,7 @@ deferred until the prefix key sequence is pressed." (let ((variable (nth 0 def)) (value (nth 1 def)) (comment (nth 2 def))) - (unless comment + (unless (and comment (stringp comment)) (setq comment (format "Customized with use-package %s" name))) `(customize-set-variable (quote ,variable) ,value ,comment))) args) From 4ddf42185a199c99b66f89e903f74a89869cb86a Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 28 Nov 2017 11:14:30 -0800 Subject: [PATCH 290/606] Explicit :defer t should override use-package-always-demand Fixes https://github.com/jwiegley/use-package/issues/514 --- lisp/use-package/use-package.el | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index e8acf5271f2..26ede8483fd 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1650,10 +1650,12 @@ this file. Usage: (let ((body (macroexp-progn (use-package-process-keywords name - (if use-package-always-demand + (if (and use-package-always-demand + (not (memq :defer args))) (append args '(:demand t)) args) - (and use-package-always-defer (list :deferred t)))))) + (and use-package-always-defer + (list :deferred t)))))) (if use-package-debug (display-buffer (save-current-buffer From 18b9bf18ad5c14dccaf0448768b0ad0435c3a93e Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 28 Nov 2017 11:16:12 -0800 Subject: [PATCH 291/606] Don't allow :commands, :bind, etc., to be given an empty list This makes the following an error: :commands :commands nil :commands () Fixes https://github.com/jwiegley/use-package/issues/512 --- lisp/use-package/use-package.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 26ede8483fd..77c2aebdc10 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -828,12 +828,12 @@ If the package is installed, its entry is removed from (defun use-package-as-one (label args f) "Call F on the first element of ARGS if it has one element, or all of ARGS." (declare (indent 1)) - (if (and (listp args) (listp (cdr args))) + (if (and (not (null args)) (listp args) (listp (cdr args))) (if (= (length args) 1) (funcall f label (car args)) (funcall f label args)) (use-package-error - (concat label " wants a list")))) + (concat label " wants a non-empty list")))) (put 'use-package-as-one 'lisp-indent-function 'defun) From 9b523d7c4eee7a24d43a7dc23d9afc28fd099a36 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 28 Nov 2017 11:22:53 -0800 Subject: [PATCH 292/606] Upgrade license to GPL 3 Fixes https://github.com/jwiegley/use-package/issues/499 --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 77c2aebdc10..9c095d73849 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -13,7 +13,7 @@ ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 2, or (at +;; 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 From 6f9d4342ca2f8b6dc4dbeb8424525b99719855c3 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 28 Nov 2017 11:31:35 -0800 Subject: [PATCH 293/606] Make unrecognized keywords a warning This could actually be used to store your own metadata in use-package declarations, to be (read) later by simply parsing init file contents. Fixes https://github.com/jwiegley/use-package/issues/483 --- lisp/use-package/use-package.el | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 9c095d73849..83b9ae4f4aa 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -534,7 +534,10 @@ This is in contrast to merely setting it to 0." (if (memq keyword use-package-keywords) (cons keyword (cons arg (use-package-normalize-plist name tail))) - (use-package-error (format "Unrecognized keyword: %s" keyword)))))) + (ignore + (display-warning 'use-package + (format "Unrecognized keyword: %s" keyword) + :warning)))))) (defun use-package-process-keywords (name plist &optional state) "Process the next keyword in the free-form property list PLIST. From 700c92c5de43bf3b4d3213b2e2ebcf33b96e577f Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 28 Nov 2017 11:41:41 -0800 Subject: [PATCH 294/606] Append to *use-package* when debugging, don't clear it Fixes https://github.com/jwiegley/use-package/issues/476 --- lisp/use-package/use-package.el | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 83b9ae4f4aa..cc8a76bd1c2 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1659,15 +1659,14 @@ this file. Usage: args) (and use-package-always-defer (list :deferred t)))))) - (if use-package-debug - (display-buffer - (save-current-buffer - (let ((buf (get-buffer-create "*use-package*"))) - (with-current-buffer buf - (delete-region (point-min) (point-max)) - (emacs-lisp-mode) - (insert (pp-to-string body))) - buf)))) + (when use-package-debug + (display-buffer + (save-current-buffer + (with-current-buffer (get-buffer-create "*use-package*") + (goto-char (point-max)) + (emacs-lisp-mode) + (insert (pp-to-string body)) + (current-buffer))))) body)))) From 4ad4a59685a947a31e2a2970b428920cd6b56ced Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 28 Nov 2017 13:58:38 -0800 Subject: [PATCH 295/606] Add support for `:hook` Fixes https://github.com/jwiegley/use-package/issues/444 --- lisp/use-package/use-package.el | 49 +++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index cc8a76bd1c2..648e2c7c8ae 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -158,6 +158,7 @@ the user specified." :defines :functions :defer + :hook :custom :custom-face :init @@ -1409,6 +1410,54 @@ deferred until the prefix key sequence is pressed." (message (format "Cannot load %s" ',name))) ,@config-body))))))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; :hook +;; + +(defun use-package-normalize/:hook (name keyword args) + (use-package-as-one (symbol-name keyword) args + (lambda (label arg) + (unless (or (symbolp arg) (consp arg)) + (use-package-error + (concat label " a or a ( . )" + " or list of these"))) + (use-package-normalize-pairs + #'(lambda (k) + (or (symbolp k) + (and (listp k) + (listp (cdr k)) + (seq-every-p #'symbolp k)))) + #'(lambda (v) + (or (symbolp v) (functionp v))) + name label arg)))) + +(defun use-package-handler/:hook (name keyword args rest state) + "Generate use-package custom keyword code." + (let ((commands (let (funs) + (dolist (def args) + (if (symbolp (cdr def)) + (setq funs (cons (cdr def) funs)))) + (nreverse funs)))) + (use-package-concat + (use-package-process-keywords name + (if commands + (use-package-sort-keywords + (use-package-plist-maybe-put rest :defer t)) + rest) + (if commands + (use-package-plist-append state :commands commands) + state)) + (cl-mapcan + (lambda (def) + (let ((syms (car def)) + (fun (cdr def))) + (mapcar + #'(lambda (sym) + `(add-hook (quote ,(intern (format "%s-hook" sym))) + (function ,fun))) + (if (symbolp syms) (list syms) syms)))) args)))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; :custom From 2ebf0767332f0b56647085392adcc533904b96ef Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 28 Nov 2017 14:16:13 -0800 Subject: [PATCH 296/606] Allow :custom (foo1 bar1) (foo2 bar2) etc Fixes https://github.com/jwiegley/use-package/issues/518 --- lisp/use-package/use-package.el | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 648e2c7c8ae..f6c21e0a903 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1420,7 +1420,7 @@ deferred until the prefix key sequence is pressed." (lambda (label arg) (unless (or (symbolp arg) (consp arg)) (use-package-error - (concat label " a or a ( . )" + (concat label " a or ( . )" " or list of these"))) (use-package-normalize-pairs #'(lambda (k) @@ -1463,20 +1463,15 @@ deferred until the prefix key sequence is pressed." ;;; :custom ;; -(defun use-package-normalize/:custom (name-symbol keyword args) +(defun use-package-normalize/:custom (name keyword args) "Normalize use-package custom keyword." - (cond - ((and (= (length args) 1) - (listp (car args)) - (listp (car (car args)))) - (car args)) - ((and (= (length args) 1) - (listp (car args))) - args) - (t - (use-package-error - (concat label " a ( [comment])" - " or list of these"))))) + (use-package-as-one (symbol-name keyword) args + (lambda (label arg) + (unless (listp arg) + (use-package-error + (concat label " a ( [comment])" + " or list of these"))) + arg))) (defun use-package-handler/:custom (name keyword args rest state) "Generate use-package custom keyword code." From c811637b303db7bb951e54f651da0ce4528ef130 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 28 Nov 2017 14:39:59 -0800 Subject: [PATCH 297/606] Fix for single :custom (foo bar) --- lisp/use-package/use-package.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index f6c21e0a903..a2ce335d1d8 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1471,7 +1471,9 @@ deferred until the prefix key sequence is pressed." (use-package-error (concat label " a ( [comment])" " or list of these"))) - arg))) + (if (symbolp (car arg)) + (list arg) + arg)))) (defun use-package-handler/:custom (name keyword args rest state) "Generate use-package custom keyword code." From 7531c374bf9cd1074ac1a1d2ec2cdb13ad4168d5 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 28 Nov 2017 16:27:09 -0800 Subject: [PATCH 298/606] Allow :diminish to take no argument, once again --- lisp/use-package/use-package.el | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index a2ce335d1d8..d9ec638474e 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -829,10 +829,12 @@ If the package is installed, its entry is removed from ;;; :requires ;; -(defun use-package-as-one (label args f) - "Call F on the first element of ARGS if it has one element, or all of ARGS." +(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 (and (not (null args)) (listp args) (listp (cdr args))) + (if (or (and (not (null args)) (listp args) (listp (cdr args))) + (and allow-empty (null args))) (if (= (length args) 1) (funcall f label (car args)) (funcall f label args)) @@ -1546,7 +1548,7 @@ deferred until the prefix key sequence is pressed." (defun use-package-normalize/:diminish (name keyword args) (use-package-as-one (symbol-name keyword) args - (apply-partially #'use-package-normalize-diminish name))) + (apply-partially #'use-package-normalize-diminish name) t)) (defun use-package-handler/:diminish (name keyword arg rest state) (let ((body (use-package-process-keywords name rest state))) From 2c32857d579b76db314627d2bc296779aab400e3 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 28 Nov 2017 20:26:34 -0800 Subject: [PATCH 299/606] Make diminish a soft dependency, as delight already was Fixes https://github.com/jwiegley/use-package/issues/493 --- lisp/use-package/use-package.el | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index d9ec638474e..7ee7ac0efa2 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -7,7 +7,7 @@ ;; Created: 17 Jun 2012 ;; Modified: 17 Oct 2016 ;; Version: 2.3 -;; Package-Requires: ((bind-key "1.0") (diminish "0.44")) +;; Package-Requires: ((bind-key "1.0")) ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package @@ -41,8 +41,6 @@ (require 'bind-key) (require 'bytecomp) -(require 'diminish nil t) -(require 'bytecomp) (eval-when-compile (require 'cl)) (eval-when-compile (require 'regexp-opt)) @@ -1607,7 +1605,8 @@ deferred until the prefix key sequence is pressed." (let ((body (use-package-process-keywords name rest state))) (use-package-concat body - `((delight '(,@args)))))) + `((if (fboundp 'delight) + (delight '(,@args))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; From a392f6da552f9fd10df626e00c4cf1105eef1029 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 28 Nov 2017 20:31:40 -0800 Subject: [PATCH 300/606] When byte-compiling, correctly output declare-function directives Fixes https://github.com/jwiegley/use-package/issues/474 --- lisp/use-package/use-package.el | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 7ee7ac0efa2..7185999d14d 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1690,6 +1690,9 @@ this file. Usage: `(eval-when-compile ,@(mapcar #'(lambda (var) `(defvar ,var)) (plist-get args :defines)) + ,@(mapcar #'(lambda (fn) `(declare-function + ,fn ,(use-package-as-string name))) + (plist-get args :functions)) (with-demoted-errors ,(format "Cannot load %s: %%S" name) ,(if (eq use-package-verbose 'debug) From 606284e374381c4286d216a94a98fcdda2d3a501 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 28 Nov 2017 20:52:29 -0800 Subject: [PATCH 301/606] Repeating a bind no longer causes duplicates in personal-keybindings Fixes https://github.com/jwiegley/use-package/issues/446 --- lisp/use-package/bind-key.el | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index d907798ae76..e5002d4ee17 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -161,9 +161,13 @@ can safely be called at any time." (key-description ,namevar)) (quote ,keymap))) (,bindingvar (lookup-key (or ,keymap global-map) ,keyvar))) - (add-to-list 'personal-keybindings - (list ,kdescvar ,command - (unless (numberp ,bindingvar) ,bindingvar))) + (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 (or ,keymap global-map) ,keyvar '(menu-item "" nil :filter (lambda (&optional _) From 282598761948048f2d352e9cf913dc3a7b68ce52 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 28 Nov 2017 20:58:04 -0800 Subject: [PATCH 302/606] Print map keys in describe-personal-keybindings Fixes https://github.com/jwiegley/use-package/issues/406 --- lisp/use-package/bind-key.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index e5002d4ee17..eb24d2396e3 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -374,8 +374,8 @@ function symbol (unquoted)." (car (compare-keybindings l r)))))) (if (not (eq (cdar last-binding) (cdar binding))) - (princ (format "\n\n%s\n%s\n\n" - (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 From b7041c0f2912dc0f75c672663f79e4506c4a2e2e Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 28 Nov 2017 21:12:25 -0800 Subject: [PATCH 303/606] When use-package-inject-hooks is non-nil, always fire init/config hooks This used to not happen if `:init` or `:config` was missing, or set to nil as with `:init nil`. Fixes https://github.com/jwiegley/use-package/issues/250 --- lisp/use-package/use-package.el | 38 ++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 7185999d14d..a1beca1fc05 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -371,19 +371,18 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." (if (not use-package-inject-hooks) (use-package-expand name-string (format "%s" keyword) body) (let ((keyword-name (substring (format "%s" keyword) 1))) - (when body - `((when ,(macroexp-progn - (use-package-expand name-string (format "pre-%s hook" keyword) - `((run-hook-with-args-until-failure - ',(intern (concat "use-package--" name-string - "--pre-" keyword-name "-hook")))))) - ,(macroexp-progn - (use-package-expand name-string (format "%s" keyword) body)) - ,(macroexp-progn - (use-package-expand name-string (format "post-%s hook" keyword) - `((run-hooks - ',(intern (concat "use-package--" name-string - "--post-" keyword-name "-hook")))))))))))) + `((when ,(macroexp-progn + (use-package-expand name-string (format "pre-%s hook" keyword) + `((run-hook-with-args-until-failure + ',(intern (concat "use-package--" name-string + "--pre-" keyword-name "-hook")))))) + ,(macroexp-progn + (use-package-expand name-string (format "%s" keyword) body)) + ,(macroexp-progn + (use-package-expand name-string (format "post-%s hook" keyword) + `((run-hooks + ',(intern (concat "use-package--" name-string + "--post-" keyword-name "-hook"))))))))))) (defun use-package--with-elapsed-timer (text body) "BODY is a list of forms, so `((foo))' if only `foo' is being called." @@ -1703,10 +1702,15 @@ this file. Usage: (let ((body (macroexp-progn (use-package-process-keywords name - (if (and use-package-always-demand - (not (memq :defer args))) - (append args '(:demand t)) - args) + (let ((args* (if (and use-package-always-demand + (not (memq :defer args))) + (append args '(:demand t)) + args))) + (unless (plist-member args* :init) + (plist-put args* :init nil)) + (unless (plist-member args* :config) + (plist-put args* :config nil)) + args*) (and use-package-always-defer (list :deferred t)))))) (when use-package-debug From 4303a2faf6de7d06b39c240bfb70a97ceea1f1d7 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" Date: Wed, 29 Nov 2017 15:47:00 +0000 Subject: [PATCH 304/606] Require cl-lib and do not use seq functions cl-lib is also required for a separate call to cl-mapcan. Fixes https://github.com/jwiegley/use-package/issues/520 --- lisp/use-package/use-package.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index a1beca1fc05..f6c437d5728 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -41,6 +41,7 @@ (require 'bind-key) (require 'bytecomp) +(require 'cl-lib) (eval-when-compile (require 'cl)) (eval-when-compile (require 'regexp-opt)) @@ -1426,7 +1427,7 @@ deferred until the prefix key sequence is pressed." (or (symbolp k) (and (listp k) (listp (cdr k)) - (seq-every-p #'symbolp k)))) + (cl-every #'symbolp k)))) #'(lambda (v) (or (symbolp v) (functionp v))) name label arg)))) @@ -1452,7 +1453,7 @@ deferred until the prefix key sequence is pressed." (let ((syms (car def)) (fun (cdr def))) (mapcar - #'(lambda (sym) + #'(lambda (sym) `(add-hook (quote ,(intern (format "%s-hook" sym))) (function ,fun))) (if (symbolp syms) (list syms) syms)))) args)))) From 9ea305beb6e2fa9eddfb4ab4e39691d35d35cdfd Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 29 Nov 2017 07:55:53 -0800 Subject: [PATCH 305/606] Add a missing (require 'seq) --- lisp/use-package/use-package.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index a1beca1fc05..06e732402b4 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -41,6 +41,7 @@ (require 'bind-key) (require 'bytecomp) +(require 'seq) (eval-when-compile (require 'cl)) (eval-when-compile (require 'regexp-opt)) From 3db39c057319f3b4910f3373d20eb4c9940e536b Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" Date: Wed, 29 Nov 2017 10:50:30 +0000 Subject: [PATCH 306/606] Require Emacs version >= 24.3 Re: https://github.com/jwiegley/use-package/issues/457 --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index f6c437d5728..68c10f3d175 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -7,7 +7,7 @@ ;; Created: 17 Jun 2012 ;; Modified: 17 Oct 2016 ;; Version: 2.3 -;; Package-Requires: ((bind-key "1.0")) +;; Package-Requires: ((emacs "24.3") (bind-key "1.0")) ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package From 7499c8812ae1f887ef0bd4262a9788aa21758607 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 29 Nov 2017 10:53:51 -0800 Subject: [PATCH 307/606] Add NEWS.md file --- etc/USE-PACKAGE-NEWS | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 etc/USE-PACKAGE-NEWS diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS new file mode 100644 index 00000000000..63e235605fa --- /dev/null +++ b/etc/USE-PACKAGE-NEWS @@ -0,0 +1,44 @@ +# Changes + +## 2.4 + +### Breaking changes + +- `use-package` no longer requires `diminish` as a dependency, allowing people + to decide whether they want to use diminish or delight. This means that if + you do use diminish, you'll now need to pull it into your configuration + before any use of the `:diminish` kewyord. For example: + + ``` elisp + (use-package diminish :ensure t) + ``` + +- Emacs 24.3 or higher is now a requirement. + +### Other changes + +- New `:hook` keyword. +- Documentation added for the `:after`, `:defer-install`, `:delight`, + `:requires`, `:when` and `:unless` keywords. +- When use-package-inject-hooks is non-nil, always fire init/config hooks. +- Print key bindings for keymaps in `describe-personal-keybindings`. +- Allow `:diminish` to take no arguments. +- Add `:custom (foo1 bar1) (foo2 bar2)` etc., and `:custom-face`. +- Add `:magic` and `:magic-fallback` keywords. +- Add `:defer-install` keyword. +- New customization variable `use-package-enable-imenu-support`. +- Upgrade license to GPL 3. +- `:bind (:map foo-map ...)` now defers binding in the map until the package + has been loaded. +- Support multiple symbols passed to `:after`, and a mini-DSL using `:all` and + `:any`. +- `:mode` and `:interpreter` can now accept `(rx ...)` forms. + +### Bug fixes + +- Repeating a bind no longer causes duplicates in personal-keybindings. +- When byte-compiling, correctly output declare-function directives. +- Append to *use-package* when debugging, don't clear it. +- Don't allow :commands, :bind, etc., to be given an empty list. +- Explicit :defer t should override use-package-always-demand. + From f256943f9b50c43a8c280c48ce7f891f834509e5 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 29 Nov 2017 10:55:47 -0800 Subject: [PATCH 308/606] Reorder some items in NEWS.md --- etc/USE-PACKAGE-NEWS | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index 63e235605fa..a4f20070e6a 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -17,22 +17,23 @@ ### Other changes -- New `:hook` keyword. -- Documentation added for the `:after`, `:defer-install`, `:delight`, - `:requires`, `:when` and `:unless` keywords. -- When use-package-inject-hooks is non-nil, always fire init/config hooks. -- Print key bindings for keymaps in `describe-personal-keybindings`. -- Allow `:diminish` to take no arguments. -- Add `:custom (foo1 bar1) (foo2 bar2)` etc., and `:custom-face`. -- Add `:magic` and `:magic-fallback` keywords. -- Add `:defer-install` keyword. -- New customization variable `use-package-enable-imenu-support`. - Upgrade license to GPL 3. -- `:bind (:map foo-map ...)` now defers binding in the map until the package - has been loaded. +- New `:hook` keyword. +- New keywords `:custom (foo1 bar1) (foo2 bar2)` etc., and `:custom-face`. +- New `:magic` and `:magic-fallback` keywords. +- New `:defer-install` keyword. +- New customization variable `use-package-enable-imenu-support`. +- Allow `:diminish` to take no arguments. - Support multiple symbols passed to `:after`, and a mini-DSL using `:all` and `:any`. - `:mode` and `:interpreter` can now accept `(rx ...)` forms. +- `:bind (:map foo-map ...)` now defers binding in the map until the package + has been loaded. +- Print key bindings for keymaps in `describe-personal-keybindings`. +- When `use-package-inject-hooks` is non-nil, always fire `:init` and + `:config` hooks. +- Documentation added for the `:after`, `:defer-install`, `:delight`, + `:requires`, `:when` and `:unless` keywords. ### Bug fixes From bff472ea80af2da0a47307e1d807f7fe330abf39 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 29 Nov 2017 14:41:12 -0800 Subject: [PATCH 309/606] Allow :bind ("C-c C-c" . (lambda () (ding))) and #'(lambda ...) Fixes https://github.com/jwiegley/use-package/issues/333 Fixes https://github.com/jwiegley/use-package/issues/461 --- lisp/use-package/bind-key.el | 8 +- lisp/use-package/use-package.el | 298 ++++++++++++--------- test/lisp/use-package/use-package-tests.el | 14 + 3 files changed, 193 insertions(+), 127 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index eb24d2396e3..ca6c2a7ceed 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -267,10 +267,10 @@ function symbol (unquoted)." (cl-mapcan (lambda (form) (if prefix-map - `((bind-key ,(car form) ',(cdr form) ,prefix-map ,filter)) + `((bind-key ,(car form) #',(cdr form) ,prefix-map ,filter)) (if (and map (not (eq map 'global-map))) - `((bind-key ,(car form) ',(cdr form) ,map ,filter)) - `((bind-key ,(car form) ',(cdr form) nil ,filter))))) + `((bind-key ,(car form) #',(cdr form) ,map ,filter)) + `((bind-key ,(car form) #',(cdr form) nil ,filter))))) first)) (when next (bind-keys-form @@ -305,7 +305,7 @@ function symbol (unquoted)." (cond ((listp elem) (cond - ((eq 'lambda (car elem)) + ((memq (car elem) '(lambda function)) (if (and bind-key-describe-special-forms (stringp (nth 2 elem))) (nth 2 elem) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 68c10f3d175..2b5de46ca35 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -472,6 +472,9 @@ This is in contrast to merely setting it to 0." "Delete all empty lists from ELEMS (nil or (list nil)), and append them." (apply #'nconc (delete nil (delete (list nil) elems)))) +(defsubst use-package--non-nil-symbolp (sym) + (and sym (symbolp sym))) + (defconst use-package-font-lock-keywords '(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" (1 font-lock-keyword-face) @@ -489,16 +492,11 @@ This is in contrast to merely setting it to 0." ;;; Normalization functions ;; -(defun use-package-regex-p (re) +(defsubst use-package-regex-p (re) "Return t if RE is some regexp-like thing." - (cond - ((and (listp re) - (eq (car re) 'rx)) - t) - ((stringp re) - t) - (t - nil))) + (or (and (listp re) + (eq (car re) 'rx)) + (stringp re))) (defun use-package-normalize-regex (re) "Given some regexp-like thing, resolve it down to a regular expression." @@ -590,7 +588,7 @@ next value for the STATE." (lambda (label arg) (cond ((stringp arg) arg) - ((symbolp arg) (symbol-name arg)) + ((use-package--non-nil-symbolp arg) (symbol-name arg)) (t (use-package-error ":pin wants an archive name (a string)")))))) @@ -724,7 +722,7 @@ If the package is installed, its entry is removed from t (use-package-only-one (symbol-name keyword) args (lambda (label arg) - (if (symbolp arg) + (if (use-package--non-nil-symbolp arg) arg (use-package-error (concat ":ensure wants an optional package name " @@ -798,7 +796,7 @@ If the package is installed, its entry is removed from (defsubst use-package-normalize-value (label arg) "Normalize a value." (cond ((null arg) nil) - ((symbolp arg) + ((use-package--non-nil-symbolp arg) `(symbol-value ',arg)) ((functionp arg) `(funcall #',arg)) @@ -831,8 +829,9 @@ If the package is installed, its entry is removed from "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 (or (and (not (null args)) (listp args) (listp (cdr args))) - (and allow-empty (null args))) + (if (if args + (listp args) (listp (cdr args)) + allow-empty) (if (= (length args) 1) (funcall f label (car args)) (funcall f label args)) @@ -844,7 +843,7 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." (defun use-package-normalize-symbols (label arg &optional recursed) "Normalize a list of symbols." (cond - ((symbolp arg) + ((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)) @@ -859,7 +858,7 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." (defun use-package-normalize-recursive-symbols (label arg) "Normalize a list of symbols." (cond - ((symbolp arg) + ((use-package--non-nil-symbolp arg) arg) ((and (listp arg) (listp (cdr arg))) (mapcar #'(lambda (x) (use-package-normalize-recursive-symbols label x)) @@ -891,7 +890,7 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." (defun use-package-normalize-paths (label arg &optional recursed) "Normalize a list of filesystem paths." (cond - ((and arg (or (symbolp arg) (functionp arg))) + ((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) @@ -986,56 +985,105 @@ If RECURSED is non-nil, recurse into sublists." ((use-package-is-pair arg key-pred val-pred) (list arg)) ((and (not recursed) (listp arg) (listp (cdr arg))) - (let ((last-item nil)) - (mapcar #'(lambda (x) - (prog1 - (let ((ret (use-package-normalize-pairs - key-pred val-pred name label x t))) - ;; Currently, the handling of keyword - ;; arguments by `use-package' and `bind-key' - ;; is non-uniform and undocumented. As a - ;; result, `use-package-normalize-pairs' (as - ;; it is currently implemented) does not - ;; correctly handle the keyword-argument - ;; syntax of `bind-keys'. A permanent solution - ;; to this problem will require a careful - ;; consideration of the desired - ;; keyword-argument interface for - ;; `use-package' and `bind-key'. However, in - ;; the meantime, we have a quick patch to fix - ;; a serious bug in the handling of keyword - ;; arguments. Namely, the code below would - ;; normally unwrap lists that were passed as - ;; keyword arguments (for example, the - ;; `:filter' argument in `:bind') without - ;; the (not (keywordp last-item)) clause. See - ;; #447 for further discussion. - (if (and (listp ret) (not (keywordp last-item))) - (car ret) - ret)) - (setq last-item x))) arg))) + (let (last-item) + (mapcar + #'(lambda (x) + (prog1 + (let ((ret (use-package-normalize-pairs + key-pred val-pred name label x t))) + ;; Currently, the handling of keyword arguments by + ;; `use-package' and `bind-key' is non-uniform and + ;; undocumented. As a result, `use-package-normalize-pairs' + ;; (as it is currently implemented) does not correctly handle + ;; the keyword-argument syntax of `bind-keys'. A permanent + ;; solution to this problem will require a careful + ;; consideration of the desired keyword-argument interface + ;; for `use-package' and `bind-key'. However, in the + ;; meantime, we have a quick patch to fix a serious bug in + ;; the handling of keyword arguments. Namely, the code below + ;; would normally unwrap lists that were passed as keyword + ;; arguments (for example, the `:filter' argument in `:bind') + ;; without the (not (keywordp last-item)) clause. See #447 + ;; for further discussion. + (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 additional-pred) + "A predicate that recognizes functional constructions: + sym + 'sym + (quote sym) + #'sym + (function sym) + (lambda () ...) + '(lambda () ...) + (quote (lambda () ...)) + #'(lambda () ...) + (function (lambda () ...))" + (pcase v + ((pred use-package--non-nil-symbolp) t) + (`(,(or 'quote 'function) + ,(pred use-package--non-nil-symbolp)) t) + ((pred functionp) t) + (`(function (lambda . ,_)) t) + (_ (and additional-pred + (funcall additional-pred v))))) + +(defun use-package--normalize-function (v) + "Reduce functional constructions to one of two normal forms: + sym + #'(lambda () ...)" + (pcase v + ((pred use-package--non-nil-symbolp) v) + (`(,(or 'quote 'function) + ,(and sym (pred use-package--non-nil-symbolp))) sym) + (`(lambda . ,_) v) + (`(quote ,(and lam `(lambda . ,_))) lam) + (`(function ,(and lam `(lambda . ,_))) lam) + (_ v))) + +(defun use-package--normalize-commands (args) + "Map over ARGS of the form ((_ . F) ...). +Normalizing functional F's and returning a list of F's +representing symbols (that may need to be autloaded)." + (let ((nargs (mapcar + #'(lambda (x) + (if (consp x) + (cons (car x) + (use-package--normalize-function (cdr x))) + x)) args))) + (cons nargs + (delete nil (mapcar #'(lambda (x) + (and (consp x) + (use-package--non-nil-symbolp (cdr x)) + (cdr x))) nargs))))) + (defun use-package-normalize-binder (name keyword args) (use-package-as-one (symbol-name keyword) args (lambda (label arg) (unless (consp arg) (use-package-error - (concat label " a ( . )" + (concat label " a ( . )" " or list of these"))) - (use-package-normalize-pairs (lambda (k) (or (stringp k) (vectorp k))) - (lambda (b) (or (symbolp b) (stringp b))) - name label arg)))) + (use-package-normalize-pairs + #'(lambda (k) + (pcase k + ((pred stringp) t) + ((pred vectorp) t))) + #'(lambda (v) (use-package--recognize-function v #'stringp)) + name label arg)))) (defalias 'use-package-normalize/:bind 'use-package-normalize-binder) (defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) (defun use-package-handler/:bind - (name keyword arg rest state &optional bind-macro) - (let ((commands (remq nil (mapcar #'(lambda (arg) - (if (listp arg) - (cdr arg) - nil)) arg)))) + (name keyword args rest state &optional bind-macro) + (cl-destructuring-bind (nargs . commands) + (use-package--normalize-commands args) (use-package-concat (use-package-process-keywords name (use-package-sort-keywords @@ -1044,7 +1092,7 @@ If RECURSED is non-nil, recurse into sublists." `((ignore ,(macroexpand `(,(if bind-macro bind-macro 'bind-keys) - :package ,name ,@arg))))))) + :package ,name ,@nargs))))))) (defun use-package-handler/:bind* (name keyword arg rest state) (use-package-handler/:bind name keyword arg rest state 'bind-keys*)) @@ -1060,15 +1108,15 @@ If RECURSED is non-nil, recurse into sublists." ;;;###autoload (defun use-package-autoload-keymap (keymap-symbol package override) "Loads PACKAGE and then binds the key sequence used to invoke -this function to KEYMAP-SYMBOL. It then simulates pressing the -same key sequence a again, so that the next key pressed is routed -to the newly loaded keymap. + this function to KEYMAP-SYMBOL. It then simulates pressing the + same key sequence a again, so that the next key pressed is routed + to the newly loaded keymap. -This function supports use-package's :bind-keymap keyword. It -works by binding the given key sequence to an invocation of this -function for a particular keymap. The keymap is expected to be -defined by the package. In this way, loading the package is -deferred until the prefix key sequence is pressed." + 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) @@ -1096,7 +1144,8 @@ deferred until the prefix key sequence is pressed." #'(lambda () (interactive) (use-package-autoload-keymap - ',(cdr binding) ',(use-package-as-symbol name) ,override)))) arg))) + ',(cdr binding) ',(use-package-as-symbol name) + ,override)))) arg))) (use-package-concat (use-package-process-keywords name (use-package-sort-keywords @@ -1117,23 +1166,27 @@ deferred until the prefix key sequence is pressed." (use-package-as-one (symbol-name keyword) args (apply-partially #'use-package-normalize-pairs #'use-package-regex-p - (lambda (m) (and (not (null m)) (symbolp m))) + #'(lambda (v) (use-package--recognize-function v #'null)) name))) -(defun use-package-handle-mode (name alist arg rest state) +(defun use-package-handle-mode (name alist args rest state) "Handle keywords which add regexp/mode pairs to an alist." - (let* (commands - (form (mapcar #'(lambda (thing) - (push (cdr thing) commands) - (setcar thing - (use-package-normalize-regex (car thing))) - `(add-to-list ',alist ',thing)) arg))) - (use-package-concat - (use-package-process-keywords name - (use-package-sort-keywords - (use-package-plist-maybe-put rest :defer t)) - (use-package-plist-append state :commands commands)) - `((ignore ,@form))))) + (cl-destructuring-bind (nargs . commands) + (use-package--normalize-commands args) + (let ((form + (mapcar + #'(lambda (thing) + `(add-to-list + ',alist + ',(cons (use-package-normalize-regex (car thing)) + (cdr thing)))) + nargs))) + (use-package-concat + (use-package-process-keywords name + (use-package-sort-keywords + (use-package-plist-maybe-put rest :defer t)) + (use-package-plist-append state :commands commands)) + `((ignore ,@form)))))) (defalias 'use-package-normalize/:interpreter 'use-package-normalize-mode) @@ -1229,7 +1282,7 @@ deferred until the prefix key sequence is pressed." (defun ,command (&rest args) "[Arg list not available until function definition is loaded.] -\(fn ...)" + \(fn ...)" (interactive) (if (bound-and-true-p use-package--recursive-autoload) (use-package-error @@ -1258,30 +1311,26 @@ deferred until the prefix key sequence is pressed." ;; 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))) - + `((run-with-idle-timer ,arg nil #'require + ',(use-package-as-symbol name) nil t))) ;; Since we deferring load, establish any necessary autoloads, and also ;; keep the byte-compiler happy. - (apply - #'nconc - (mapcar - #'(lambda (command) - (when (not (stringp command)) - (append - `((unless (fboundp ',command) - ;; Here we are checking the marker value set in - ;; `use-package-handler/:ensure' to see if deferred - ;; installation is actually happening. See - ;; `use-package-handler/:defer-install' for more - ;; information. - ,(if (eq (plist-get state :defer-install) :ensure) - (use-package--autoload-with-deferred-install - command name) - `(autoload #',command ,name-string nil t)))) - (when (bound-and-true-p byte-compile-current-file) - `((eval-when-compile - (declare-function ,command ,name-string))))))) - (delete-dups (plist-get state :commands)))) + (cl-mapcan + #'(lambda (command) + (when (symbolp command) + (append + `((unless (fboundp ',command) + ;; Here we are checking the marker value set in + ;; `use-package-handler/:ensure' to see if deferred + ;; installation is actually happening. See + ;; `use-package-handler/:defer-install' for more information. + ,(if (eq (plist-get state :defer-install) :ensure) + (use-package--autoload-with-deferred-install command name) + `(autoload #',command ,name-string nil t)))) + (when (bound-and-true-p byte-compile-current-file) + `((eval-when-compile + (declare-function ,command ,name-string))))))) + (delete-dups (plist-get state :commands))) body))) @@ -1293,11 +1342,10 @@ deferred until the prefix key sequence is pressed." (defalias 'use-package-normalize/:after 'use-package-normalize-recursive-symlist) -(defun use-package-require-after-load - (features) +(defun use-package-require-after-load (features) "Return form for after any of FEATURES require NAME." (pcase features - ((and (pred symbolp) feat) + ((and (pred use-package--non-nil-symbolp) feat) `(lambda (body) (list 'eval-after-load (list 'quote ',feat) (list 'quote body)))) @@ -1418,27 +1466,27 @@ deferred until the prefix key sequence is pressed." (defun use-package-normalize/:hook (name keyword args) (use-package-as-one (symbol-name keyword) args (lambda (label arg) - (unless (or (symbolp arg) (consp arg)) + (unless (or (use-package--non-nil-symbolp arg) (consp arg)) (use-package-error (concat label " a or ( . )" " or list of these"))) (use-package-normalize-pairs #'(lambda (k) - (or (symbolp k) - (and (listp k) - (listp (cdr k)) - (cl-every #'symbolp k)))) - #'(lambda (v) - (or (symbolp v) (functionp v))) + (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 name label arg)))) (defun use-package-handler/:hook (name keyword args rest state) "Generate use-package custom keyword code." - (let ((commands (let (funs) - (dolist (def args) - (if (symbolp (cdr def)) - (setq funs (cons (cdr def) funs)))) - (nreverse funs)))) + (cl-destructuring-bind (nargs . commands) + (use-package--normalize-commands args) (use-package-concat (use-package-process-keywords name (if commands @@ -1456,7 +1504,8 @@ deferred until the prefix key sequence is pressed." #'(lambda (sym) `(add-hook (quote ,(intern (format "%s-hook" sym))) (function ,fun))) - (if (symbolp syms) (list syms) syms)))) args)))) + (if (use-package--non-nil-symbolp syms) (list syms) syms)))) + nargs)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -1471,7 +1520,7 @@ deferred until the prefix key sequence is pressed." (use-package-error (concat label " a ( [comment])" " or list of these"))) - (if (symbolp (car arg)) + (if (use-package--non-nil-symbolp (car arg)) (list arg) arg)))) @@ -1530,7 +1579,7 @@ deferred until the prefix key sequence is pressed." (cond ((not arg) (list (use-package-as-mode name))) - ((symbolp arg) + ((use-package--non-nil-symbolp arg) (list arg)) ((stringp arg) (list (cons (use-package-as-mode name) arg))) @@ -1538,7 +1587,7 @@ deferred until the prefix key sequence is pressed." (list arg)) ((and (not recursed) (listp arg) (listp (cdr arg))) (mapcar #'(lambda (x) (car (use-package-normalize-diminish - name label x t))) arg)) + name label x t))) arg)) (t (use-package-error (concat label " wants a string, symbol, " @@ -1569,7 +1618,8 @@ deferred until the prefix key sequence is pressed." (when (eq :eval (car args)) ;; Handle likely common mistake. (use-package-error ":delight mode line constructs must be quoted")) - (cond ((and (= (length args) 1) (symbolp (car args))) + (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)) @@ -1584,7 +1634,7 @@ deferred until the prefix key sequence is pressed." (cond ((null args) `((,(use-package-as-mode name) nil ,name))) ((and (= (length args) 1) - (symbolp (car args))) + (use-package--non-nil-symbolp (car args))) `((,(car args) nil ,name))) ((and (= (length args) 1) (stringp (car args))) @@ -1599,7 +1649,9 @@ deferred until the prefix key sequence is pressed." `((,(car args) ,@(cdr (nth 1 args)) ,name))) (t (mapcar (apply-partially #'use-package--normalize-delight-1 name) - (if (symbolp (car args)) (list args) args))))) + (if (use-package--non-nil-symbolp (car args)) + (list args) + args))))) (defun use-package-handler/:delight (name keyword args rest state) (let ((body (use-package-process-keywords name rest state))) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index c52c3810439..830ca644990 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -84,6 +84,20 @@ (should (equal (use-package-normalize-diminish 'foopkg :diminish '(foo . "bar")) '((foo . "bar"))))) +(ert-deftest use-package--recognize-function-test () + (should (use-package--recognize-function 'sym)) + (should (use-package--recognize-function #'sym)) + (should (use-package--recognize-function (lambda () ...))) + (should (use-package--recognize-function '(lambda () ...))) + (should (use-package--recognize-function #'(lambda () ...)))) + +(ert-deftest use-package--normalize-function-test () + (should (equal (use-package--normalize-function 'sym) 'sym)) + (should (equal (use-package--normalize-function #'sym) 'sym)) + (should (equal (use-package--normalize-function (lambda () ...)) (lambda () ...))) + (should (equal (use-package--normalize-function '(lambda () ...)) (lambda () ...))) + (should (equal (use-package--normalize-function #'(lambda () ...)) (lambda () ...)))) + ;; Local Variables: ;; indent-tabs-mode: nil ;; no-byte-compile: t From 8051c9f5cdb9455e3c2f1eadb8b201e2f103fee3 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 29 Nov 2017 16:37:55 -0800 Subject: [PATCH 310/606] Update version and copyright --- lisp/use-package/bind-key.el | 9 +++++---- lisp/use-package/use-package.el | 12 ++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index ca6c2a7ceed..eb1ea804d2a 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -1,11 +1,12 @@ ;;; bind-key.el --- A simple way to manage personal keybindings -;; Copyright (c) 2012-2015 john wiegley +;; Copyright (c) 2012-2017 John Wiegley -;; Author: John Wiegley -;; Maintainer: John Wiegley +;; Author: John Wiegley +;; Maintainer: John Wiegley ;; Created: 16 Jun 2012 -;; Version: 1.0 +;; Modified: 29 Nov 2017 +;; Version: 2.4 ;; Keywords: keys keybinding config dotemacs ;; URL: https://github.com/jwiegley/use-package diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 2b5de46ca35..4f3fb137d31 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1,13 +1,13 @@ ;;; use-package.el --- A use-package declaration for simplifying your .emacs -;; Copyright (C) 2012 John Wiegley +;; Copyright (C) 2012-2017 John Wiegley -;; Author: John Wiegley -;; Maintainer: John Wiegley +;; Author: John Wiegley +;; Maintainer: John Wiegley ;; Created: 17 Jun 2012 -;; Modified: 17 Oct 2016 -;; Version: 2.3 -;; Package-Requires: ((emacs "24.3") (bind-key "1.0")) +;; Modified: 29 Nov 2017 +;; Version: 2.4 +;; Package-Requires: ((emacs "24.3") (bind-key "2.4")) ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package From d8c1f02bf4d7ee3720a79ebd7c08e4668bcae310 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 29 Nov 2017 16:44:11 -0800 Subject: [PATCH 311/606] Whitespace fix --- test/lisp/use-package/use-package-tests.el | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 830ca644990..766222b412a 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -68,9 +68,7 @@ (b-mode " b" foo)) (use-package-normalize/:delight 'foo :delight '((a-mode) (b-mode " b"))))) - (should-error (use-package-normalize/:delight 'foo :delight '((:eval 1)))) - - ) + (should-error (use-package-normalize/:delight 'foo :delight '((:eval 1))))) (ert-deftest use-package-normalize-diminish () (should (equal (use-package-normalize-diminish 'foopkg :diminish nil) From 0887e1f9d07f7a0c82836d5991e2dc402b1d967d Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 29 Nov 2017 16:44:20 -0800 Subject: [PATCH 312/606] Correct use-package-normalize-mode --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 4f3fb137d31..07bc2a2a777 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1166,7 +1166,7 @@ representing symbols (that may need to be autloaded)." (use-package-as-one (symbol-name keyword) args (apply-partially #'use-package-normalize-pairs #'use-package-regex-p - #'(lambda (v) (use-package--recognize-function v #'null)) + #'use-package--recognize-function name))) (defun use-package-handle-mode (name alist args rest state) From 6a62122e9c8eca3fe794482c4606e2cdfc976a5f Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 29 Nov 2017 16:48:58 -0800 Subject: [PATCH 313/606] Use backquote rather than quote --- lisp/use-package/use-package.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 07bc2a2a777..c651316ce3c 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1026,7 +1026,7 @@ If RECURSED is non-nil, recurse into sublists." (function (lambda () ...))" (pcase v ((pred use-package--non-nil-symbolp) t) - (`(,(or 'quote 'function) + (`(,(or `quote `function) ,(pred use-package--non-nil-symbolp)) t) ((pred functionp) t) (`(function (lambda . ,_)) t) @@ -1039,7 +1039,7 @@ If RECURSED is non-nil, recurse into sublists." #'(lambda () ...)" (pcase v ((pred use-package--non-nil-symbolp) v) - (`(,(or 'quote 'function) + (`(,(or `quote `function) ,(and sym (pred use-package--non-nil-symbolp))) sym) (`(lambda . ,_) v) (`(quote ,(and lam `(lambda . ,_))) lam) From 1167e7d063a146be0bc7bef2ca3bc1ae61b45277 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 29 Nov 2017 16:53:41 -0800 Subject: [PATCH 314/606] Fix a missing `and' --- lisp/use-package/use-package.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index c651316ce3c..2b8daae009d 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -830,8 +830,8 @@ If the package is installed, its entry is removed from If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." (declare (indent 1)) (if (if args - (listp args) (listp (cdr args)) - allow-empty) + (and (listp args) (listp (cdr args))) + allow-empty) (if (= (length args) 1) (funcall f label (car args)) (funcall f label args)) From 5f2b0cbe8fd7e4293357fb4788afb5ea41e58779 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 29 Nov 2017 21:43:52 -0800 Subject: [PATCH 315/606] Allow keys to be bound to nil Fixes https://github.com/jwiegley/use-package/issues/525 --- lisp/use-package/bind-key.el | 11 ++++++----- lisp/use-package/use-package.el | 33 ++++++++++++++++++--------------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index eb1ea804d2a..e5e06c7cd2a 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -267,11 +267,12 @@ function symbol (unquoted)." (wrap map (cl-mapcan (lambda (form) - (if prefix-map - `((bind-key ,(car form) #',(cdr form) ,prefix-map ,filter)) - (if (and map (not (eq map 'global-map))) - `((bind-key ,(car form) #',(cdr form) ,map ,filter)) - `((bind-key ,(car form) #',(cdr form) nil ,filter))))) + (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))) + `((bind-key ,(car form) ,fun ,map ,filter)) + `((bind-key ,(car form) ,fun nil ,filter)))))) first)) (when next (bind-keys-form diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 2b8daae009d..bc8dd70609f 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1014,6 +1014,7 @@ If RECURSED is non-nil, recurse into sublists." (defun use-package--recognize-function (v &optional additional-pred) "A predicate that recognizes functional constructions: + nil sym 'sym (quote sym) @@ -1025,11 +1026,10 @@ If RECURSED is non-nil, recurse into sublists." #'(lambda () ...) (function (lambda () ...))" (pcase v - ((pred use-package--non-nil-symbolp) t) + ((pred symbolp) t) (`(,(or `quote `function) - ,(pred use-package--non-nil-symbolp)) t) - ((pred functionp) t) - (`(function (lambda . ,_)) t) + ,(pred symbolp)) t) + ((pred commandp) t) (_ (and additional-pred (funcall additional-pred v))))) @@ -1038,9 +1038,9 @@ If RECURSED is non-nil, recurse into sublists." sym #'(lambda () ...)" (pcase v - ((pred use-package--non-nil-symbolp) v) + ((pred symbolp) v) (`(,(or `quote `function) - ,(and sym (pred use-package--non-nil-symbolp))) sym) + ,(and sym (pred symbolp))) sym) (`(lambda . ,_) v) (`(quote ,(and lam `(lambda . ,_))) lam) (`(function ,(and lam `(lambda . ,_))) lam) @@ -1057,10 +1057,12 @@ representing symbols (that may need to be autloaded)." (use-package--normalize-function (cdr x))) x)) args))) (cons nargs - (delete nil (mapcar #'(lambda (x) - (and (consp x) - (use-package--non-nil-symbolp (cdr x)) - (cdr x))) nargs))))) + (delete + nil (mapcar + #'(lambda (x) + (and (consp x) + (use-package--non-nil-symbolp (cdr x)) + (cdr x))) nargs))))) (defun use-package-normalize-binder (name keyword args) (use-package-as-one (symbol-name keyword) args @@ -1500,11 +1502,12 @@ representing symbols (that may need to be autloaded)." (lambda (def) (let ((syms (car def)) (fun (cdr def))) - (mapcar - #'(lambda (sym) - `(add-hook (quote ,(intern (format "%s-hook" sym))) - (function ,fun))) - (if (use-package--non-nil-symbolp syms) (list syms) syms)))) + (when fun + (mapcar + #'(lambda (sym) + `(add-hook (quote ,(intern (format "%s-hook" sym))) + (function ,fun))) + (if (use-package--non-nil-symbolp syms) (list syms) syms))))) nargs)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; From fab33fef3a145e5216f9c708a31b1a4639f64f95 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 29 Nov 2017 22:03:03 -0800 Subject: [PATCH 316/606] Correction to use-package--recognize-function Finishes https://github.com/jwiegley/use-package/issues/525 --- lisp/use-package/use-package.el | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index bc8dd70609f..5eb2b23936d 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1012,7 +1012,7 @@ If RECURSED is non-nil, recurse into sublists." (setq last-item x))) arg))) (t arg))) -(defun use-package--recognize-function (v &optional additional-pred) +(defun use-package--recognize-function (v &optional binding additional-pred) "A predicate that recognizes functional constructions: nil sym @@ -1026,10 +1026,12 @@ If RECURSED is non-nil, recurse into sublists." #'(lambda () ...) (function (lambda () ...))" (pcase v - ((pred symbolp) t) + ((and x (guard (if binding + (symbolp x) + (use-package--non-nil-symbolp x)))) t) (`(,(or `quote `function) - ,(pred symbolp)) t) - ((pred commandp) t) + ,(pred use-package--non-nil-symbolp)) t) + ((and x (guard (if binding (commandp x) (functionp x)))) t) (_ (and additional-pred (funcall additional-pred v))))) @@ -1076,7 +1078,7 @@ representing symbols (that may need to be autloaded)." (pcase k ((pred stringp) t) ((pred vectorp) t))) - #'(lambda (v) (use-package--recognize-function v #'stringp)) + #'(lambda (v) (use-package--recognize-function v t #'stringp)) name label arg)))) (defalias 'use-package-normalize/:bind 'use-package-normalize-binder) From 5e1a656e06654d297c21dbf1c6ebb31696d3b4f9 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 29 Nov 2017 22:10:01 -0800 Subject: [PATCH 317/606] Using :load-path without also using :ensure now implies :ensure nil Fixes https://github.com/jwiegley/use-package/issues/190 --- etc/USE-PACKAGE-NEWS | 1 + lisp/use-package/use-package.el | 3 +++ 2 files changed, 4 insertions(+) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index a4f20070e6a..b0265fa5515 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -27,6 +27,7 @@ - Support multiple symbols passed to `:after`, and a mini-DSL using `:all` and `:any`. - `:mode` and `:interpreter` can now accept `(rx ...)` forms. +- Using `:load-path` without also using `:ensure` now implies `:ensure nil`. - `:bind (:map foo-map ...)` now defers binding in the map until the package has been loaded. - Print key bindings for keymaps in `describe-personal-keybindings`. diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 5eb2b23936d..b07f205adc7 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1764,6 +1764,9 @@ this file. Usage: (not (memq :defer args))) (append args '(:demand t)) args))) + (when (and (plist-member args* :load-path) + (not (plist-member args* :ensure))) + (plist-put args* :ensure nil)) (unless (plist-member args* :init) (plist-put args* :init nil)) (unless (plist-member args* :config) From 35f46f7b42a3a282a8b00492120031b82e1391f7 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 29 Nov 2017 22:20:43 -0800 Subject: [PATCH 318/606] Restructure some code --- lisp/use-package/use-package.el | 39 +++++++++++++++++---------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index b07f205adc7..8d44d37e0af 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -729,31 +729,32 @@ If the package is installed, its entry is removed from "(an unquoted symbol name)"))))))) (defun use-package-ensure-elpa (name ensure state context &optional no-refresh) - (let ((package (or (when (eq ensure t) (use-package-as-symbol name)) + (let ((package (or (and (eq ensure t) (use-package-as-symbol name)) ensure))) (when package (require 'package) (or (package-installed-p package) - (not (or - ;; Contexts in which the confirmation prompt is - ;; bypassed. - (member context '(:byte-compile :ensure :config)) - (y-or-n-p (format "Install package %S?" package)))) + ;; Contexts in which the confirmation prompt is bypassed. + (not (or (member context '(:byte-compile :ensure :config)) + (y-or-n-p (format "Install package %S?" package)))) (condition-case-unless-debug err - (progn - (when (assoc package (bound-and-true-p package-pinned-packages)) + (let ((pinned (assoc package (bound-and-true-p + package-pinned-packages)))) + (when pinned (package-read-all-archive-contents)) - (cond ((assoc package package-archive-contents) - (package-install package) - t) - (t - (package-refresh-contents) - (when (assoc package - (bound-and-true-p package-pinned-packages)) - (package-read-all-archive-contents)) - (package-install package)))) - (error (message "Error: Cannot load %s: %S" name err) - nil)))))) + (if (assoc package package-archive-contents) + (package-install package) + (package-refresh-contents) + (when pinned + (package-read-all-archive-contents)) + (package-install package)) + t) + (error + (ignore + (display-warning 'use-package + (format "Failed to install %s: %s" + name (error-message-string err)) + :error)))))))) (defun use-package-handler/:ensure (name keyword ensure rest state) (let* ((body (use-package-process-keywords name rest From 3cb64648fcbe9732a88f5f59ee4f9c20a723e863 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 29 Nov 2017 23:08:22 -0800 Subject: [PATCH 319/606] Only add :ensure nil on :load-path if use-package-always-ensure is t --- lisp/use-package/use-package.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 8d44d37e0af..7a09a3be1b2 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1765,7 +1765,8 @@ this file. Usage: (not (memq :defer args))) (append args '(:demand t)) args))) - (when (and (plist-member args* :load-path) + (when (and use-package-always-ensure + (plist-member args* :load-path) (not (plist-member args* :ensure))) (plist-put args* :ensure nil)) (unless (plist-member args* :init) From 3847ec28ca1dc252042871b4b109fd5f906ce6af Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 30 Nov 2017 09:14:28 -0800 Subject: [PATCH 320/606] Allow :ensure to take a nil value again Fixes https://github.com/jwiegley/use-package/issues/526 --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 7a09a3be1b2..bf9d1c82709 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -722,7 +722,7 @@ If the package is installed, its entry is removed from t (use-package-only-one (symbol-name keyword) args (lambda (label arg) - (if (use-package--non-nil-symbolp arg) + (if (symbolp arg) arg (use-package-error (concat ":ensure wants an optional package name " From 3ea2d34219af6b23f0d8414a4d5b966f8bfd8e79 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 30 Nov 2017 09:42:47 -0800 Subject: [PATCH 321/606] Add stubs for future tests of all keywords --- test/lisp/use-package/use-package-tests.el | 197 +++++++++++++++++---- 1 file changed, 167 insertions(+), 30 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 766222b412a..a0851b0dd57 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -25,10 +25,76 @@ (require 'ert) (require 'use-package) -(ert-deftest use-package-normalize-binder () +(ert-deftest use-package-test-recognize-function () + (should (use-package--recognize-function 'sym)) + (should (use-package--recognize-function #'sym)) + (should (use-package--recognize-function (lambda () ...))) + (should (use-package--recognize-function '(lambda () ...))) + (should (use-package--recognize-function #'(lambda () ...))) + + (should-not (use-package--recognize-function 1)) + (should-not (use-package--recognize-function "Hello")) + (should-not (use-package--recognize-function '(nil . nil)))) + +(ert-deftest use-package-test-normalize-function () + (should (equal (use-package--normalize-function 'sym) 'sym)) + (should (equal (use-package--normalize-function #'sym) 'sym)) + (should (equal (use-package--normalize-function (lambda () ...)) (lambda () ...))) + (should (equal (use-package--normalize-function '(lambda () ...)) (lambda () ...))) + (should (equal (use-package--normalize-function #'(lambda () ...)) (lambda () ...))) + + (should (equal (use-package--normalize-function 1) 1)) + (should (equal (use-package--normalize-function "Hello") "Hello")) + (should (equal (use-package--normalize-function '(nil . nil)) '(nil . nil)))) + +;; (ert-deftest use-package-test/:disabled () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:preface () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:pin () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:defer-install () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:ensure () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:if () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:when () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:unless () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:requires () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:load-path () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:no-require () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +(ert-deftest use-package-test-normalize/:bind () (let ((good-values '(:map map-sym - ("str" . sym) ("str" . "str") - ([vec] . sym) ([vec] . "str")))) + ("str" . sym) ("str" . "str") + ([vec] . sym) ([vec] . "str")))) (should (equal (use-package-normalize-binder 'foopkg :bind good-values) good-values))) @@ -39,7 +105,27 @@ (should-error (use-package-normalize-binder 'foopkg :bind '(99 . sym)))) -(ert-deftest use-package-normalize-mode () +;; (ert-deftest use-package-test/:bind () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:bind* () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:bind-keymap () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:bind-keymap* () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:interpreter () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +(ert-deftest use-package-test-normalize/:mode () (should (equal (use-package-normalize-mode 'foopkg :mode '(".foo")) '((".foo" . foopkg)))) (should (equal (use-package-normalize-mode 'foopkg :mode '(".foo" ".bar")) @@ -51,7 +137,80 @@ (should (equal (use-package-normalize-mode 'foopkg :mode '((".foo" . foo) (".bar" . bar))) '((".foo" . foo) (".bar" . bar))))) -(ert-deftest use-package-normalize-delight () +;; (ert-deftest use-package-test/:mode () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:magic () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:magic-fallback () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:commands () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:defines () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:functions () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:defer () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:hook () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:custom () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:custom-face () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:init () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +(ert-deftest use-package-test/:after () + (should (equal (macroexpand '(use-package foo :after bar)) + '(eval-after-load 'bar + '(require 'foo nil t))))) + +;; (ert-deftest use-package-test/:demand () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +;; (ert-deftest use-package-test/:config () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +(ert-deftest use-package-test-normalize/:diminish () + (should (equal (use-package-normalize-diminish 'foopkg :diminish nil) + '(foopkg-mode))) + (should (equal (use-package-normalize-diminish 'foopkg :diminish 'bar) + '(bar))) + (should (equal (use-package-normalize-diminish 'foopkg :diminish "bar") + '((foopkg-mode . "bar")))) + (should (equal (use-package-normalize-diminish 'foopkg :diminish 'foo-mode) + '(foo-mode))) + (should (equal (use-package-normalize-diminish 'foopkg :diminish '(foo . "bar")) + '((foo . "bar"))))) + +;; (ert-deftest use-package-test/:diminish () +;; (should (equal (macroexpand (use-package)) +;; '()))) + +(ert-deftest use-package-test-normalize/:delight () (should (equal `((foo-mode nil foo)) (use-package-normalize/:delight 'foo :delight nil))) (should (equal `((foo-mode nil foo-mode)) @@ -70,31 +229,9 @@ (b-mode " b"))))) (should-error (use-package-normalize/:delight 'foo :delight '((:eval 1))))) -(ert-deftest use-package-normalize-diminish () - (should (equal (use-package-normalize-diminish 'foopkg :diminish nil) - '(foopkg-mode))) - (should (equal (use-package-normalize-diminish 'foopkg :diminish 'bar) - '(bar))) - (should (equal (use-package-normalize-diminish 'foopkg :diminish "bar") - '((foopkg-mode . "bar")))) - (should (equal (use-package-normalize-diminish 'foopkg :diminish 'foo-mode) - '(foo-mode))) - (should (equal (use-package-normalize-diminish 'foopkg :diminish '(foo . "bar")) - '((foo . "bar"))))) - -(ert-deftest use-package--recognize-function-test () - (should (use-package--recognize-function 'sym)) - (should (use-package--recognize-function #'sym)) - (should (use-package--recognize-function (lambda () ...))) - (should (use-package--recognize-function '(lambda () ...))) - (should (use-package--recognize-function #'(lambda () ...)))) - -(ert-deftest use-package--normalize-function-test () - (should (equal (use-package--normalize-function 'sym) 'sym)) - (should (equal (use-package--normalize-function #'sym) 'sym)) - (should (equal (use-package--normalize-function (lambda () ...)) (lambda () ...))) - (should (equal (use-package--normalize-function '(lambda () ...)) (lambda () ...))) - (should (equal (use-package--normalize-function #'(lambda () ...)) (lambda () ...)))) +;; (ert-deftest use-package-test/:delight () +;; (should (equal (macroexpand (use-package)) +;; '()))) ;; Local Variables: ;; indent-tabs-mode: nil From c3b9cc2403a4a8773b26c74d79d4090cdee2cf55 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 30 Nov 2017 10:38:01 -0800 Subject: [PATCH 322/606] Add two new tests --- test/lisp/use-package/use-package-tests.el | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index a0851b0dd57..4eb91165780 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -165,10 +165,40 @@ ;; (should (equal (macroexpand (use-package)) ;; '()))) +(ert-deftest use-package-test-normalize/:hook () + (should-error (use-package-normalize/:hook 'foopkg :hook nil)) + (should (equal (use-package-normalize/:hook 'foopkg :hook '(bar)) + '((bar . foopkg)))) + (should (equal (use-package-normalize/:hook 'foopkg :hook '((bar . baz))) + '((bar . baz)))) + (should (equal (use-package-normalize/:hook 'foopkg :hook '(((bar baz) . quux))) + '(((bar baz) . quux)))) + (should (equal (use-package-normalize/:hook 'foopkg :hook '(bar baz)) + '(((bar baz) . foopkg)))) + (should (equal (use-package-normalize/:hook 'foopkg :hook '((bar baz) (quux bow))) + '(((bar baz) . foopkg) ((quux bow) . foopkg)))) + (should (equal (use-package-normalize/:hook 'foopkg :hook '((bar . baz) (quux . bow))) + '((bar . baz) (quux . bow)))) + (should (equal (use-package-normalize/:hook 'foopkg :hook '(((bar1 bar2) . baz) + ((quux1 quux2) . bow))) + '(((bar1 bar2) . baz) + ((quux1 quux2) . bow))))) + ;; (ert-deftest use-package-test/:hook () ;; (should (equal (macroexpand (use-package)) ;; '()))) +(ert-deftest use-package-test-normalize/:custom () + (should-error (use-package-normalize/:custom 'foopkg :custom nil)) + (should-error (use-package-normalize/:custom 'foopkg :custom '(bar))) + ;; (should-error (use-package-normalize/:custom 'foopkg :custom '((foo bar baz quux)))) + (should (equal (use-package-normalize/:custom 'foopkg :custom '(foo bar)) + '((foo bar)))) + ;; (should-error (use-package-normalize/:custom 'foopkg :custom '(foo bar baz))) + ;; (should (equal (use-package-normalize/:custom 'foopkg :custom '(foo bar "baz")) + ;; '((foo bar baz)))) + ) + ;; (ert-deftest use-package-test/:custom () ;; (should (equal (macroexpand (use-package)) ;; '()))) From 2ff8af64956d77dfea001306c857b70196f051f8 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 30 Nov 2017 11:05:46 -0800 Subject: [PATCH 323/606] Add a use-package-version variable --- lisp/use-package/use-package.el | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index bf9d1c82709..850e37be00c 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -48,6 +48,9 @@ (declare-function package-installed-p "package") (declare-function package-read-all-archive-contents "package" ()) +(defconst use-package-version "2.4" + "This version of use-package.") + (defgroup use-package nil "A use-package declaration for simplifying your `.emacs'." :group 'startup) From 1fc543a212021bc911a082bdfc7cc81eb401c0d4 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 30 Nov 2017 11:20:17 -0800 Subject: [PATCH 324/606] Don't check for an :ensure that use-package-always-ensure may have added Fixes https://github.com/jwiegley/use-package/issues/190 --- lisp/use-package/use-package.el | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 850e37be00c..0d86cc00e99 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1769,8 +1769,7 @@ this file. Usage: (append args '(:demand t)) args))) (when (and use-package-always-ensure - (plist-member args* :load-path) - (not (plist-member args* :ensure))) + (plist-member args* :load-path)) (plist-put args* :ensure nil)) (unless (plist-member args* :init) (plist-put args* :init nil)) From ca94036dce4b8018d3ac8f4798eba49af87e6bf6 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 30 Nov 2017 12:38:01 -0800 Subject: [PATCH 325/606] Add a test case for :ensure, following up from GitHub-reference: https://github.com/jwiegley/use-package/issues/190 --- test/lisp/use-package/use-package-tests.el | 114 +++++++++++++++++++-- 1 file changed, 108 insertions(+), 6 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 4eb91165780..f45c4a38462 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -25,6 +25,19 @@ (require 'ert) (require 'use-package) +(defmacro expand-minimally (form) + `(let ((use-package-verbose nil) + (use-package-expand-minimally t)) + (macroexpand ',form))) + +(defmacro match-expansion (form value) + `(should (pcase (expand-minimally ,form) + (,value t)))) + +;; `cl-flet' does not work for the mocking we do below, while `flet' does. +(eval-when-compile + (setplist 'flet (plist-delete (symbol-plist 'flet) 'byte-obsolete-info))) + (ert-deftest use-package-test-recognize-function () (should (use-package--recognize-function 'sym)) (should (use-package--recognize-function #'sym)) @@ -63,9 +76,97 @@ ;; (should (equal (macroexpand (use-package)) ;; '()))) -;; (ert-deftest use-package-test/:ensure () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(defvar tried-to-install) + +(ert-deftest use-package-test/:ensure () + (let ((use-package-always-ensure nil)) + (match-expansion + (use-package foo :ensure t) + `(progn + (use-package-ensure-elpa 'foo 't 'nil :ensure) + (require 'foo nil 'nil)))) + + (let ((use-package-always-ensure t)) + (match-expansion + (use-package foo :ensure t) + `(progn + (use-package-ensure-elpa 'foo 't 'nil :ensure) + (require 'foo nil 'nil)))) + + (let ((use-package-always-ensure nil)) + (match-expansion + (use-package foo :ensure nil) + `(progn + (use-package-ensure-elpa 'foo 'nil 'nil :ensure) + (require 'foo nil 'nil)))) + + (let ((use-package-always-ensure t)) + (match-expansion + (use-package foo :ensure nil) + `(progn + (use-package-ensure-elpa 'foo 'nil 'nil :ensure) + (require 'foo nil 'nil)))) + + (let ((use-package-always-ensure nil)) + (match-expansion + (use-package foo :load-path "foo") + `(progn + (eval-and-compile + (add-to-list 'load-path ,(pred stringp))) + (require 'foo nil 'nil)))) + + (let ((use-package-always-ensure t)) + (match-expansion + (use-package foo :load-path "foo") + `(progn + (use-package-ensure-elpa 'foo 'nil 'nil :ensure) + (eval-and-compile + (add-to-list 'load-path ,(pred stringp))) + (require 'foo nil 'nil)))) + + (let ((use-package-always-ensure nil)) + (match-expansion + (use-package foo :ensure nil :load-path "foo") + `(progn + (use-package-ensure-elpa 'foo 'nil 'nil :ensure) + (eval-and-compile + (add-to-list 'load-path ,(pred stringp))) + (require 'foo nil 'nil)))) + + (let ((use-package-always-ensure t)) + (match-expansion + (use-package foo :ensure nil :load-path "foo") + `(progn + (use-package-ensure-elpa 'foo 'nil 'nil :ensure) + (eval-and-compile + (add-to-list 'load-path ,(pred stringp))) + (require 'foo nil 'nil)))) + + (let ((use-package-always-ensure nil)) + (match-expansion + (use-package foo :ensure t :load-path "foo") + `(progn + (use-package-ensure-elpa 'foo 't 'nil :ensure) + (eval-and-compile + (add-to-list 'load-path ,(pred stringp))) + (require 'foo nil 'nil)))) + + (let ((use-package-always-ensure t)) + (match-expansion + (use-package foo :ensure t :load-path "foo") + `(progn + (use-package-ensure-elpa 'foo 't 'nil :ensure) + (eval-and-compile + (add-to-list 'load-path ,(pred stringp))) + (require 'foo nil 'nil)))) + + (flet ((use-package-ensure-elpa + (name ensure state context &optional no-refresh) + (when ensure + (setq tried-to-install name)))) + (let (tried-to-install) + (eval '(use-package foo :ensure t)) + (should (eq tried-to-install 'foo))))) ;; (ert-deftest use-package-test/:if () ;; (should (equal (macroexpand (use-package)) @@ -212,9 +313,10 @@ ;; '()))) (ert-deftest use-package-test/:after () - (should (equal (macroexpand '(use-package foo :after bar)) - '(eval-after-load 'bar - '(require 'foo nil t))))) + (match-expansion + (use-package foo :after bar) + `(eval-after-load 'bar + '(require 'foo nil t)))) ;; (ert-deftest use-package-test/:demand () ;; (should (equal (macroexpand (use-package)) From 0be868d39b544a00f274eb03305b85f13386e5d2 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 30 Nov 2017 12:38:13 -0800 Subject: [PATCH 326/606] A final fix to :ensure + :load-path Fixes https://github.com/jwiegley/use-package/issues/190 --- lisp/use-package/use-package.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 0d86cc00e99..748074ad115 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1734,6 +1734,7 @@ this file. Usage: (declare (indent 1)) (unless (member :disabled args) (let ((name-symbol (if (stringp name) (intern name) name)) + (orig-args args) (args (use-package-normalize-plist name args))) (dolist (spec use-package-defaults) (setq args (use-package-sort-keywords @@ -1769,7 +1770,8 @@ this file. Usage: (append args '(:demand t)) args))) (when (and use-package-always-ensure - (plist-member args* :load-path)) + (plist-member args* :load-path) + (not (plist-member orig-args :ensure))) (plist-put args* :ensure nil)) (unless (plist-member args* :init) (plist-put args* :init nil)) From 98ee89a7525cd1216c663de81445bfaa680e5b48 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 30 Nov 2017 12:39:04 -0800 Subject: [PATCH 327/606] Remove an unneeded defvar --- test/lisp/use-package/use-package-tests.el | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index f45c4a38462..29a0b99512e 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -76,8 +76,6 @@ ;; (should (equal (macroexpand (use-package)) ;; '()))) -(defvar tried-to-install) - (ert-deftest use-package-test/:ensure () (let ((use-package-always-ensure nil)) (match-expansion @@ -160,11 +158,11 @@ (add-to-list 'load-path ,(pred stringp))) (require 'foo nil 'nil)))) - (flet ((use-package-ensure-elpa - (name ensure state context &optional no-refresh) - (when ensure - (setq tried-to-install name)))) - (let (tried-to-install) + (let (tried-to-install) + (flet ((use-package-ensure-elpa + (name ensure state context &optional no-refresh) + (when ensure + (setq tried-to-install name)))) (eval '(use-package foo :ensure t)) (should (eq tried-to-install 'foo))))) From 9465b915a84a330665e6e2334a8c9635f68caa5e Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 30 Nov 2017 18:36:45 -0800 Subject: [PATCH 328/606] Add the missing plist-delete --- test/lisp/use-package/use-package-tests.el | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 29a0b99512e..43ecb316aca 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -36,6 +36,15 @@ ;; `cl-flet' does not work for the mocking we do below, while `flet' does. (eval-when-compile + (defun plist-delete (plist property) + "Delete PROPERTY from PLIST" + (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)) + (setplist 'flet (plist-delete (symbol-plist 'flet) 'byte-obsolete-info))) (ert-deftest use-package-test-recognize-function () From 7a562f10cbdcf13e1f37a2aa964f63c7f7cdb1a3 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 30 Nov 2017 18:37:27 -0800 Subject: [PATCH 329/606] Add test for use-package-test-normalize/:ensure --- test/lisp/use-package/use-package-tests.el | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 43ecb316aca..e27d7f28851 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -85,6 +85,16 @@ ;; (should (equal (macroexpand (use-package)) ;; '()))) +(ert-deftest use-package-test-normalize/:ensure () + (flet ((norm (&rest args) + (apply #'use-package-normalize/:ensure + 'foopkg :ensure args))) + (should (equal (norm '(t)) t)) + (should (equal (norm '(nil)) nil)) + (should (equal (norm '(sym)) 'sym)) + (should-error (norm '(1))) + (should-error (norm '("Hello"))))) + (ert-deftest use-package-test/:ensure () (let ((use-package-always-ensure nil)) (match-expansion From dfd3194d80e9c0ccd4623e47c745debf4028e06f Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 30 Nov 2017 19:40:54 -0800 Subject: [PATCH 330/606] Allow match-expansion to take multiple cases --- test/lisp/use-package/use-package-tests.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index e27d7f28851..35645fdce82 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -30,9 +30,9 @@ (use-package-expand-minimally t)) (macroexpand ',form))) -(defmacro match-expansion (form value) +(defmacro match-expansion (form &rest value) `(should (pcase (expand-minimally ,form) - (,value t)))) + ,@(mapcar #'(lambda (x) (list x t)) value)))) ;; `cl-flet' does not work for the mocking we do below, while `flet' does. (eval-when-compile From 0791e3fefe73e09b853014129db78b3b16949f3f Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 30 Nov 2017 20:35:29 -0800 Subject: [PATCH 331/606] Code reformatting --- lisp/use-package/use-package.el | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 748074ad115..7a7b4660ca0 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -42,8 +42,9 @@ (require 'bind-key) (require 'bytecomp) (require 'cl-lib) -(eval-when-compile (require 'cl)) -(eval-when-compile (require 'regexp-opt)) +(eval-when-compile + (require 'cl) + (require 'regexp-opt)) (declare-function package-installed-p "package") (declare-function package-read-all-archive-contents "package" ()) @@ -683,11 +684,8 @@ If the package is installed, its entry is removed from (if packages (list (intern - (completing-read - "Select package: " - packages - nil - 'require-match)) + (completing-read "Select package: " + packages nil 'require-match)) :interactive) (user-error "No packages with deferred installation")))) (let ((spec (gethash name use-package--deferred-packages))) @@ -960,7 +958,7 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." (defun use-package-handler/:preface (name keyword arg rest state) (let ((body (use-package-process-keywords name rest state))) (use-package-concat - (unless (null arg) + (when arg `((eval-and-compile ,@arg))) body))) @@ -1450,11 +1448,13 @@ representing symbols (that may need to be autloaded)." (unless (or (null config-body) (equal config-body '(t))) `((eval-after-load ,(if (symbolp name) `',name name) ',(macroexp-progn config-body)))) - ;; Here we are checking the marker value for deferred - ;; installation set in `use-package-handler/:ensure'. See also + + ;; Here we are checking the marker value for deferred installation set + ;; in `use-package-handler/:ensure'. See also ;; `use-package-handler/:defer-install'. (when (eq (plist-get state :defer-install) :ensure) (use-package-install-deferred-package name :config)) + (use-package--with-elapsed-timer (format "Loading package %s" name) (if use-package-expand-minimally From 1a09f8fef22d477c2a04fdf4bcda62f26d818a6f Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 30 Nov 2017 21:45:17 -0800 Subject: [PATCH 332/606] :no-require t should never require --- lisp/use-package/use-package.el | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 7a7b4660ca0..d55a4c0c437 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -933,7 +933,8 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." (defun use-package-handler/:no-require (name keyword arg rest state) ;; This keyword has no functional meaning. - (use-package-process-keywords name rest state)) + (use-package-process-keywords name rest + (plist-put state :no-require t))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -1459,12 +1460,15 @@ representing symbols (that may need to be autloaded)." (format "Loading package %s" name) (if use-package-expand-minimally (use-package-concat - (list (use-package-load-name name)) + (unless (plist-get state ':no-require) + (list (use-package-load-name name))) config-body) - `((if (not ,(use-package-load-name name t)) - (ignore - (message (format "Cannot load %s" ',name))) - ,@config-body))))))) + (if (plist-get state ':no-require) + config-body + `((if (not ,(use-package-load-name name t)) + (ignore + (message (format "Cannot load %s" ',name))) + ,@config-body)))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; From af8b961716e4338b779a916b5ea203fc4ba63309 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 1 Dec 2017 00:44:17 -0800 Subject: [PATCH 333/606] Change the :config default, if none has been set in vars --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index d55a4c0c437..0983500e3a9 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1780,7 +1780,7 @@ this file. Usage: (unless (plist-member args* :init) (plist-put args* :init nil)) (unless (plist-member args* :config) - (plist-put args* :config nil)) + (plist-put args* :config '(t))) args*) (and use-package-always-defer (list :deferred t)))))) From 669e8527fb28d51dc0b12ab0dfa2c749ab549fec Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 1 Dec 2017 00:44:49 -0800 Subject: [PATCH 334/606] Sort keywords at the appropriate time --- lisp/use-package/use-package.el | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 0983500e3a9..2ab0135e753 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1741,11 +1741,10 @@ this file. Usage: (orig-args args) (args (use-package-normalize-plist name args))) (dolist (spec use-package-defaults) - (setq args (use-package-sort-keywords - (if (eval (nth 2 spec)) - (use-package-plist-maybe-put - args (nth 0 spec) (eval (nth 1 spec))) - args)))) + (setq args (if (eval (nth 2 spec)) + (use-package-plist-maybe-put + args (nth 0 spec) (eval (nth 1 spec))) + args))) ;; When byte-compiling, pre-load the package so all its symbols are in ;; scope. @@ -1769,10 +1768,12 @@ this file. Usage: (let ((body (macroexp-progn (use-package-process-keywords name - (let ((args* (if (and use-package-always-demand - (not (memq :defer args))) - (append args '(:demand t)) - args))) + (let ((args* + (use-package-sort-keywords + (if (and use-package-always-demand + (not (memq :defer args))) + (plist-put args :demand t) + args)))) (when (and use-package-always-ensure (plist-member args* :load-path) (not (plist-member orig-args :ensure))) From 5f1e8b6b72cdd3abca0a59d22608146b67d1ef32 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 1 Dec 2017 00:45:04 -0800 Subject: [PATCH 335/606] Always use `load' when loading for the sake of compilation --- lisp/use-package/use-package.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 2ab0135e753..044d79d4a95 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1763,7 +1763,9 @@ this file. Usage: ,(if (eq use-package-verbose 'debug) `(message "Compiling package %s" ',name-symbol)) ,(unless (plist-get args :no-require) - (use-package-load-name name))))))) + `(load ,(if (stringp name) + name + (symbol-name name)) nil t))))))) (let ((body (macroexp-progn From 2c618e17c6f6ef024a4ea30fec2a5fbf12d2b2f1 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 1 Dec 2017 00:45:43 -0800 Subject: [PATCH 336/606] Don't macroexpand bind-keys, leave that to the evaluator --- lisp/use-package/use-package.el | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 044d79d4a95..c6c83f7e3d2 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1097,9 +1097,8 @@ representing symbols (that may need to be autloaded)." (use-package-plist-maybe-put rest :defer t)) (use-package-plist-append state :commands commands)) `((ignore - ,(macroexpand - `(,(if bind-macro bind-macro 'bind-keys) - :package ,name ,@nargs))))))) + (,(if bind-macro bind-macro 'bind-keys) + :package ,name ,@nargs)))))) (defun use-package-handler/:bind* (name keyword arg rest state) (use-package-handler/:bind name keyword arg rest state 'bind-keys*)) From f674a75b6145b8f7eb7e2430405f7cf394e4f2b5 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 1 Dec 2017 00:46:45 -0800 Subject: [PATCH 337/606] Move :hook before :defer --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index c6c83f7e3d2..b3afefe1490 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -160,8 +160,8 @@ the user specified." :commands :defines :functions - :defer :hook + :defer :custom :custom-face :init From 07ab280741b91e1c96fa757e2ac5b6b6b56ac9eb Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 1 Dec 2017 00:46:57 -0800 Subject: [PATCH 338/606] Whitespace fix --- lisp/use-package/use-package.el | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index b3afefe1490..8f08865f334 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1141,17 +1141,18 @@ representing symbols (that may need to be autloaded)." (defun use-package-handler/:bind-keymap (name keyword arg rest state &optional override) - (let ((form (mapcar - #'(lambda (binding) - `(,(if override - 'bind-key* - 'bind-key) - ,(car binding) - #'(lambda () - (interactive) - (use-package-autoload-keymap - ',(cdr binding) ',(use-package-as-symbol name) - ,override)))) arg))) + (let ((form + (mapcar + #'(lambda (binding) + `(,(if override + 'bind-key* + 'bind-key) + ,(car binding) + #'(lambda () + (interactive) + (use-package-autoload-keymap + ',(cdr binding) ',(use-package-as-symbol name) + ,override)))) arg))) (use-package-concat (use-package-process-keywords name (use-package-sort-keywords From b5b432d0febb8348f137024a6320d25a98a25aeb Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 1 Dec 2017 01:04:35 -0800 Subject: [PATCH 339/606] Correct the ordering of :preface, :load-path, :defines and :functions --- lisp/use-package/use-package.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 8f08865f334..95c20b72cd2 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -139,7 +139,6 @@ the user specified." (defcustom use-package-keywords '(:disabled - :preface :pin :defer-install :ensure @@ -148,6 +147,9 @@ the user specified." :unless :requires :load-path + :defines + :functions + :preface :no-require :bind :bind* @@ -158,8 +160,6 @@ the user specified." :magic :magic-fallback :commands - :defines - :functions :hook :defer :custom From 88f8c1bb8f87dead10a8c4f980c1c32df9100f6f Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 1 Dec 2017 01:04:52 -0800 Subject: [PATCH 340/606] Generate :defines and :functions correctly So they actually inhibit byte-compilation warnings as they were meant to. --- lisp/use-package/use-package.el | 45 +++++++++++++-------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 95c20b72cd2..513ec1314e5 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1252,8 +1252,7 @@ representing symbols (that may need to be autloaded)." (defalias 'use-package-normalize/:defines 'use-package-normalize-symlist) (defun use-package-handler/:defines (name keyword arg rest state) - (let ((body (use-package-process-keywords name rest state))) - body)) + (use-package-process-keywords name rest state)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -1263,16 +1262,7 @@ representing symbols (that may need to be autloaded)." (defalias 'use-package-normalize/:functions 'use-package-normalize-symlist) (defun use-package-handler/:functions (name keyword arg rest state) - (let ((body (use-package-process-keywords name rest state))) - (if (not (bound-and-true-p byte-compile-current-file)) - body - (use-package-concat - (unless (null arg) - `((eval-when-compile - ,@(mapcar - #'(lambda (fn) - `(declare-function ,fn ,(use-package-as-string name))) arg)))) - body)))) + (use-package-process-keywords name rest state)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -1750,22 +1740,23 @@ this file. Usage: ;; scope. (if (bound-and-true-p byte-compile-current-file) (setq args - (use-package-plist-cons + (use-package-plist-append args :preface - `(eval-when-compile - ,@(mapcar #'(lambda (var) `(defvar ,var)) - (plist-get args :defines)) - ,@(mapcar #'(lambda (fn) `(declare-function - ,fn ,(use-package-as-string name))) - (plist-get args :functions)) - (with-demoted-errors - ,(format "Cannot load %s: %%S" name) - ,(if (eq use-package-verbose 'debug) - `(message "Compiling package %s" ',name-symbol)) - ,(unless (plist-get args :no-require) - `(load ,(if (stringp name) - name - (symbol-name name)) nil t))))))) + (use-package-concat + (mapcar #'(lambda (var) `(defvar ,var)) + (plist-get args :defines)) + (mapcar #'(lambda (fn) `(declare-function + ,fn ,(use-package-as-string name))) + (plist-get args :functions)) + `((eval-when-compile + (with-demoted-errors + ,(format "Cannot load %s: %%S" name) + ,(if (eq use-package-verbose 'debug) + `(message "Compiling package %s" ',name-symbol)) + ,(unless (plist-get args :no-require) + `(load ,(if (stringp name) + name + (symbol-name name)) nil t))))))))) (let ((body (macroexp-progn From 7f2eec9e654cb0faf9da423b8f7a69738c2336dd Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 1 Dec 2017 01:33:01 -0800 Subject: [PATCH 341/606] Add many new tests --- test/lisp/use-package/use-package-tests.el | 310 ++++++++++++++++++--- 1 file changed, 277 insertions(+), 33 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 35645fdce82..75ed42c229b 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -25,6 +25,10 @@ (require 'ert) (require 'use-package) +(setq use-package-always-ensure nil + use-package-verbose nil + use-package-expand-minimally t) + (defmacro expand-minimally (form) `(let ((use-package-verbose nil) (use-package-expand-minimally t)) @@ -34,7 +38,6 @@ `(should (pcase (expand-minimally ,form) ,@(mapcar #'(lambda (x) (list x t)) value)))) -;; `cl-flet' does not work for the mocking we do below, while `flet' does. (eval-when-compile (defun plist-delete (plist property) "Delete PROPERTY from PLIST" @@ -45,9 +48,14 @@ (setq plist (cddr plist))) p)) + ;; `cl-flet' does not work for some of the mocking we do below, while `flet' + ;; always does. (setplist 'flet (plist-delete (symbol-plist 'flet) 'byte-obsolete-info))) (ert-deftest use-package-test-recognize-function () + (should (use-package--recognize-function nil t)) + (should-not (use-package--recognize-function nil)) + (should (use-package--recognize-function t)) (should (use-package--recognize-function 'sym)) (should (use-package--recognize-function #'sym)) (should (use-package--recognize-function (lambda () ...))) @@ -59,6 +67,8 @@ (should-not (use-package--recognize-function '(nil . nil)))) (ert-deftest use-package-test-normalize-function () + (should (equal (use-package--normalize-function nil) nil)) + (should (equal (use-package--normalize-function t) t)) (should (equal (use-package--normalize-function 'sym) 'sym)) (should (equal (use-package--normalize-function #'sym) 'sym)) (should (equal (use-package--normalize-function (lambda () ...)) (lambda () ...))) @@ -69,13 +79,81 @@ (should (equal (use-package--normalize-function "Hello") "Hello")) (should (equal (use-package--normalize-function '(nil . nil)) '(nil . nil)))) -;; (ert-deftest use-package-test/:disabled () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:disabled () + (match-expansion + (use-package foo :disabled t) + `()) -;; (ert-deftest use-package-test/:preface () -;; (should (equal (macroexpand (use-package)) -;; '()))) + (match-expansion + ;; jww (2017-11-30): Should :disabled ignore its argument? + (use-package foo :disabled nil) + `())) + +(ert-deftest use-package-test/:preface () + (match-expansion + (use-package foo :preface (t)) + `(progn + (eval-and-compile + (t)) + (require 'foo nil 'nil))) + + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo :preface (t)) + `(progn + (eval-and-compile + (eval-when-compile + (with-demoted-errors + "Cannot load foo: %S" nil + (load "foo" nil t))) + (t)) + (require 'foo nil 'nil)))) + + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo + :preface (preface) + :init (init) + :config (config) + :functions func + :defines def) + `(progn + (eval-and-compile + (defvar def) + (declare-function func "foo") + (eval-when-compile + (with-demoted-errors + "Cannot load foo: %S" nil + (load "foo" nil t))) + (preface)) + (init) + (require 'foo nil 'nil) + (config) + t))) + + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo + :preface (preface) + :init (init) + :config (config) + :functions func + :defines def + :defer t) + `(progn + (eval-and-compile + (defvar def) + (declare-function func "foo") + (eval-when-compile + (with-demoted-errors + "Cannot load foo: %S" nil + (load "foo" nil t))) + (preface)) + (init) + (eval-after-load 'foo + '(progn + (config) + t)))))) ;; (ert-deftest use-package-test/:pin () ;; (should (equal (macroexpand (use-package)) @@ -181,33 +259,127 @@ (flet ((use-package-ensure-elpa (name ensure state context &optional no-refresh) (when ensure - (setq tried-to-install name)))) - (eval '(use-package foo :ensure t)) + (setq tried-to-install name))) + (require (&rest ignore))) + (use-package foo :ensure t) (should (eq tried-to-install 'foo))))) -;; (ert-deftest use-package-test/:if () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:if () + (match-expansion + (use-package foo :if t) + `(if (symbol-value 't) + (progn + (require 'foo nil 'nil)))) -;; (ert-deftest use-package-test/:when () -;; (should (equal (macroexpand (use-package)) -;; '()))) + (match-expansion + (use-package foo :if (and t t)) + `(if (and t t) + (progn + (require 'foo nil 'nil)))) -;; (ert-deftest use-package-test/:unless () -;; (should (equal (macroexpand (use-package)) -;; '()))) + (match-expansion + (use-package foo :if nil) + `(if nil + (progn + (require 'foo nil 'nil))))) + +(ert-deftest use-package-test/:when () + (match-expansion + (use-package foo :when t) + `(if (symbol-value 't) + (progn + (require 'foo nil 'nil)))) + + (match-expansion + (use-package foo :when (and t t)) + `(if (and t t) + (progn + (require 'foo nil 'nil)))) + + (match-expansion + (use-package foo :when nil) + `(if nil + (progn + (require 'foo nil 'nil))))) + +(ert-deftest use-package-test/:when () + (match-expansion + (use-package foo :unless t) + `(if (symbol-value 't) + nil + (require 'foo nil 'nil))) + + (match-expansion + (use-package foo :unless (and t t)) + `(if (and t t) + nil + (require 'foo nil 'nil))) + + (match-expansion + (use-package foo :unless nil) + `(if nil + nil + (require 'foo nil 'nil)))) ;; (ert-deftest use-package-test/:requires () ;; (should (equal (macroexpand (use-package)) ;; '()))) -;; (ert-deftest use-package-test/:load-path () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:load-path () + (match-expansion + (use-package foo :load-path "bar") + `(progn + (eval-and-compile + (add-to-list 'load-path + ,(pred (apply-partially + #'string= + (expand-file-name + "bar" user-emacs-directory))))) + (require 'foo nil 'nil))) -;; (ert-deftest use-package-test/:no-require () -;; (should (equal (macroexpand (use-package)) -;; '()))) + (match-expansion + (use-package foo :load-path ("bar" "quux")) + `(progn + (eval-and-compile + (add-to-list 'load-path + ,(pred (apply-partially + #'string= + (expand-file-name + "bar" user-emacs-directory))))) + (eval-and-compile + (add-to-list 'load-path + ,(pred (apply-partially + #'string= + (expand-file-name + "quux" user-emacs-directory))))) + (require 'foo nil 'nil))) + + (match-expansion + (use-package foo :load-path (lambda () (list "bar" "quux"))) + `(progn + (eval-and-compile + (add-to-list 'load-path + ,(pred (apply-partially + #'string= + (expand-file-name + "bar" user-emacs-directory))))) + (eval-and-compile + (add-to-list 'load-path + ,(pred (apply-partially + #'string= + (expand-file-name + "quux" user-emacs-directory))))) + (require 'foo nil 'nil)))) + +(ert-deftest use-package-test/:no-require () + (match-expansion + (use-package foo :no-require t) + `nil) + + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo :no-require t) + `'nil))) (ert-deftest use-package-test-normalize/:bind () (let ((good-values '(:map map-sym @@ -271,13 +443,64 @@ ;; (should (equal (macroexpand (use-package)) ;; '()))) -;; (ert-deftest use-package-test/:defines () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:defines () + (match-expansion + (use-package foo :defines bar) + `(require 'foo nil 'nil)) -;; (ert-deftest use-package-test/:functions () -;; (should (equal (macroexpand (use-package)) -;; '()))) + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo :defines bar) + `(progn + (eval-and-compile + (defvar bar) + (eval-when-compile + (with-demoted-errors + "Cannot load foo: %S" nil + (load "foo" nil t)))) + (require 'foo nil 'nil))))) + +(ert-deftest use-package-test/:functions () + (match-expansion + (use-package foo :functions bar) + `(require 'foo nil 'nil)) + + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo :functions bar) + `(progn + (eval-and-compile + (declare-function bar "foo") + (eval-when-compile + (with-demoted-errors + "Cannot load foo: %S" nil + (load "foo" nil t)))) + (require 'foo nil 'nil)))) + + (match-expansion + (use-package foo :defer t :functions bar) + `nil) + + ;; jww (2017-12-01): This exposes a bug. + ;; (let ((byte-compile-current-file t)) + ;; (match-expansion + ;; (use-package foo :defer t :functions bar) + ;; `'nil)) + + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo :defer t :config (config) :functions bar) + `(progn + (eval-and-compile + (declare-function bar "foo") + (eval-when-compile + (with-demoted-errors + "Cannot load foo: %S" nil + (load "foo" nil t)))) + (eval-after-load 'foo + '(progn + (config) + t)))))) ;; (ert-deftest use-package-test/:defer () ;; (should (equal (macroexpand (use-package)) @@ -302,9 +525,30 @@ '(((bar1 bar2) . baz) ((quux1 quux2) . bow))))) -;; (ert-deftest use-package-test/:hook () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:hook () + (let ((byte-compile-current-file t)) + (should + (equal ; pcase crashes + (expand-minimally + (use-package foo + :bind (("C-a" . key)) + :hook (hook . fun))) + '(progn + (eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load foo: %S" nil + (load "foo" nil t)))) + (unless (fboundp 'fun) + (autoload #'fun "foo" nil t)) + (eval-when-compile + (declare-function fun "foo")) + (unless (fboundp 'key) + (autoload #'key "foo" nil t)) + (eval-when-compile + (declare-function key "foo")) + (add-hook 'hook-hook #'fun) + (ignore + (bind-keys :package foo ("C-a" . key)))))))) (ert-deftest use-package-test-normalize/:custom () (should-error (use-package-normalize/:custom 'foopkg :custom nil)) From 6954c3f5829e46725c4a9d343c27f8e1c8a37f0e Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 1 Dec 2017 01:36:36 -0800 Subject: [PATCH 342/606] Don't factor out a volatile variable Possibly fixes https://github.com/jwiegley/use-package/issues/527 --- lisp/use-package/use-package.el | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 513ec1314e5..878fa673409 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -739,14 +739,15 @@ If the package is installed, its entry is removed from (not (or (member context '(:byte-compile :ensure :config)) (y-or-n-p (format "Install package %S?" package)))) (condition-case-unless-debug err - (let ((pinned (assoc package (bound-and-true-p - package-pinned-packages)))) - (when pinned + (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 pinned + (when (assoc package (bound-and-true-p + package-pinned-packages)) (package-read-all-archive-contents)) (package-install package)) t) From 21b9b6551dae815a5ccee491735d7b9a0d27d2ad Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 1 Dec 2017 01:40:58 -0800 Subject: [PATCH 343/606] Comment out :no-require test for now It works on my machine, but not with what Travis runs. --- test/lisp/use-package/use-package-tests.el | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 75ed42c229b..6710d48faa8 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -371,15 +371,15 @@ "quux" user-emacs-directory))))) (require 'foo nil 'nil)))) -(ert-deftest use-package-test/:no-require () - (match-expansion - (use-package foo :no-require t) - `nil) +;; (ert-deftest use-package-test/:no-require () +;; (match-expansion +;; (use-package foo :no-require t) +;; `nil) - (let ((byte-compile-current-file t)) - (match-expansion - (use-package foo :no-require t) - `'nil))) +;; (let ((byte-compile-current-file t)) +;; (match-expansion +;; (use-package foo :no-require t) +;; `'nil))) (ert-deftest use-package-test-normalize/:bind () (let ((good-values '(:map map-sym From f5b034154f8fa2bab0375e34143de9d462ee1232 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 1 Dec 2017 10:23:06 -0800 Subject: [PATCH 344/606] Always wrap the expanded body from use-package in (progn) --- lisp/use-package/use-package.el | 39 +++++----- test/lisp/use-package/use-package-tests.el | 83 ++++++++++++---------- 2 files changed, 65 insertions(+), 57 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 878fa673409..fe223305770 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1760,25 +1760,25 @@ this file. Usage: (symbol-name name)) nil t))))))))) (let ((body - (macroexp-progn - (use-package-process-keywords name - (let ((args* - (use-package-sort-keywords - (if (and use-package-always-demand - (not (memq :defer args))) - (plist-put args :demand t) - args)))) - (when (and use-package-always-ensure - (plist-member args* :load-path) - (not (plist-member orig-args :ensure))) - (plist-put args* :ensure nil)) - (unless (plist-member args* :init) - (plist-put args* :init nil)) - (unless (plist-member args* :config) - (plist-put args* :config '(t))) - args*) - (and use-package-always-defer - (list :deferred t)))))) + `(progn + ,@(use-package-process-keywords name + (let ((args* + (use-package-sort-keywords + (if (and use-package-always-demand + (not (memq :defer args))) + (plist-put args :demand t) + args)))) + (when (and use-package-always-ensure + (plist-member args* :load-path) + (not (plist-member orig-args :ensure))) + (plist-put args* :ensure nil)) + (unless (plist-member args* :init) + (plist-put args* :init nil)) + (unless (plist-member args* :config) + (plist-put args* :config '(t))) + args*) + (and use-package-always-defer + (list :deferred t)))))) (when use-package-debug (display-buffer (save-current-buffer @@ -1787,6 +1787,7 @@ this file. Usage: (emacs-lisp-mode) (insert (pp-to-string body)) (current-buffer))))) + (message "body = %s" body) body)))) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 6710d48faa8..66a4af30b52 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -267,59 +267,59 @@ (ert-deftest use-package-test/:if () (match-expansion (use-package foo :if t) - `(if (symbol-value 't) - (progn - (require 'foo nil 'nil)))) + `(progn + (when (symbol-value 't) + (require 'foo nil 'nil)))) (match-expansion (use-package foo :if (and t t)) - `(if (and t t) - (progn - (require 'foo nil 'nil)))) + `(progn + (when (and t t) + (require 'foo nil 'nil)))) (match-expansion (use-package foo :if nil) - `(if nil - (progn - (require 'foo nil 'nil))))) + `(progn + (when nil + (require 'foo nil 'nil))))) (ert-deftest use-package-test/:when () (match-expansion (use-package foo :when t) - `(if (symbol-value 't) - (progn - (require 'foo nil 'nil)))) + `(progn + (when (symbol-value 't) + (require 'foo nil 'nil)))) (match-expansion (use-package foo :when (and t t)) - `(if (and t t) - (progn - (require 'foo nil 'nil)))) + `(progn + (when (and t t) + (require 'foo nil 'nil)))) (match-expansion (use-package foo :when nil) - `(if nil - (progn - (require 'foo nil 'nil))))) + `(progn + (when nil + (require 'foo nil 'nil))))) -(ert-deftest use-package-test/:when () +(ert-deftest use-package-test/:unless () (match-expansion (use-package foo :unless t) - `(if (symbol-value 't) - nil - (require 'foo nil 'nil))) + `(progn + (unless (symbol-value 't) + (require 'foo nil 'nil)))) (match-expansion (use-package foo :unless (and t t)) - `(if (and t t) - nil - (require 'foo nil 'nil))) + `(progn + (unless (and t t) + (require 'foo nil 'nil)))) (match-expansion (use-package foo :unless nil) - `(if nil - nil - (require 'foo nil 'nil)))) + `(progn + (unless nil + (require 'foo nil 'nil))))) ;; (ert-deftest use-package-test/:requires () ;; (should (equal (macroexpand (use-package)) @@ -446,7 +446,8 @@ (ert-deftest use-package-test/:defines () (match-expansion (use-package foo :defines bar) - `(require 'foo nil 'nil)) + `(progn + (require 'foo nil 'nil))) (let ((byte-compile-current-file t)) (match-expansion @@ -463,7 +464,8 @@ (ert-deftest use-package-test/:functions () (match-expansion (use-package foo :functions bar) - `(require 'foo nil 'nil)) + `(progn + (require 'foo nil 'nil))) (let ((byte-compile-current-file t)) (match-expansion @@ -479,13 +481,17 @@ (match-expansion (use-package foo :defer t :functions bar) - `nil) + `(progn)) - ;; jww (2017-12-01): This exposes a bug. - ;; (let ((byte-compile-current-file t)) - ;; (match-expansion - ;; (use-package foo :defer t :functions bar) - ;; `'nil)) + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo :defer t :functions bar) + `(progn + (eval-and-compile + (declare-function bar "foo") + (eval-when-compile + (with-demoted-errors "Cannot load foo: %S" nil + (load "foo" nil t))))))) (let ((byte-compile-current-file t)) (match-expansion @@ -576,8 +582,9 @@ (ert-deftest use-package-test/:after () (match-expansion (use-package foo :after bar) - `(eval-after-load 'bar - '(require 'foo nil t)))) + `(progn + (eval-after-load 'bar + '(require 'foo nil t))))) ;; (ert-deftest use-package-test/:demand () ;; (should (equal (macroexpand (use-package)) From cd4790b3df8a7707431cb397db603b7bcce6275d Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 1 Dec 2017 11:07:08 -0800 Subject: [PATCH 345/606] Add many more tests --- test/lisp/use-package/use-package-tests.el | 664 +++++++++++++++++---- 1 file changed, 548 insertions(+), 116 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 66a4af30b52..7c860f568a0 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -27,7 +27,12 @@ (setq use-package-always-ensure nil use-package-verbose nil - use-package-expand-minimally t) + use-package-expand-minimally t + max-lisp-eval-depth 8000) + +;; (let ((byte-compile-current-file nil)) (expand-minimally ()) +(fset 'insert-expansion + [?\C-\M- ?\M-w ?\M-: ?\M-p ?\C-e ?\C-b ?\C-b ?\C-\M-b ?\C-y ?\C-\M-k return ?\C-\M- ?\M-w C-return ?\C-z ?\C-n ?\C-f ?\C-y ?\C-\M-k]) (defmacro expand-minimally (form) `(let ((use-package-verbose nil) @@ -321,9 +326,23 @@ (unless nil (require 'foo nil 'nil))))) -;; (ert-deftest use-package-test/:requires () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:requires () + (match-expansion + (use-package foo :requires bar) + `(progn + (when (not (member nil (mapcar #'featurep '(bar)))) + (require 'foo nil 'nil)))) + + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo :requires bar) + `(progn + (when (not (member nil (mapcar #'featurep '(bar)))) + (eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load foo: %S" nil + (load "foo" nil t)))) + (require 'foo nil 'nil)))))) (ert-deftest use-package-test/:load-path () (match-expansion @@ -337,6 +356,22 @@ "bar" user-emacs-directory))))) (require 'foo nil 'nil))) + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo :load-path "bar") + `(progn + (eval-and-compile + (add-to-list 'load-path + ,(pred (apply-partially + #'string= + (expand-file-name + "bar" user-emacs-directory))))) + (eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load foo: %S" nil + (load "foo" nil t)))) + (require 'foo nil 'nil)))) + (match-expansion (use-package foo :load-path ("bar" "quux")) `(progn @@ -371,77 +406,197 @@ "quux" user-emacs-directory))))) (require 'foo nil 'nil)))) -;; (ert-deftest use-package-test/:no-require () -;; (match-expansion -;; (use-package foo :no-require t) -;; `nil) +(ert-deftest use-package-test/:no-require () + (match-expansion + (use-package foo :no-require t) + `(progn)) -;; (let ((byte-compile-current-file t)) -;; (match-expansion -;; (use-package foo :no-require t) -;; `'nil))) + (match-expansion + (use-package foo :no-require t :config (config)) + `(progn + (config) + t)) + + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo :no-require t) + `(progn + (eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load foo: %S" nil nil))))))) (ert-deftest use-package-test-normalize/:bind () - (let ((good-values '(:map map-sym - ("str" . sym) ("str" . "str") - ([vec] . sym) ([vec] . "str")))) - (should (equal (use-package-normalize-binder - 'foopkg :bind good-values) - good-values))) - (should-error (use-package-normalize-binder - 'foopkg :bind '("foo"))) - (should-error (use-package-normalize-binder - 'foopkg :bind '("foo" . 99))) - (should-error (use-package-normalize-binder - 'foopkg :bind '(99 . sym)))) + (flet ((norm (&rest args) + (apply #'use-package-normalize-binder + 'foopkg :bind args))) + (let ((good-values '(:map map-sym + ("str" . sym) ("str" . "str") + ([vec] . sym) ([vec] . "str")))) + (should (equal (norm good-values) good-values))) + (should-error (norm '("foo"))) + (should-error (norm '("foo" . 99))) + (should-error (norm '(99 . sym))))) -;; (ert-deftest use-package-test/:bind () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:bind () + (match-expansion + (use-package foo :bind ("C-k" . key)) + `(progn + (unless (fboundp 'key) + (autoload #'key "foo" nil t)) + (ignore + (bind-keys :package foo ("C-k" . key)))))) -;; (ert-deftest use-package-test/:bind* () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:bind* () + (match-expansion + (use-package foo :bind* ("C-k" . key)) + `(progn + (unless (fboundp 'key) + (autoload #'key "foo" nil t)) + (ignore + (bind-keys* :package foo ("C-k" . key)))))) -;; (ert-deftest use-package-test/:bind-keymap () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:bind-keymap () + (match-expansion + (use-package foo :bind-keymap ("C-k" . key)) + `(progn + (ignore + (bind-key "C-k" + #'(lambda () + (interactive) + (use-package-autoload-keymap 'key 'foo nil))))))) -;; (ert-deftest use-package-test/:bind-keymap* () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:bind-keymap* () + (match-expansion + (use-package foo :bind-keymap* ("C-k" . key)) + `(progn + (ignore + (bind-key* "C-k" + #'(lambda () + (interactive) + (use-package-autoload-keymap 'key 'foo t))))))) -;; (ert-deftest use-package-test/:interpreter () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:interpreter () + (match-expansion + (use-package foo :interpreter "interp") + `(progn + (unless (fboundp 'foo) + (autoload #'foo "foo" nil t)) + (ignore + (add-to-list 'interpreter-mode-alist + '("interp" . foo))))) + + (match-expansion + (use-package foo :interpreter ("interp" . fun)) + `(progn + (unless (fboundp 'fun) + (autoload #'fun "foo" nil t)) + (ignore + (add-to-list 'interpreter-mode-alist + '("interp" . fun)))))) (ert-deftest use-package-test-normalize/:mode () - (should (equal (use-package-normalize-mode 'foopkg :mode '(".foo")) - '((".foo" . foopkg)))) - (should (equal (use-package-normalize-mode 'foopkg :mode '(".foo" ".bar")) - '((".foo" . foopkg) (".bar" . foopkg)))) - (should (equal (use-package-normalize-mode 'foopkg :mode '((".foo" ".bar"))) - '((".foo" . foopkg) (".bar" . foopkg)))) - (should (equal (use-package-normalize-mode 'foopkg :mode '((".foo"))) - '((".foo" . foopkg)))) - (should (equal (use-package-normalize-mode 'foopkg :mode '((".foo" . foo) (".bar" . bar))) - '((".foo" . foo) (".bar" . bar))))) + (flet ((norm (&rest args) + (apply #'use-package-normalize/:mode + 'foopkg :mode args))) + (should (equal (norm '(".foo")) + '((".foo" . foopkg)))) + (should (equal (norm '(".foo" ".bar")) + '((".foo" . foopkg) (".bar" . foopkg)))) + (should (equal (norm '((".foo" ".bar"))) + '((".foo" . foopkg) (".bar" . foopkg)))) + (should (equal (norm '((".foo"))) + '((".foo" . foopkg)))) + (should (equal (norm '((".foo" . foo) (".bar" . bar))) + '((".foo" . foo) (".bar" . bar)))))) -;; (ert-deftest use-package-test/:mode () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:mode () + (match-expansion + (use-package foo :mode "interp") + `(progn + (unless (fboundp 'foo) + (autoload #'foo "foo" nil t)) + (ignore + (add-to-list 'auto-mode-alist + '("interp" . foo))))) -;; (ert-deftest use-package-test/:magic () -;; (should (equal (macroexpand (use-package)) -;; '()))) + (match-expansion + (use-package foo :mode ("interp" . fun)) + `(progn + (unless (fboundp 'fun) + (autoload #'fun "foo" nil t)) + (ignore + (add-to-list 'auto-mode-alist + '("interp" . fun)))))) -;; (ert-deftest use-package-test/:magic-fallback () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:magic () + (match-expansion + (use-package foo :magic "interp") + `(progn + (unless (fboundp 'foo) + (autoload #'foo "foo" nil t)) + (ignore + (add-to-list 'magic-mode-alist + '("interp" . foo))))) -;; (ert-deftest use-package-test/:commands () -;; (should (equal (macroexpand (use-package)) -;; '()))) + (match-expansion + (use-package foo :magic ("interp" . fun)) + `(progn + (unless (fboundp 'fun) + (autoload #'fun "foo" nil t)) + (ignore + (add-to-list 'magic-mode-alist + '("interp" . fun)))))) + +(ert-deftest use-package-test/:magic-fallback () + (match-expansion + (use-package foo :magic-fallback "interp") + `(progn + (unless (fboundp 'foo) + (autoload #'foo "foo" nil t)) + (ignore + (add-to-list 'magic-fallback-mode-alist + '("interp" . foo))))) + + (match-expansion + (use-package foo :magic-fallback ("interp" . fun)) + `(progn + (unless (fboundp 'fun) + (autoload #'fun "foo" nil t)) + (ignore + (add-to-list 'magic-fallback-mode-alist + '("interp" . fun)))))) + +(ert-deftest use-package-test/:commands () + (match-expansion + (use-package foo :commands bar) + `(progn + (unless (fboundp 'bar) + (autoload #'bar "foo" nil t)))) + + (match-expansion + (use-package foo :commands (bar quux)) + `(progn + (unless (fboundp 'bar) + (autoload #'bar "foo" nil t)) + (unless (fboundp 'quux) + (autoload #'quux "foo" nil t)))) + + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo :commands (bar quux)) + `(progn + (eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load foo: %S" nil + (load "foo" nil t)))) + (unless (fboundp 'bar) + (autoload #'bar "foo" nil t)) + (eval-when-compile + (declare-function bar "foo")) + (unless (fboundp 'quux) + (autoload #'quux "foo" nil t)) + (eval-when-compile + (declare-function quux "foo")))))) (ert-deftest use-package-test/:defines () (match-expansion @@ -508,28 +663,54 @@ (config) t)))))) -;; (ert-deftest use-package-test/:defer () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:defer () + (match-expansion + (use-package foo) + `(progn + (require 'foo nil 'nil))) + + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo) + `(progn + (eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load foo: %S" nil + (load "foo" nil t)))) + (require 'foo nil 'nil)))) + + (match-expansion + (use-package foo :defer t) + `(progn)) + + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo :defer t) + `(progn + (eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load foo: %S" nil + (load "foo" nil t)))))))) (ert-deftest use-package-test-normalize/:hook () - (should-error (use-package-normalize/:hook 'foopkg :hook nil)) - (should (equal (use-package-normalize/:hook 'foopkg :hook '(bar)) - '((bar . foopkg)))) - (should (equal (use-package-normalize/:hook 'foopkg :hook '((bar . baz))) - '((bar . baz)))) - (should (equal (use-package-normalize/:hook 'foopkg :hook '(((bar baz) . quux))) - '(((bar baz) . quux)))) - (should (equal (use-package-normalize/:hook 'foopkg :hook '(bar baz)) - '(((bar baz) . foopkg)))) - (should (equal (use-package-normalize/:hook 'foopkg :hook '((bar baz) (quux bow))) - '(((bar baz) . foopkg) ((quux bow) . foopkg)))) - (should (equal (use-package-normalize/:hook 'foopkg :hook '((bar . baz) (quux . bow))) - '((bar . baz) (quux . bow)))) - (should (equal (use-package-normalize/:hook 'foopkg :hook '(((bar1 bar2) . baz) - ((quux1 quux2) . bow))) - '(((bar1 bar2) . baz) - ((quux1 quux2) . bow))))) + (flet ((norm (&rest args) + (apply #'use-package-normalize/:hook + 'foopkg :hook args))) + (should-error (norm nil)) + (should (equal (norm '(bar)) + '((bar . foopkg)))) + (should (equal (norm '((bar . baz))) + '((bar . baz)))) + (should (equal (norm '(((bar baz) . quux))) + '(((bar baz) . quux)))) + (should (equal (norm '(bar baz)) + '(((bar baz) . foopkg)))) + (should (equal (norm '((bar baz) (quux bow))) + '(((bar baz) . foopkg) ((quux bow) . foopkg)))) + (should (equal (norm '((bar . baz) (quux . bow))) + '((bar . baz) (quux . bow)))) + (should (equal (norm '(((bar1 bar2) . baz) ((quux1 quux2) . bow))) + '(((bar1 bar2) . baz) ((quux1 quux2) . bow)))))) (ert-deftest use-package-test/:hook () (let ((byte-compile-current-file t)) @@ -557,42 +738,227 @@ (bind-keys :package foo ("C-a" . key)))))))) (ert-deftest use-package-test-normalize/:custom () - (should-error (use-package-normalize/:custom 'foopkg :custom nil)) - (should-error (use-package-normalize/:custom 'foopkg :custom '(bar))) - ;; (should-error (use-package-normalize/:custom 'foopkg :custom '((foo bar baz quux)))) - (should (equal (use-package-normalize/:custom 'foopkg :custom '(foo bar)) - '((foo bar)))) - ;; (should-error (use-package-normalize/:custom 'foopkg :custom '(foo bar baz))) - ;; (should (equal (use-package-normalize/:custom 'foopkg :custom '(foo bar "baz")) - ;; '((foo bar baz)))) - ) + (flet ((norm (&rest args) + (apply #'use-package-normalize/:custom + 'foopkg :custom args))) + (should-error (norm nil)) + (should-error (norm '(bar))) + ;; (should-error (norm '((foo bar baz quux)))) + (should (equal (norm '(foo bar)) '((foo bar)))) + ;; (should-error (norm '(foo bar baz))) + ;; (should (equal (norm '(foo bar "baz")) + ;; '((foo bar baz)))) + )) -;; (ert-deftest use-package-test/:custom () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:custom () + (match-expansion + (use-package foo :custom (foo bar)) + `(progn + (customize-set-variable 'foo bar "Customized with use-package foo") + (require 'foo nil 'nil)))) -;; (ert-deftest use-package-test/:custom-face () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:custom-face () + (match-expansion + (use-package foo :custom-face (foo ((t (:background "#e4edfc"))))) + `(progn + (custom-set-faces '(foo ((t (:background "#e4edfc"))))) + (require 'foo nil 'nil)))) -;; (ert-deftest use-package-test/:init () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:init () + (match-expansion + (use-package foo :init (init)) + `(progn + (init) + (require 'foo nil 'nil))) + + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo :init (init)) + `(progn + (eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load foo: %S" nil + (load "foo" nil t)))) + (init) + (require 'foo nil 'nil))))) (ert-deftest use-package-test/:after () (match-expansion (use-package foo :after bar) `(progn (eval-after-load 'bar - '(require 'foo nil t))))) + '(require 'foo nil t)))) -;; (ert-deftest use-package-test/:demand () -;; (should (equal (macroexpand (use-package)) -;; '()))) + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo :after bar) + `(progn + (eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load foo: %S" nil + (load "foo" nil t)))) + (eval-after-load 'bar + '(require 'foo nil t))))) -;; (ert-deftest use-package-test/:config () -;; (should (equal (macroexpand (use-package)) -;; '()))) + (match-expansion + (use-package foo :after (bar quux)) + `(progn + (eval-after-load 'quux + '(eval-after-load 'bar + '(require 'foo nil t))))) + + (match-expansion + (use-package foo :after (:all bar quux)) + `(progn + (eval-after-load 'quux + '(eval-after-load 'bar + '(require 'foo nil t))))) + + (match-expansion + (use-package foo :after (:any bar quux)) + `(progn + (progn + (eval-after-load 'bar + '(require 'foo nil t)) + (eval-after-load 'quux + '(require 'foo nil t))))) + + (match-expansion + (use-package foo :after (:all (:any bar quux) bow)) + `(progn + (eval-after-load 'bow + '(progn + (eval-after-load 'bar + '(require 'foo nil t)) + (eval-after-load 'quux + '(require 'foo nil t)))))) + + (match-expansion + (use-package foo :after (:any (:all bar quux) bow)) + `(progn + (progn + (eval-after-load 'quux + '(eval-after-load 'bar + '(require 'foo nil t))) + (eval-after-load 'bow + '(require 'foo nil t))))) + + (match-expansion + (use-package foo :after (:all (:any bar quux) (:any bow baz))) + `(progn + (progn + (eval-after-load 'bow + '(progn + (eval-after-load 'bar + '(require 'foo nil t)) + (eval-after-load 'quux + '(require 'foo nil t)))) + (eval-after-load 'baz + '(progn + (eval-after-load 'bar + '(require 'foo nil t)) + (eval-after-load 'quux + '(require 'foo nil t))))))) + + (match-expansion + (use-package foo :after (:any (:all bar quux) (:all bow baz))) + `(progn + (progn + (eval-after-load 'quux + '(eval-after-load 'bar + '(require 'foo nil t))) + (eval-after-load 'baz + '(eval-after-load 'bow + '(require 'foo nil t)))))) + + (match-expansion + (use-package foo :after (:any (:all bar quux) (:any bow baz))) + `(progn + (progn + (eval-after-load 'quux + '(eval-after-load 'bar + '(require 'foo nil t))) + (progn + (eval-after-load 'bow + '(require 'foo nil t)) + (eval-after-load 'baz + '(require 'foo nil t))))))) + +(ert-deftest use-package-test/:demand () + (match-expansion + (use-package foo :demand t) + `(progn + (require 'foo nil 'nil))) + + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo :demand t) + `(progn + (eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load foo: %S" nil + (load "foo" nil t)))) + (require 'foo nil 'nil)))) + + (match-expansion + (use-package foo :demand t :config (config)) + `(progn + (require 'foo nil 'nil) + (config) + t)) + + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo :demand t :config (config)) + `(progn + (eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load foo: %S" nil + (load "foo" nil t)))) + (require 'foo nil 'nil) + (config) + t)))) + +(ert-deftest use-package-test/:config () + (match-expansion + (use-package foo :config (config)) + `(progn + (require 'foo nil 'nil) + (config) + t)) + + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo :config (config)) + `(progn + (eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load foo: %S" nil + (load "foo" nil t)))) + (require 'foo nil 'nil) + (config) + t))) + + (match-expansion + (use-package foo :defer t :config (config)) + `(progn + (eval-after-load 'foo + '(progn + (config) + t)))) + + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo :defer t :config (config)) + `(progn + (eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load foo: %S" nil + (load "foo" nil t)))) + (eval-after-load 'foo + '(progn + (config) + t)))))) (ert-deftest use-package-test-normalize/:diminish () (should (equal (use-package-normalize-diminish 'foopkg :diminish nil) @@ -606,9 +972,35 @@ (should (equal (use-package-normalize-diminish 'foopkg :diminish '(foo . "bar")) '((foo . "bar"))))) -;; (ert-deftest use-package-test/:diminish () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:diminish () + (match-expansion + (use-package foo :diminish nil) + `(progn + (require 'foo nil 'nil) + (if (fboundp 'diminish) + (diminish 'foo-mode)))) + + (match-expansion + (use-package foo :diminish bar) + `(progn + (require 'foo nil 'nil) + (if (fboundp 'diminish) + (diminish 'bar)))) + + (match-expansion + (use-package foo :diminish "bar") + `(progn + (require 'foo nil 'nil) + (if (fboundp 'diminish) + (diminish 'foo-mode "bar")))) + + + (match-expansion + (use-package foo :diminish (foo . "bar")) + `(progn + (require 'foo nil 'nil) + (if (fboundp 'diminish) + (diminish 'foo "bar"))))) (ert-deftest use-package-test-normalize/:delight () (should (equal `((foo-mode nil foo)) @@ -623,19 +1015,59 @@ (use-package-normalize/:delight 'foo :delight '("abc")))) (should (equal `((foo-mode (:eval 1) foo)) (use-package-normalize/:delight 'foo :delight '('(:eval 1))))) - (should (equal `((a-mode nil foo) - (b-mode " b" foo)) - (use-package-normalize/:delight 'foo :delight '((a-mode) - (b-mode " b"))))) + (should (equal (use-package-normalize/:delight 'foo :delight '((a-mode) (b-mode " b"))) + `((a-mode nil foo) (b-mode " b" foo)))) (should-error (use-package-normalize/:delight 'foo :delight '((:eval 1))))) -;; (ert-deftest use-package-test/:delight () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:delight () + (match-expansion + (use-package foo :delight) + `(progn + (require 'foo nil 'nil) + (if (fboundp 'delight) + (delight '((foo-mode nil foo)))))) + + (should-error + (match-expansion + (use-package foo :delight nil) + `(progn + (require 'foo nil 'nil) + (if (fboundp 'diminish) + (diminish 'foo-mode))))) + + (match-expansion + (use-package foo :delight bar) + `(progn + (require 'foo nil 'nil) + (if (fboundp 'delight) + (delight '((bar nil foo)))))) + + (match-expansion + (use-package foo :delight "bar") + `(progn + (require 'foo nil 'nil) + (if (fboundp 'delight) + (delight '((foo-mode "bar" foo)))))) + + (should-error + (match-expansion + (use-package foo :delight (foo . "bar")) + `(progn + (require 'foo nil 'nil) + (if (fboundp 'diminish) + (diminish 'foo "bar"))))) + + (match-expansion + (use-package foo :delight (foo "bar")) + `(progn + (require 'foo nil 'nil) + (if (fboundp 'delight) + (delight '((foo "bar" foo))))))) ;; Local Variables: ;; indent-tabs-mode: nil ;; no-byte-compile: t ;; no-update-autoloads: t ;; End: + ;;; use-package-tests.el ends here From cb846d188ab401bbac216e0d20fba72ad8c208b7 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 1 Dec 2017 11:16:19 -0800 Subject: [PATCH 346/606] Add tests for the last two keywords --- test/lisp/use-package/use-package-tests.el | 25 ++++++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 7c860f568a0..3db6f19e901 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -30,7 +30,7 @@ use-package-expand-minimally t max-lisp-eval-depth 8000) -;; (let ((byte-compile-current-file nil)) (expand-minimally ()) +;; (let ((byte-compile-current-file nil)) (expand-minimally ())) (fset 'insert-expansion [?\C-\M- ?\M-w ?\M-: ?\M-p ?\C-e ?\C-b ?\C-b ?\C-\M-b ?\C-y ?\C-\M-k return ?\C-\M- ?\M-w C-return ?\C-z ?\C-n ?\C-f ?\C-y ?\C-\M-k]) @@ -160,13 +160,24 @@ (config) t)))))) -;; (ert-deftest use-package-test/:pin () -;; (should (equal (macroexpand (use-package)) -;; '()))) +(ert-deftest use-package-test/:pin () + (match-expansion + (use-package foo :pin foo) + `(progn + (use-package-pin-package 'foo "foo") + (require 'foo nil 'nil))) -;; (ert-deftest use-package-test/:defer-install () -;; (should (equal (macroexpand (use-package)) -;; '()))) + (match-expansion + (use-package foo :pin "foo") + `(progn + (use-package-pin-package 'foo "foo") + (require 'foo nil 'nil)))) + +(ert-deftest use-package-test/:defer-install () + (match-expansion + (use-package foo :defer-install t) + `(progn + (require 'foo nil 'nil)))) (ert-deftest use-package-test-normalize/:ensure () (flet ((norm (&rest args) From 9e8e9aa4eed75b23231f8593d57c257be92cda49 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 1 Dec 2017 11:17:34 -0800 Subject: [PATCH 347/606] Remove some debug code that crept in --- lisp/use-package/use-package.el | 1 - 1 file changed, 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index fe223305770..4e652649861 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1787,7 +1787,6 @@ this file. Usage: (emacs-lisp-mode) (insert (pp-to-string body)) (current-buffer))))) - (message "body = %s" body) body)))) From 09be976c1852fa5d36fe26794c43ad48a4ea12ee Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 1 Dec 2017 11:30:11 -0800 Subject: [PATCH 348/606] :demand should not override an explicit use of :after Fixes https://github.com/jwiegley/use-package/issues/529 --- lisp/use-package/use-package.el | 4 ++++ test/lisp/use-package/use-package-tests.el | 20 +++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 4e652649861..5119e394ebe 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1768,6 +1768,10 @@ this file. Usage: (not (memq :defer args))) (plist-put args :demand t) args)))) + ;; The :demand keyword should not override :after + (if (and (plist-member args* :after) + (plist-member args* :demand)) + (setq args* (use-package-plist-delete args* :demand))) (when (and use-package-always-ensure (plist-member args* :load-path) (not (plist-member orig-args :ensure))) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 3db6f19e901..64f5ab534d3 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -928,7 +928,25 @@ (load "foo" nil t)))) (require 'foo nil 'nil) (config) - t)))) + t))) + + ;; #529 - :demand should not override an explicit use of :after + (match-expansion + (use-package foo :demand t :after bar) + `(progn + (eval-after-load 'bar + '(require 'foo nil t)))) + + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo :demand t :after bar) + `(progn + (eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load foo: %S" nil + (load "foo" nil t)))) + (eval-after-load 'bar + '(require 'foo nil t)))))) (ert-deftest use-package-test/:config () (match-expansion From af3b34b02294d5c1e23010ad249ce3922a4a474b Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 1 Dec 2017 11:42:40 -0800 Subject: [PATCH 349/606] Remove the :defer-install keyword This may reappear as its own add-on to use-package in the future. See https://github.com/jwiegley/use-package/issues/442. --- etc/USE-PACKAGE-NEWS | 3 + lisp/use-package/use-package.el | 264 +++------------------ test/lisp/use-package/use-package-tests.el | 20 +- 3 files changed, 52 insertions(+), 235 deletions(-) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index b0265fa5515..06adac97188 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -15,6 +15,9 @@ - Emacs 24.3 or higher is now a requirement. +- The `:defer-install` keyword has been remove. It may reappear as an add-on + module for use-package in a future release. See issue #442 for more details. + ### Other changes - Upgrade license to GPL 3. diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 5119e394ebe..ae361de6f6b 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -88,11 +88,6 @@ The check is performed by looking for the module using `locate-library'." :type 'boolean :group 'use-package) -(defcustom use-package-always-defer-install nil - "If non-nil, assume `:defer-install t` unless `:defer-install nil` is given." - :type 'boolean - :group 'use-package) - (defcustom use-package-always-ensure nil "Treat every package as though it had specified `:ensure SEXP`." :type 'sexp @@ -140,7 +135,6 @@ the user specified." (defcustom use-package-keywords '(:disabled :pin - :defer-install :ensure :if :when @@ -200,9 +194,8 @@ Must be set before loading use-package." "Function that ensures a package is installed. This function is called with four arguments: the name of the package declared in the `use-package' form; the argument passed -to `:ensure'; the current `state' plist created by previous -handlers; and a keyword indicating the context in which the -installation is occurring. +to `:ensure'; 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 @@ -210,50 +203,14 @@ 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. - -Possible values for the context keyword are: - -:byte-compile - package installed during byte-compilation -:ensure - package installed normally by :ensure -:autoload - deferred installation triggered by an autoloaded - function -:after - deferred installation triggered by the loading of a - feature listed in the :after declaration -:config - deferred installation was specified at the same time - as :demand, so the installation was triggered - immediately -:unknown - context not provided - -Note that third-party code can provide other values for the -context keyword by calling `use-package-install-deferred-package' -with the appropriate value." +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) -(defcustom use-package-pre-ensure-function 'ignore - "Function that is called upon installation deferral. -It is called immediately with the first three arguments that -would be passed to `use-package-ensure-function' (the context -keyword is omitted), but only if installation has been deferred. -It is intended for package managers other than package.el which -might want to activate the autoloads of a package immediately, if -it's installed, but otherwise defer installation until later (if -`:defer-install' is specified). The reason it is set to `ignore' -by default is that package.el activates the autoloads for all -known packages at initialization time, rather than one by one -when the packages are actually requested." - :type '(choice (const :tag "None" ignore) - (function :tag "Custom")) - :group 'use-package) - (defcustom use-package-defaults '((:config '(t) t) (:ensure use-package-always-ensure use-package-always-ensure) - (:defer-install - use-package-always-defer-install - use-package-always-defer-install) (:pin use-package-always-pin use-package-always-pin)) "Alist of default values for `use-package' keywords. Each entry in the alist is a list of three elements. The first @@ -639,80 +596,6 @@ manually updated package." (push pin-form body)) ; or else wait until runtime. body)) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :defer-install -;; - -(defvar use-package--deferred-packages (make-hash-table) - "Hash mapping packages to data about their installation. - -The keys are not actually symbols naming packages, but rather -symbols naming the features which are the names of \"packages\" -required by `use-package' forms. Since -`use-package-ensure-function' could be set to anything, it is -actually impossible for `use-package' to determine what package -is supposed to provide the feature being ensured just based on -the value of `:ensure'. - -Each value is a cons, with the car being the the value passed to -`:ensure' and the cdr being the `state' plist. See -`use-package-install-deferred-package' for information about how -these values are used to call `use-package-ensure-function'.") - -(defun use-package-install-deferred-package (name &optional context) - "Install a package whose installation has been deferred. -NAME should be a symbol naming a package (actually, a feature). -This is done by calling `use-package-ensure-function' is called -with four arguments: the key (NAME) and the two elements of the -cons in `use-package--deferred-packages' (the value passed to -`:ensure', and the `state' plist), and a keyword providing -information about the context in which the installation is -happening. (This defaults to `:unknown' but can be overridden by -providing CONTEXT.) - -Return t if the package is installed, nil otherwise. (This is -determined by the return value of `use-package-ensure-function'.) -If the package is installed, its entry is removed from -`use-package--deferred-packages'. If the package has no entry in -`use-package--deferred-packages', do nothing and return t." - (interactive - (let ((packages nil)) - (maphash (lambda (package info) - (push package packages)) - use-package--deferred-packages) - (if packages - (list - (intern - (completing-read "Select package: " - packages nil 'require-match)) - :interactive) - (user-error "No packages with deferred installation")))) - (let ((spec (gethash name use-package--deferred-packages))) - (if spec - (when (funcall use-package-ensure-function - name (car spec) (cdr spec) - (or context :unknown)) - (remhash name use-package--deferred-packages) - t) - t))) - -(defalias 'use-package-normalize/:defer-install 'use-package-normalize-test) - -(defun use-package-handler/:defer-install (name keyword defer rest state) - (use-package-process-keywords name rest - ;; Just specifying `:defer-install' does not do anything; this - ;; sets up a marker so that if `:ensure' is specified as well then - ;; it knows to set up deferred installation. But then later, when - ;; `:config' is processed, it might turn out that `:demand' was - ;; specified as well, and the deferred installation needs to be - ;; run immediately. For this we need to know if the deferred - ;; installation was actually set up or not, so we need to set one - ;; marker value in `:defer-install', and then change it to a - ;; different value in `:ensure', if the first one is present. (The - ;; first marker is `:defer-install', and the second is `:ensure'.) - (plist-put state :defer-install (when defer :defer-install)))) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; :ensure @@ -729,66 +612,45 @@ If the package is installed, its entry is removed from (concat ":ensure wants an optional package name " "(an unquoted symbol name)"))))))) -(defun use-package-ensure-elpa (name ensure state context &optional no-refresh) - (let ((package (or (and (eq ensure t) (use-package-as-symbol name)) - ensure))) +(defun use-package-ensure-elpa (name ensure state &optional no-refresh) + (let ((package + (or (and (eq ensure t) (use-package-as-symbol name)) + ensure))) (when package (require 'package) - (or (package-installed-p package) - ;; Contexts in which the confirmation prompt is bypassed. - (not (or (member context '(:byte-compile :ensure :config)) - (y-or-n-p (format "Install package %S?" package)))) - (condition-case-unless-debug err - (progn + (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)) - (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 - (ignore - (display-warning 'use-package - (format "Failed to install %s: %s" - name (error-message-string err)) - :error)))))))) + (package-install package)) + t) + (error + (ignore + (display-warning 'use-package + (format "Failed to install %s: %s" + name (error-message-string err)) + :error)))))))) (defun use-package-handler/:ensure (name keyword ensure rest state) - (let* ((body (use-package-process-keywords name rest - ;; Here we are conditionally updating the marker - ;; value for deferred installation; this will be - ;; checked later by `:config'. For more information - ;; see `use-package-handler/:defer-install'. - (if (eq (plist-get state :defer-install) - :defer-install) - (plist-put state :defer-install :ensure) - state)))) - ;; We want to avoid installing packages when the `use-package' - ;; macro is being macro-expanded by elisp completion (see - ;; `lisp--local-variables'), but still do install packages when - ;; byte-compiling to avoid requiring `package' at runtime. - (cond - ((plist-get state :defer-install) - (push - `(puthash ',name '(,ensure . ,state) - use-package--deferred-packages) - body) - (push `(,use-package-pre-ensure-function - ',name ',ensure ',state) + (let* ((body (use-package-process-keywords name rest state))) + ;; 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)) - ((bound-and-true-p byte-compile-current-file) - ;; Eval when byte-compiling, - (funcall use-package-ensure-function - name ensure state :byte-compile)) - ;; or else wait until runtime. - (t (push `(,use-package-ensure-function - ',name ',ensure ',state :ensure) - body))) body)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1272,35 +1134,6 @@ representing symbols (that may need to be autloaded)." (defalias 'use-package-normalize/:defer 'use-package-normalize-predicate) -(defun use-package--autoload-with-deferred-install - (command package-name) - "Return a form defining an autoload supporting deferred install." - `(let* ((load-list-item '(defun . ,command)) - (already-loaded (member load-list-item current-load-list))) - (defun ,command (&rest args) - "[Arg list not available until function definition is loaded.] - - \(fn ...)" - (interactive) - (if (bound-and-true-p use-package--recursive-autoload) - (use-package-error - (format "Autoloading failed to define function %S" - ',command)) - (when (use-package-install-deferred-package - ',package-name :autoload) - (require ',package-name) - (let ((use-package--recursive-autoload t)) - (if (called-interactively-p 'any) - (call-interactively ',command) - (apply ',command args)))))) - ;; This prevents the user's init-file from being recorded as the - ;; definition location for the function before it is actually - ;; loaded. (Our goal is to leave the `current-load-list' - ;; unchanged, so we only remove the entry for this function if it - ;; was not already present.) - (unless already-loaded - (setq current-load-list (remove load-list-item current-load-list))))) - (defun use-package-handler/:defer (name keyword arg rest state) (let ((body (use-package-process-keywords name rest (plist-put state :deferred t))) @@ -1318,13 +1151,7 @@ representing symbols (that may need to be autloaded)." (when (symbolp command) (append `((unless (fboundp ',command) - ;; Here we are checking the marker value set in - ;; `use-package-handler/:ensure' to see if deferred - ;; installation is actually happening. See - ;; `use-package-handler/:defer-install' for more information. - ,(if (eq (plist-get state :defer-install) :ensure) - (use-package--autoload-with-deferred-install command name) - `(autoload #',command ,name-string nil t)))) + (autoload #',command ,name-string nil t))) (when (bound-and-true-p byte-compile-current-file) `((eval-when-compile (declare-function ,command ,name-string))))))) @@ -1374,15 +1201,10 @@ representing symbols (that may need to be autloaded)." (setq arg (cons :all arg))) (use-package-concat (when arg - (list (funcall (use-package-require-after-load arg) - (macroexp-progn - ;; Here we are checking the marker value for deferred - ;; installation set in `use-package-handler/:ensure'. - ;; See also `use-package-handler/:defer-install'. - `(,@(when (eq (plist-get state :defer-install) :ensure) - `((use-package-install-deferred-package - 'name :after))) - (require (quote ,name) nil t)))))) + (list (funcall + (use-package-require-after-load arg) + (macroexp-progn + `((require (quote ,name) nil t)))))) body))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1441,12 +1263,6 @@ representing symbols (that may need to be autloaded)." `((eval-after-load ,(if (symbolp name) `',name name) ',(macroexp-progn config-body)))) - ;; Here we are checking the marker value for deferred installation set - ;; in `use-package-handler/:ensure'. See also - ;; `use-package-handler/:defer-install'. - (when (eq (plist-get state :defer-install) :ensure) - (use-package-install-deferred-package name :config)) - (use-package--with-elapsed-timer (format "Loading package %s" name) (if use-package-expand-minimally @@ -1709,10 +1525,8 @@ this file. Usage: `: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. - :after Defer loading of a package until after any of the named features are loaded. - :demand Prevent deferred loading in all cases. :if EXPR Initialize and load only if EXPR evaluates to a non-nil value. diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 64f5ab534d3..60cf2ff7b15 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -194,28 +194,28 @@ (match-expansion (use-package foo :ensure t) `(progn - (use-package-ensure-elpa 'foo 't 'nil :ensure) + (use-package-ensure-elpa 'foo 't 'nil) (require 'foo nil 'nil)))) (let ((use-package-always-ensure t)) (match-expansion (use-package foo :ensure t) `(progn - (use-package-ensure-elpa 'foo 't 'nil :ensure) + (use-package-ensure-elpa 'foo 't 'nil) (require 'foo nil 'nil)))) (let ((use-package-always-ensure nil)) (match-expansion (use-package foo :ensure nil) `(progn - (use-package-ensure-elpa 'foo 'nil 'nil :ensure) + (use-package-ensure-elpa 'foo 'nil 'nil) (require 'foo nil 'nil)))) (let ((use-package-always-ensure t)) (match-expansion (use-package foo :ensure nil) `(progn - (use-package-ensure-elpa 'foo 'nil 'nil :ensure) + (use-package-ensure-elpa 'foo 'nil 'nil) (require 'foo nil 'nil)))) (let ((use-package-always-ensure nil)) @@ -230,7 +230,7 @@ (match-expansion (use-package foo :load-path "foo") `(progn - (use-package-ensure-elpa 'foo 'nil 'nil :ensure) + (use-package-ensure-elpa 'foo 'nil 'nil) (eval-and-compile (add-to-list 'load-path ,(pred stringp))) (require 'foo nil 'nil)))) @@ -239,7 +239,7 @@ (match-expansion (use-package foo :ensure nil :load-path "foo") `(progn - (use-package-ensure-elpa 'foo 'nil 'nil :ensure) + (use-package-ensure-elpa 'foo 'nil 'nil) (eval-and-compile (add-to-list 'load-path ,(pred stringp))) (require 'foo nil 'nil)))) @@ -248,7 +248,7 @@ (match-expansion (use-package foo :ensure nil :load-path "foo") `(progn - (use-package-ensure-elpa 'foo 'nil 'nil :ensure) + (use-package-ensure-elpa 'foo 'nil 'nil) (eval-and-compile (add-to-list 'load-path ,(pred stringp))) (require 'foo nil 'nil)))) @@ -257,7 +257,7 @@ (match-expansion (use-package foo :ensure t :load-path "foo") `(progn - (use-package-ensure-elpa 'foo 't 'nil :ensure) + (use-package-ensure-elpa 'foo 't 'nil) (eval-and-compile (add-to-list 'load-path ,(pred stringp))) (require 'foo nil 'nil)))) @@ -266,14 +266,14 @@ (match-expansion (use-package foo :ensure t :load-path "foo") `(progn - (use-package-ensure-elpa 'foo 't 'nil :ensure) + (use-package-ensure-elpa 'foo 't 'nil) (eval-and-compile (add-to-list 'load-path ,(pred stringp))) (require 'foo nil 'nil)))) (let (tried-to-install) (flet ((use-package-ensure-elpa - (name ensure state context &optional no-refresh) + (name ensure state &optional no-refresh) (when ensure (setq tried-to-install name))) (require (&rest ignore))) From dee6b36286c9244e10112061866e0ecb5ae3a234 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 1 Dec 2017 13:38:41 -0800 Subject: [PATCH 350/606] If use-package-verbose is t, show loading times when :after is used --- lisp/use-package/use-package.el | 36 ++--- test/lisp/use-package/use-package-tests.el | 156 ++++++++++----------- 2 files changed, 97 insertions(+), 95 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index ae361de6f6b..04a811f4d4c 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -305,8 +305,8 @@ appended." "Return a form which will load or require NAME depending on whether it's a string or symbol." (if (stringp name) - `(load ,name ',noerror) - `(require ',name nil ',noerror))) + `(load ,name ,noerror) + `(require ',name nil ,noerror))) (defun use-package-expand (name label form) "FORM is a list of forms, so `((foo))' if only `foo' is being called." @@ -346,6 +346,20 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." ',(intern (concat "use-package--" name-string "--post-" keyword-name "-hook"))))))))))) +(defun use-package--require (name &optional no-require body) + (use-package--with-elapsed-timer + (format "Loading package %s" name) + (if use-package-expand-minimally + (use-package-concat + (unless no-require + (list (use-package-load-name name))) + body) + (if no-require + body + `((if (not ,(use-package-load-name name t)) + (ignore (message (format "Cannot load %s" ',name))) + ,@body)))))) + (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)) @@ -1204,7 +1218,7 @@ representing symbols (that may need to be autloaded)." (list (funcall (use-package-require-after-load arg) (macroexp-progn - `((require (quote ,name) nil t)))))) + (use-package--require name))))) body))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1262,20 +1276,8 @@ representing symbols (that may need to be autloaded)." (unless (or (null config-body) (equal config-body '(t))) `((eval-after-load ,(if (symbolp name) `',name name) ',(macroexp-progn config-body)))) - - (use-package--with-elapsed-timer - (format "Loading package %s" name) - (if use-package-expand-minimally - (use-package-concat - (unless (plist-get state ':no-require) - (list (use-package-load-name name))) - config-body) - (if (plist-get state ':no-require) - config-body - `((if (not ,(use-package-load-name name t)) - (ignore - (message (format "Cannot load %s" ',name))) - ,@config-body)))))))) + (use-package--require name (plist-get state ':no-require) + config-body)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 60cf2ff7b15..7bc2a486b79 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -100,7 +100,7 @@ `(progn (eval-and-compile (t)) - (require 'foo nil 'nil))) + (require 'foo nil nil))) (let ((byte-compile-current-file t)) (match-expansion @@ -112,7 +112,7 @@ "Cannot load foo: %S" nil (load "foo" nil t))) (t)) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (let ((byte-compile-current-file t)) (match-expansion @@ -132,7 +132,7 @@ (load "foo" nil t))) (preface)) (init) - (require 'foo nil 'nil) + (require 'foo nil nil) (config) t))) @@ -165,19 +165,19 @@ (use-package foo :pin foo) `(progn (use-package-pin-package 'foo "foo") - (require 'foo nil 'nil))) + (require 'foo nil nil))) (match-expansion (use-package foo :pin "foo") `(progn (use-package-pin-package 'foo "foo") - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (ert-deftest use-package-test/:defer-install () (match-expansion (use-package foo :defer-install t) `(progn - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (ert-deftest use-package-test-normalize/:ensure () (flet ((norm (&rest args) @@ -195,28 +195,28 @@ (use-package foo :ensure t) `(progn (use-package-ensure-elpa 'foo 't 'nil) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (let ((use-package-always-ensure t)) (match-expansion (use-package foo :ensure t) `(progn (use-package-ensure-elpa 'foo 't 'nil) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (let ((use-package-always-ensure nil)) (match-expansion (use-package foo :ensure nil) `(progn (use-package-ensure-elpa 'foo 'nil 'nil) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (let ((use-package-always-ensure t)) (match-expansion (use-package foo :ensure nil) `(progn (use-package-ensure-elpa 'foo 'nil 'nil) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (let ((use-package-always-ensure nil)) (match-expansion @@ -224,7 +224,7 @@ `(progn (eval-and-compile (add-to-list 'load-path ,(pred stringp))) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (let ((use-package-always-ensure t)) (match-expansion @@ -233,7 +233,7 @@ (use-package-ensure-elpa 'foo 'nil 'nil) (eval-and-compile (add-to-list 'load-path ,(pred stringp))) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (let ((use-package-always-ensure nil)) (match-expansion @@ -242,7 +242,7 @@ (use-package-ensure-elpa 'foo 'nil 'nil) (eval-and-compile (add-to-list 'load-path ,(pred stringp))) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (let ((use-package-always-ensure t)) (match-expansion @@ -251,7 +251,7 @@ (use-package-ensure-elpa 'foo 'nil 'nil) (eval-and-compile (add-to-list 'load-path ,(pred stringp))) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (let ((use-package-always-ensure nil)) (match-expansion @@ -260,7 +260,7 @@ (use-package-ensure-elpa 'foo 't 'nil) (eval-and-compile (add-to-list 'load-path ,(pred stringp))) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (let ((use-package-always-ensure t)) (match-expansion @@ -269,7 +269,7 @@ (use-package-ensure-elpa 'foo 't 'nil) (eval-and-compile (add-to-list 'load-path ,(pred stringp))) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (let (tried-to-install) (flet ((use-package-ensure-elpa @@ -285,64 +285,64 @@ (use-package foo :if t) `(progn (when (symbol-value 't) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (match-expansion (use-package foo :if (and t t)) `(progn (when (and t t) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (match-expansion (use-package foo :if nil) `(progn (when nil - (require 'foo nil 'nil))))) + (require 'foo nil nil))))) (ert-deftest use-package-test/:when () (match-expansion (use-package foo :when t) `(progn (when (symbol-value 't) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (match-expansion (use-package foo :when (and t t)) `(progn (when (and t t) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (match-expansion (use-package foo :when nil) `(progn (when nil - (require 'foo nil 'nil))))) + (require 'foo nil nil))))) (ert-deftest use-package-test/:unless () (match-expansion (use-package foo :unless t) `(progn (unless (symbol-value 't) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (match-expansion (use-package foo :unless (and t t)) `(progn (unless (and t t) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (match-expansion (use-package foo :unless nil) `(progn (unless nil - (require 'foo nil 'nil))))) + (require 'foo nil nil))))) (ert-deftest use-package-test/:requires () (match-expansion (use-package foo :requires bar) `(progn (when (not (member nil (mapcar #'featurep '(bar)))) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (let ((byte-compile-current-file t)) (match-expansion @@ -353,7 +353,7 @@ (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) - (require 'foo nil 'nil)))))) + (require 'foo nil nil)))))) (ert-deftest use-package-test/:load-path () (match-expansion @@ -365,7 +365,7 @@ #'string= (expand-file-name "bar" user-emacs-directory))))) - (require 'foo nil 'nil))) + (require 'foo nil nil))) (let ((byte-compile-current-file t)) (match-expansion @@ -381,7 +381,7 @@ (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (match-expansion (use-package foo :load-path ("bar" "quux")) @@ -398,7 +398,7 @@ #'string= (expand-file-name "quux" user-emacs-directory))))) - (require 'foo nil 'nil))) + (require 'foo nil nil))) (match-expansion (use-package foo :load-path (lambda () (list "bar" "quux"))) @@ -415,7 +415,7 @@ #'string= (expand-file-name "quux" user-emacs-directory))))) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (ert-deftest use-package-test/:no-require () (match-expansion @@ -613,7 +613,7 @@ (match-expansion (use-package foo :defines bar) `(progn - (require 'foo nil 'nil))) + (require 'foo nil nil))) (let ((byte-compile-current-file t)) (match-expansion @@ -625,13 +625,13 @@ (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) - (require 'foo nil 'nil))))) + (require 'foo nil nil))))) (ert-deftest use-package-test/:functions () (match-expansion (use-package foo :functions bar) `(progn - (require 'foo nil 'nil))) + (require 'foo nil nil))) (let ((byte-compile-current-file t)) (match-expansion @@ -643,7 +643,7 @@ (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (match-expansion (use-package foo :defer t :functions bar) @@ -678,7 +678,7 @@ (match-expansion (use-package foo) `(progn - (require 'foo nil 'nil))) + (require 'foo nil nil))) (let ((byte-compile-current-file t)) (match-expansion @@ -688,7 +688,7 @@ (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (match-expansion (use-package foo :defer t) @@ -766,21 +766,21 @@ (use-package foo :custom (foo bar)) `(progn (customize-set-variable 'foo bar "Customized with use-package foo") - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (ert-deftest use-package-test/:custom-face () (match-expansion (use-package foo :custom-face (foo ((t (:background "#e4edfc"))))) `(progn (custom-set-faces '(foo ((t (:background "#e4edfc"))))) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (ert-deftest use-package-test/:init () (match-expansion (use-package foo :init (init)) `(progn (init) - (require 'foo nil 'nil))) + (require 'foo nil nil))) (let ((byte-compile-current-file t)) (match-expansion @@ -791,14 +791,14 @@ (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) (init) - (require 'foo nil 'nil))))) + (require 'foo nil nil))))) (ert-deftest use-package-test/:after () (match-expansion (use-package foo :after bar) `(progn (eval-after-load 'bar - '(require 'foo nil t)))) + '(require 'foo nil nil)))) (let ((byte-compile-current-file t)) (match-expansion @@ -809,30 +809,30 @@ (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) (eval-after-load 'bar - '(require 'foo nil t))))) + '(require 'foo nil nil))))) (match-expansion (use-package foo :after (bar quux)) `(progn (eval-after-load 'quux '(eval-after-load 'bar - '(require 'foo nil t))))) + '(require 'foo nil nil))))) (match-expansion (use-package foo :after (:all bar quux)) `(progn (eval-after-load 'quux '(eval-after-load 'bar - '(require 'foo nil t))))) + '(require 'foo nil nil))))) (match-expansion (use-package foo :after (:any bar quux)) `(progn (progn (eval-after-load 'bar - '(require 'foo nil t)) + '(require 'foo nil nil)) (eval-after-load 'quux - '(require 'foo nil t))))) + '(require 'foo nil nil))))) (match-expansion (use-package foo :after (:all (:any bar quux) bow)) @@ -840,9 +840,9 @@ (eval-after-load 'bow '(progn (eval-after-load 'bar - '(require 'foo nil t)) + '(require 'foo nil nil)) (eval-after-load 'quux - '(require 'foo nil t)))))) + '(require 'foo nil nil)))))) (match-expansion (use-package foo :after (:any (:all bar quux) bow)) @@ -850,9 +850,9 @@ (progn (eval-after-load 'quux '(eval-after-load 'bar - '(require 'foo nil t))) + '(require 'foo nil nil))) (eval-after-load 'bow - '(require 'foo nil t))))) + '(require 'foo nil nil))))) (match-expansion (use-package foo :after (:all (:any bar quux) (:any bow baz))) @@ -861,15 +861,15 @@ (eval-after-load 'bow '(progn (eval-after-load 'bar - '(require 'foo nil t)) + '(require 'foo nil nil)) (eval-after-load 'quux - '(require 'foo nil t)))) + '(require 'foo nil nil)))) (eval-after-load 'baz '(progn (eval-after-load 'bar - '(require 'foo nil t)) + '(require 'foo nil nil)) (eval-after-load 'quux - '(require 'foo nil t))))))) + '(require 'foo nil nil))))))) (match-expansion (use-package foo :after (:any (:all bar quux) (:all bow baz))) @@ -877,10 +877,10 @@ (progn (eval-after-load 'quux '(eval-after-load 'bar - '(require 'foo nil t))) + '(require 'foo nil nil))) (eval-after-load 'baz '(eval-after-load 'bow - '(require 'foo nil t)))))) + '(require 'foo nil nil)))))) (match-expansion (use-package foo :after (:any (:all bar quux) (:any bow baz))) @@ -888,18 +888,18 @@ (progn (eval-after-load 'quux '(eval-after-load 'bar - '(require 'foo nil t))) + '(require 'foo nil nil))) (progn (eval-after-load 'bow - '(require 'foo nil t)) + '(require 'foo nil nil)) (eval-after-load 'baz - '(require 'foo nil t))))))) + '(require 'foo nil nil))))))) (ert-deftest use-package-test/:demand () (match-expansion (use-package foo :demand t) `(progn - (require 'foo nil 'nil))) + (require 'foo nil nil))) (let ((byte-compile-current-file t)) (match-expansion @@ -909,12 +909,12 @@ (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) - (require 'foo nil 'nil)))) + (require 'foo nil nil)))) (match-expansion (use-package foo :demand t :config (config)) `(progn - (require 'foo nil 'nil) + (require 'foo nil nil) (config) t)) @@ -926,7 +926,7 @@ (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) - (require 'foo nil 'nil) + (require 'foo nil nil) (config) t))) @@ -935,7 +935,7 @@ (use-package foo :demand t :after bar) `(progn (eval-after-load 'bar - '(require 'foo nil t)))) + '(require 'foo nil nil)))) (let ((byte-compile-current-file t)) (match-expansion @@ -946,13 +946,13 @@ (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) (eval-after-load 'bar - '(require 'foo nil t)))))) + '(require 'foo nil nil)))))) (ert-deftest use-package-test/:config () (match-expansion (use-package foo :config (config)) `(progn - (require 'foo nil 'nil) + (require 'foo nil nil) (config) t)) @@ -964,7 +964,7 @@ (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) - (require 'foo nil 'nil) + (require 'foo nil nil) (config) t))) @@ -1005,21 +1005,21 @@ (match-expansion (use-package foo :diminish nil) `(progn - (require 'foo nil 'nil) + (require 'foo nil nil) (if (fboundp 'diminish) (diminish 'foo-mode)))) (match-expansion (use-package foo :diminish bar) `(progn - (require 'foo nil 'nil) + (require 'foo nil nil) (if (fboundp 'diminish) (diminish 'bar)))) (match-expansion (use-package foo :diminish "bar") `(progn - (require 'foo nil 'nil) + (require 'foo nil nil) (if (fboundp 'diminish) (diminish 'foo-mode "bar")))) @@ -1027,7 +1027,7 @@ (match-expansion (use-package foo :diminish (foo . "bar")) `(progn - (require 'foo nil 'nil) + (require 'foo nil nil) (if (fboundp 'diminish) (diminish 'foo "bar"))))) @@ -1052,7 +1052,7 @@ (match-expansion (use-package foo :delight) `(progn - (require 'foo nil 'nil) + (require 'foo nil nil) (if (fboundp 'delight) (delight '((foo-mode nil foo)))))) @@ -1060,21 +1060,21 @@ (match-expansion (use-package foo :delight nil) `(progn - (require 'foo nil 'nil) + (require 'foo nil nil) (if (fboundp 'diminish) (diminish 'foo-mode))))) (match-expansion (use-package foo :delight bar) `(progn - (require 'foo nil 'nil) + (require 'foo nil nil) (if (fboundp 'delight) (delight '((bar nil foo)))))) (match-expansion (use-package foo :delight "bar") `(progn - (require 'foo nil 'nil) + (require 'foo nil nil) (if (fboundp 'delight) (delight '((foo-mode "bar" foo)))))) @@ -1082,14 +1082,14 @@ (match-expansion (use-package foo :delight (foo . "bar")) `(progn - (require 'foo nil 'nil) + (require 'foo nil nil) (if (fboundp 'diminish) (diminish 'foo "bar"))))) (match-expansion (use-package foo :delight (foo "bar")) `(progn - (require 'foo nil 'nil) + (require 'foo nil nil) (if (fboundp 'delight) (delight '((foo "bar" foo))))))) From a9429350d53d4b408600e1b43542e09aa9dc503d Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sat, 2 Dec 2017 11:48:12 -0800 Subject: [PATCH 351/606] Fix `use-package-ensure-function' docstring typo --- lisp/use-package/use-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 04a811f4d4c..bfaac24e48e 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -192,7 +192,7 @@ Must be set before loading use-package." (defcustom use-package-ensure-function 'use-package-ensure-elpa "Function that ensures a package is installed. -This function is called with four arguments: the name of the +This function is called with three arguments: the name of the package declared in the `use-package' form; the argument passed to `:ensure'; and the current `state' plist created by previous handlers. From 9ab797cccdcb8bd583c0e3148e1aeb251bf05fec Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 03:07:30 -0800 Subject: [PATCH 352/606] A great deal of internal reorganization and simplification All handlers now address their own domain of work; :after has become safer; keyword normalization is multi-stage process; setting use-package-verbose to `debug' produces useful output in the *use-package* buffer in the case of load time errors; use-package errors (even internal) won't stop Emacs from starting (though a serious internal bug that errors out every use-package form may stop anything from being configured!); and more. --- etc/USE-PACKAGE-NEWS | 6 + lisp/use-package/use-package.el | 881 ++++++++++++--------- test/lisp/use-package/use-package-tests.el | 422 +++++----- 3 files changed, 719 insertions(+), 590 deletions(-) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index 06adac97188..c65aae64f10 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -18,6 +18,12 @@ - The `:defer-install` keyword has been remove. It may reappear as an add-on module for use-package in a future release. See issue #442 for more details. +- The ordering of several elements of `use-package-keywords' have changed; if + you have this customized you will need to rework your changes. + +- There is no longer a `use-package-debug` option, since `use-package-verbose` + already has the possible value of `debug`. + ### Other changes - Upgrade license to GPL 3. diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index bfaac24e48e..3dab8ec8521 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -67,11 +67,6 @@ then the expanded macros do their job silently." (const :tag "Debug" debug)) :group 'use-package) -(defcustom use-package-debug nil - "Whether to display use-package expansions in a *use-package* buffer." - :type 'boolean - :group 'use-package) - (defcustom use-package-check-before-init nil "If non-nil, check that package exists before executing its `:init' block. The check is performed by looking for the module using `locate-library'." @@ -136,15 +131,15 @@ the user specified." '(:disabled :pin :ensure - :if - :when - :unless + :if :when :unless :requires :load-path - :defines - :functions - :preface :no-require + :preface :defines :functions + :after + :custom + :custom-face + :init :bind :bind* :bind-keymap @@ -153,14 +148,15 @@ the user specified." :mode :magic :magic-fallback - :commands :hook + ;; Any other keyword that also declares commands to be autoloaded (such as + ;; :bind) must appear before this keyword. + :commands :defer - :custom - :custom-face - :init - :after :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 :diminish :delight) @@ -209,8 +205,23 @@ The default value uses package.el to install the package." :group 'use-package) (defcustom use-package-defaults - '((:config '(t) t) - (:ensure use-package-always-ensure use-package-always-ensure) + '((:config '(t) t) ; this '(t) has special meaning; see + ; the handler for :config + (:init nil t) + (:defer use-package-always-defer + (lambda (args) + (and use-package-always-defer + (not (plist-member args :defer)) + (not (plist-member args :demand))))) + (:demand use-package-always-demand + (lambda (args) + (and use-package-always-demand + (not (plist-member args :defer)) + (not (plist-member args :demand))))) + (:ensure use-package-always-ensure + (lambda (args) + (and use-package-always-ensure + (not (plist-member args :load-path))))) (:pin use-package-always-pin use-package-always-pin)) "Alist of default values for `use-package' keywords. Each entry in the alist is a list of three elements. The first @@ -219,9 +230,19 @@ that can be evaluated to get the default value. 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." - :type '(repeat (list symbol sexp sexp))) +`use-package' form. This third element may also be a function, in +which case it receives the list of keywords (in normalized form), +and should return nil or t according to whether defaulting should +be attempted." + :type `(repeat + (list (choice :tag "Keyword" + ,@(mapcar #'(lambda (k) (list 'const k)) + use-package-keywords)) + (choice :tag "Default value" sexp) + (choice :tag "Enable if non-nil" sexp function))) + :group 'use-package) +;;; jww (2017-12-02): This should be in the :set for the option. (when use-package-enable-imenu-support (eval-after-load 'lisp-mode `(let ((sym-regexp (or (bound-and-true-p lisp-mode-symbol-regexp) @@ -308,56 +329,35 @@ whether it's a string or symbol." `(load ,name ,noerror) `(require ',name nil ,noerror))) -(defun use-package-expand (name label form) - "FORM is a list of forms, so `((foo))' if only `foo' is being called." - (declare (indent 1)) - (when form - (if use-package-expand-minimally - form - (let ((err (make-symbol "err"))) - (list - `(condition-case-unless-debug ,err - ,(macroexp-progn form) - (error - (ignore - (display-warning 'use-package - (format "%s %s: %s" - ,name ,label (error-message-string ,err)) - :error))))))))) - -(put 'use-package-expand 'lisp-indent-function 'defun) - (defun use-package-hook-injector (name-string keyword body) "Wrap pre/post hook injections around a given keyword form. ARGS is a list of forms, so `((foo))' if only `foo' is being called." (if (not use-package-inject-hooks) - (use-package-expand name-string (format "%s" keyword) body) + body (let ((keyword-name (substring (format "%s" keyword) 1))) - `((when ,(macroexp-progn - (use-package-expand name-string (format "pre-%s hook" keyword) - `((run-hook-with-args-until-failure - ',(intern (concat "use-package--" name-string - "--pre-" keyword-name "-hook")))))) - ,(macroexp-progn - (use-package-expand name-string (format "%s" keyword) body)) - ,(macroexp-progn - (use-package-expand name-string (format "post-%s hook" keyword) - `((run-hooks - ',(intern (concat "use-package--" name-string - "--post-" keyword-name "-hook"))))))))))) + `((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--require (name &optional no-require body) - (use-package--with-elapsed-timer - (format "Loading package %s" name) - (if use-package-expand-minimally - (use-package-concat - (unless no-require - (list (use-package-load-name name))) - body) - (if 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)) - (ignore (message (format "Cannot load %s" ',name))) + (ignore + (display-warning 'use-package + (format "Cannot load %s" ',name) + :error)) ,@body)))))) (defun use-package--with-elapsed-timer (text body) @@ -408,6 +408,18 @@ This is in contrast to merely setting it to 0." (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)) + (defun use-package-split-list (pred xs) (let ((ys (list nil)) (zs (list nil)) flip) (dolist (x xs) @@ -445,7 +457,7 @@ This is in contrast to merely setting it to 0." (defsubst use-package-concat (&rest elems) "Delete all empty lists from ELEMS (nil or (list nil)), and append them." - (apply #'nconc (delete nil (delete (list nil) elems)))) + (apply #'append (delete nil (delete (list nil) elems)))) (defsubst use-package--non-nil-symbolp (sym) (and sym (symbolp sym))) @@ -484,28 +496,32 @@ This is in contrast to merely setting it to 0." (t (error "Not recognized as regular expression: %s" re)))) -(defun use-package-normalize-plist (name input) - "Given a pseudo-plist, normalize it to a regular plist." - (unless (null input) +(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." + (when input (let* ((keyword (car input)) (xs (use-package-split-list #'keywordp (cdr input))) (args (car xs)) (tail (cdr xs)) (normalizer (intern (concat "use-package-normalize/" (symbol-name keyword)))) - (arg - (cond - ((eq keyword :disabled) - (use-package-normalize-plist name tail)) - ((functionp normalizer) - (funcall normalizer name keyword args)) - ((= (length args) 1) - (car args)) - (t - args)))) + (arg (cond ((functionp normalizer) + (funcall normalizer name keyword args)) + ((= (length args) 1) + (car args)) + (t + args)))) (if (memq keyword use-package-keywords) - (cons keyword - (cons arg (use-package-normalize-plist name tail))) + (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))) (ignore (display-warning 'use-package (format "Unrecognized keyword: %s" keyword) @@ -540,6 +556,16 @@ next value for the STATE." (put 'use-package-process-keywords 'lisp-indent-function 'defun) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; :disabled +;; + +(defalias 'use-package-normalize/:disabled 'ignore) + +(defun use-package-handler/:disabled (name keyword arg rest state) + (use-package-process-keywords name rest state)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; :pin @@ -560,13 +586,13 @@ next value for the STATE." (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)")))))) + #'(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) @@ -619,12 +645,12 @@ manually updated package." (if (null args) t (use-package-only-one (symbol-name keyword) args - (lambda (label arg) - (if (symbolp arg) - arg - (use-package-error - (concat ":ensure wants an optional package name " - "(an unquoted symbol name)"))))))) + #'(lambda (label arg) + (if (symbolp arg) + arg + (use-package-error + (concat ":ensure wants an optional package name " + "(an unquoted symbol name)"))))))) (defun use-package-ensure-elpa (name ensure state &optional no-refresh) (let ((package @@ -675,6 +701,7 @@ manually updated package." (defsubst use-package-normalize-value (label arg) "Normalize a value." (cond ((null arg) nil) + ((eq t arg) t) ((use-package--non-nil-symbolp arg) `(symbol-value ',arg)) ((functionp arg) @@ -756,9 +783,9 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." (let ((body (use-package-process-keywords name rest state))) (if (null requires) body - `((when ,(if (listp requires) + `((when ,(if (> (length requires) 1) `(not (member nil (mapcar #'featurep ',requires))) - `(featurep ',requires)) + `(featurep ',(car requires))) ,@body))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -809,9 +836,7 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." (defalias 'use-package-normalize/:no-require 'use-package-normalize-predicate) (defun use-package-handler/:no-require (name keyword arg rest state) - ;; This keyword has no functional meaning. - (use-package-process-keywords name rest - (plist-put state :no-require t))) + (use-package-process-keywords name rest state)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -840,6 +865,26 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." `((eval-and-compile ,@arg))) body))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; :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)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; :bind, :bind* @@ -948,18 +993,18 @@ representing symbols (that may need to be autloaded)." (defun use-package-normalize-binder (name keyword args) (use-package-as-one (symbol-name keyword) args - (lambda (label arg) - (unless (consp arg) - (use-package-error - (concat label " a ( . )" - " or list of these"))) - (use-package-normalize-pairs - #'(lambda (k) - (pcase k - ((pred stringp) t) - ((pred vectorp) t))) - #'(lambda (v) (use-package--recognize-function v t #'stringp)) - name label arg)))) + #'(lambda (label arg) + (unless (consp arg) + (use-package-error + (concat label " a ( . )" + " or list of these"))) + (use-package-normalize-pairs + #'(lambda (k) + (pcase k + ((pred stringp) t) + ((pred vectorp) t))) + #'(lambda (v) (use-package--recognize-function v t #'stringp)) + name label arg)))) (defalias 'use-package-normalize/:bind 'use-package-normalize-binder) (defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) @@ -971,8 +1016,8 @@ representing symbols (that may need to be autloaded)." (use-package-concat (use-package-process-keywords name (use-package-sort-keywords - (use-package-plist-maybe-put rest :defer t)) - (use-package-plist-append state :commands commands)) + (use-package-plist-append rest :commands commands)) + state) `((ignore (,(if bind-macro bind-macro 'bind-keys) :package ,name ,@nargs)))))) @@ -1031,10 +1076,7 @@ representing symbols (that may need to be autloaded)." ',(cdr binding) ',(use-package-as-symbol name) ,override)))) arg))) (use-package-concat - (use-package-process-keywords name - (use-package-sort-keywords - (use-package-plist-maybe-put rest :defer t)) - state) + (use-package-process-keywords name rest state) `((ignore ,@form))))) (defun use-package-handler/:bind-keymap* (name keyword arg rest state) @@ -1057,20 +1099,18 @@ representing symbols (that may need to be autloaded)." "Handle keywords which add regexp/mode pairs to an alist." (cl-destructuring-bind (nargs . commands) (use-package--normalize-commands args) - (let ((form - (mapcar - #'(lambda (thing) - `(add-to-list - ',alist - ',(cons (use-package-normalize-regex (car thing)) - (cdr thing)))) - nargs))) - (use-package-concat - (use-package-process-keywords name - (use-package-sort-keywords - (use-package-plist-maybe-put rest :defer t)) - (use-package-plist-append state :commands commands)) - `((ignore ,@form)))))) + (use-package-concat + (mapcar + #'(lambda (thing) + `(add-to-list + ',alist + ',(cons (use-package-normalize-regex (car thing)) + (cdr thing)))) + nargs) + (use-package-process-keywords name + (use-package-sort-keywords + (use-package-plist-append rest :commands commands)) + state)))) (defalias 'use-package-normalize/:interpreter 'use-package-normalize-mode) @@ -1107,6 +1147,52 @@ representing symbols (that may need to be autloaded)." (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 or ( . )" + " 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 + name label arg)))) + +(defun use-package-handler/:hook (name keyword args rest state) + "Generate use-package custom keyword code." + (cl-destructuring-bind (nargs . commands) + (use-package--normalize-commands args) + (use-package-concat + (cl-mapcan + #'(lambda (def) + (let ((syms (car def)) + (fun (cdr def))) + (when fun + (mapcar + #'(lambda (sym) + `(add-hook (quote ,(intern (format "%s-hook" sym))) + (function ,fun))) + (if (use-package--non-nil-symbolp syms) (list syms) syms))))) + nargs) + (use-package-process-keywords name + (use-package-sort-keywords + (use-package-plist-append rest :commands commands)) + state)))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; :commands @@ -1115,31 +1201,22 @@ representing symbols (that may need to be autloaded)." (defalias 'use-package-normalize/:commands 'use-package-normalize-symlist) (defun use-package-handler/:commands (name keyword arg rest state) - ;; The actual processing for commands is done in :defer - (use-package-process-keywords name - (use-package-sort-keywords - (use-package-plist-maybe-put rest :defer t)) - (use-package-plist-append state :commands arg))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :defines -;; - -(defalias 'use-package-normalize/:defines 'use-package-normalize-symlist) - -(defun use-package-handler/:defines (name keyword arg rest state) - (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)) + (use-package-concat + (unless (plist-get state :demand) + ;; 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 (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))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -1149,77 +1226,89 @@ representing symbols (that may need to be autloaded)." (defalias 'use-package-normalize/:defer 'use-package-normalize-predicate) (defun use-package-handler/:defer (name keyword arg rest state) - (let ((body (use-package-process-keywords name rest - (plist-put state :deferred t))) - (name-string (use-package-as-string name))) + (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))) - ;; Since we deferring load, establish any necessary autoloads, and also - ;; keep the byte-compiler happy. - (cl-mapcan - #'(lambda (command) - (when (symbolp command) - (append - `((unless (fboundp ',command) - (autoload #',command ,name-string nil t))) - (when (bound-and-true-p byte-compile-current-file) - `((eval-when-compile - (declare-function ,command ,name-string))))))) - (delete-dups (plist-get state :commands))) - - body))) - + (if (or (not arg) (null body)) + body + (list (use-package--require-after-load + name (macroexp-progn body))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; :after ;; -(defalias 'use-package-normalize/:after 'use-package-normalize-recursive-symlist) +(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-require-after-load (features) - "Return form for after any of FEATURES require NAME." +(defun use-package--after-count-uses (features) + "Count the number of time the body would appear in the result." (pcase features ((and (pred use-package--non-nil-symbolp) feat) - `(lambda (body) - (list 'eval-after-load (list 'quote ',feat) - (list 'quote body)))) - (`(,(or :or :any) . ,rest) - `(lambda (body) - (append (list 'progn) - (mapcar (lambda (form) - (funcall form body)) - (list ,@(use-package-require-after-load rest)))))) - (`(,(or :and :all) . ,rest) - `(lambda (body) - (let ((result body)) - (dolist (form (list ,@(use-package-require-after-load rest))) - (setq result (funcall form result))) - result))) + 1) + (`(,(or `:or `:any) . ,rest) + (let ((num 0)) + (dolist (next rest) + (setq num (+ num (use-package--after-count-uses next)))) + num)) + (`(,(or `:and `:all) . ,rest) + (apply #'max (mapcar #'use-package--after-count-uses rest))) (`(,feat . ,rest) - (if rest - (cons (use-package-require-after-load feat) - (use-package-require-after-load rest)) - (list (use-package-require-after-load feat)))))) + (use-package--after-count-uses (cons :all (cons feat rest)))))) + +(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'." + (pcase features + ((and (pred use-package--non-nil-symbolp) feat) + `(eval-after-load ',feat + ,(if (member (car body) '(quote backquote \' \`)) + body + (list 'quote body)))) + (`(,(or `:or `:any) . ,rest) + (macroexp-progn + (mapcar #'(lambda (x) (use-package--require-after-load x body)) rest))) + (`(,(or `:and `:all) . ,rest) + (dolist (next rest) + (setq body (use-package--require-after-load next body))) + body) + (`(,feat . ,rest) + (use-package--require-after-load (cons :all (cons feat rest)) body)))) + +(defun use-package--memoize (f arg) + "Ensure the macro-expansion of F applied to ARG evaluates ARG +no more than once." + (let ((loaded (gensym "use-package--loaded")) + (result (gensym "use-package--result")) + (next (gensym "use-package--next"))) + `((lexical-let (,loaded ,result) + (lexical-let ((,next (lambda () + (if ,loaded + ,result + (setq ,loaded t) + (setq ,result ,arg))))) + ,(funcall f ``(funcall ,,next))))))) (defun use-package-handler/:after (name keyword arg rest state) - (let ((body (use-package-process-keywords name rest - (plist-put state :deferred t))) - (name-string (use-package-as-string name))) - (if (and (consp arg) - (not (memq (car arg) '(:or :any :and :all)))) - (setq arg (cons :all arg))) - (use-package-concat - (when arg - (list (funcall - (use-package-require-after-load arg) - (macroexp-progn - (use-package--require name))))) - body))) + (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) + (list (use-package--require-after-load + arg (list 'quote (macroexp-progn body)))) + (use-package--memoize + (apply-partially #'use-package--require-after-load arg) + (macroexp-progn body)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -1229,105 +1318,7 @@ representing symbols (that may need to be autloaded)." (defalias 'use-package-normalize/:demand 'use-package-normalize-predicate) (defun use-package-handler/:demand (name keyword arg rest state) - (use-package-process-keywords name rest - (use-package-plist-delete state :deferred))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :init -;; - -(defalias 'use-package-normalize/:init 'use-package-normalize-forms) - -(defun use-package-handler/:init (name keyword arg rest state) - (let ((body (use-package-process-keywords name rest state))) - (use-package-concat - ;; The user's initializations - (let ((init-body - (use-package-hook-injector (use-package-as-string name) - :init arg))) - (if use-package-check-before-init - `((if (locate-library ,(use-package-as-string name)) - ,(macroexp-progn init-body))) - init-body)) - body))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :config -;; - -(defalias 'use-package-normalize/:config 'use-package-normalize-forms) - -(defun use-package-handler/:config (name keyword arg rest state) - (let* ((body (use-package-process-keywords name rest state)) - (name-symbol (use-package-as-symbol name)) - (config-body - (if (equal arg '(t)) - body - (use-package--with-elapsed-timer - (format "Configuring package %s" name-symbol) - (use-package-concat - (use-package-hook-injector (symbol-name name-symbol) - :config arg) - body - (list t)))))) - (if (plist-get state :deferred) - (unless (or (null config-body) (equal config-body '(t))) - `((eval-after-load ,(if (symbolp name) `',name name) - ',(macroexp-progn config-body)))) - (use-package--require name (plist-get state ':no-require) - config-body)))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :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 or ( . )" - " 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 - name label arg)))) - -(defun use-package-handler/:hook (name keyword args rest state) - "Generate use-package custom keyword code." - (cl-destructuring-bind (nargs . commands) - (use-package--normalize-commands args) - (use-package-concat - (use-package-process-keywords name - (if commands - (use-package-sort-keywords - (use-package-plist-maybe-put rest :defer t)) - rest) - (if commands - (use-package-plist-append state :commands commands) - state)) - (cl-mapcan - (lambda (def) - (let ((syms (car def)) - (fun (cdr def))) - (when fun - (mapcar - #'(lambda (sym) - `(add-hook (quote ,(intern (format "%s-hook" sym))) - (function ,fun))) - (if (use-package--non-nil-symbolp syms) (list syms) syms))))) - nargs)))) + (use-package-process-keywords name rest state)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -1337,28 +1328,27 @@ representing symbols (that may need to be autloaded)." (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 ( [comment])" - " or list of these"))) - (if (use-package--non-nil-symbolp (car arg)) - (list arg) - arg)))) + #'(lambda (label arg) + (unless (listp arg) + (use-package-error + (concat label " a ( [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." - (let ((body (use-package-process-keywords name rest state))) - (use-package-concat - (mapcar (lambda (def) + (use-package-concat + (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) - body))) + args) + (use-package-process-keywords name rest state))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -1382,12 +1372,66 @@ representing symbols (that may need to be autloaded)." (defun use-package-handler/:custom-face (name keyword args rest state) "Generate use-package custom-face keyword code." + (use-package-concat + (mapcar #'(lambda (def) `(custom-set-faces (quote ,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 + ;; The user's initializations + (let ((init-body + (use-package-hook-injector (use-package-as-string name) + :init arg))) + (if use-package-check-before-init + `((if (locate-library ,(use-package-as-string name)) + ,(macroexp-progn init-body))) + init-body)) + (use-package-process-keywords name rest state))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; :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))) - (use-package-concat - (mapcar (lambda (def) - `(custom-set-faces (quote ,def))) - args) - body))) + (dolist (pkg arg) + (setq body (use-package--require 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))) + (if (or (null arg) + (equal arg '(t))) + body + (use-package--with-elapsed-timer + (format "Configuring package %s" name-symbol) + (use-package-concat + (use-package-hook-injector + (symbol-name name-symbol) :config arg) + body + (list t)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -1487,6 +1531,119 @@ representing symbols (that may need to be autloaded)." ;;; The main macro ;; +(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) + (pcase key + (`:if `(and ,new ,old)) + (`:after `(:all ,new ,old)) + (`:defer old) + (_ (append new old)))) + +(defun use-package-normalize-keywords (name args) + (let* ((name-symbol (if (stringp name) (intern name) name)) + (name-string (symbol-name name-symbol))) + + ;; 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. + (dolist (spec use-package-defaults) + (when (pcase (nth 2 spec) + ((and func (pred functionp)) (funcall func args)) + (sexp (eval sexp))) + (setq args (use-package-plist-maybe-put + args (nth 0 spec) (eval (nth 1 spec)))))) + + ;; 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) + `(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)) + (or (plist-member args :bind) + (plist-member args :bind*) + (plist-member args :bind-keymap) + (plist-member args :bind-keymap*) + (plist-member args :interpreter) + (plist-member args :mode) + (plist-member args :magic) + (plist-member args :magic-fallback) + (plist-member args :commands) + (plist-member args :hook))) + (setq args (append args '(:defer t)))) + + (when (and (plist-member args :load) + (plist-member args :no-require)) + (setq args (use-package-plist-delete args :no-require))) + + (when (and (not (plist-member args :load)) + (not (plist-member args :defer)) + (not (plist-member 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--core (name args) + (let ((orig-args (cl-copy-list args))) + (setq args (use-package-normalize-keywords name args)) + (let ((body (macroexp-progn + (use-package-process-keywords name args + (and (plist-get args :demand) + (list :demand t)))))) + (if (not (eq use-package-verbose 'debug)) + body + `(condition-case-unless-debug err + ,body + (error + (let ((msg (format "%s: %s" ',name (error-message-string err)))) + (with-current-buffer (get-buffer-create "*use-package*") + (goto-char (point-max)) + (insert "-----\n" msg "\n\n" + (pp-to-string ',`(use-package ,name ,@orig-args)) + "\n -->\n\n" + (pp-to-string ',`(use-package ,name ,@args)) + "\n ==>\n\n" + (pp-to-string + ',(let ((use-package-verbose 'errors) + (use-package-expand-minimally t)) + (macroexp-progn + (use-package-process-keywords name args + (and (plist-get args :demand) + (list :demand t))))))) + (emacs-lisp-mode)) + (ignore + (display-warning + 'use-package (concat msg " (see the *use-package* buffer)") + :error))))))))) + ;;;###autoload (defmacro use-package (name &rest args) "Declare an Emacs package by specifying a group of configuration options. @@ -1543,72 +1700,18 @@ this file. Usage: :ensure Loads the package using package.el if necessary. :pin Pin the package to an archive." (declare (indent 1)) - (unless (member :disabled args) - (let ((name-symbol (if (stringp name) (intern name) name)) - (orig-args args) - (args (use-package-normalize-plist name args))) - (dolist (spec use-package-defaults) - (setq args (if (eval (nth 2 spec)) - (use-package-plist-maybe-put - args (nth 0 spec) (eval (nth 1 spec))) - args))) - - ;; When byte-compiling, pre-load the package so all its symbols are in - ;; scope. - (if (bound-and-true-p byte-compile-current-file) - (setq args - (use-package-plist-append - args :preface - (use-package-concat - (mapcar #'(lambda (var) `(defvar ,var)) - (plist-get args :defines)) - (mapcar #'(lambda (fn) `(declare-function - ,fn ,(use-package-as-string name))) - (plist-get args :functions)) - `((eval-when-compile - (with-demoted-errors - ,(format "Cannot load %s: %%S" name) - ,(if (eq use-package-verbose 'debug) - `(message "Compiling package %s" ',name-symbol)) - ,(unless (plist-get args :no-require) - `(load ,(if (stringp name) - name - (symbol-name name)) nil t))))))))) - - (let ((body - `(progn - ,@(use-package-process-keywords name - (let ((args* - (use-package-sort-keywords - (if (and use-package-always-demand - (not (memq :defer args))) - (plist-put args :demand t) - args)))) - ;; The :demand keyword should not override :after - (if (and (plist-member args* :after) - (plist-member args* :demand)) - (setq args* (use-package-plist-delete args* :demand))) - (when (and use-package-always-ensure - (plist-member args* :load-path) - (not (plist-member orig-args :ensure))) - (plist-put args* :ensure nil)) - (unless (plist-member args* :init) - (plist-put args* :init nil)) - (unless (plist-member args* :config) - (plist-put args* :config '(t))) - args*) - (and use-package-always-defer - (list :deferred t)))))) - (when use-package-debug - (display-buffer - (save-current-buffer - (with-current-buffer (get-buffer-create "*use-package*") - (goto-char (point-max)) - (emacs-lisp-mode) - (insert (pp-to-string body)) - (current-buffer))))) - body)))) - + (unless (memq :disabled args) + (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: %s" + name args (error-message-string err)) + :error))))))) (put 'use-package 'lisp-indent-function 'defun) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 7bc2a486b79..5cf7a342b36 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -26,23 +26,36 @@ (require 'use-package) (setq use-package-always-ensure nil - use-package-verbose nil + use-package-verbose 'errors use-package-expand-minimally t - max-lisp-eval-depth 8000) - -;; (let ((byte-compile-current-file nil)) (expand-minimally ())) -(fset 'insert-expansion - [?\C-\M- ?\M-w ?\M-: ?\M-p ?\C-e ?\C-b ?\C-b ?\C-\M-b ?\C-y ?\C-\M-k return ?\C-\M- ?\M-w C-return ?\C-z ?\C-n ?\C-f ?\C-y ?\C-\M-k]) + max-lisp-eval-depth 8000 + max-specpdl-size 8000) (defmacro expand-minimally (form) - `(let ((use-package-verbose nil) + `(let ((use-package-verbose 'errors) (use-package-expand-minimally t)) - (macroexpand ',form))) + (macroexpand-1 ',form))) (defmacro match-expansion (form &rest value) `(should (pcase (expand-minimally ,form) ,@(mapcar #'(lambda (x) (list x t)) value)))) +(defun fix-expansion () + (interactive) + (save-excursion + (unless (looking-at "(match-expansion") + (backward-up-list)) + (when (looking-at "(match-expansion") + (search-forward "(use-package") + (goto-char (match-beginning 0)) + (let ((decl (read (current-buffer)))) + (kill-sexp) + (let ((use-package-verbose 'errors) + (use-package-expand-minimally t)) + (insert ?\n ?\` (pp-to-string (macroexpand-1 decl)))))))) + +(bind-key "C-c C-u" #'fix-expansion emacs-lisp-mode-map) + (eval-when-compile (defun plist-delete (plist property) "Delete PROPERTY from PLIST" @@ -87,11 +100,6 @@ (ert-deftest use-package-test/:disabled () (match-expansion (use-package foo :disabled t) - `()) - - (match-expansion - ;; jww (2017-11-30): Should :disabled ignore its argument? - (use-package foo :disabled nil) `())) (ert-deftest use-package-test/:preface () @@ -176,8 +184,7 @@ (ert-deftest use-package-test/:defer-install () (match-expansion (use-package foo :defer-install t) - `(progn - (require 'foo nil nil)))) + `(require 'foo nil nil))) (ert-deftest use-package-test-normalize/:ensure () (flet ((norm (&rest args) @@ -230,7 +237,6 @@ (match-expansion (use-package foo :load-path "foo") `(progn - (use-package-ensure-elpa 'foo 'nil 'nil) (eval-and-compile (add-to-list 'load-path ,(pred stringp))) (require 'foo nil nil)))) @@ -283,77 +289,82 @@ (ert-deftest use-package-test/:if () (match-expansion (use-package foo :if t) - `(progn - (when (symbol-value 't) - (require 'foo nil nil)))) + `(when t + (require 'foo nil nil))) (match-expansion (use-package foo :if (and t t)) - `(progn - (when (and t t) - (require 'foo nil nil)))) + `(when (and t t) + (require 'foo nil nil))) (match-expansion (use-package foo :if nil) - `(progn - (when nil - (require 'foo nil nil))))) + `(when nil + (require 'foo nil nil)))) (ert-deftest use-package-test/:when () (match-expansion (use-package foo :when t) - `(progn - (when (symbol-value 't) - (require 'foo nil nil)))) + `(when t + (require 'foo nil nil))) (match-expansion (use-package foo :when (and t t)) - `(progn - (when (and t t) - (require 'foo nil nil)))) + `(when (and t t) + (require 'foo nil nil))) (match-expansion (use-package foo :when nil) - `(progn - (when nil - (require 'foo nil nil))))) + `(when nil + (require 'foo nil nil)))) (ert-deftest use-package-test/:unless () (match-expansion (use-package foo :unless t) - `(progn - (unless (symbol-value 't) - (require 'foo nil nil)))) + `(when (not t) + (require 'foo nil nil))) (match-expansion (use-package foo :unless (and t t)) - `(progn - (unless (and t t) - (require 'foo nil nil)))) + `(when (not (and t t)) + (require 'foo nil nil))) (match-expansion (use-package foo :unless nil) - `(progn - (unless nil - (require 'foo nil nil))))) + `(unless nil + (require 'foo nil nil)))) (ert-deftest use-package-test/:requires () (match-expansion (use-package foo :requires bar) - `(progn - (when (not (member nil (mapcar #'featurep '(bar)))) - (require 'foo nil nil)))) + `(when (featurep 'bar) + (require 'foo nil nil))) (let ((byte-compile-current-file t)) (match-expansion (use-package foo :requires bar) - `(progn - (when (not (member nil (mapcar #'featurep '(bar)))) - (eval-and-compile - (eval-when-compile - (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))) - (require 'foo nil nil)))))) + `(when (featurep 'bar) + (eval-and-compile + (eval-when-compile + (with-demoted-errors + "Cannot load foo: %S" nil + (load "foo" nil t)))) + (require 'foo nil nil)))) + + (match-expansion + (use-package foo :requires (bar quux)) + `(when (not (member nil (mapcar #'featurep '(bar quux)))) + (require 'foo nil nil))) + + (let ((byte-compile-current-file t)) + (match-expansion + (use-package foo :requires bar) + `(when (featurep 'bar) + (eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load foo: %S" nil + (load "foo" nil t)))) + (require 'foo nil nil))))) (ert-deftest use-package-test/:load-path () (match-expansion @@ -420,7 +431,7 @@ (ert-deftest use-package-test/:no-require () (match-expansion (use-package foo :no-require t) - `(progn)) + `nil) (match-expansion (use-package foo :no-require t :config (config)) @@ -431,10 +442,9 @@ (let ((byte-compile-current-file t)) (match-expansion (use-package foo :no-require t) - `(progn - (eval-and-compile - (eval-when-compile - (with-demoted-errors "Cannot load foo: %S" nil nil))))))) + `(eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load foo: %S" nil nil)))))) (ert-deftest use-package-test-normalize/:bind () (flet ((norm (&rest args) @@ -469,41 +479,35 @@ (ert-deftest use-package-test/:bind-keymap () (match-expansion (use-package foo :bind-keymap ("C-k" . key)) - `(progn - (ignore - (bind-key "C-k" - #'(lambda () - (interactive) - (use-package-autoload-keymap 'key 'foo nil))))))) + `(ignore + (bind-key "C-k" + #'(lambda nil + (interactive) + (use-package-autoload-keymap 'key 'foo nil)))))) (ert-deftest use-package-test/:bind-keymap* () (match-expansion (use-package foo :bind-keymap* ("C-k" . key)) - `(progn - (ignore - (bind-key* "C-k" - #'(lambda () - (interactive) - (use-package-autoload-keymap 'key 'foo t))))))) + `(ignore + (bind-key* "C-k" + #'(lambda () + (interactive) + (use-package-autoload-keymap 'key 'foo t)))))) (ert-deftest use-package-test/:interpreter () (match-expansion (use-package foo :interpreter "interp") `(progn + (add-to-list 'interpreter-mode-alist '("interp" . foo)) (unless (fboundp 'foo) - (autoload #'foo "foo" nil t)) - (ignore - (add-to-list 'interpreter-mode-alist - '("interp" . foo))))) + (autoload #'foo "foo" nil t)))) (match-expansion (use-package foo :interpreter ("interp" . fun)) `(progn + (add-to-list 'interpreter-mode-alist '("interp" . fun)) (unless (fboundp 'fun) - (autoload #'fun "foo" nil t)) - (ignore - (add-to-list 'interpreter-mode-alist - '("interp" . fun)))))) + (autoload #'fun "foo" nil t))))) (ert-deftest use-package-test-normalize/:mode () (flet ((norm (&rest args) @@ -524,65 +528,52 @@ (match-expansion (use-package foo :mode "interp") `(progn + (add-to-list 'auto-mode-alist '("interp" . foo)) (unless (fboundp 'foo) - (autoload #'foo "foo" nil t)) - (ignore - (add-to-list 'auto-mode-alist - '("interp" . foo))))) + (autoload #'foo "foo" nil t)))) (match-expansion (use-package foo :mode ("interp" . fun)) `(progn + (add-to-list 'auto-mode-alist '("interp" . fun)) (unless (fboundp 'fun) - (autoload #'fun "foo" nil t)) - (ignore - (add-to-list 'auto-mode-alist - '("interp" . fun)))))) + (autoload #'fun "foo" nil t))))) (ert-deftest use-package-test/:magic () (match-expansion (use-package foo :magic "interp") `(progn + (add-to-list 'magic-mode-alist '("interp" . foo)) (unless (fboundp 'foo) - (autoload #'foo "foo" nil t)) - (ignore - (add-to-list 'magic-mode-alist - '("interp" . foo))))) + (autoload #'foo "foo" nil t)))) (match-expansion (use-package foo :magic ("interp" . fun)) `(progn + (add-to-list 'magic-mode-alist '("interp" . fun)) (unless (fboundp 'fun) - (autoload #'fun "foo" nil t)) - (ignore - (add-to-list 'magic-mode-alist - '("interp" . fun)))))) + (autoload #'fun "foo" nil t))))) (ert-deftest use-package-test/:magic-fallback () (match-expansion (use-package foo :magic-fallback "interp") `(progn + (add-to-list 'magic-fallback-mode-alist '("interp" . foo)) (unless (fboundp 'foo) - (autoload #'foo "foo" nil t)) - (ignore - (add-to-list 'magic-fallback-mode-alist - '("interp" . foo))))) + (autoload #'foo "foo" nil t)))) (match-expansion (use-package foo :magic-fallback ("interp" . fun)) `(progn + (add-to-list 'magic-fallback-mode-alist '("interp" . fun)) (unless (fboundp 'fun) - (autoload #'fun "foo" nil t)) - (ignore - (add-to-list 'magic-fallback-mode-alist - '("interp" . fun)))))) + (autoload #'fun "foo" nil t))))) (ert-deftest use-package-test/:commands () (match-expansion (use-package foo :commands bar) - `(progn - (unless (fboundp 'bar) - (autoload #'bar "foo" nil t)))) + `(unless (fboundp 'bar) + (autoload #'bar "foo" nil t))) (match-expansion (use-package foo :commands (bar quux)) @@ -612,8 +603,7 @@ (ert-deftest use-package-test/:defines () (match-expansion (use-package foo :defines bar) - `(progn - (require 'foo nil nil))) + `(require 'foo nil nil)) (let ((byte-compile-current-file t)) (match-expansion @@ -630,8 +620,7 @@ (ert-deftest use-package-test/:functions () (match-expansion (use-package foo :functions bar) - `(progn - (require 'foo nil nil))) + `(require 'foo nil nil)) (let ((byte-compile-current-file t)) (match-expansion @@ -647,17 +636,16 @@ (match-expansion (use-package foo :defer t :functions bar) - `(progn)) + `nil) (let ((byte-compile-current-file t)) (match-expansion (use-package foo :defer t :functions bar) - `(progn - (eval-and-compile - (declare-function bar "foo") - (eval-when-compile - (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t))))))) + `(eval-and-compile + (declare-function bar "foo") + (eval-when-compile + (with-demoted-errors "Cannot load foo: %S" nil + (load "foo" nil t)))))) (let ((byte-compile-current-file t)) (match-expansion @@ -677,8 +665,7 @@ (ert-deftest use-package-test/:defer () (match-expansion (use-package foo) - `(progn - (require 'foo nil nil))) + `(require 'foo nil nil)) (let ((byte-compile-current-file t)) (match-expansion @@ -692,16 +679,15 @@ (match-expansion (use-package foo :defer t) - `(progn)) + `nil) (let ((byte-compile-current-file t)) (match-expansion (use-package foo :defer t) - `(progn - (eval-and-compile - (eval-when-compile - (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))))))) + `(eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load foo: %S" nil + (load "foo" nil t))))))) (ert-deftest use-package-test-normalize/:hook () (flet ((norm (&rest args) @@ -726,7 +712,7 @@ (ert-deftest use-package-test/:hook () (let ((byte-compile-current-file t)) (should - (equal ; pcase crashes + (equal (expand-minimally (use-package foo :bind (("C-a" . key)) @@ -734,8 +720,10 @@ '(progn (eval-and-compile (eval-when-compile - (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))) + (with-demoted-errors + "Cannot load foo: %S" nil + (load "foo" nil t)))) + (add-hook 'hook-hook #'fun) (unless (fboundp 'fun) (autoload #'fun "foo" nil t)) (eval-when-compile @@ -744,7 +732,6 @@ (autoload #'key "foo" nil t)) (eval-when-compile (declare-function key "foo")) - (add-hook 'hook-hook #'fun) (ignore (bind-keys :package foo ("C-a" . key)))))))) @@ -796,9 +783,8 @@ (ert-deftest use-package-test/:after () (match-expansion (use-package foo :after bar) - `(progn - (eval-after-load 'bar - '(require 'foo nil nil)))) + `(eval-after-load 'bar + '(require 'foo nil nil))) (let ((byte-compile-current-file t)) (match-expansion @@ -813,93 +799,96 @@ (match-expansion (use-package foo :after (bar quux)) - `(progn - (eval-after-load 'quux - '(eval-after-load 'bar - '(require 'foo nil nil))))) + `(eval-after-load 'quux + '(eval-after-load 'bar + '(require 'foo nil nil)))) (match-expansion (use-package foo :after (:all bar quux)) - `(progn - (eval-after-load 'quux - '(eval-after-load 'bar - '(require 'foo nil nil))))) + `(eval-after-load 'quux + '(eval-after-load 'bar + '(require 'foo nil nil)))) (match-expansion (use-package foo :after (:any bar quux)) - `(progn - (progn - (eval-after-load 'bar - '(require 'foo nil nil)) - (eval-after-load 'quux - '(require 'foo nil nil))))) + `(lexical-let ,_ + (lexical-let ,_ + (progn + (eval-after-load 'bar + `(funcall ,_)) + (eval-after-load 'quux + `(funcall ,_)))))) (match-expansion (use-package foo :after (:all (:any bar quux) bow)) - `(progn - (eval-after-load 'bow - '(progn - (eval-after-load 'bar - '(require 'foo nil nil)) - (eval-after-load 'quux - '(require 'foo nil nil)))))) + `(lexical-let ,_ + (lexical-let ,_ + (eval-after-load 'bow + '(progn + (eval-after-load 'bar + `(funcall ,_)) + (eval-after-load 'quux + `(funcall ,_))))))) (match-expansion (use-package foo :after (:any (:all bar quux) bow)) - `(progn - (progn - (eval-after-load 'quux - '(eval-after-load 'bar - '(require 'foo nil nil))) - (eval-after-load 'bow - '(require 'foo nil nil))))) + `(lexical-let ,_ + (lexical-let ,_ + (progn + (eval-after-load 'quux + '(eval-after-load 'bar + `(funcall ,_))) + (eval-after-load 'bow + `(funcall ,_)))))) (match-expansion (use-package foo :after (:all (:any bar quux) (:any bow baz))) - `(progn - (progn - (eval-after-load 'bow - '(progn - (eval-after-load 'bar - '(require 'foo nil nil)) - (eval-after-load 'quux - '(require 'foo nil nil)))) - (eval-after-load 'baz - '(progn - (eval-after-load 'bar - '(require 'foo nil nil)) - (eval-after-load 'quux - '(require 'foo nil nil))))))) + `(lexical-let ,_ + (lexical-let ,_ + (progn + (eval-after-load 'bow + '(progn + (eval-after-load 'bar + `(funcall ,_)) + (eval-after-load 'quux + `(funcall ,_)))) + (eval-after-load 'baz + '(progn + (eval-after-load 'bar + `(funcall ,_)) + (eval-after-load 'quux + `(funcall ,_)))))))) (match-expansion (use-package foo :after (:any (:all bar quux) (:all bow baz))) - `(progn - (progn - (eval-after-load 'quux - '(eval-after-load 'bar - '(require 'foo nil nil))) - (eval-after-load 'baz - '(eval-after-load 'bow - '(require 'foo nil nil)))))) + `(lexical-let ,_ + (lexical-let ,_ + (progn + (eval-after-load 'quux + '(eval-after-load 'bar + `(funcall ,_))) + (eval-after-load 'baz + '(eval-after-load 'bow + `(funcall ,_))))))) (match-expansion (use-package foo :after (:any (:all bar quux) (:any bow baz))) - `(progn - (progn - (eval-after-load 'quux - '(eval-after-load 'bar - '(require 'foo nil nil))) + `(lexical-let ,_ + (lexical-let ,_ (progn - (eval-after-load 'bow - '(require 'foo nil nil)) - (eval-after-load 'baz - '(require 'foo nil nil))))))) + (eval-after-load 'quux + '(eval-after-load 'bar + `(funcall ,_))) + (progn + (eval-after-load 'bow + `(funcall ,use-package--next142993)) + (eval-after-load 'baz + `(funcall ,_)))))))) (ert-deftest use-package-test/:demand () (match-expansion (use-package foo :demand t) - `(progn - (require 'foo nil nil))) + `(require 'foo nil nil)) (let ((byte-compile-current-file t)) (match-expansion @@ -933,9 +922,8 @@ ;; #529 - :demand should not override an explicit use of :after (match-expansion (use-package foo :demand t :after bar) - `(progn - (eval-after-load 'bar - '(require 'foo nil nil)))) + `(eval-after-load 'bar + '(require 'foo nil nil))) (let ((byte-compile-current-file t)) (match-expansion @@ -946,7 +934,40 @@ (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) (eval-after-load 'bar - '(require 'foo nil nil)))))) + '(require 'foo nil nil))))) + + (match-expansion + (use-package counsel + :load-path "site-lisp/swiper" + :after ivy + :demand t + :diminish + :bind (("C-*" . counsel-org-agenda-headlines) + ("M-x" . counsel-M-x)) + :commands (counsel-minibuffer-history + counsel-find-library + counsel-unicode-char) + :preface (preface-code) + :init + ;; This is actually wrong, but it's just part of the example. + (define-key minibuffer-local-map (kbd "M-r") + 'counsel-minibuffer-history)) + `(progn + (eval-and-compile + (add-to-list 'load-path "/Users/johnw/.emacs.d/site-lisp/swiper")) + (eval-and-compile + (preface-code)) + (eval-after-load 'ivy + '(progn + (define-key minibuffer-local-map (kbd "M-r") + 'counsel-minibuffer-history) + (require 'counsel nil nil) + (if (fboundp 'diminish) + (diminish 'counsel-mode)) + (ignore + (bind-keys :package counsel + ("C-*" . counsel-org-agenda-headlines) + ("M-x" . counsel-M-x)))))))) (ert-deftest use-package-test/:config () (match-expansion @@ -970,11 +991,10 @@ (match-expansion (use-package foo :defer t :config (config)) - `(progn - (eval-after-load 'foo - '(progn - (config) - t)))) + `(eval-after-load 'foo + '(progn + (config) + t))) (let ((byte-compile-current-file t)) (match-expansion From 4c1b82aed582271d2159a3ae280ff79c272f6a46 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 10:33:12 -0800 Subject: [PATCH 353/606] Define macroexpand-1 for older Emacsen --- test/lisp/use-package/use-package-tests.el | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 5cf7a342b36..fc9c0f184b6 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -31,6 +31,31 @@ max-lisp-eval-depth 8000 max-specpdl-size 8000) +(unless (fboundp 'macroexpand-1) + (defun macroexpand-1 (form &optional environment) + "Perform (at most) one step of macroexpansion." + (cond + ((consp form) + (let* ((head (car form)) + (env-expander (assq head environment))) + (if env-expander + (if (cdr env-expander) + (apply (cdr env-expander) (cdr form)) + form) + (if (not (and (symbolp head) (fboundp head))) + form + (let ((def (autoload-do-load (symbol-function head) head 'macro))) + (cond + ;; Follow alias, but only for macros, otherwise we may end up + ;; skipping an important compiler-macro (e.g. cl--block-wrapper). + ((and (symbolp def) (macrop def)) (cons def (cdr form))) + ((not (consp def)) form) + (t + (if (eq 'macro (car def)) + (apply (cdr def) (cdr form)) + form)))))))) + (t form)))) + (defmacro expand-minimally (form) `(let ((use-package-verbose 'errors) (use-package-expand-minimally t)) From e5aa510d48aa1bd709b100102e86fd1b7db78a5c Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 10:49:33 -0800 Subject: [PATCH 354/606] Separate out all tests, the better to identify which one failed --- test/lisp/use-package/use-package-tests.el | 275 +++++++++++++-------- 1 file changed, 169 insertions(+), 106 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index fc9c0f184b6..14e8bcd3dd5 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -122,19 +122,20 @@ (should (equal (use-package--normalize-function "Hello") "Hello")) (should (equal (use-package--normalize-function '(nil . nil)) '(nil . nil)))) -(ert-deftest use-package-test/:disabled () +(ert-deftest use-package-test/:disabled-1 () (match-expansion (use-package foo :disabled t) `())) -(ert-deftest use-package-test/:preface () +(ert-deftest use-package-test/:preface-1 () (match-expansion (use-package foo :preface (t)) `(progn (eval-and-compile (t)) - (require 'foo nil nil))) + (require 'foo nil nil)))) +(ert-deftest use-package-test/:preface-2 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo :preface (t)) @@ -145,8 +146,9 @@ "Cannot load foo: %S" nil (load "foo" nil t))) (t)) - (require 'foo nil nil)))) + (require 'foo nil nil))))) +(ert-deftest use-package-test/:preface-3 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo @@ -167,8 +169,9 @@ (init) (require 'foo nil nil) (config) - t))) + t)))) +(ert-deftest use-package-test/:preface-4 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo @@ -193,24 +196,20 @@ (config) t)))))) -(ert-deftest use-package-test/:pin () +(ert-deftest use-package-test/:pin-1 () (match-expansion (use-package foo :pin foo) `(progn (use-package-pin-package 'foo "foo") - (require 'foo nil nil))) + (require 'foo nil nil)))) +(ert-deftest use-package-test/:pin-2 () (match-expansion (use-package foo :pin "foo") `(progn (use-package-pin-package 'foo "foo") (require 'foo nil nil)))) -(ert-deftest use-package-test/:defer-install () - (match-expansion - (use-package foo :defer-install t) - `(require 'foo nil nil))) - (ert-deftest use-package-test-normalize/:ensure () (flet ((norm (&rest args) (apply #'use-package-normalize/:ensure @@ -221,51 +220,57 @@ (should-error (norm '(1))) (should-error (norm '("Hello"))))) -(ert-deftest use-package-test/:ensure () +(ert-deftest use-package-test/:ensure-1 () (let ((use-package-always-ensure nil)) (match-expansion (use-package foo :ensure t) `(progn (use-package-ensure-elpa 'foo 't 'nil) - (require 'foo nil nil)))) + (require 'foo nil nil))))) +(ert-deftest use-package-test/:ensure-2 () (let ((use-package-always-ensure t)) (match-expansion (use-package foo :ensure t) `(progn (use-package-ensure-elpa 'foo 't 'nil) - (require 'foo nil nil)))) + (require 'foo nil nil))))) +(ert-deftest use-package-test/:ensure-3 () (let ((use-package-always-ensure nil)) (match-expansion (use-package foo :ensure nil) `(progn (use-package-ensure-elpa 'foo 'nil 'nil) - (require 'foo nil nil)))) + (require 'foo nil nil))))) +(ert-deftest use-package-test/:ensure-4 () (let ((use-package-always-ensure t)) (match-expansion (use-package foo :ensure nil) `(progn (use-package-ensure-elpa 'foo 'nil 'nil) - (require 'foo nil nil)))) + (require 'foo nil nil))))) +(ert-deftest use-package-test/:ensure-5 () (let ((use-package-always-ensure nil)) (match-expansion (use-package foo :load-path "foo") `(progn (eval-and-compile (add-to-list 'load-path ,(pred stringp))) - (require 'foo nil nil)))) + (require 'foo nil nil))))) +(ert-deftest use-package-test/:ensure-6 () (let ((use-package-always-ensure t)) (match-expansion (use-package foo :load-path "foo") `(progn (eval-and-compile (add-to-list 'load-path ,(pred stringp))) - (require 'foo nil nil)))) + (require 'foo nil nil))))) +(ert-deftest use-package-test/:ensure-7 () (let ((use-package-always-ensure nil)) (match-expansion (use-package foo :ensure nil :load-path "foo") @@ -273,8 +278,9 @@ (use-package-ensure-elpa 'foo 'nil 'nil) (eval-and-compile (add-to-list 'load-path ,(pred stringp))) - (require 'foo nil nil)))) + (require 'foo nil nil))))) +(ert-deftest use-package-test/:ensure-8 () (let ((use-package-always-ensure t)) (match-expansion (use-package foo :ensure nil :load-path "foo") @@ -282,8 +288,9 @@ (use-package-ensure-elpa 'foo 'nil 'nil) (eval-and-compile (add-to-list 'load-path ,(pred stringp))) - (require 'foo nil nil)))) + (require 'foo nil nil))))) +(ert-deftest use-package-test/:ensure-9 () (let ((use-package-always-ensure nil)) (match-expansion (use-package foo :ensure t :load-path "foo") @@ -291,8 +298,9 @@ (use-package-ensure-elpa 'foo 't 'nil) (eval-and-compile (add-to-list 'load-path ,(pred stringp))) - (require 'foo nil nil)))) + (require 'foo nil nil))))) +(ert-deftest use-package-test/:ensure-10 () (let ((use-package-always-ensure t)) (match-expansion (use-package foo :ensure t :load-path "foo") @@ -300,8 +308,9 @@ (use-package-ensure-elpa 'foo 't 'nil) (eval-and-compile (add-to-list 'load-path ,(pred stringp))) - (require 'foo nil nil)))) + (require 'foo nil nil))))) +(ert-deftest use-package-test/:ensure-11 () (let (tried-to-install) (flet ((use-package-ensure-elpa (name ensure state &optional no-refresh) @@ -311,60 +320,67 @@ (use-package foo :ensure t) (should (eq tried-to-install 'foo))))) -(ert-deftest use-package-test/:if () +(ert-deftest use-package-test/:if-1 () (match-expansion (use-package foo :if t) `(when t - (require 'foo nil nil))) + (require 'foo nil nil)))) +(ert-deftest use-package-test/:if-2 () (match-expansion (use-package foo :if (and t t)) `(when (and t t) - (require 'foo nil nil))) + (require 'foo nil nil)))) +(ert-deftest use-package-test/:if-3 () (match-expansion (use-package foo :if nil) `(when nil (require 'foo nil nil)))) -(ert-deftest use-package-test/:when () +(ert-deftest use-package-test/:when-1 () (match-expansion (use-package foo :when t) `(when t - (require 'foo nil nil))) + (require 'foo nil nil)))) +(ert-deftest use-package-test/:when-2 () (match-expansion (use-package foo :when (and t t)) `(when (and t t) - (require 'foo nil nil))) + (require 'foo nil nil)))) +(ert-deftest use-package-test/:when-3 () (match-expansion (use-package foo :when nil) `(when nil (require 'foo nil nil)))) -(ert-deftest use-package-test/:unless () +(ert-deftest use-package-test/:unless-1 () (match-expansion (use-package foo :unless t) `(when (not t) - (require 'foo nil nil))) + (require 'foo nil nil)))) +(ert-deftest use-package-test/:unless-2 () (match-expansion (use-package foo :unless (and t t)) `(when (not (and t t)) - (require 'foo nil nil))) + (require 'foo nil nil)))) +(ert-deftest use-package-test/:unless-3 () (match-expansion (use-package foo :unless nil) `(unless nil (require 'foo nil nil)))) -(ert-deftest use-package-test/:requires () +(ert-deftest use-package-test/:requires-1 () (match-expansion (use-package foo :requires bar) `(when (featurep 'bar) - (require 'foo nil nil))) + (require 'foo nil nil)))) +(ert-deftest use-package-test/:requires-2 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo :requires bar) @@ -374,13 +390,15 @@ (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) - (require 'foo nil nil)))) + (require 'foo nil nil))))) +(ert-deftest use-package-test/:requires-3 () (match-expansion (use-package foo :requires (bar quux)) `(when (not (member nil (mapcar #'featurep '(bar quux)))) - (require 'foo nil nil))) + (require 'foo nil nil)))) +(ert-deftest use-package-test/:requires-4 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo :requires bar) @@ -391,7 +409,7 @@ (load "foo" nil t)))) (require 'foo nil nil))))) -(ert-deftest use-package-test/:load-path () +(ert-deftest use-package-test/:load-path-1 () (match-expansion (use-package foo :load-path "bar") `(progn @@ -401,8 +419,9 @@ #'string= (expand-file-name "bar" user-emacs-directory))))) - (require 'foo nil nil))) + (require 'foo nil nil)))) +(ert-deftest use-package-test/:load-path-2 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo :load-path "bar") @@ -417,8 +436,9 @@ (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) - (require 'foo nil nil)))) + (require 'foo nil nil))))) +(ert-deftest use-package-test/:load-path-3 () (match-expansion (use-package foo :load-path ("bar" "quux")) `(progn @@ -434,8 +454,9 @@ #'string= (expand-file-name "quux" user-emacs-directory))))) - (require 'foo nil nil))) + (require 'foo nil nil)))) +(ert-deftest use-package-test/:load-path-4 () (match-expansion (use-package foo :load-path (lambda () (list "bar" "quux"))) `(progn @@ -453,17 +474,19 @@ "quux" user-emacs-directory))))) (require 'foo nil nil)))) -(ert-deftest use-package-test/:no-require () +(ert-deftest use-package-test/:no-require-1 () (match-expansion (use-package foo :no-require t) - `nil) + `nil)) +(ert-deftest use-package-test/:no-require-2 () (match-expansion (use-package foo :no-require t :config (config)) `(progn (config) - t)) + t))) +(ert-deftest use-package-test/:no-require-3 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo :no-require t) @@ -483,7 +506,7 @@ (should-error (norm '("foo" . 99))) (should-error (norm '(99 . sym))))) -(ert-deftest use-package-test/:bind () +(ert-deftest use-package-test/:bind-1 () (match-expansion (use-package foo :bind ("C-k" . key)) `(progn @@ -492,7 +515,7 @@ (ignore (bind-keys :package foo ("C-k" . key)))))) -(ert-deftest use-package-test/:bind* () +(ert-deftest use-package-test/:bind*-1 () (match-expansion (use-package foo :bind* ("C-k" . key)) `(progn @@ -501,7 +524,7 @@ (ignore (bind-keys* :package foo ("C-k" . key)))))) -(ert-deftest use-package-test/:bind-keymap () +(ert-deftest use-package-test/:bind-keymap-1 () (match-expansion (use-package foo :bind-keymap ("C-k" . key)) `(ignore @@ -510,7 +533,7 @@ (interactive) (use-package-autoload-keymap 'key 'foo nil)))))) -(ert-deftest use-package-test/:bind-keymap* () +(ert-deftest use-package-test/:bind-keymap*-1 () (match-expansion (use-package foo :bind-keymap* ("C-k" . key)) `(ignore @@ -519,14 +542,15 @@ (interactive) (use-package-autoload-keymap 'key 'foo t)))))) -(ert-deftest use-package-test/:interpreter () +(ert-deftest use-package-test/:interpreter-1 () (match-expansion (use-package foo :interpreter "interp") `(progn (add-to-list 'interpreter-mode-alist '("interp" . foo)) (unless (fboundp 'foo) - (autoload #'foo "foo" nil t)))) + (autoload #'foo "foo" nil t))))) +(ert-deftest use-package-test/:interpreter-2 () (match-expansion (use-package foo :interpreter ("interp" . fun)) `(progn @@ -549,14 +573,15 @@ (should (equal (norm '((".foo" . foo) (".bar" . bar))) '((".foo" . foo) (".bar" . bar)))))) -(ert-deftest use-package-test/:mode () +(ert-deftest use-package-test/:mode-1 () (match-expansion (use-package foo :mode "interp") `(progn (add-to-list 'auto-mode-alist '("interp" . foo)) (unless (fboundp 'foo) - (autoload #'foo "foo" nil t)))) + (autoload #'foo "foo" nil t))))) +(ert-deftest use-package-test/:mode-2 () (match-expansion (use-package foo :mode ("interp" . fun)) `(progn @@ -564,14 +589,15 @@ (unless (fboundp 'fun) (autoload #'fun "foo" nil t))))) -(ert-deftest use-package-test/:magic () +(ert-deftest use-package-test/:magic-1 () (match-expansion (use-package foo :magic "interp") `(progn (add-to-list 'magic-mode-alist '("interp" . foo)) (unless (fboundp 'foo) - (autoload #'foo "foo" nil t)))) + (autoload #'foo "foo" nil t))))) +(ert-deftest use-package-test/:magic-2 () (match-expansion (use-package foo :magic ("interp" . fun)) `(progn @@ -579,14 +605,15 @@ (unless (fboundp 'fun) (autoload #'fun "foo" nil t))))) -(ert-deftest use-package-test/:magic-fallback () +(ert-deftest use-package-test/:magic-fallback-1 () (match-expansion (use-package foo :magic-fallback "interp") `(progn (add-to-list 'magic-fallback-mode-alist '("interp" . foo)) (unless (fboundp 'foo) - (autoload #'foo "foo" nil t)))) + (autoload #'foo "foo" nil t))))) +(ert-deftest use-package-test/:magic-fallback-2 () (match-expansion (use-package foo :magic-fallback ("interp" . fun)) `(progn @@ -594,20 +621,22 @@ (unless (fboundp 'fun) (autoload #'fun "foo" nil t))))) -(ert-deftest use-package-test/:commands () +(ert-deftest use-package-test/:commands-1 () (match-expansion (use-package foo :commands bar) `(unless (fboundp 'bar) - (autoload #'bar "foo" nil t))) + (autoload #'bar "foo" nil t)))) +(ert-deftest use-package-test/:commands-2 () (match-expansion (use-package foo :commands (bar quux)) `(progn (unless (fboundp 'bar) (autoload #'bar "foo" nil t)) (unless (fboundp 'quux) - (autoload #'quux "foo" nil t)))) + (autoload #'quux "foo" nil t))))) +(ert-deftest use-package-test/:commands-3 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo :commands (bar quux)) @@ -625,11 +654,12 @@ (eval-when-compile (declare-function quux "foo")))))) -(ert-deftest use-package-test/:defines () +(ert-deftest use-package-test/:defines-1 () (match-expansion (use-package foo :defines bar) - `(require 'foo nil nil)) + `(require 'foo nil nil))) +(ert-deftest use-package-test/:defines-2 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo :defines bar) @@ -642,11 +672,12 @@ (load "foo" nil t)))) (require 'foo nil nil))))) -(ert-deftest use-package-test/:functions () +(ert-deftest use-package-test/:functions-1 () (match-expansion (use-package foo :functions bar) - `(require 'foo nil nil)) + `(require 'foo nil nil))) +(ert-deftest use-package-test/:functions-2 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo :functions bar) @@ -657,12 +688,14 @@ (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) - (require 'foo nil nil)))) + (require 'foo nil nil))))) +(ert-deftest use-package-test/:functions-3 () (match-expansion (use-package foo :defer t :functions bar) - `nil) + `nil)) +(ert-deftest use-package-test/:functions-4 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo :defer t :functions bar) @@ -670,8 +703,9 @@ (declare-function bar "foo") (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))))) + (load "foo" nil t))))))) +(ert-deftest use-package-test/:functions-5 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo :defer t :config (config) :functions bar) @@ -687,11 +721,12 @@ (config) t)))))) -(ert-deftest use-package-test/:defer () +(ert-deftest use-package-test/:defer-1 () (match-expansion (use-package foo) - `(require 'foo nil nil)) + `(require 'foo nil nil))) +(ert-deftest use-package-test/:defer-2 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo) @@ -700,12 +735,14 @@ (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) - (require 'foo nil nil)))) + (require 'foo nil nil))))) +(ert-deftest use-package-test/:defer-3 () (match-expansion (use-package foo :defer t) - `nil) + `nil)) +(ert-deftest use-package-test/:defer-4 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo :defer t) @@ -734,7 +771,7 @@ (should (equal (norm '(((bar1 bar2) . baz) ((quux1 quux2) . bow))) '(((bar1 bar2) . baz) ((quux1 quux2) . bow)))))) -(ert-deftest use-package-test/:hook () +(ert-deftest use-package-test/:hook-1 () (let ((byte-compile-current-file t)) (should (equal @@ -773,27 +810,28 @@ ;; '((foo bar baz)))) )) -(ert-deftest use-package-test/:custom () +(ert-deftest use-package-test/:custom-1 () (match-expansion (use-package foo :custom (foo bar)) `(progn (customize-set-variable 'foo bar "Customized with use-package foo") (require 'foo nil nil)))) -(ert-deftest use-package-test/:custom-face () +(ert-deftest use-package-test/:custom-face-1 () (match-expansion (use-package foo :custom-face (foo ((t (:background "#e4edfc"))))) `(progn (custom-set-faces '(foo ((t (:background "#e4edfc"))))) (require 'foo nil nil)))) -(ert-deftest use-package-test/:init () +(ert-deftest use-package-test/:init-1 () (match-expansion (use-package foo :init (init)) `(progn (init) - (require 'foo nil nil))) + (require 'foo nil nil)))) +(ert-deftest use-package-test/:init-2 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo :init (init)) @@ -805,12 +843,13 @@ (init) (require 'foo nil nil))))) -(ert-deftest use-package-test/:after () +(ert-deftest use-package-test/:after-1 () (match-expansion (use-package foo :after bar) `(eval-after-load 'bar - '(require 'foo nil nil))) + '(require 'foo nil nil)))) +(ert-deftest use-package-test/:after-2 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo :after bar) @@ -820,20 +859,23 @@ (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) (eval-after-load 'bar - '(require 'foo nil nil))))) + '(require 'foo nil nil)))))) +(ert-deftest use-package-test/:after-3 () (match-expansion (use-package foo :after (bar quux)) `(eval-after-load 'quux '(eval-after-load 'bar - '(require 'foo nil nil)))) + '(require 'foo nil nil))))) +(ert-deftest use-package-test/:after-4 () (match-expansion (use-package foo :after (:all bar quux)) `(eval-after-load 'quux '(eval-after-load 'bar - '(require 'foo nil nil)))) + '(require 'foo nil nil))))) +(ert-deftest use-package-test/:after-5 () (match-expansion (use-package foo :after (:any bar quux)) `(lexical-let ,_ @@ -842,8 +884,9 @@ (eval-after-load 'bar `(funcall ,_)) (eval-after-load 'quux - `(funcall ,_)))))) + `(funcall ,_))))))) +(ert-deftest use-package-test/:after-6 () (match-expansion (use-package foo :after (:all (:any bar quux) bow)) `(lexical-let ,_ @@ -853,8 +896,9 @@ (eval-after-load 'bar `(funcall ,_)) (eval-after-load 'quux - `(funcall ,_))))))) + `(funcall ,_)))))))) +(ert-deftest use-package-test/:after-7 () (match-expansion (use-package foo :after (:any (:all bar quux) bow)) `(lexical-let ,_ @@ -864,8 +908,9 @@ '(eval-after-load 'bar `(funcall ,_))) (eval-after-load 'bow - `(funcall ,_)))))) + `(funcall ,_))))))) +(ert-deftest use-package-test/:after-8 () (match-expansion (use-package foo :after (:all (:any bar quux) (:any bow baz))) `(lexical-let ,_ @@ -882,8 +927,9 @@ (eval-after-load 'bar `(funcall ,_)) (eval-after-load 'quux - `(funcall ,_)))))))) + `(funcall ,_))))))))) +(ert-deftest use-package-test/:after-9 () (match-expansion (use-package foo :after (:any (:all bar quux) (:all bow baz))) `(lexical-let ,_ @@ -894,8 +940,9 @@ `(funcall ,_))) (eval-after-load 'baz '(eval-after-load 'bow - `(funcall ,_))))))) + `(funcall ,_)))))))) +(ert-deftest use-package-test/:after-10 () (match-expansion (use-package foo :after (:any (:all bar quux) (:any bow baz))) `(lexical-let ,_ @@ -910,11 +957,12 @@ (eval-after-load 'baz `(funcall ,_)))))))) -(ert-deftest use-package-test/:demand () +(ert-deftest use-package-test/:demand-1 () (match-expansion (use-package foo :demand t) - `(require 'foo nil nil)) + `(require 'foo nil nil))) +(ert-deftest use-package-test/:demand-2 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo :demand t) @@ -923,15 +971,17 @@ (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) - (require 'foo nil nil)))) + (require 'foo nil nil))))) +(ert-deftest use-package-test/:demand-3 () (match-expansion (use-package foo :demand t :config (config)) `(progn (require 'foo nil nil) (config) - t)) + t))) +(ert-deftest use-package-test/:demand-4 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo :demand t :config (config)) @@ -942,14 +992,16 @@ (load "foo" nil t)))) (require 'foo nil nil) (config) - t))) + t)))) +(ert-deftest use-package-test/:demand-5 () ;; #529 - :demand should not override an explicit use of :after (match-expansion (use-package foo :demand t :after bar) `(eval-after-load 'bar - '(require 'foo nil nil))) + '(require 'foo nil nil)))) +(ert-deftest use-package-test/:demand-6 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo :demand t :after bar) @@ -959,8 +1011,9 @@ (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) (eval-after-load 'bar - '(require 'foo nil nil))))) + '(require 'foo nil nil)))))) +(ert-deftest use-package-test/:demand-7 () (match-expansion (use-package counsel :load-path "site-lisp/swiper" @@ -994,14 +1047,15 @@ ("C-*" . counsel-org-agenda-headlines) ("M-x" . counsel-M-x)))))))) -(ert-deftest use-package-test/:config () +(ert-deftest use-package-test/:config-1 () (match-expansion (use-package foo :config (config)) `(progn (require 'foo nil nil) (config) - t)) + t))) +(ert-deftest use-package-test/:config-2 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo :config (config)) @@ -1012,15 +1066,17 @@ (load "foo" nil t)))) (require 'foo nil nil) (config) - t))) + t)))) +(ert-deftest use-package-test/:config-3 () (match-expansion (use-package foo :defer t :config (config)) `(eval-after-load 'foo '(progn (config) - t))) + t)))) +(ert-deftest use-package-test/:config-4 () (let ((byte-compile-current-file t)) (match-expansion (use-package foo :defer t :config (config)) @@ -1046,29 +1102,31 @@ (should (equal (use-package-normalize-diminish 'foopkg :diminish '(foo . "bar")) '((foo . "bar"))))) -(ert-deftest use-package-test/:diminish () +(ert-deftest use-package-test/:diminish-1 () (match-expansion (use-package foo :diminish nil) `(progn (require 'foo nil nil) (if (fboundp 'diminish) - (diminish 'foo-mode)))) + (diminish 'foo-mode))))) +(ert-deftest use-package-test/:diminish-2 () (match-expansion (use-package foo :diminish bar) `(progn (require 'foo nil nil) (if (fboundp 'diminish) - (diminish 'bar)))) + (diminish 'bar))))) +(ert-deftest use-package-test/:diminish-3 () (match-expansion (use-package foo :diminish "bar") `(progn (require 'foo nil nil) (if (fboundp 'diminish) - (diminish 'foo-mode "bar")))) - + (diminish 'foo-mode "bar"))))) +(ert-deftest use-package-test/:diminish-4 () (match-expansion (use-package foo :diminish (foo . "bar")) `(progn @@ -1093,44 +1151,49 @@ `((a-mode nil foo) (b-mode " b" foo)))) (should-error (use-package-normalize/:delight 'foo :delight '((:eval 1))))) -(ert-deftest use-package-test/:delight () +(ert-deftest use-package-test/:delight-1 () (match-expansion (use-package foo :delight) `(progn (require 'foo nil nil) (if (fboundp 'delight) - (delight '((foo-mode nil foo)))))) + (delight '((foo-mode nil foo))))))) +(ert-deftest use-package-test/:delight-2 () (should-error (match-expansion (use-package foo :delight nil) `(progn (require 'foo nil nil) (if (fboundp 'diminish) - (diminish 'foo-mode))))) + (diminish 'foo-mode)))))) +(ert-deftest use-package-test/:delight-3 () (match-expansion (use-package foo :delight bar) `(progn (require 'foo nil nil) (if (fboundp 'delight) - (delight '((bar nil foo)))))) + (delight '((bar nil foo))))))) +(ert-deftest use-package-test/:delight-4 () (match-expansion (use-package foo :delight "bar") `(progn (require 'foo nil nil) (if (fboundp 'delight) - (delight '((foo-mode "bar" foo)))))) + (delight '((foo-mode "bar" foo))))))) +(ert-deftest use-package-test/:delight-5 () (should-error (match-expansion (use-package foo :delight (foo . "bar")) `(progn (require 'foo nil nil) (if (fboundp 'diminish) - (diminish 'foo "bar"))))) + (diminish 'foo "bar")))))) +(ert-deftest use-package-test/:delight-6 () (match-expansion (use-package foo :delight (foo "bar")) `(progn From 223c321a1da4935af94d6ae87d1356d30b95f9dd Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 10:57:42 -0800 Subject: [PATCH 355/606] Always catch errors during configuration --- lisp/use-package/use-package.el | 39 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 3dab8ec8521..e34fb735cbd 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1618,31 +1618,30 @@ no more than once." (use-package-process-keywords name args (and (plist-get args :demand) (list :demand t)))))) - (if (not (eq use-package-verbose 'debug)) + (if use-package-expand-minimally body `(condition-case-unless-debug err ,body (error (let ((msg (format "%s: %s" ',name (error-message-string err)))) - (with-current-buffer (get-buffer-create "*use-package*") - (goto-char (point-max)) - (insert "-----\n" msg "\n\n" - (pp-to-string ',`(use-package ,name ,@orig-args)) - "\n -->\n\n" - (pp-to-string ',`(use-package ,name ,@args)) - "\n ==>\n\n" - (pp-to-string - ',(let ((use-package-verbose 'errors) - (use-package-expand-minimally t)) - (macroexp-progn - (use-package-process-keywords name args - (and (plist-get args :demand) - (list :demand t))))))) - (emacs-lisp-mode)) - (ignore - (display-warning - 'use-package (concat msg " (see the *use-package* buffer)") - :error))))))))) + (when (eq use-package-verbose 'debug) + (setq msg (concat msg " (see the *use-package* buffer)")) + (with-current-buffer (get-buffer-create "*use-package*") + (goto-char (point-max)) + (insert "-----\n" msg "\n\n" + (pp-to-string ',`(use-package ,name ,@orig-args)) + "\n -->\n\n" + (pp-to-string ',`(use-package ,name ,@args)) + "\n ==>\n\n" + (pp-to-string + ',(let ((use-package-verbose 'errors) + (use-package-expand-minimally t)) + (macroexp-progn + (use-package-process-keywords name args + (and (plist-get args :demand) + (list :demand t))))))) + (emacs-lisp-mode))) + (ignore (display-warning 'use-package msg :error))))))))) ;;;###autoload (defmacro use-package (name &rest args) From d5c1fdf4e8058ade053604f77cbed908eab7067a Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 10:57:55 -0800 Subject: [PATCH 356/606] Remove a local variable binding --- lisp/use-package/use-package.el | 1 - 1 file changed, 1 deletion(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index e34fb735cbd..94b3ec7c975 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1717,7 +1717,6 @@ this file. Usage: (provide 'use-package) ;; Local Variables: -;; outline-regexp: ";;;\\(;* [^\s\t\n]\\|###autoload\\)\\|(" ;; indent-tabs-mode: nil ;; End: From 149c4878fc92fa810b074da8723f1e1d9a2e18ea Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 10:58:06 -0800 Subject: [PATCH 357/606] Change most use-package-- prefixes to just use-package- --- lisp/use-package/use-package.el | 334 ++++++++++++++++---------------- 1 file changed, 166 insertions(+), 168 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 94b3ec7c975..fe307235c99 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1,4 +1,4 @@ -;;; use-package.el --- A use-package declaration for simplifying your .emacs +;;; use-package.el --- A configuration macro for simplifying your .emacs ;; Copyright (C) 2012-2017 John Wiegley @@ -260,7 +260,7 @@ be attempted." "Regexp used in `use-package-jump-to-package-form' to find use package forms in user files.") -(defun use-package--find-require (package) +(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." @@ -278,7 +278,7 @@ 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)) + (requiring-file (use-package-find-require package)) file location) (if (null requiring-file) (user-error "Can't find file that requires this feature.") @@ -343,24 +343,7 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." ',(intern (concat "use-package--" name-string "--post-" keyword-name "-hook")))))))) -(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)) - (ignore - (display-warning 'use-package - (format "Cannot load %s" ',name) - :error)) - ,@body)))))) - -(defun use-package--with-elapsed-timer (text body) +(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 @@ -378,7 +361,24 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." (message "%s...done" ,text)))))) body)))) -(put 'use-package--with-elapsed-timer 'lisp-indent-function 1) +(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)) + (ignore + (display-warning 'use-package + (format "Cannot load %s" ',name) + :error)) + ,@body)))))) (defsubst use-package-error (msg) "Report MSG as an error, so the user knows it came from this package." @@ -459,7 +459,7 @@ This is in contrast to merely setting it to 0." "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) +(defsubst use-package-non-nil-symbolp (sym) (and sym (symbolp sym))) (defconst use-package-font-lock-keywords @@ -474,6 +474,86 @@ This is in contrast to merely setting it to 0." ;;; Keyword processing ;; +(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) + (pcase key + (`:if `(and ,new ,old)) + (`:after `(:all ,new ,old)) + (`:defer old) + (_ (append new old)))) + +(defun use-package-normalize-keywords (name args) + (let* ((name-symbol (if (stringp name) (intern name) name)) + (name-string (symbol-name name-symbol))) + + ;; 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. + (dolist (spec use-package-defaults) + (when (pcase (nth 2 spec) + ((and func (pred functionp)) (funcall func args)) + (sexp (eval sexp))) + (setq args (use-package-plist-maybe-put + args (nth 0 spec) (eval (nth 1 spec)))))) + + ;; 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) + `(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)) + (or (plist-member args :bind) + (plist-member args :bind*) + (plist-member args :bind-keymap) + (plist-member args :bind-keymap*) + (plist-member args :interpreter) + (plist-member args :mode) + (plist-member args :magic) + (plist-member args :magic-fallback) + (plist-member args :commands) + (plist-member args :hook))) + (setq args (append args '(:defer t)))) + + (when (and (plist-member args :load) + (plist-member args :no-require)) + (setq args (use-package-plist-delete args :no-require))) + + (when (and (not (plist-member args :load)) + (not (plist-member args :defer)) + (not (plist-member 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))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Normalization functions @@ -589,7 +669,7 @@ next value for the STATE." #'(lambda (label arg) (cond ((stringp arg) arg) - ((use-package--non-nil-symbolp arg) (symbol-name arg)) + ((use-package-non-nil-symbolp arg) (symbol-name arg)) (t (use-package-error ":pin wants an archive name (a string)")))))) @@ -598,7 +678,7 @@ next value for the STATE." (defvar package-pinned-packages) (defvar package-archives)) -(defun use-package--archive-exists-p (archive) +(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 @@ -617,7 +697,7 @@ manually updated package." (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) + (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)) @@ -702,7 +782,7 @@ manually updated package." "Normalize a value." (cond ((null arg) nil) ((eq t arg) t) - ((use-package--non-nil-symbolp arg) + ((use-package-non-nil-symbolp arg) `(symbol-value ',arg)) ((functionp arg) `(funcall #',arg)) @@ -749,7 +829,7 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." (defun use-package-normalize-symbols (label arg &optional recursed) "Normalize a list of symbols." (cond - ((use-package--non-nil-symbolp arg) + ((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)) @@ -764,7 +844,7 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." (defun use-package-normalize-recursive-symbols (label arg) "Normalize a list of symbols." (cond - ((use-package--non-nil-symbolp arg) + ((use-package-non-nil-symbolp arg) arg) ((and (listp arg) (listp (cdr arg))) (mapcar #'(lambda (x) (use-package-normalize-recursive-symbols label x)) @@ -796,7 +876,7 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." (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))) + ((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) @@ -937,7 +1017,7 @@ If RECURSED is non-nil, recurse into sublists." (setq last-item x))) arg))) (t arg))) -(defun use-package--recognize-function (v &optional binding additional-pred) +(defun use-package-recognize-function (v &optional binding additional-pred) "A predicate that recognizes functional constructions: nil sym @@ -953,14 +1033,14 @@ If RECURSED is non-nil, recurse into sublists." (pcase v ((and x (guard (if binding (symbolp x) - (use-package--non-nil-symbolp x)))) t) + (use-package-non-nil-symbolp x)))) t) (`(,(or `quote `function) - ,(pred use-package--non-nil-symbolp)) t) + ,(pred use-package-non-nil-symbolp)) t) ((and x (guard (if binding (commandp x) (functionp x)))) t) (_ (and additional-pred (funcall additional-pred v))))) -(defun use-package--normalize-function (v) +(defun use-package-normalize-function (v) "Reduce functional constructions to one of two normal forms: sym #'(lambda () ...)" @@ -973,7 +1053,7 @@ If RECURSED is non-nil, recurse into sublists." (`(function ,(and lam `(lambda . ,_))) lam) (_ v))) -(defun use-package--normalize-commands (args) +(defun use-package-normalize-commands (args) "Map over ARGS of the form ((_ . F) ...). Normalizing functional F's and returning a list of F's representing symbols (that may need to be autloaded)." @@ -981,14 +1061,14 @@ representing symbols (that may need to be autloaded)." #'(lambda (x) (if (consp x) (cons (car x) - (use-package--normalize-function (cdr x))) + (use-package-normalize-function (cdr x))) x)) args))) (cons nargs (delete nil (mapcar #'(lambda (x) (and (consp x) - (use-package--non-nil-symbolp (cdr x)) + (use-package-non-nil-symbolp (cdr x)) (cdr x))) nargs))))) (defun use-package-normalize-binder (name keyword args) @@ -1003,7 +1083,7 @@ representing symbols (that may need to be autloaded)." (pcase k ((pred stringp) t) ((pred vectorp) t))) - #'(lambda (v) (use-package--recognize-function v t #'stringp)) + #'(lambda (v) (use-package-recognize-function v t #'stringp)) name label arg)))) (defalias 'use-package-normalize/:bind 'use-package-normalize-binder) @@ -1012,7 +1092,7 @@ representing symbols (that may need to be autloaded)." (defun use-package-handler/:bind (name keyword args rest state &optional bind-macro) (cl-destructuring-bind (nargs . commands) - (use-package--normalize-commands args) + (use-package-normalize-commands args) (use-package-concat (use-package-process-keywords name (use-package-sort-keywords @@ -1036,15 +1116,15 @@ representing symbols (that may need to be autloaded)." ;;;###autoload (defun use-package-autoload-keymap (keymap-symbol package override) "Loads PACKAGE and then binds the key sequence used to invoke - this function to KEYMAP-SYMBOL. It then simulates pressing the - same key sequence a again, so that the next key pressed is routed - to the newly loaded keymap. +this function to KEYMAP-SYMBOL. It then simulates pressing the +same key sequence a again, so that the next key pressed is routed +to the newly loaded keymap. - This function supports use-package's :bind-keymap keyword. It - works by binding the given key sequence to an invocation of this - function for a particular keymap. The keymap is expected to be - defined by the package. In this way, loading the package is - deferred until the prefix key sequence is pressed." +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) @@ -1092,13 +1172,13 @@ representing symbols (that may need to be autloaded)." (use-package-as-one (symbol-name keyword) args (apply-partially #'use-package-normalize-pairs #'use-package-regex-p - #'use-package--recognize-function + #'use-package-recognize-function name))) (defun use-package-handle-mode (name alist args rest state) "Handle keywords which add regexp/mode pairs to an alist." (cl-destructuring-bind (nargs . commands) - (use-package--normalize-commands args) + (use-package-normalize-commands args) (use-package-concat (mapcar #'(lambda (thing) @@ -1155,27 +1235,27 @@ representing symbols (that may need to be autloaded)." (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)) + (unless (or (use-package-non-nil-symbolp arg) (consp arg)) (use-package-error (concat label " a or ( . )" " or list of these"))) (use-package-normalize-pairs #'(lambda (k) - (or (use-package--non-nil-symbolp 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))) + (use-package-non-nil-symbolp (car k))) (setq k (cdr k)) (setq every nil))) every)))) - #'use-package--recognize-function + #'use-package-recognize-function name label arg)))) (defun use-package-handler/:hook (name keyword args rest state) "Generate use-package custom keyword code." (cl-destructuring-bind (nargs . commands) - (use-package--normalize-commands args) + (use-package-normalize-commands args) (use-package-concat (cl-mapcan #'(lambda (def) @@ -1186,7 +1266,7 @@ representing symbols (that may need to be autloaded)." #'(lambda (sym) `(add-hook (quote ,(intern (format "%s-hook" sym))) (function ,fun))) - (if (use-package--non-nil-symbolp syms) (list syms) syms))))) + (if (use-package-non-nil-symbolp syms) (list syms) syms))))) nargs) (use-package-process-keywords name (use-package-sort-keywords @@ -1235,7 +1315,7 @@ representing symbols (that may need to be autloaded)." ',(use-package-as-symbol name) nil t))) (if (or (not arg) (null body)) body - (list (use-package--require-after-load + (list (use-package-require-after-load name (macroexp-progn body))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1249,42 +1329,42 @@ representing symbols (that may need to be autloaded)." args (list args))) -(defun use-package--after-count-uses (features) +(defun use-package-after-count-uses (features) "Count the number of time the body would appear in the result." (pcase features - ((and (pred use-package--non-nil-symbolp) feat) + ((and (pred use-package-non-nil-symbolp) feat) 1) (`(,(or `:or `:any) . ,rest) (let ((num 0)) (dolist (next rest) - (setq num (+ num (use-package--after-count-uses next)))) + (setq num (+ num (use-package-after-count-uses next)))) num)) (`(,(or `:and `:all) . ,rest) - (apply #'max (mapcar #'use-package--after-count-uses rest))) + (apply #'max (mapcar #'use-package-after-count-uses rest))) (`(,feat . ,rest) - (use-package--after-count-uses (cons :all (cons feat rest)))))) + (use-package-after-count-uses (cons :all (cons feat rest)))))) -(defun use-package--require-after-load (features body) +(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'." (pcase features - ((and (pred use-package--non-nil-symbolp) feat) + ((and (pred use-package-non-nil-symbolp) feat) `(eval-after-load ',feat ,(if (member (car body) '(quote backquote \' \`)) body (list 'quote body)))) (`(,(or `:or `:any) . ,rest) (macroexp-progn - (mapcar #'(lambda (x) (use-package--require-after-load x body)) rest))) + (mapcar #'(lambda (x) (use-package-require-after-load x body)) rest))) (`(,(or `:and `:all) . ,rest) (dolist (next rest) - (setq body (use-package--require-after-load next body))) + (setq body (use-package-require-after-load next body))) body) (`(,feat . ,rest) - (use-package--require-after-load (cons :all (cons feat rest)) body)))) + (use-package-require-after-load (cons :all (cons feat rest)) body)))) -(defun use-package--memoize (f arg) +(defun use-package-memoize (f arg) "Ensure the macro-expansion of F applied to ARG evaluates ARG no more than once." (let ((loaded (gensym "use-package--loaded")) @@ -1300,14 +1380,14 @@ no more than once." (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))) + (uses (use-package-after-count-uses arg))) (if (or (null uses) (null body)) body (if (<= uses 1) - (list (use-package--require-after-load + (list (use-package-require-after-load arg (list 'quote (macroexp-progn body)))) - (use-package--memoize - (apply-partially #'use-package--require-after-load arg) + (use-package-memoize + (apply-partially #'use-package-require-after-load arg) (macroexp-progn body)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1333,7 +1413,7 @@ no more than once." (use-package-error (concat label " a ( [comment])" " or list of these"))) - (if (use-package--non-nil-symbolp (car arg)) + (if (use-package-non-nil-symbolp (car arg)) (list arg) arg)))) @@ -1409,7 +1489,7 @@ no more than once." (defun use-package-handler/:load (name keyword arg rest state) (let ((body (use-package-process-keywords name rest state))) (dolist (pkg arg) - (setq body (use-package--require pkg nil body))) + (setq body (use-package-require pkg nil body))) body)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1425,7 +1505,7 @@ no more than once." (if (or (null arg) (equal arg '(t))) body - (use-package--with-elapsed-timer + (use-package-with-elapsed-timer (format "Configuring package %s" name-symbol) (use-package-concat (use-package-hook-injector @@ -1445,7 +1525,7 @@ no more than once." (cond ((not arg) (list (use-package-as-mode name))) - ((use-package--non-nil-symbolp arg) + ((use-package-non-nil-symbolp arg) (list arg)) ((stringp arg) (list (cons (use-package-as-mode name) arg))) @@ -1479,13 +1559,13 @@ no more than once." ;;; :delight ;; -(defun use-package--normalize-delight-1 (name args) +(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))) + (use-package-non-nil-symbolp (car args))) `(,(nth 0 args) nil ,name)) ((= (length args) 2) `(,(nth 0 args) ,(nth 1 args) ,name)) @@ -1500,7 +1580,7 @@ no more than once." (cond ((null args) `((,(use-package-as-mode name) nil ,name))) ((and (= (length args) 1) - (use-package--non-nil-symbolp (car args))) + (use-package-non-nil-symbolp (car args))) `((,(car args) nil ,name))) ((and (= (length args) 1) (stringp (car args))) @@ -1514,8 +1594,8 @@ no more than once." (eq 'quote (car (nth 1 args)))) `((,(car args) ,@(cdr (nth 1 args)) ,name))) (t (mapcar - (apply-partially #'use-package--normalize-delight-1 name) - (if (use-package--non-nil-symbolp (car args)) + (apply-partially #'use-package-normalize-delight name) + (if (use-package-non-nil-symbolp (car args)) (list args) args))))) @@ -1531,87 +1611,7 @@ no more than once." ;;; The main macro ;; -(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) - (pcase key - (`:if `(and ,new ,old)) - (`:after `(:all ,new ,old)) - (`:defer old) - (_ (append new old)))) - -(defun use-package-normalize-keywords (name args) - (let* ((name-symbol (if (stringp name) (intern name) name)) - (name-string (symbol-name name-symbol))) - - ;; 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. - (dolist (spec use-package-defaults) - (when (pcase (nth 2 spec) - ((and func (pred functionp)) (funcall func args)) - (sexp (eval sexp))) - (setq args (use-package-plist-maybe-put - args (nth 0 spec) (eval (nth 1 spec)))))) - - ;; 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) - `(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)) - (or (plist-member args :bind) - (plist-member args :bind*) - (plist-member args :bind-keymap) - (plist-member args :bind-keymap*) - (plist-member args :interpreter) - (plist-member args :mode) - (plist-member args :magic) - (plist-member args :magic-fallback) - (plist-member args :commands) - (plist-member args :hook))) - (setq args (append args '(:defer t)))) - - (when (and (plist-member args :load) - (plist-member args :no-require)) - (setq args (use-package-plist-delete args :no-require))) - - (when (and (not (plist-member args :load)) - (not (plist-member args :defer)) - (not (plist-member 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--core (name args) +(defun use-package-core (name args) (let ((orig-args (cl-copy-list args))) (setq args (use-package-normalize-keywords name args)) (let ((body (macroexp-progn @@ -1701,16 +1701,14 @@ this file. Usage: (declare (indent 1)) (unless (memq :disabled args) (if (eq use-package-verbose 'errors) - (use-package--core name args) + (use-package-core name args) (condition-case-unless-debug err - (use-package--core name args) + (use-package-core name args) (error (ignore - (display-warning - 'use-package - (format "Failed to parse package %s %s: %s" - name args (error-message-string err)) - :error))))))) + (let ((msg (format "Failed to parse package %s %s: %s" + name args (error-message-string err)))) + (display-warning 'use-package msg :error)))))))) (put 'use-package 'lisp-indent-function 'defun) From 3625b3f712889f3133b41621ee21e724c3c0f0c3 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 11:00:41 -0800 Subject: [PATCH 358/606] More variable renaming needed in the tests --- test/lisp/use-package/use-package-tests.el | 44 +++++++++++----------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 14e8bcd3dd5..13ca070b4f7 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -96,31 +96,31 @@ (setplist 'flet (plist-delete (symbol-plist 'flet) 'byte-obsolete-info))) (ert-deftest use-package-test-recognize-function () - (should (use-package--recognize-function nil t)) - (should-not (use-package--recognize-function nil)) - (should (use-package--recognize-function t)) - (should (use-package--recognize-function 'sym)) - (should (use-package--recognize-function #'sym)) - (should (use-package--recognize-function (lambda () ...))) - (should (use-package--recognize-function '(lambda () ...))) - (should (use-package--recognize-function #'(lambda () ...))) + (should (use-package-recognize-function nil t)) + (should-not (use-package-recognize-function nil)) + (should (use-package-recognize-function t)) + (should (use-package-recognize-function 'sym)) + (should (use-package-recognize-function #'sym)) + (should (use-package-recognize-function (lambda () ...))) + (should (use-package-recognize-function '(lambda () ...))) + (should (use-package-recognize-function #'(lambda () ...))) - (should-not (use-package--recognize-function 1)) - (should-not (use-package--recognize-function "Hello")) - (should-not (use-package--recognize-function '(nil . nil)))) + (should-not (use-package-recognize-function 1)) + (should-not (use-package-recognize-function "Hello")) + (should-not (use-package-recognize-function '(nil . nil)))) (ert-deftest use-package-test-normalize-function () - (should (equal (use-package--normalize-function nil) nil)) - (should (equal (use-package--normalize-function t) t)) - (should (equal (use-package--normalize-function 'sym) 'sym)) - (should (equal (use-package--normalize-function #'sym) 'sym)) - (should (equal (use-package--normalize-function (lambda () ...)) (lambda () ...))) - (should (equal (use-package--normalize-function '(lambda () ...)) (lambda () ...))) - (should (equal (use-package--normalize-function #'(lambda () ...)) (lambda () ...))) + (should (equal (use-package-normalize-function nil) nil)) + (should (equal (use-package-normalize-function t) t)) + (should (equal (use-package-normalize-function 'sym) 'sym)) + (should (equal (use-package-normalize-function #'sym) 'sym)) + (should (equal (use-package-normalize-function (lambda () ...)) (lambda () ...))) + (should (equal (use-package-normalize-function '(lambda () ...)) (lambda () ...))) + (should (equal (use-package-normalize-function #'(lambda () ...)) (lambda () ...))) - (should (equal (use-package--normalize-function 1) 1)) - (should (equal (use-package--normalize-function "Hello") "Hello")) - (should (equal (use-package--normalize-function '(nil . nil)) '(nil . nil)))) + (should (equal (use-package-normalize-function 1) 1)) + (should (equal (use-package-normalize-function "Hello") "Hello")) + (should (equal (use-package-normalize-function '(nil . nil)) '(nil . nil)))) (ert-deftest use-package-test/:disabled-1 () (match-expansion @@ -953,7 +953,7 @@ `(funcall ,_))) (progn (eval-after-load 'bow - `(funcall ,use-package--next142993)) + `(funcall ,_)) (eval-after-load 'baz `(funcall ,_)))))))) From 0c148eb777e05650c6e951170f365c767594c149 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 11:43:16 -0800 Subject: [PATCH 359/606] Move functions around for better logical grouping --- lisp/use-package/use-package.el | 1065 +++++++++++++++---------------- 1 file changed, 509 insertions(+), 556 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index fe307235c99..16a1df6dc3f 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -42,67 +42,105 @@ (require 'bind-key) (require 'bytecomp) (require 'cl-lib) + (eval-when-compile (require 'cl) - (require 'regexp-opt)) + (require 'regexp-opt) -(declare-function package-installed-p "package") -(declare-function package-read-all-archive-contents "package" ()) - -(defconst use-package-version "2.4" - "This version of use-package.") + (declare-function package-installed-p "package") + (declare-function package-read-all-archive-contents "package" ())) (defgroup use-package nil "A use-package declaration for simplifying your `.emacs'." :group 'startup) +(defconst use-package-version "2.4" + "This version of 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, +contain compiled expansions of the macros. If you don't do so, then the expanded macros do their job silently." - :type '(choice (const :tag "Quiet" nil) (const :tag "Verbose" t) + :type '(choice (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. -The check is performed by looking for the module using `locate-library'." +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 t` is given." + "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 t` is given." + "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-always-ensure nil - "Treat every package as though it had specified `:ensure SEXP`." + "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) (defcustom use-package-always-pin nil - "Treat every package as though it had specified `:pin SYM`." + "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) +(defcustom use-package-defaults + '(;; this '(t) has special meaning; see `use-package-handler/:config' + (:config '(t) t) + (:init nil t) + (:defer use-package-always-defer + (lambda (args) + (and use-package-always-defer + (not (plist-member args :defer)) + (not (plist-member args :demand))))) + (:demand use-package-always-demand + (lambda (args) + (and use-package-always-demand + (not (plist-member args :defer)) + (not (plist-member args :demand))))) + (:ensure use-package-always-ensure + (lambda (args) + (and use-package-always-ensure + (not (plist-member args :load-path))))) + (:pin use-package-always-pin use-package-always-pin)) + "Alist of default values for `use-package' keywords. +Each entry in the alist is a list of three elements. The first +element is the `use-package' keyword and the second is a form +that can be evaluated to get the default value. 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 list of keywords (in normalized form), +and should return nil or t according to whether defaulting should +be attempted." + :type `(repeat + (list (choice :tag "Keyword" + ,@(mapcar #'(lambda (k) (list 'const k)) + use-package-keywords)) + (choice :tag "Default value" sexp) + (choice :tag "Enable if non-nil" sexp function))) + :group 'use-package) + (defcustom use-package-minimum-reported-time 0.1 "Minimal load time that will be reported. - -Note that `use-package-verbose' has to be set to t, for anything -to be reported at all. - -If you customize this, then you should require the `use-package' -feature in files that use `use-package', even if these files only -contain compiled expansions of the macros. If you don't do so, -then the expanded macros do their job silently." +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) @@ -120,10 +158,15 @@ This way, you can add to these hooks before evaluation of a `use-package` declaration, and exercise some control over what happens. -Note that if either `pre-init' hooks returns a nil value, that -block's user-supplied configuration is not evaluated, so be -certain to return `t' if you only wish to add behavior to what -the user specified." +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) @@ -160,30 +203,64 @@ the user specified." :config :diminish :delight) - "Establish which keywords are valid, and the order they are processed in. + "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 that it causes nothing at all to happen, -even if the rest of the use-package declaration is incorrect." +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-expand-minimally nil "If non-nil, make the expanded code as minimal as possible. This disables: + - Printing to the *Messages* buffer of slowly-evaluating forms - - Capture of load errors (normally redisplayed as warnings) + - Capturing of load errors (normally redisplayed as warnings) - Conditional loading of packages (load failures become errors) -The only advantage is that, if you know your configuration works, -then your byte-compiled init file is as minimal as possible." + +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, adjust `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) + (if value + (eval-after-load 'lisp-mode + `(add-to-list 'lisp-imenu-generic-expression + (list "Packages" ,use-package-form-regexp-eval 2))) + (eval-after-load 'lisp-mode + `(setq lisp-imenu-generic-expression + (remove (list "Packages" ,use-package-form-regexp-eval 2) + lisp-imenu-generic-expression))))) :group 'use-package) (defcustom use-package-ensure-function 'use-package-ensure-elpa @@ -204,125 +281,71 @@ The default value uses package.el to install the package." (function :tag "Custom")) :group 'use-package) -(defcustom use-package-defaults - '((:config '(t) t) ; this '(t) has special meaning; see - ; the handler for :config - (:init nil t) - (:defer use-package-always-defer - (lambda (args) - (and use-package-always-defer - (not (plist-member args :defer)) - (not (plist-member args :demand))))) - (:demand use-package-always-demand - (lambda (args) - (and use-package-always-demand - (not (plist-member args :defer)) - (not (plist-member args :demand))))) - (:ensure use-package-always-ensure - (lambda (args) - (and use-package-always-ensure - (not (plist-member args :load-path))))) - (:pin use-package-always-pin use-package-always-pin)) - "Alist of default values for `use-package' keywords. -Each entry in the alist is a list of three elements. The first -element is the `use-package' keyword and the second is a form -that can be evaluated to get the default value. 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 list of keywords (in normalized form), -and should return nil or t according to whether defaulting should -be attempted." - :type `(repeat - (list (choice :tag "Keyword" - ,@(mapcar #'(lambda (k) (list 'const k)) - use-package-keywords)) - (choice :tag "Default value" sexp) - (choice :tag "Enable if non-nil" sexp function))) - :group 'use-package) +(defconst use-package-font-lock-keywords + '(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" + (1 font-lock-keyword-face) + (2 font-lock-constant-face nil t)))) -;;; jww (2017-12-02): This should be in the :set for the option. -(when use-package-enable-imenu-support - (eval-after-load 'lisp-mode - `(let ((sym-regexp (or (bound-and-true-p lisp-mode-symbol-regexp) - "\\(?:\\sw\\|\\s_\\|\\\\.\\)+"))) - (add-to-list - 'lisp-imenu-generic-expression - (list "Packages" - (concat "^\\s-*(" - ,(eval-when-compile - (regexp-opt '("use-package" "require") t)) - "\\s-+\\(" sym-regexp "\\)") - 2))))) - -(defvar use-package-form-regexp "^\\s-*(\\s-*use-package\\s-+\\_<%s\\_>" - "Regexp used in `use-package-jump-to-package-form' to find use -package forms in user files.") - -(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))))))) - -(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 that requires this feature.") - (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 use-package-form-regexp package) nil t))) - (if (null location) - (message "No use-package form found.") - (goto-char location) - (beginning-of-line)))))) +(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Utility functions ;; -(defun use-package-as-symbol (string-or-symbol) +(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))) -(defun use-package-as-string (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, resolve it down 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 + (intern (if (string-match "-mode\\'" string) + string (concat string "-mode"))))) -(defun use-package-load-name (name &optional noerror) +(defsubst use-package-load-name (name &optional noerror) "Return a form which will load or require NAME depending on whether it's a string or symbol." (if (stringp name) @@ -372,31 +395,18 @@ ARGS is a list of forms, so `((foo))' if only `foo' is being called." (if no-require body (use-package-with-elapsed-timer - (format "Loading package %s" name) - `((if (not ,(use-package-load-name name t)) - (ignore - (display-warning 'use-package - (format "Cannot load %s" ',name) - :error)) - ,@body)))))) + (format "Loading package %s" name) + `((if (not ,(use-package-load-name name t)) + (ignore + (display-warning 'use-package + (format "Cannot load %s" ',name) + :error)) + ,@body)))))) -(defsubst use-package-error (msg) - "Report MSG as an error, so the user knows it came from this package." - (error "use-package: %s" msg)) - -(defsubst use-package-plist-maybe-put (plist property value) - "Add a VALUE for PROPERTY to PLIST, if it does not already exist." - (if (plist-member plist property) - plist - (plist-put plist property value))) - -(defsubst use-package-plist-cons (plist property value) - "Cons VALUE onto the head of the list at PROPERTY in PLIST." - (plist-put plist property (cons value (plist-get plist property)))) - -(defsubst use-package-plist-append (plist property value) - "Append VALUE onto the front of the list at PROPERTY in PLIST." - (plist-put plist property (append value (plist-get plist property)))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Property lists +;; (defun use-package-plist-delete (plist property) "Delete PROPERTY from PLIST. @@ -420,6 +430,20 @@ This is in contrast to merely setting it to 0." 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) (dolist (x xs) @@ -432,6 +456,11 @@ This is in contrast to merely setting it to 0." (nconc ys (list x))))) (cons (cdr ys) (cdr zs)))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Keywords +;; + (defun use-package-keyword-index (keyword) (loop named outer with index = 0 @@ -455,25 +484,6 @@ This is in contrast to merely setting it to 0." (setq result (cons (car x) (cons (cdr x) result)))) result))) -(defsubst use-package-concat (&rest elems) - "Delete all empty lists from ELEMS (nil or (list nil)), and append them." - (apply #'append (delete nil (delete (list nil) elems)))) - -(defsubst use-package-non-nil-symbolp (sym) - (and sym (symbolp sym))) - -(defconst use-package-font-lock-keywords - '(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" - (1 font-lock-keyword-face) - (2 font-lock-constant-face nil t)))) - -(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; Keyword processing -;; - (defun use-package-unalias-keywords (name args) (setq args (cl-nsubstitute :if :when args)) (let (temp) @@ -554,28 +564,6 @@ This is in contrast to merely setting it to 0." ;; Sort the list of keywords based on the order of `use-package-keywords'. (use-package-sort-keywords args))) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; Normalization functions -;; - -(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, resolve it down 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)))) - (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, @@ -638,17 +626,7 @@ next value for the STATE." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;;; :disabled -;; - -(defalias 'use-package-normalize/:disabled 'ignore) - -(defun use-package-handler/:disabled (name keyword arg rest state) - (use-package-process-keywords name rest state)) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :pin +;;; Arguments ;; (defun use-package-only-one (label args f) @@ -664,153 +642,6 @@ next value for the STATE." (put 'use-package-only-one 'lisp-indent-function 'defun) -(defun use-package-normalize/:pin (name keyword args) - (use-package-only-one (symbol-name keyword) args - #'(lambda (label arg) - (cond - ((stringp arg) arg) - ((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) -(defun use-package-normalize/:ensure (name keyword args) - (if (null args) - t - (use-package-only-one (symbol-name keyword) args - #'(lambda (label arg) - (if (symbolp arg) - arg - (use-package-error - (concat ":ensure wants an optional package name " - "(an unquoted symbol name)"))))))) - -(defun use-package-ensure-elpa (name ensure state &optional no-refresh) - (let ((package - (or (and (eq ensure t) (use-package-as-symbol name)) - ensure))) - (when package - (require '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 - (ignore - (display-warning 'use-package - (format "Failed to install %s: %s" - name (error-message-string err)) - :error)))))))) - -(defun use-package-handler/:ensure (name keyword ensure rest state) - (let* ((body (use-package-process-keywords name rest state))) - ;; 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)) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :if, :when and :unless -;; - -(defsubst use-package-normalize-value (label arg) - "Normalize a value." - (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-test (name keyword args) - (use-package-only-one (symbol-name keyword) args - #'use-package-normalize-value)) - -(defalias 'use-package-normalize/:if 'use-package-normalize-test) -(defalias 'use-package-normalize/:when 'use-package-normalize-test) -(defalias 'use-package-normalize/:unless 'use-package-normalize-test) - -(defun use-package-handler/:if (name keyword pred rest state) - (let ((body (use-package-process-keywords name rest state))) - `((when ,pred ,@body)))) - -(defalias 'use-package-handler/:when 'use-package-handler/:if) - -(defun use-package-handler/:unless (name keyword pred rest state) - (let ((body (use-package-process-keywords name rest state))) - `((unless ,pred ,@body)))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :requires -;; - (defun use-package-as-one (label args f &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." @@ -826,6 +657,30 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an 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 (gensym "use-package--loaded")) + (result (gensym "use-package--result")) + (next (gensym "use-package--next"))) + `((lexical-let (,loaded ,result) + (lexical-let ((,next (lambda () + (if ,loaded + ,result + (setq ,loaded t) + (setq ,result ,arg))))) + ,(funcall f ``(funcall ,,next))))))) + +(defsubst use-package-normalize-value (label arg) + "Normalize a value." + (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 @@ -857,22 +712,6 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." (use-package-as-one (symbol-name keyword) args #'use-package-normalize-recursive-symbols)) -(defalias 'use-package-normalize/:requires 'use-package-normalize-symlist) - -(defun use-package-handler/:requires (name keyword requires rest state) - (let ((body (use-package-process-keywords name rest state))) - (if (null requires) - body - `((when ,(if (> (length requires) 1) - `(not (member nil (mapcar #'featurep ',requires))) - `(featurep ',(car requires))) - ,@body))))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :load-path -;; - (defun use-package-normalize-paths (label arg &optional recursed) "Normalize a list of filesystem paths." (cond @@ -891,38 +730,12 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." (use-package-error (concat label " wants a directory path, or list of paths"))))) -(defun use-package-normalize/:load-path (name keyword args) - (use-package-as-one (symbol-name keyword) args - #'use-package-normalize-paths)) - -(defun use-package-handler/:load-path (name keyword arg rest state) - (let ((body (use-package-process-keywords name rest state))) - (use-package-concat - (mapcar #'(lambda (path) - `(eval-and-compile (add-to-list 'load-path ,path))) arg) - body))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :no-require -;; - (defun use-package-normalize-predicate (name keyword args) (if (null args) t (use-package-only-one (symbol-name keyword) args #'use-package-normalize-value))) -(defalias 'use-package-normalize/:no-require 'use-package-normalize-predicate) - -(defun use-package-handler/:no-require (name keyword arg rest state) - (use-package-process-keywords name rest state)) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :preface -;; - (defun use-package-normalize-form (label args) "Given a list of forms, return it wrapped in `progn'." (unless (listp (car args)) @@ -936,48 +749,6 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." (defun use-package-normalize-forms (name keyword args) (use-package-normalize-form (symbol-name keyword) args)) -(defalias 'use-package-normalize/:preface 'use-package-normalize-forms) - -(defun use-package-handler/:preface (name keyword arg rest state) - (let ((body (use-package-process-keywords name rest state))) - (use-package-concat - (when arg - `((eval-and-compile ,@arg))) - body))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :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)) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :bind, :bind* -;; - -(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-normalize-pairs (key-pred val-pred name label arg &optional recursed) "Normalize a list of pairs. @@ -1086,33 +857,6 @@ representing symbols (that may need to be autloaded)." #'(lambda (v) (use-package-recognize-function v t #'stringp)) name label arg)))) -(defalias 'use-package-normalize/:bind 'use-package-normalize-binder) -(defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) - -(defun use-package-handler/:bind - (name keyword args rest state &optional bind-macro) - (cl-destructuring-bind (nargs . commands) - (use-package-normalize-commands args) - (use-package-concat - (use-package-process-keywords name - (use-package-sort-keywords - (use-package-plist-append rest :commands commands)) - state) - `((ignore - (,(if bind-macro bind-macro 'bind-keys) - :package ,name ,@nargs)))))) - -(defun use-package-handler/:bind* (name keyword arg rest state) - (use-package-handler/:bind name keyword arg rest state 'bind-keys*)) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :bind-keymap, :bind-keymap* -;; - -(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder) -(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder) - ;;;###autoload (defun use-package-autoload-keymap (keymap-symbol package override) "Loads PACKAGE and then binds the key sequence used to invoke @@ -1141,6 +885,242 @@ deferred until the prefix key sequence is pressed." (format "use-package: package.el %s failed to define keymap %s" package keymap-symbol))))) +(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))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Handlers +;; + +;;;; :disabled + +(defalias 'use-package-normalize/:disabled 'ignore) + +(defun use-package-handler/:disabled (name keyword arg rest state) + (use-package-process-keywords name rest state)) + +;;;; :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) + +(defun use-package-normalize/:ensure (name keyword args) + (if (null args) + t + (use-package-only-one (symbol-name keyword) args + #'(lambda (label arg) + (if (symbolp arg) + arg + (use-package-error + (concat ":ensure wants an optional package name " + "(an unquoted symbol name)"))))))) + +(defun use-package-ensure-elpa (name ensure state &optional no-refresh) + (let ((package + (or (and (eq ensure t) (use-package-as-symbol name)) + ensure))) + (when package + (require '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 + (ignore + (display-warning 'use-package + (format "Failed to install %s: %s" + name (error-message-string err)) + :error)))))))) + +(defun use-package-handler/:ensure (name keyword ensure rest state) + (let* ((body (use-package-process-keywords name rest state))) + ;; 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)) + +;;;; :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 state))) + (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)) + +;;;; :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 arg + `((eval-and-compile ,@arg))) + body))) + +;;;; :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)) + +;;;; :bind, :bind* + +(defalias 'use-package-normalize/:bind 'use-package-normalize-binder) +(defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) + +(defun use-package-handler/:bind + (name keyword args rest state &optional bind-macro) + (cl-destructuring-bind (nargs . commands) + (use-package-normalize-commands args) + (use-package-concat + (use-package-process-keywords name + (use-package-sort-keywords + (use-package-plist-append rest :commands commands)) + state) + `((ignore + (,(if bind-macro bind-macro 'bind-keys) + :package ,name ,@nargs)))))) + +(defun use-package-handler/:bind* (name keyword arg rest state) + (use-package-handler/:bind name keyword arg rest state 'bind-keys*)) + +;;;; :bind-keymap, :bind-keymap* + +(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder) +(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder) + (defun use-package-handler/:bind-keymap (name keyword arg rest state &optional override) (let ((form @@ -1162,18 +1142,7 @@ deferred until the prefix key sequence is pressed." (defun use-package-handler/:bind-keymap* (name keyword arg rest state) (use-package-handler/:bind-keymap name keyword arg rest state t)) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :interpreter -;; - -(defun use-package-normalize-mode (name keyword args) - "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))) +;;;; :interpreter (defun use-package-handle-mode (name alist args rest state) "Handle keywords which add regexp/mode pairs to an alist." @@ -1197,40 +1166,28 @@ deferred until the prefix key sequence is pressed." (defun use-package-handler/:interpreter (name keyword arg rest state) (use-package-handle-mode name 'interpreter-mode-alist arg rest state)) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :mode -;; +;;;; :mode (defalias 'use-package-normalize/:mode 'use-package-normalize-mode) (defun use-package-handler/:mode (name keyword arg rest state) (use-package-handle-mode name 'auto-mode-alist arg rest state)) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :magic -;; +;;;; :magic (defalias 'use-package-normalize/:magic 'use-package-normalize-mode) (defun use-package-handler/:magic (name keyword arg rest state) (use-package-handle-mode name 'magic-mode-alist arg rest state)) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :magic-fallback -;; +;;;; :magic-fallback (defalias 'use-package-normalize/:magic-fallback 'use-package-normalize-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 -;; +;;;; :hook (defun use-package-normalize/:hook (name keyword args) (use-package-as-one (symbol-name keyword) args @@ -1273,10 +1230,7 @@ deferred until the prefix key sequence is pressed." (use-package-plist-append rest :commands commands)) state)))) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :commands -;; +;;;; :commands (defalias 'use-package-normalize/:commands 'use-package-normalize-symlist) @@ -1298,10 +1252,7 @@ deferred until the prefix key sequence is pressed." (delete-dups arg)))) (use-package-process-keywords name rest state))) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :defer -;; +;;;; :defer (defalias 'use-package-normalize/:defer 'use-package-normalize-predicate) @@ -1318,10 +1269,7 @@ deferred until the prefix key sequence is pressed." (list (use-package-require-after-load name (macroexp-progn body))))))) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :after -;; +;;;; :after (defun use-package-normalize/:after (name keyword args) (setq args (use-package-normalize-recursive-symlist name keyword args)) @@ -1364,20 +1312,6 @@ no keyword implies `:all'." (`(,feat . ,rest) (use-package-require-after-load (cons :all (cons feat rest)) body)))) -(defun use-package-memoize (f arg) - "Ensure the macro-expansion of F applied to ARG evaluates ARG -no more than once." - (let ((loaded (gensym "use-package--loaded")) - (result (gensym "use-package--result")) - (next (gensym "use-package--next"))) - `((lexical-let (,loaded ,result) - (lexical-let ((,next (lambda () - (if ,loaded - ,result - (setq ,loaded t) - (setq ,result ,arg))))) - ,(funcall f ``(funcall ,,next))))))) - (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))) @@ -1390,20 +1324,14 @@ no more than once." (apply-partially #'use-package-require-after-load arg) (macroexp-progn body)))))) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :demand -;; +;;;; :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 -;; +;;;; :custom (defun use-package-normalize/:custom (name keyword args) "Normalize use-package custom keyword." @@ -1420,24 +1348,24 @@ no more than once." (defun use-package-handler/:custom (name keyword args rest state) "Generate use-package custom keyword code." (use-package-concat - (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) + (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 -;; +;;;; :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 ( ) or list of these" name-symbol))) + (let ((error-msg + (format "%s wants a ( ) or list of these" + name-symbol))) (unless (listp arg) (use-package-error error-msg)) (dolist (def arg arg) @@ -1456,16 +1384,12 @@ no more than once." (mapcar #'(lambda (def) `(custom-set-faces (quote ,def))) args) (use-package-process-keywords name rest state))) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :init -;; +;;;; :init (defalias 'use-package-normalize/:init 'use-package-normalize-forms) (defun use-package-handler/:init (name keyword arg rest state) (use-package-concat - ;; The user's initializations (let ((init-body (use-package-hook-injector (use-package-as-string name) :init arg))) @@ -1475,10 +1399,7 @@ no more than once." init-body)) (use-package-process-keywords name rest state))) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :load -;; +;;;; :load (defun use-package-normalize/:load (name keyword args) (setq args (use-package-normalize-recursive-symlist name keyword args)) @@ -1492,10 +1413,7 @@ no more than once." (setq body (use-package-require pkg nil body))) body)) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :config -;; +;;;; :config (defalias 'use-package-normalize/:config 'use-package-normalize-forms) @@ -1513,10 +1431,7 @@ no more than once." body (list t)))))) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :diminish -;; +;;;; :diminish (defun use-package-normalize-diminish (name label arg &optional recursed) "Normalize the arguments to diminish down to a list of one of two forms: @@ -1554,10 +1469,7 @@ no more than once." arg) body))) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; :delight -;; +;;;; :delight (defun use-package-normalize-delight (name args) "Normalize ARGS for a single call to `delight'." @@ -1712,6 +1624,47 @@ this file. Usage: (put 'use-package 'lisp-indent-function 'defun) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Jump to declaration +;; + +(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))))))) + +(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) ;; Local Variables: From 22fb8f8c4b1ba9c9907bfab0d1c7f656d3cbb7f6 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 11:43:53 -0800 Subject: [PATCH 360/606] Disable a test that is not working on Travis --- test/lisp/use-package/use-package-tests.el | 66 +++++++++++----------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 13ca070b4f7..7f0dfe3dd73 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1013,39 +1013,39 @@ (eval-after-load 'bar '(require 'foo nil nil)))))) -(ert-deftest use-package-test/:demand-7 () - (match-expansion - (use-package counsel - :load-path "site-lisp/swiper" - :after ivy - :demand t - :diminish - :bind (("C-*" . counsel-org-agenda-headlines) - ("M-x" . counsel-M-x)) - :commands (counsel-minibuffer-history - counsel-find-library - counsel-unicode-char) - :preface (preface-code) - :init - ;; This is actually wrong, but it's just part of the example. - (define-key minibuffer-local-map (kbd "M-r") - 'counsel-minibuffer-history)) - `(progn - (eval-and-compile - (add-to-list 'load-path "/Users/johnw/.emacs.d/site-lisp/swiper")) - (eval-and-compile - (preface-code)) - (eval-after-load 'ivy - '(progn - (define-key minibuffer-local-map (kbd "M-r") - 'counsel-minibuffer-history) - (require 'counsel nil nil) - (if (fboundp 'diminish) - (diminish 'counsel-mode)) - (ignore - (bind-keys :package counsel - ("C-*" . counsel-org-agenda-headlines) - ("M-x" . counsel-M-x)))))))) +;; (ert-deftest use-package-test/:demand-7 () +;; (match-expansion +;; (use-package counsel +;; :load-path "site-lisp/swiper" +;; :after ivy +;; :demand t +;; :diminish +;; :bind (("C-*" . counsel-org-agenda-headlines) +;; ("M-x" . counsel-M-x)) +;; :commands (counsel-minibuffer-history +;; counsel-find-library +;; counsel-unicode-char) +;; :preface (preface-code) +;; :init +;; ;; This is actually wrong, but it's just part of the example. +;; (define-key minibuffer-local-map (kbd "M-r") +;; 'counsel-minibuffer-history)) +;; `(progn +;; (eval-and-compile +;; (add-to-list 'load-path "/Users/johnw/.emacs.d/site-lisp/swiper")) +;; (eval-and-compile +;; (preface-code)) +;; (eval-after-load 'ivy +;; '(progn +;; (define-key minibuffer-local-map (kbd "M-r") +;; 'counsel-minibuffer-history) +;; (require 'counsel nil nil) +;; (if (fboundp 'diminish) +;; (diminish 'counsel-mode)) +;; (ignore +;; (bind-keys :package counsel +;; ("C-*" . counsel-org-agenda-headlines) +;; ("M-x" . counsel-M-x)))))))) (ert-deftest use-package-test/:config-1 () (match-expansion From cdbb2cbe97d12fa9d0a6d22ca8b69068f0ad06f6 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 11:44:56 -0800 Subject: [PATCH 361/606] Move the use-package-keywords defcustom to the top of the file --- lisp/use-package/use-package.el | 94 ++++++++++++++++----------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 16a1df6dc3f..aa8a204fe0e 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -57,6 +57,53 @@ (defconst use-package-version "2.4" "This version of use-package.") +(defcustom use-package-keywords + '(:disabled + :pin + :ensure + :if :when :unless + :requires + :load-path + :no-require + :preface :defines :functions + :after + :custom + :custom-face + :init + :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 + :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 + :diminish + :delight) + "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-verbose nil "Whether to report about loading and configuration details. @@ -170,53 +217,6 @@ had specified." :type 'boolean :group 'use-package) -(defcustom use-package-keywords - '(:disabled - :pin - :ensure - :if :when :unless - :requires - :load-path - :no-require - :preface :defines :functions - :after - :custom - :custom-face - :init - :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 - :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 - :diminish - :delight) - "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-expand-minimally nil "If non-nil, make the expanded code as minimal as possible. This disables: From fff47a1331f3b50257f6583ccc1549caa94744c5 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 11:54:19 -0800 Subject: [PATCH 362/606] Break out ensure/diminish/delight into their own support files --- etc/USE-PACKAGE-NEWS | 17 + lisp/use-package/use-package.el | 1629 +---------------- up-core.el | 1476 +++++++++++++++ up-delight.el | 87 + up-diminish.el | 76 + up-ensure.el | 190 ++ .../use-package-tests.el => up-tests.el | 0 7 files changed, 1850 insertions(+), 1625 deletions(-) create mode 100644 up-core.el create mode 100644 up-delight.el create mode 100644 up-diminish.el create mode 100644 up-ensure.el rename test/lisp/use-package/use-package-tests.el => up-tests.el (100%) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index c65aae64f10..eeaf91bdb0a 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -27,24 +27,41 @@ ### Other changes - Upgrade license to GPL 3. + - New `:hook` keyword. + - New keywords `:custom (foo1 bar1) (foo2 bar2)` etc., and `:custom-face`. + - New `:magic` and `:magic-fallback` keywords. + - New `:defer-install` keyword. + - New customization variable `use-package-enable-imenu-support`. + - Allow `:diminish` to take no arguments. + - Support multiple symbols passed to `:after`, and a mini-DSL using `:all` and `:any`. + - `:mode` and `:interpreter` can now accept `(rx ...)` forms. + - Using `:load-path` without also using `:ensure` now implies `:ensure nil`. + - `:bind (:map foo-map ...)` now defers binding in the map until the package has been loaded. + - Print key bindings for keymaps in `describe-personal-keybindings`. + - When `use-package-inject-hooks` is non-nil, always fire `:init` and `:config` hooks. + - Documentation added for the `:after`, `:defer-install`, `:delight`, `:requires`, `:when` and `:unless` keywords. +- The source code is now broken into several files, so that certain optional + features (diminish, delight, ensure) may be maintained separately from the + core functionality. + ### Bug fixes - Repeating a bind no longer causes duplicates in personal-keybindings. diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index aa8a204fe0e..6169732614d 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -39,1631 +39,10 @@ ;;; Code: -(require 'bind-key) -(require 'bytecomp) -(require 'cl-lib) - -(eval-when-compile - (require 'cl) - (require 'regexp-opt) - - (declare-function package-installed-p "package") - (declare-function package-read-all-archive-contents "package" ())) - -(defgroup use-package nil - "A use-package declaration for simplifying your `.emacs'." - :group 'startup) - -(defconst use-package-version "2.4" - "This version of use-package.") - -(defcustom use-package-keywords - '(:disabled - :pin - :ensure - :if :when :unless - :requires - :load-path - :no-require - :preface :defines :functions - :after - :custom - :custom-face - :init - :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 - :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 - :diminish - :delight) - "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-verbose nil - "Whether to report about loading and configuration details. - -If you customize this, then you should require the `use-package' -feature in files that use `use-package', even if these files only -contain compiled expansions of the macros. If you don't do so, -then the expanded macros do their job silently." - :type '(choice (const :tag "Quiet" nil) - (const :tag "Verbose" t) - (const :tag "Debug" debug)) - :group 'use-package) - -(defcustom use-package-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-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) - -(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) - -(defcustom use-package-defaults - '(;; this '(t) has special meaning; see `use-package-handler/:config' - (:config '(t) t) - (:init nil t) - (:defer use-package-always-defer - (lambda (args) - (and use-package-always-defer - (not (plist-member args :defer)) - (not (plist-member args :demand))))) - (:demand use-package-always-demand - (lambda (args) - (and use-package-always-demand - (not (plist-member args :defer)) - (not (plist-member args :demand))))) - (:ensure use-package-always-ensure - (lambda (args) - (and use-package-always-ensure - (not (plist-member args :load-path))))) - (:pin use-package-always-pin use-package-always-pin)) - "Alist of default values for `use-package' keywords. -Each entry in the alist is a list of three elements. The first -element is the `use-package' keyword and the second is a form -that can be evaluated to get the default value. 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 list of keywords (in normalized form), -and should return nil or t according to whether defaulting should -be attempted." - :type `(repeat - (list (choice :tag "Keyword" - ,@(mapcar #'(lambda (k) (list 'const k)) - use-package-keywords)) - (choice :tag "Default value" sexp) - (choice :tag "Enable if non-nil" sexp function))) - :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, adjust `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) - (if value - (eval-after-load 'lisp-mode - `(add-to-list 'lisp-imenu-generic-expression - (list "Packages" ,use-package-form-regexp-eval 2))) - (eval-after-load 'lisp-mode - `(setq lisp-imenu-generic-expression - (remove (list "Packages" ,use-package-form-regexp-eval 2) - lisp-imenu-generic-expression))))) - :group 'use-package) - -(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 argument passed -to `:ensure'; 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) - -(defconst use-package-font-lock-keywords - '(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" - (1 font-lock-keyword-face) - (2 font-lock-constant-face nil t)))) - -(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; 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, resolve it down 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 depending on -whether it's a string or symbol." - (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 a given keyword form. -ARGS 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)) - (ignore - (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) - (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)))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; Keywords -;; - -(defun use-package-keyword-index (keyword) - (loop named outer - with index = 0 - for k in use-package-keywords do - (if (eq k keyword) - (return-from outer index)) - (incf index))) - -(defun use-package-sort-keywords (plist) - (let (plist-grouped) - (while plist - (push (cons (car plist) (cadr plist)) - plist-grouped) - (setq plist (cddr plist))) - (let (result) - (dolist (x - (nreverse - (sort plist-grouped - #'(lambda (l r) (< (use-package-keyword-index (car l)) - (use-package-keyword-index (car r))))))) - (setq result (cons (car x) (cons (cdr x) result)))) - result))) - -(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) - (pcase key - (`:if `(and ,new ,old)) - (`:after `(:all ,new ,old)) - (`:defer old) - (_ (append new old)))) - -(defun use-package-normalize-keywords (name args) - (let* ((name-symbol (if (stringp name) (intern name) name)) - (name-string (symbol-name name-symbol))) - - ;; 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. - (dolist (spec use-package-defaults) - (when (pcase (nth 2 spec) - ((and func (pred functionp)) (funcall func args)) - (sexp (eval sexp))) - (setq args (use-package-plist-maybe-put - args (nth 0 spec) (eval (nth 1 spec)))))) - - ;; 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) - `(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)) - (or (plist-member args :bind) - (plist-member args :bind*) - (plist-member args :bind-keymap) - (plist-member args :bind-keymap*) - (plist-member args :interpreter) - (plist-member args :mode) - (plist-member args :magic) - (plist-member args :magic-fallback) - (plist-member args :commands) - (plist-member args :hook))) - (setq args (append args '(:defer t)))) - - (when (and (plist-member args :load) - (plist-member args :no-require)) - (setq args (use-package-plist-delete args :no-require))) - - (when (and (not (plist-member args :load)) - (not (plist-member args :defer)) - (not (plist-member 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-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." - (when input - (let* ((keyword (car input)) - (xs (use-package-split-list #'keywordp (cdr input))) - (args (car xs)) - (tail (cdr xs)) - (normalizer (intern (concat "use-package-normalize/" - (symbol-name keyword)))) - (arg (cond ((functionp normalizer) - (funcall normalizer name keyword args)) - ((= (length args) 1) - (car args)) - (t - args)))) - (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))) - (ignore - (display-warning 'use-package - (format "Unrecognized keyword: %s" keyword) - :warning)))))) - -(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) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; Arguments -;; - -(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 (gensym "use-package--loaded")) - (result (gensym "use-package--result")) - (next (gensym "use-package--next"))) - `((lexical-let (,loaded ,result) - (lexical-let ((,next (lambda () - (if ,loaded - ,result - (setq ,loaded t) - (setq ,result ,arg))))) - ,(funcall f ``(funcall ,,next))))))) - -(defsubst use-package-normalize-value (label arg) - "Normalize a value." - (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) - (eq (car form) 'use-package)) - (macroexpand form) - form)) args)) - -(defun use-package-normalize-forms (name keyword args) - (use-package-normalize-form (symbol-name keyword) args)) - -(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))) - ;; Currently, the handling of keyword arguments by - ;; `use-package' and `bind-key' is non-uniform and - ;; undocumented. As a result, `use-package-normalize-pairs' - ;; (as it is currently implemented) does not correctly handle - ;; the keyword-argument syntax of `bind-keys'. A permanent - ;; solution to this problem will require a careful - ;; consideration of the desired keyword-argument interface - ;; for `use-package' and `bind-key'. However, in the - ;; meantime, we have a quick patch to fix a serious bug in - ;; the handling of keyword arguments. Namely, the code below - ;; would normally unwrap lists that were passed as keyword - ;; arguments (for example, the `:filter' argument in `:bind') - ;; without the (not (keywordp last-item)) clause. See #447 - ;; for further discussion. - (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 () ...))" - (pcase v - ((and x (guard (if binding - (symbolp x) - (use-package-non-nil-symbolp x)))) t) - (`(,(or `quote `function) - ,(pred use-package-non-nil-symbolp)) t) - ((and x (guard (if binding (commandp x) (functionp x)))) t) - (_ (and additional-pred - (funcall additional-pred v))))) - -(defun use-package-normalize-function (v) - "Reduce functional constructions to one of two normal forms: - sym - #'(lambda () ...)" - (pcase v - ((pred symbolp) v) - (`(,(or `quote `function) - ,(and sym (pred symbolp))) sym) - (`(lambda . ,_) v) - (`(quote ,(and lam `(lambda . ,_))) lam) - (`(function ,(and lam `(lambda . ,_))) lam) - (_ v))) - -(defun use-package-normalize-commands (args) - "Map over ARGS of the form ((_ . F) ...). -Normalizing functional F's and returning a list of F's -representing symbols (that may need to be autloaded)." - (let ((nargs (mapcar - #'(lambda (x) - (if (consp x) - (cons (car x) - (use-package-normalize-function (cdr x))) - x)) args))) - (cons nargs - (delete - nil (mapcar - #'(lambda (x) - (and (consp x) - (use-package-non-nil-symbolp (cdr x)) - (cdr x))) nargs))))) - -(defun use-package-normalize-binder (name keyword args) - (use-package-as-one (symbol-name keyword) args - #'(lambda (label arg) - (unless (consp arg) - (use-package-error - (concat label " a ( . )" - " or list of these"))) - (use-package-normalize-pairs - #'(lambda (k) - (pcase k - ((pred stringp) t) - ((pred vectorp) t))) - #'(lambda (v) (use-package-recognize-function v t #'stringp)) - name label arg)))) - -;;;###autoload -(defun use-package-autoload-keymap (keymap-symbol package override) - "Loads PACKAGE and then binds the key sequence used to invoke -this function to KEYMAP-SYMBOL. It then simulates pressing the -same key sequence a again, so that the next key pressed is routed -to the newly loaded keymap. - -This function supports use-package's :bind-keymap keyword. It -works by binding the given key sequence to an invocation of this -function for a particular keymap. The keymap is expected to be -defined by the package. In this way, loading the package is -deferred until the prefix key sequence is pressed." - (if (not (require package nil t)) - (use-package-error (format "Cannot load package.el: %s" package)) - (if (and (boundp keymap-symbol) - (keymapp (symbol-value keymap-symbol))) - (let* ((kv (this-command-keys-vector)) - (key (key-description kv)) - (keymap (symbol-value keymap-symbol))) - (if override - (bind-key* key keymap) - (bind-key key keymap)) - (setq unread-command-events - (listify-key-sequence kv))) - (use-package-error - (format "use-package: package.el %s failed to define keymap %s" - package keymap-symbol))))) - -(defun use-package-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))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; Handlers -;; - -;;;; :disabled - -(defalias 'use-package-normalize/:disabled 'ignore) - -(defun use-package-handler/:disabled (name keyword arg rest state) - (use-package-process-keywords name rest state)) - -;;;; :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) - -(defun use-package-normalize/:ensure (name keyword args) - (if (null args) - t - (use-package-only-one (symbol-name keyword) args - #'(lambda (label arg) - (if (symbolp arg) - arg - (use-package-error - (concat ":ensure wants an optional package name " - "(an unquoted symbol name)"))))))) - -(defun use-package-ensure-elpa (name ensure state &optional no-refresh) - (let ((package - (or (and (eq ensure t) (use-package-as-symbol name)) - ensure))) - (when package - (require '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 - (ignore - (display-warning 'use-package - (format "Failed to install %s: %s" - name (error-message-string err)) - :error)))))))) - -(defun use-package-handler/:ensure (name keyword ensure rest state) - (let* ((body (use-package-process-keywords name rest state))) - ;; 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)) - -;;;; :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 state))) - (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)) - -;;;; :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 arg - `((eval-and-compile ,@arg))) - body))) - -;;;; :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)) - -;;;; :bind, :bind* - -(defalias 'use-package-normalize/:bind 'use-package-normalize-binder) -(defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) - -(defun use-package-handler/:bind - (name keyword args rest state &optional bind-macro) - (cl-destructuring-bind (nargs . commands) - (use-package-normalize-commands args) - (use-package-concat - (use-package-process-keywords name - (use-package-sort-keywords - (use-package-plist-append rest :commands commands)) - state) - `((ignore - (,(if bind-macro bind-macro 'bind-keys) - :package ,name ,@nargs)))))) - -(defun use-package-handler/:bind* (name keyword arg rest state) - (use-package-handler/:bind name keyword arg rest state 'bind-keys*)) - -;;;; :bind-keymap, :bind-keymap* - -(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder) -(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder) - -(defun use-package-handler/:bind-keymap - (name keyword arg rest state &optional override) - (let ((form - (mapcar - #'(lambda (binding) - `(,(if override - 'bind-key* - 'bind-key) - ,(car binding) - #'(lambda () - (interactive) - (use-package-autoload-keymap - ',(cdr binding) ',(use-package-as-symbol name) - ,override)))) arg))) - (use-package-concat - (use-package-process-keywords name rest state) - `((ignore ,@form))))) - -(defun use-package-handler/:bind-keymap* (name keyword arg rest state) - (use-package-handler/:bind-keymap name keyword arg rest state t)) - -;;;; :interpreter - -(defun use-package-handle-mode (name alist args rest state) - "Handle keywords which add regexp/mode pairs to an alist." - (cl-destructuring-bind (nargs . commands) - (use-package-normalize-commands args) - (use-package-concat - (mapcar - #'(lambda (thing) - `(add-to-list - ',alist - ',(cons (use-package-normalize-regex (car thing)) - (cdr thing)))) - nargs) - (use-package-process-keywords name - (use-package-sort-keywords - (use-package-plist-append rest :commands commands)) - state)))) - -(defalias 'use-package-normalize/:interpreter 'use-package-normalize-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) - -(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) - -(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) - -(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 or ( . )" - " 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 - name label arg)))) - -(defun use-package-handler/:hook (name keyword args rest state) - "Generate use-package custom keyword code." - (cl-destructuring-bind (nargs . commands) - (use-package-normalize-commands args) - (use-package-concat - (cl-mapcan - #'(lambda (def) - (let ((syms (car def)) - (fun (cdr def))) - (when fun - (mapcar - #'(lambda (sym) - `(add-hook (quote ,(intern (format "%s-hook" sym))) - (function ,fun))) - (if (use-package-non-nil-symbolp syms) (list syms) syms))))) - nargs) - (use-package-process-keywords name - (use-package-sort-keywords - (use-package-plist-append rest :commands commands)) - state)))) - -;;;; :commands - -(defalias 'use-package-normalize/:commands 'use-package-normalize-symlist) - -(defun use-package-handler/:commands (name keyword arg rest state) - (use-package-concat - (unless (plist-get state :demand) - ;; 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 (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))) - -;;;; :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 - (list (use-package-require-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." - (pcase features - ((and (pred use-package-non-nil-symbolp) feat) - 1) - (`(,(or `:or `:any) . ,rest) - (let ((num 0)) - (dolist (next rest) - (setq num (+ num (use-package-after-count-uses next)))) - num)) - (`(,(or `:and `:all) . ,rest) - (apply #'max (mapcar #'use-package-after-count-uses rest))) - (`(,feat . ,rest) - (use-package-after-count-uses (cons :all (cons feat rest)))))) - -(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'." - (pcase features - ((and (pred use-package-non-nil-symbolp) feat) - `(eval-after-load ',feat - ,(if (member (car body) '(quote backquote \' \`)) - body - (list 'quote body)))) - (`(,(or `:or `:any) . ,rest) - (macroexp-progn - (mapcar #'(lambda (x) (use-package-require-after-load x body)) rest))) - (`(,(or `:and `:all) . ,rest) - (dolist (next rest) - (setq body (use-package-require-after-load next body))) - body) - (`(,feat . ,rest) - (use-package-require-after-load (cons :all (cons feat rest)) 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) - (list (use-package-require-after-load - arg (list 'quote (macroexp-progn 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 ( [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 - (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 ( ) or list of these" - name-symbol))) - (unless (listp arg) - (use-package-error error-msg)) - (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 arg) 2)) - (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) `(custom-set-faces (quote ,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 - (let ((init-body - (use-package-hook-injector (use-package-as-string name) - :init arg))) - (if use-package-check-before-init - `((if (locate-library ,(use-package-as-string name)) - ,(macroexp-progn init-body))) - init-body)) - (use-package-process-keywords name rest state))) - -;;;; :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))) - (dolist (pkg arg) - (setq body (use-package-require 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))) - (if (or (null arg) - (equal arg '(t))) - body - (use-package-with-elapsed-timer - (format "Configuring package %s" name-symbol) - (use-package-concat - (use-package-hook-injector - (symbol-name name-symbol) :config arg) - body - (list t)))))) - -;;;; :diminish - -(defun use-package-normalize-diminish (name label arg &optional recursed) - "Normalize the arguments to diminish down to a list of one of two forms: - SYMBOL - (SYMBOL . STRING)" - (cond - ((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"))))) - -(defun use-package-normalize/:diminish (name keyword args) - (use-package-as-one (symbol-name keyword) args - (apply-partially #'use-package-normalize-diminish name) t)) - -(defun use-package-handler/:diminish (name keyword arg rest state) - (let ((body (use-package-process-keywords name rest state))) - (use-package-concat - (mapcar #'(lambda (var) - `(if (fboundp 'diminish) - ,(if (consp var) - `(diminish ',(car var) ,(cdr var)) - `(diminish ',var)))) - arg) - body))) - -;;;; :delight - -(defun use-package-normalize-delight (name 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")))) - -(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))))) - -(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))))))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; The main macro -;; - -(defun use-package-core (name args) - (let ((orig-args (cl-copy-list args))) - (setq args (use-package-normalize-keywords name args)) - (let ((body (macroexp-progn - (use-package-process-keywords name args - (and (plist-get args :demand) - (list :demand t)))))) - (if use-package-expand-minimally - body - `(condition-case-unless-debug err - ,body - (error - (let ((msg (format "%s: %s" ',name (error-message-string err)))) - (when (eq use-package-verbose 'debug) - (setq msg (concat msg " (see the *use-package* buffer)")) - (with-current-buffer (get-buffer-create "*use-package*") - (goto-char (point-max)) - (insert "-----\n" msg "\n\n" - (pp-to-string ',`(use-package ,name ,@orig-args)) - "\n -->\n\n" - (pp-to-string ',`(use-package ,name ,@args)) - "\n ==>\n\n" - (pp-to-string - ',(let ((use-package-verbose 'errors) - (use-package-expand-minimally t)) - (macroexp-progn - (use-package-process-keywords name args - (and (plist-get args :demand) - (list :demand t))))))) - (emacs-lisp-mode))) - (ignore (display-warning 'use-package msg :error))))))))) - -;;;###autoload -(defmacro use-package (name &rest args) - "Declare an Emacs package by specifying a group of configuration options. - -For full documentation, please see the README file that came with -this file. Usage: - - (use-package package-name - [:keyword [option]]...) - -:init Code to run before PACKAGE-NAME has been loaded. -:config Code to run after PACKAGE-NAME has been loaded. Note that - if loading is deferred for any reason, this code does not - execute until the lazy load has occurred. -:preface Code to be run before everything except `:disabled'; this - can be used to define functions for use in `:if', or that - should be seen by the byte-compiler. - -:mode Form to be added to `auto-mode-alist'. -: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. - -: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', - `: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. -:after Defer loading of a package until after any of the named - features are loaded. -:demand Prevent deferred loading in all cases. - -:if EXPR Initialize and load only if EXPR evaluates to a non-nil value. -:disabled The package is ignored completely if this keyword is present. -:defines Declare certain variables to silence the byte-compiler. -:functions Declare certain functions to silence the byte-compiler. -:load-path Add to the `load-path' before attempting to load the package. -:diminish Support for diminish.el (if installed). -:delight Support for delight.el (if installed). -:custom Call `customize-set-variable' with each variable definition. -:custom-face Call `customize-set-faces' with each face definition. -:ensure Loads the package using package.el if necessary. -:pin Pin the package to an archive." - (declare (indent 1)) - (unless (memq :disabled args) - (if (eq use-package-verbose 'errors) - (use-package-core name args) - (condition-case-unless-debug err - (use-package-core name args) - (error - (ignore - (let ((msg (format "Failed to parse package %s %s: %s" - name args (error-message-string err)))) - (display-warning 'use-package msg :error)))))))) - -(put 'use-package 'lisp-indent-function 'defun) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; Jump to declaration -;; - -(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))))))) - -(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)))))) +(require 'up-core) +(require 'up-ensure) +(require 'up-diminish) +(require 'up-delight) (provide 'use-package) diff --git a/up-core.el b/up-core.el new file mode 100644 index 00000000000..d11c2d7106f --- /dev/null +++ b/up-core.el @@ -0,0 +1,1476 @@ +;;; up-core.el --- A configuration macro for simplifying your .emacs + +;; Copyright (C) 2012-2017 John Wiegley + +;; Author: John Wiegley +;; Maintainer: John Wiegley +;; Created: 17 Jun 2012 +;; Modified: 29 Nov 2017 +;; Version: 2.4 +;; Package-Requires: ((emacs "24.3") (bind-key "2.4")) +;; Keywords: dotemacs startup speed config package +;; URL: https://github.com/jwiegley/use-package + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 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: + +;; The `use-package' declaration macro allows you to isolate package +;; configuration in your ".emacs" in a way that is performance-oriented and, +;; well, just tidy. I created it because I have over 80 packages that I use +;; in Emacs, and things were getting difficult to manage. Yet with this +;; utility my total load time is just under 1 second, with no loss of +;; functionality! +;; +;; Please see README.md from the same repository for documentation. + +;;; Code: + +(require 'bind-key) +(require 'bytecomp) +(require 'cl-lib) + +(eval-when-compile + (require 'cl) + (require 'regexp-opt) + + (declare-function package-installed-p "package") + (declare-function package-read-all-archive-contents "package" ())) + +(defgroup use-package nil + "A use-package declaration for simplifying your `.emacs'." + :group 'startup) + +(defconst use-package-version "2.4" + "This version of use-package.") + +(defcustom use-package-keywords + '(:disabled + :if :when :unless + :requires + :load-path + :no-require + :preface :defines :functions + :after + :custom + :custom-face + :init + :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 + :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-verbose nil + "Whether to report about loading and configuration details. + +If you customize this, then you should require the `use-package' +feature in files that use `use-package', even if these files only +contain compiled expansions of the macros. If you don't do so, +then the expanded macros do their job silently." + :type '(choice (const :tag "Quiet" nil) + (const :tag "Verbose" t) + (const :tag "Debug" debug)) + :group 'use-package) + +(defcustom use-package-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) + (:defer use-package-always-defer + (lambda (args) + (and use-package-always-defer + (not (plist-member args :defer)) + (not (plist-member args :demand))))) + (:demand use-package-always-demand + (lambda (args) + (and use-package-always-demand + (not (plist-member args :defer)) + (not (plist-member args :demand)))))) + "Alist of default values for `use-package' keywords. +Each entry in the alist is a list of three elements. The first +element is the `use-package' keyword and the second is a form +that can be evaluated to get the default value. 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 list of keywords (in normalized form), +and should return nil or t according to whether defaulting should +be attempted." + :type `(repeat + (list (choice :tag "Keyword" + ,@(mapcar #'(lambda (k) (list 'const k)) + use-package-keywords)) + (choice :tag "Default value" sexp) + (choice :tag "Enable if non-nil" sexp function))) + :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, adjust `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) + (if value + (eval-after-load 'lisp-mode + `(add-to-list 'lisp-imenu-generic-expression + (list "Packages" ,use-package-form-regexp-eval 2))) + (eval-after-load 'lisp-mode + `(setq lisp-imenu-generic-expression + (remove (list "Packages" ,use-package-form-regexp-eval 2) + lisp-imenu-generic-expression))))) + :group 'use-package) + +(defconst use-package-font-lock-keywords + '(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" + (1 font-lock-keyword-face) + (2 font-lock-constant-face nil t)))) + +(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; 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, resolve it down 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 depending on +whether it's a string or symbol." + (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 a given keyword form. +ARGS 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)) + (ignore + (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) + (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)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Keywords +;; + +(defun use-package-keyword-index (keyword) + (loop named outer + with index = 0 + for k in use-package-keywords do + (if (eq k keyword) + (return-from outer index)) + (incf index))) + +(defun use-package-sort-keywords (plist) + (let (plist-grouped) + (while plist + (push (cons (car plist) (cadr plist)) + plist-grouped) + (setq plist (cddr plist))) + (let (result) + (dolist (x + (nreverse + (sort plist-grouped + #'(lambda (l r) (< (use-package-keyword-index (car l)) + (use-package-keyword-index (car r))))))) + (setq result (cons (car x) (cons (cdr x) result)))) + result))) + +(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) + (pcase key + (`:if `(and ,new ,old)) + (`:after `(:all ,new ,old)) + (`:defer old) + (_ (append new old)))) + +(defun use-package-normalize-keywords (name args) + (let* ((name-symbol (if (stringp name) (intern name) name)) + (name-string (symbol-name name-symbol))) + + ;; 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. + (dolist (spec use-package-defaults) + (when (pcase (nth 2 spec) + ((and func (pred functionp)) (funcall func args)) + (sexp (eval sexp))) + (setq args (use-package-plist-maybe-put + args (nth 0 spec) (eval (nth 1 spec)))))) + + ;; 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) + `(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)) + (or (plist-member args :bind) + (plist-member args :bind*) + (plist-member args :bind-keymap) + (plist-member args :bind-keymap*) + (plist-member args :interpreter) + (plist-member args :mode) + (plist-member args :magic) + (plist-member args :magic-fallback) + (plist-member args :commands) + (plist-member args :hook))) + (setq args (append args '(:defer t)))) + + (when (and (plist-member args :load) + (plist-member args :no-require)) + (setq args (use-package-plist-delete args :no-require))) + + (when (and (not (plist-member args :load)) + (not (plist-member args :defer)) + (not (plist-member 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-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." + (when input + (let* ((keyword (car input)) + (xs (use-package-split-list #'keywordp (cdr input))) + (args (car xs)) + (tail (cdr xs)) + (normalizer (intern (concat "use-package-normalize/" + (symbol-name keyword)))) + (arg (cond ((functionp normalizer) + (funcall normalizer name keyword args)) + ((= (length args) 1) + (car args)) + (t + args)))) + (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))) + (ignore + (display-warning 'use-package + (format "Unrecognized keyword: %s" keyword) + :warning)))))) + +(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) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Arguments +;; + +(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 (gensym "use-package--loaded")) + (result (gensym "use-package--result")) + (next (gensym "use-package--next"))) + `((lexical-let (,loaded ,result) + (lexical-let ((,next (lambda () + (if ,loaded + ,result + (setq ,loaded t) + (setq ,result ,arg))))) + ,(funcall f ``(funcall ,,next))))))) + +(defsubst use-package-normalize-value (label arg) + "Normalize a value." + (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) + (eq (car form) 'use-package)) + (macroexpand form) + form)) args)) + +(defun use-package-normalize-forms (name keyword args) + (use-package-normalize-form (symbol-name keyword) args)) + +(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))) + ;; Currently, the handling of keyword arguments by + ;; `use-package' and `bind-key' is non-uniform and + ;; undocumented. As a result, `use-package-normalize-pairs' + ;; (as it is currently implemented) does not correctly handle + ;; the keyword-argument syntax of `bind-keys'. A permanent + ;; solution to this problem will require a careful + ;; consideration of the desired keyword-argument interface + ;; for `use-package' and `bind-key'. However, in the + ;; meantime, we have a quick patch to fix a serious bug in + ;; the handling of keyword arguments. Namely, the code below + ;; would normally unwrap lists that were passed as keyword + ;; arguments (for example, the `:filter' argument in `:bind') + ;; without the (not (keywordp last-item)) clause. See #447 + ;; for further discussion. + (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 () ...))" + (pcase v + ((and x (guard (if binding + (symbolp x) + (use-package-non-nil-symbolp x)))) t) + (`(,(or `quote `function) + ,(pred use-package-non-nil-symbolp)) t) + ((and x (guard (if binding (commandp x) (functionp x)))) t) + (_ (and additional-pred + (funcall additional-pred v))))) + +(defun use-package-normalize-function (v) + "Reduce functional constructions to one of two normal forms: + sym + #'(lambda () ...)" + (pcase v + ((pred symbolp) v) + (`(,(or `quote `function) + ,(and sym (pred symbolp))) sym) + (`(lambda . ,_) v) + (`(quote ,(and lam `(lambda . ,_))) lam) + (`(function ,(and lam `(lambda . ,_))) lam) + (_ v))) + +(defun use-package-normalize-commands (args) + "Map over ARGS of the form ((_ . F) ...). +Normalizing functional F's and returning a list of F's +representing symbols (that may need to be autloaded)." + (let ((nargs (mapcar + #'(lambda (x) + (if (consp x) + (cons (car x) + (use-package-normalize-function (cdr x))) + x)) args))) + (cons nargs + (delete + nil (mapcar + #'(lambda (x) + (and (consp x) + (use-package-non-nil-symbolp (cdr x)) + (cdr x))) nargs))))) + +(defun use-package-normalize-binder (name keyword args) + (use-package-as-one (symbol-name keyword) args + #'(lambda (label arg) + (unless (consp arg) + (use-package-error + (concat label " a ( . )" + " or list of these"))) + (use-package-normalize-pairs + #'(lambda (k) + (pcase k + ((pred stringp) t) + ((pred vectorp) t))) + #'(lambda (v) (use-package-recognize-function v t #'stringp)) + name label arg)))) + +;;;###autoload +(defun use-package-autoload-keymap (keymap-symbol package override) + "Loads PACKAGE and then binds the key sequence used to invoke +this function to KEYMAP-SYMBOL. It then simulates pressing the +same key sequence a again, so that the next key pressed is routed +to the newly loaded keymap. + +This function supports use-package's :bind-keymap keyword. It +works by binding the given key sequence to an invocation of this +function for a particular keymap. The keymap is expected to be +defined by the package. In this way, loading the package is +deferred until the prefix key sequence is pressed." + (if (not (require package nil t)) + (use-package-error (format "Cannot load package.el: %s" package)) + (if (and (boundp keymap-symbol) + (keymapp (symbol-value keymap-symbol))) + (let* ((kv (this-command-keys-vector)) + (key (key-description kv)) + (keymap (symbol-value keymap-symbol))) + (if override + (bind-key* key keymap) + (bind-key key keymap)) + (setq unread-command-events + (listify-key-sequence kv))) + (use-package-error + (format "use-package: package.el %s failed to define keymap %s" + package keymap-symbol))))) + +(defun use-package-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))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Handlers +;; + +;;;; :disabled + +(defalias 'use-package-normalize/:disabled 'ignore) + +(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 state))) + (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)) + +;;;; :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 arg + `((eval-and-compile ,@arg))) + body))) + +;;;; :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)) + +;;;; :bind, :bind* + +(defalias 'use-package-normalize/:bind 'use-package-normalize-binder) +(defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) + +(defun use-package-handler/:bind + (name keyword args rest state &optional bind-macro) + (cl-destructuring-bind (nargs . commands) + (use-package-normalize-commands args) + (use-package-concat + (use-package-process-keywords name + (use-package-sort-keywords + (use-package-plist-append rest :commands commands)) + state) + `((ignore + (,(if bind-macro bind-macro 'bind-keys) + :package ,name ,@nargs)))))) + +(defun use-package-handler/:bind* (name keyword arg rest state) + (use-package-handler/:bind name keyword arg rest state 'bind-keys*)) + +;;;; :bind-keymap, :bind-keymap* + +(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder) +(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder) + +(defun use-package-handler/:bind-keymap + (name keyword arg rest state &optional override) + (let ((form + (mapcar + #'(lambda (binding) + `(,(if override + 'bind-key* + 'bind-key) + ,(car binding) + #'(lambda () + (interactive) + (use-package-autoload-keymap + ',(cdr binding) ',(use-package-as-symbol name) + ,override)))) arg))) + (use-package-concat + (use-package-process-keywords name rest state) + `((ignore ,@form))))) + +(defun use-package-handler/:bind-keymap* (name keyword arg rest state) + (use-package-handler/:bind-keymap name keyword arg rest state t)) + +;;;; :interpreter + +(defun use-package-handle-mode (name alist args rest state) + "Handle keywords which add regexp/mode pairs to an alist." + (cl-destructuring-bind (nargs . commands) + (use-package-normalize-commands args) + (use-package-concat + (mapcar + #'(lambda (thing) + `(add-to-list + ',alist + ',(cons (use-package-normalize-regex (car thing)) + (cdr thing)))) + nargs) + (use-package-process-keywords name + (use-package-sort-keywords + (use-package-plist-append rest :commands commands)) + state)))) + +(defalias 'use-package-normalize/:interpreter 'use-package-normalize-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) + +(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) + +(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) + +(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 or ( . )" + " 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 + name label arg)))) + +(defun use-package-handler/:hook (name keyword args rest state) + "Generate use-package custom keyword code." + (cl-destructuring-bind (nargs . commands) + (use-package-normalize-commands args) + (use-package-concat + (cl-mapcan + #'(lambda (def) + (let ((syms (car def)) + (fun (cdr def))) + (when fun + (mapcar + #'(lambda (sym) + `(add-hook (quote ,(intern (format "%s-hook" sym))) + (function ,fun))) + (if (use-package-non-nil-symbolp syms) (list syms) syms))))) + nargs) + (use-package-process-keywords name + (use-package-sort-keywords + (use-package-plist-append rest :commands commands)) + state)))) + +;;;; :commands + +(defalias 'use-package-normalize/:commands 'use-package-normalize-symlist) + +(defun use-package-handler/:commands (name keyword arg rest state) + (use-package-concat + (unless (plist-get state :demand) + ;; 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 (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))) + +;;;; :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 + (list (use-package-require-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." + (pcase features + ((and (pred use-package-non-nil-symbolp) feat) + 1) + (`(,(or `:or `:any) . ,rest) + (let ((num 0)) + (dolist (next rest) + (setq num (+ num (use-package-after-count-uses next)))) + num)) + (`(,(or `:and `:all) . ,rest) + (apply #'max (mapcar #'use-package-after-count-uses rest))) + (`(,feat . ,rest) + (use-package-after-count-uses (cons :all (cons feat rest)))))) + +(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'." + (pcase features + ((and (pred use-package-non-nil-symbolp) feat) + `(eval-after-load ',feat + ,(if (member (car body) '(quote backquote \' \`)) + body + (list 'quote body)))) + (`(,(or `:or `:any) . ,rest) + (macroexp-progn + (mapcar #'(lambda (x) (use-package-require-after-load x body)) rest))) + (`(,(or `:and `:all) . ,rest) + (dolist (next rest) + (setq body (use-package-require-after-load next body))) + body) + (`(,feat . ,rest) + (use-package-require-after-load (cons :all (cons feat rest)) 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) + (list (use-package-require-after-load + arg (list 'quote (macroexp-progn 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 ( [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 + (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 ( ) or list of these" + name-symbol))) + (unless (listp arg) + (use-package-error error-msg)) + (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 arg) 2)) + (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) `(custom-set-faces (quote ,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 + (let ((init-body + (use-package-hook-injector (use-package-as-string name) + :init arg))) + (if use-package-check-before-init + `((if (locate-library ,(use-package-as-string name)) + ,(macroexp-progn init-body))) + init-body)) + (use-package-process-keywords name rest state))) + +;;;; :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))) + (dolist (pkg arg) + (setq body (use-package-require 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))) + (if (or (null arg) + (equal arg '(t))) + body + (use-package-with-elapsed-timer + (format "Configuring package %s" name-symbol) + (use-package-concat + (use-package-hook-injector + (symbol-name name-symbol) :config arg) + body + (list t)))))) + +;;;; :diminish + +(defun use-package-normalize-diminish (name label arg &optional recursed) + "Normalize the arguments to diminish down to a list of one of two forms: + SYMBOL + (SYMBOL . STRING)" + (cond + ((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"))))) + +(defun use-package-normalize/:diminish (name keyword args) + (use-package-as-one (symbol-name keyword) args + (apply-partially #'use-package-normalize-diminish name) t)) + +(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))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; The main macro +;; + +(defun use-package-core (name args) + (let ((orig-args (cl-copy-list args))) + (setq args (use-package-normalize-keywords name args)) + (let ((body (macroexp-progn + (use-package-process-keywords name args + (and (plist-get args :demand) + (list :demand t)))))) + (if use-package-expand-minimally + body + `(condition-case-unless-debug err + ,body + (error + (let ((msg (format "%s: %s" ',name (error-message-string err)))) + (when (eq use-package-verbose 'debug) + (setq msg (concat msg " (see the *use-package* buffer)")) + (with-current-buffer (get-buffer-create "*use-package*") + (goto-char (point-max)) + (insert "-----\n" msg "\n\n" + (pp-to-string ',`(use-package ,name ,@orig-args)) + "\n -->\n\n" + (pp-to-string ',`(use-package ,name ,@args)) + "\n ==>\n\n" + (pp-to-string + ',(let ((use-package-verbose 'errors) + (use-package-expand-minimally t)) + (macroexp-progn + (use-package-process-keywords name args + (and (plist-get args :demand) + (list :demand t))))))) + (emacs-lisp-mode))) + (ignore (display-warning 'use-package msg :error))))))))) + +;;;###autoload +(defmacro use-package (name &rest args) + "Declare an Emacs package by specifying a group of configuration options. + +For full documentation, please see the README file that came with +this file. Usage: + + (use-package package-name + [:keyword [option]]...) + +:init Code to run before PACKAGE-NAME has been loaded. +:config Code to run after PACKAGE-NAME has been loaded. Note that + if loading is deferred for any reason, this code does not + execute until the lazy load has occurred. +:preface Code to be run before everything except `:disabled'; this + can be used to define functions for use in `:if', or that + should be seen by the byte-compiler. + +:mode Form to be added to `auto-mode-alist'. +: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. + +: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', + `: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. +:after Defer loading of a package until after any of the named + features are loaded. +:demand Prevent deferred loading in all cases. + +:if EXPR Initialize and load only if EXPR evaluates to a non-nil value. +:disabled The package is ignored completely if this keyword is present. +:defines Declare certain variables to silence the byte-compiler. +:functions Declare certain functions to silence the byte-compiler. +:load-path Add to the `load-path' before attempting to load the package. +:diminish Support for diminish.el (if installed). +:delight Support for delight.el (if installed). +:custom Call `customize-set-variable' with each variable definition. +:custom-face Call `customize-set-faces' with each face definition. +:ensure Loads the package using package.el if necessary. +:pin Pin the package to an archive." + (declare (indent 1)) + (unless (memq :disabled args) + (if (eq use-package-verbose 'errors) + (use-package-core name args) + (condition-case-unless-debug err + (use-package-core name args) + (error + (ignore + (let ((msg (format "Failed to parse package %s %s: %s" + name args (error-message-string err)))) + (display-warning 'use-package msg :error)))))))) + +(put 'use-package 'lisp-indent-function 'defun) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Jump to declaration +;; + +(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))))))) + +(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 'up-core) + +;; Local Variables: +;; indent-tabs-mode: nil +;; End: + +;;; use-package.el ends here diff --git a/up-delight.el b/up-delight.el new file mode 100644 index 00000000000..2a2138a56db --- /dev/null +++ b/up-delight.el @@ -0,0 +1,87 @@ +;;; up-delight.el --- Support for the :delight keyword + +;; Copyright (C) 2012-2017 John Wiegley + +;; Author: John Wiegley +;; Maintainer: John Wiegley +;; Created: 17 Jun 2012 +;; Modified: 3 Dec 2017 +;; Version: 1.0 +;; Package-Requires: ((emacs "24.3") (use-package "2.4") (delight "1.5")) +;; Keywords: dotemacs startup speed config package +;; URL: https://github.com/jwiegley/use-package + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 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: + +;; Provides support for the :delight keyword, which is made available by +;; default by requiring `use-package'. + +;;; Code: + +(require 'up-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")))) + +(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))))) + +(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 'up-delight) diff --git a/up-diminish.el b/up-diminish.el new file mode 100644 index 00000000000..f848531875a --- /dev/null +++ b/up-diminish.el @@ -0,0 +1,76 @@ +;;; up-diminish.el --- Support for the :diminish keyword + +;; Copyright (C) 2012-2017 John Wiegley + +;; Author: John Wiegley +;; Maintainer: John Wiegley +;; Created: 17 Jun 2012 +;; Modified: 3 Dec 2017 +;; Version: 1.0 +;; Package-Requires: ((emacs "24.3") (use-package "2.4") (diminish "0.45")) +;; Keywords: dotemacs startup speed config package +;; URL: https://github.com/jwiegley/use-package + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 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: + +;; Provides support for the :diminish keyword, which is made available by +;; default by requiring `use-package'. + +;;; Code: + +(require 'up-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"))))) + +(defun use-package-normalize/:diminish (name keyword args) + (use-package-as-one (symbol-name keyword) args + (apply-partially #'use-package-normalize-diminish name) t)) + +(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 'up-diminish) diff --git a/up-ensure.el b/up-ensure.el new file mode 100644 index 00000000000..75b0ea16fe1 --- /dev/null +++ b/up-ensure.el @@ -0,0 +1,190 @@ +;;; up-ensure.el --- Support for the :ensure and :pin keywords + +;; Copyright (C) 2012-2017 John Wiegley + +;; Author: John Wiegley +;; Maintainer: John Wiegley +;; Created: 17 Jun 2012 +;; Modified: 3 Dec 2017 +;; Version: 1.0 +;; Package-Requires: ((emacs "24.3") (use-package "2.4")) +;; Keywords: dotemacs startup speed config package +;; URL: https://github.com/jwiegley/use-package + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 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: + +;; Provides support for the :ensure and :pin keywords, which is made available +;; by default by requiring `use-package'. + +;;; Code: + +(require 'up-core) + +(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) + +(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) + +(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 argument passed +to `:ensure'; 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) + +;;;; :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) + +(defun use-package-normalize/:ensure (name keyword args) + (if (null args) + t + (use-package-only-one (symbol-name keyword) args + #'(lambda (label arg) + (if (symbolp arg) + arg + (use-package-error + (concat ":ensure wants an optional package name " + "(an unquoted symbol name)"))))))) + +(defun use-package-ensure-elpa (name ensure state &optional no-refresh) + (let ((package + (or (and (eq ensure t) (use-package-as-symbol name)) + ensure))) + (when package + (require '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 + (ignore + (display-warning 'use-package + (format "Failed to install %s: %s" + name (error-message-string err)) + :error)))))))) + +(defun use-package-handler/:ensure (name keyword ensure rest state) + (let* ((body (use-package-process-keywords name rest state))) + ;; 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 use-package-always-ensure + (lambda (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 'up-ensure) diff --git a/test/lisp/use-package/use-package-tests.el b/up-tests.el similarity index 100% rename from test/lisp/use-package/use-package-tests.el rename to up-tests.el From 7c95d0a0e0693844c68a6451c5c89b8f273a6c51 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 13:11:40 -0800 Subject: [PATCH 363/606] Move optional jumping functionality to its own module --- lisp/use-package/use-package.el | 3 ++ up-core.el | 41 ------------------ up-jump.el | 77 +++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 41 deletions(-) create mode 100644 up-jump.el diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 6169732614d..ec459ab1662 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -40,10 +40,13 @@ ;;; Code: (require 'up-core) + (require 'up-ensure) (require 'up-diminish) (require 'up-delight) +(autoload #'use-package-jump-to-package-form "up-jump" nil t) + (provide 'use-package) ;; Local Variables: diff --git a/up-core.el b/up-core.el index d11c2d7106f..81cae6e177b 100644 --- a/up-core.el +++ b/up-core.el @@ -1426,47 +1426,6 @@ this file. Usage: (put 'use-package 'lisp-indent-function 'defun) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; Jump to declaration -;; - -(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))))))) - -(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 'up-core) ;; Local Variables: diff --git a/up-jump.el b/up-jump.el new file mode 100644 index 00000000000..721c17c7100 --- /dev/null +++ b/up-jump.el @@ -0,0 +1,77 @@ +;;; up-jump.el --- Attempt to jump to a use-package declaration + +;; Copyright (C) 2012-2017 John Wiegley + +;; Author: John Wiegley +;; Maintainer: John Wiegley +;; Created: 17 Jun 2012 +;; Modified: 3 Dec 2017 +;; Version: 1.0 +;; Package-Requires: ((emacs "24.3") (use-package "2.4")) +;; Keywords: dotemacs startup speed config package +;; URL: https://github.com/jwiegley/use-package + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 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: + +;; 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 delay-loaded, it will not work. Improvements are +;; needed. + +;;; Code: + +(require 'up-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 'up-jump) From 99200a1642318a09f77d42a298e2e063c378dee4 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 13:11:49 -0800 Subject: [PATCH 364/606] Fix a byte-compiler warning in up-ensure.el --- up-core.el | 5 +---- up-ensure.el | 4 ++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/up-core.el b/up-core.el index 81cae6e177b..95d4fbb7860 100644 --- a/up-core.el +++ b/up-core.el @@ -45,10 +45,7 @@ (eval-when-compile (require 'cl) - (require 'regexp-opt) - - (declare-function package-installed-p "package") - (declare-function package-read-all-archive-contents "package" ())) + (require 'regexp-opt)) (defgroup use-package nil "A use-package declaration for simplifying your `.emacs'." diff --git a/up-ensure.el b/up-ensure.el index 75b0ea16fe1..2e3d4ec4116 100644 --- a/up-ensure.el +++ b/up-ensure.el @@ -35,6 +35,10 @@ (require 'up-core) +(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." From f356c838c1d4224f3a7fe49b2fa9b6911522b375 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 13:12:07 -0800 Subject: [PATCH 365/606] Minor simplification --- up-core.el | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/up-core.el b/up-core.el index 95d4fbb7860..a5fc25e6e07 100644 --- a/up-core.el +++ b/up-core.el @@ -229,11 +229,10 @@ Must be set before loading use-package." :type 'boolean :set #'(lambda (sym value) - (if value - (eval-after-load 'lisp-mode + (eval-after-load 'lisp-mode + (if value `(add-to-list 'lisp-imenu-generic-expression - (list "Packages" ,use-package-form-regexp-eval 2))) - (eval-after-load 'lisp-mode + (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))))) From 8dd0f274d09156fb9f98ec1809c88fedbc2ec73c Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 13:12:30 -0800 Subject: [PATCH 366/606] Drop some unnecessary detail from a warning message --- up-core.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/up-core.el b/up-core.el index a5fc25e6e07..a15a3ce9733 100644 --- a/up-core.el +++ b/up-core.el @@ -1416,8 +1416,8 @@ this file. Usage: (use-package-core name args) (error (ignore - (let ((msg (format "Failed to parse package %s %s: %s" - name args (error-message-string err)))) + (let ((msg (format "Failed to parse package %s: %s" + name (error-message-string err)))) (display-warning 'use-package msg :error)))))))) (put 'use-package 'lisp-indent-function 'defun) From 8428dafcfab52b73f13e32c68a5d56cd1acf3f33 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 13:12:43 -0800 Subject: [PATCH 367/606] Report errors during deferred :config as intelligent warnings also --- up-core.el | 71 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/up-core.el b/up-core.el index a15a3ce9733..d21a822b307 100644 --- a/up-core.el +++ b/up-core.el @@ -245,6 +245,8 @@ Must be set before loading use-package." (font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords) +(defvar use-package--hush-function) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Utility functions @@ -1113,8 +1115,8 @@ deferred until the prefix key sequence is pressed." ',(use-package-as-symbol name) nil t))) (if (or (not arg) (null body)) body - (list (use-package-require-after-load - name (macroexp-progn body))))))) + `((eval-after-load ',name + ',(funcall use-package--hush-function body))))))) ;;;; :after @@ -1321,37 +1323,44 @@ no keyword implies `:all'." ;;; The main macro ;; -(defun use-package-core (name args) - (let ((orig-args (cl-copy-list args))) - (setq args (use-package-normalize-keywords name args)) - (let ((body (macroexp-progn - (use-package-process-keywords name args - (and (plist-get args :demand) - (list :demand t)))))) - (if use-package-expand-minimally - body - `(condition-case-unless-debug err - ,body - (error - (let ((msg (format "%s: %s" ',name (error-message-string err)))) - (when (eq use-package-verbose 'debug) - (setq msg (concat msg " (see the *use-package* buffer)")) - (with-current-buffer (get-buffer-create "*use-package*") - (goto-char (point-max)) - (insert "-----\n" msg "\n\n" - (pp-to-string ',`(use-package ,name ,@orig-args)) +(defun use-package-hush (name args args* expanded body) + `(condition-case-unless-debug err + ,(macroexp-progn body) + (error + (let ((msg (format "%s: %s" ',name (error-message-string err)))) + ,(when (eq use-package-verbose 'debug) + `(progn + (setq msg (concat msg " (see the *use-package* buffer)")) + (with-current-buffer (get-buffer-create "*use-package*") + (goto-char (point-max)) + (insert "-----\n" msg + ,(concat + "\n\n" + (pp-to-string `(use-package ,name ,@args)) "\n -->\n\n" - (pp-to-string ',`(use-package ,name ,@args)) + (pp-to-string `(use-package ,name ,@args*)) "\n ==>\n\n" - (pp-to-string - ',(let ((use-package-verbose 'errors) - (use-package-expand-minimally t)) - (macroexp-progn - (use-package-process-keywords name args - (and (plist-get args :demand) - (list :demand t))))))) - (emacs-lisp-mode))) - (ignore (display-warning 'use-package msg :error))))))))) + (pp-to-string (macroexp-progn expanded)))) + (emacs-lisp-mode)))) + (ignore (display-warning 'use-package msg :error)))))) + +(defun use-package-core (name args) + (let* ((args* (use-package-normalize-keywords name args)) + (use-package--hush-function + (if use-package-expand-minimally + #'macroexp-progn + (let ((use-package--hush-function #'macroexp-progn)) + (apply-partially + #'use-package-hush name args args* + (let ((use-package-verbose 'errors) + (use-package-expand-minimally t)) + (use-package-process-keywords name args* + (and (plist-get args* :demand) + (list :demand t))))))))) + (funcall use-package--hush-function + (use-package-process-keywords name args* + (and (plist-get args* :demand) + (list :demand t)))))) ;;;###autoload (defmacro use-package (name &rest args) From 35b975563ca8b018e9fea6792af814a0a2144733 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 19:54:57 -0800 Subject: [PATCH 368/606] Correction to error detection at both :init and :config times --- up-core.el | 88 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/up-core.el b/up-core.el index d21a822b307..2dcf729abfa 100644 --- a/up-core.el +++ b/up-core.el @@ -1115,8 +1115,7 @@ deferred until the prefix key sequence is pressed." ',(use-package-as-symbol name) nil t))) (if (or (not arg) (null body)) body - `((eval-after-load ',name - ',(funcall use-package--hush-function body))))))) + `((eval-after-load ',name ',(macroexp-progn body))))))) ;;;; :after @@ -1242,10 +1241,12 @@ no keyword implies `:all'." (let ((init-body (use-package-hook-injector (use-package-as-string name) :init arg))) - (if use-package-check-before-init - `((if (locate-library ,(use-package-as-string name)) - ,(macroexp-progn init-body))) - init-body)) + (when init-body + (funcall use-package--hush-function + (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))) ;;;; :load @@ -1269,16 +1270,16 @@ no keyword implies `:all'." (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))) - (if (or (null arg) - (equal arg '(t))) + (if (or (null arg) (equal arg '(t))) body (use-package-with-elapsed-timer (format "Configuring package %s" name-symbol) - (use-package-concat - (use-package-hook-injector - (symbol-name name-symbol) :config arg) - body - (list t)))))) + (funcall use-package--hush-function + (use-package-concat + (use-package-hook-injector + (symbol-name name-symbol) :config arg) + body + (list t))))))) ;;;; :diminish @@ -1324,32 +1325,32 @@ no keyword implies `:all'." ;; (defun use-package-hush (name args args* expanded body) - `(condition-case-unless-debug err - ,(macroexp-progn body) - (error - (let ((msg (format "%s: %s" ',name (error-message-string err)))) - ,(when (eq use-package-verbose 'debug) - `(progn - (setq msg (concat msg " (see the *use-package* buffer)")) - (with-current-buffer (get-buffer-create "*use-package*") - (goto-char (point-max)) - (insert "-----\n" msg - ,(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 expanded)))) - (emacs-lisp-mode)))) - (ignore (display-warning 'use-package msg :error)))))) + `((condition-case-unless-debug err + ,(macroexp-progn body) + (error + (let ((msg (format "%s: %s" ',name (error-message-string err)))) + ,(when (eq use-package-verbose 'debug) + `(progn + (setq msg (concat msg " (see the *use-package* buffer)")) + (with-current-buffer (get-buffer-create "*use-package*") + (goto-char (point-max)) + (insert "-----\n" msg + ,(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 expanded)))) + (emacs-lisp-mode)))) + (ignore (display-warning 'use-package msg :error))))))) (defun use-package-core (name args) (let* ((args* (use-package-normalize-keywords name args)) (use-package--hush-function (if use-package-expand-minimally - #'macroexp-progn - (let ((use-package--hush-function #'macroexp-progn)) + #'identity + (let ((use-package--hush-function #'identity)) (apply-partially #'use-package-hush name args args* (let ((use-package-verbose 'errors) @@ -1419,15 +1420,16 @@ this file. Usage: :pin Pin the package to an archive." (declare (indent 1)) (unless (memq :disabled args) - (if (eq use-package-verbose 'errors) - (use-package-core name args) - (condition-case-unless-debug err - (use-package-core name args) - (error - (ignore - (let ((msg (format "Failed to parse package %s: %s" - name (error-message-string err)))) - (display-warning 'use-package msg :error)))))))) + (macroexp-progn + (if (eq use-package-verbose 'errors) + (use-package-core name args) + (condition-case-unless-debug err + (use-package-core name args) + (error + (ignore + (let ((msg (format "Failed to parse package %s: %s" + name (error-message-string err)))) + (display-warning 'use-package msg :error))))))))) (put 'use-package 'lisp-indent-function 'defun) From f08f8a7ba9b7a0d49be4e524c04c61957cf00345 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 22:54:34 -0800 Subject: [PATCH 369/606] Only emit the debugging context text once --- up-core.el | 70 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/up-core.el b/up-core.el index 2dcf729abfa..e66d9510b1e 100644 --- a/up-core.el +++ b/up-core.el @@ -1324,44 +1324,54 @@ no keyword implies `:all'." ;;; The main macro ;; -(defun use-package-hush (name args args* expanded body) +(defsubst use-package-hush (context body) `((condition-case-unless-debug err ,(macroexp-progn body) - (error - (let ((msg (format "%s: %s" ',name (error-message-string err)))) - ,(when (eq use-package-verbose 'debug) - `(progn - (setq msg (concat msg " (see the *use-package* buffer)")) - (with-current-buffer (get-buffer-create "*use-package*") - (goto-char (point-max)) - (insert "-----\n" msg + (error (,context err))))) + +(defun use-package-core (name args) + (let ((context (gensym "use-package--warning")) + (args* (use-package-normalize-keywords name args)) + (use-package--hush-function #'identity)) + (if use-package-expand-minimally + (funcall use-package--hush-function + (use-package-process-keywords name args* + (and (plist-get args* :demand) + (list :demand t)))) + `((cl-flet + ((,context + (err) + (let ((msg (format "%s: %s" ',name + (error-message-string err)))) + ,(when (eq use-package-verbose 'debug) + `(progn + (setq msg (concat msg " (see the *use-package* buffer)")) + (with-current-buffer (get-buffer-create "*use-package*") + (goto-char (point-max)) + (insert + "-----\n" msg ,(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 expanded)))) - (emacs-lisp-mode)))) - (ignore (display-warning 'use-package msg :error))))))) - -(defun use-package-core (name args) - (let* ((args* (use-package-normalize-keywords name args)) - (use-package--hush-function - (if use-package-expand-minimally - #'identity - (let ((use-package--hush-function #'identity)) - (apply-partially - #'use-package-hush name args args* - (let ((use-package-verbose 'errors) - (use-package-expand-minimally t)) - (use-package-process-keywords name args* - (and (plist-get args* :demand) - (list :demand t))))))))) - (funcall use-package--hush-function - (use-package-process-keywords name args* - (and (plist-get args* :demand) - (list :demand t)))))) + (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)))))))) + (emacs-lisp-mode)))) + (ignore (display-warning 'use-package msg :error))))) + ,(let ((use-package--hush-function + (apply-partially #'use-package-hush context))) + (macroexp-progn + (funcall use-package--hush-function + (use-package-process-keywords name args* + (and (plist-get args* :demand) + (list :demand t))))))))))) ;;;###autoload (defmacro use-package (name &rest args) From 36cf79985375ed205e1715154cc6e2d9632c6dd1 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 23:05:17 -0800 Subject: [PATCH 370/606] Add 'errors as another option to `use-package-verbose' --- up-core.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/up-core.el b/up-core.el index e66d9510b1e..1476f756889 100644 --- a/up-core.el +++ b/up-core.el @@ -104,7 +104,8 @@ If you customize this, then you should require the `use-package' feature in files that use `use-package', even if these files only contain compiled expansions of the macros. If you don't do so, then the expanded macros do their job silently." - :type '(choice (const :tag "Quiet" nil) + :type '(choice (const :tag "Quiet, without catching errors" errors) + (const :tag "Quiet" nil) (const :tag "Verbose" t) (const :tag "Debug" debug)) :group 'use-package) From 28084551ac66814cd602aa31a9a0bade8dbd2d61 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 23:05:43 -0800 Subject: [PATCH 371/606] Normalize the code emitted by :mode, :interpreter, :magic, etc --- up-core.el | 71 +++++++++++++++++++++++++++-------------------------- up-tests.el | 43 +++++++++++++++++++------------- 2 files changed, 62 insertions(+), 52 deletions(-) diff --git a/up-core.el b/up-core.el index 1476f756889..f4d9d0b3a81 100644 --- a/up-core.el +++ b/up-core.el @@ -973,21 +973,20 @@ deferred until the prefix key sequence is pressed." (defun use-package-handler/:bind-keymap (name keyword arg rest state &optional override) - (let ((form - (mapcar - #'(lambda (binding) - `(,(if override - 'bind-key* - 'bind-key) - ,(car binding) - #'(lambda () - (interactive) - (use-package-autoload-keymap - ',(cdr binding) ',(use-package-as-symbol name) - ,override)))) arg))) - (use-package-concat - (use-package-process-keywords name rest state) - `((ignore ,@form))))) + (use-package-concat + (use-package-process-keywords name rest state) + `((ignore + ,@(mapcar + #'(lambda (binding) + `(,(if override + 'bind-key* + 'bind-key) + ,(car binding) + #'(lambda () + (interactive) + (use-package-autoload-keymap + ',(cdr binding) ',(use-package-as-symbol name) + ,override)))) arg))))) (defun use-package-handler/:bind-keymap* (name keyword arg rest state) (use-package-handler/:bind-keymap name keyword arg rest state t)) @@ -999,17 +998,18 @@ deferred until the prefix key sequence is pressed." (cl-destructuring-bind (nargs . commands) (use-package-normalize-commands args) (use-package-concat - (mapcar - #'(lambda (thing) - `(add-to-list - ',alist - ',(cons (use-package-normalize-regex (car thing)) - (cdr thing)))) - nargs) (use-package-process-keywords name (use-package-sort-keywords (use-package-plist-append rest :commands commands)) - state)))) + state) + `((ignore + ,@(mapcar + #'(lambda (thing) + `(add-to-list + ',alist + ',(cons (use-package-normalize-regex (car thing)) + (cdr thing)))) + nargs)))))) (defalias 'use-package-normalize/:interpreter 'use-package-normalize-mode) @@ -1064,21 +1064,22 @@ deferred until the prefix key sequence is pressed." (cl-destructuring-bind (nargs . commands) (use-package-normalize-commands args) (use-package-concat - (cl-mapcan - #'(lambda (def) - (let ((syms (car def)) - (fun (cdr def))) - (when fun - (mapcar - #'(lambda (sym) - `(add-hook (quote ,(intern (format "%s-hook" sym))) - (function ,fun))) - (if (use-package-non-nil-symbolp syms) (list syms) syms))))) - nargs) (use-package-process-keywords name (use-package-sort-keywords (use-package-plist-append rest :commands commands)) - state)))) + state) + `((ignore + ,@(cl-mapcan + #'(lambda (def) + (let ((syms (car def)) + (fun (cdr def))) + (when fun + (mapcar + #'(lambda (sym) + `(add-hook (quote ,(intern (format "%s-hook" sym))) + (function ,fun))) + (if (use-package-non-nil-symbolp syms) (list syms) syms))))) + nargs)))))) ;;;; :commands diff --git a/up-tests.el b/up-tests.el index 7f0dfe3dd73..8de058c4512 100644 --- a/up-tests.el +++ b/up-tests.el @@ -546,17 +546,19 @@ (match-expansion (use-package foo :interpreter "interp") `(progn - (add-to-list 'interpreter-mode-alist '("interp" . foo)) (unless (fboundp 'foo) - (autoload #'foo "foo" nil t))))) + (autoload #'foo "foo" nil t)) + (ignore + (add-to-list 'interpreter-mode-alist '("interp" . foo)))))) (ert-deftest use-package-test/:interpreter-2 () (match-expansion (use-package foo :interpreter ("interp" . fun)) `(progn - (add-to-list 'interpreter-mode-alist '("interp" . fun)) (unless (fboundp 'fun) - (autoload #'fun "foo" nil t))))) + (autoload #'fun "foo" nil t)) + (ignore + (add-to-list 'interpreter-mode-alist '("interp" . fun)))))) (ert-deftest use-package-test-normalize/:mode () (flet ((norm (&rest args) @@ -577,49 +579,55 @@ (match-expansion (use-package foo :mode "interp") `(progn - (add-to-list 'auto-mode-alist '("interp" . foo)) (unless (fboundp 'foo) - (autoload #'foo "foo" nil t))))) + (autoload #'foo "foo" nil t)) + (ignore + (add-to-list 'auto-mode-alist '("interp" . foo)))))) (ert-deftest use-package-test/:mode-2 () (match-expansion (use-package foo :mode ("interp" . fun)) `(progn - (add-to-list 'auto-mode-alist '("interp" . fun)) (unless (fboundp 'fun) - (autoload #'fun "foo" nil t))))) + (autoload #'fun "foo" nil t)) + (ignore + (add-to-list 'auto-mode-alist '("interp" . fun)))))) (ert-deftest use-package-test/:magic-1 () (match-expansion (use-package foo :magic "interp") `(progn - (add-to-list 'magic-mode-alist '("interp" . foo)) (unless (fboundp 'foo) - (autoload #'foo "foo" nil t))))) + (autoload #'foo "foo" nil t)) + (ignore + (add-to-list 'magic-mode-alist '("interp" . foo)))))) (ert-deftest use-package-test/:magic-2 () (match-expansion (use-package foo :magic ("interp" . fun)) `(progn - (add-to-list 'magic-mode-alist '("interp" . fun)) (unless (fboundp 'fun) - (autoload #'fun "foo" nil t))))) + (autoload #'fun "foo" nil t)) + (ignore + (add-to-list 'magic-mode-alist '("interp" . fun)))))) (ert-deftest use-package-test/:magic-fallback-1 () (match-expansion (use-package foo :magic-fallback "interp") `(progn - (add-to-list 'magic-fallback-mode-alist '("interp" . foo)) (unless (fboundp 'foo) - (autoload #'foo "foo" nil t))))) + (autoload #'foo "foo" nil t)) + (ignore + (add-to-list 'magic-fallback-mode-alist '("interp" . foo)))))) (ert-deftest use-package-test/:magic-fallback-2 () (match-expansion (use-package foo :magic-fallback ("interp" . fun)) `(progn - (add-to-list 'magic-fallback-mode-alist '("interp" . fun)) (unless (fboundp 'fun) - (autoload #'fun "foo" nil t))))) + (autoload #'fun "foo" nil t)) + (ignore + (add-to-list 'magic-fallback-mode-alist '("interp" . fun)))))) (ert-deftest use-package-test/:commands-1 () (match-expansion @@ -785,7 +793,6 @@ (with-demoted-errors "Cannot load foo: %S" nil (load "foo" nil t)))) - (add-hook 'hook-hook #'fun) (unless (fboundp 'fun) (autoload #'fun "foo" nil t)) (eval-when-compile @@ -794,6 +801,8 @@ (autoload #'key "foo" nil t)) (eval-when-compile (declare-function key "foo")) + (ignore + (add-hook 'hook-hook #'fun)) (ignore (bind-keys :package foo ("C-a" . key)))))))) From a1bdd958d3b23d147d610716f427175114223e85 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 23:06:14 -0800 Subject: [PATCH 372/606] Reduce some code duplication --- up-core.el | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/up-core.el b/up-core.el index f4d9d0b3a81..652fecff8f5 100644 --- a/up-core.el +++ b/up-core.el @@ -1332,14 +1332,14 @@ no keyword implies `:all'." (error (,context err))))) (defun use-package-core (name args) - (let ((context (gensym "use-package--warning")) - (args* (use-package-normalize-keywords name args)) - (use-package--hush-function #'identity)) + (let* ((context (gensym "use-package--warning")) + (args* (use-package-normalize-keywords name args)) + (use-package--hush-function #'identity) + (process `(use-package-process-keywords ',name ',args* + ',(and (plist-get args* :demand) + (list :demand t))))) (if use-package-expand-minimally - (funcall use-package--hush-function - (use-package-process-keywords name args* - (and (plist-get args* :demand) - (list :demand t)))) + (eval process) `((cl-flet ((,context (err) @@ -1362,18 +1362,14 @@ no keyword implies `:all'." (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)))))))) + (eval process)))))) (emacs-lisp-mode)))) (ignore (display-warning 'use-package msg :error))))) ,(let ((use-package--hush-function (apply-partially #'use-package-hush context))) (macroexp-progn (funcall use-package--hush-function - (use-package-process-keywords name args* - (and (plist-get args* :demand) - (list :demand t))))))))))) + (eval process))))))))) ;;;###autoload (defmacro use-package (name &rest args) @@ -1439,9 +1435,10 @@ this file. Usage: (use-package-core name args) (error (ignore - (let ((msg (format "Failed to parse package %s: %s" - name (error-message-string err)))) - (display-warning 'use-package msg :error))))))))) + (display-warning + 'use-package + (format "Failed to parse package %s: %s" + name (error-message-string err)) :error)))))))) (put 'use-package 'lisp-indent-function 'defun) From 62f866caf79341e71faba681002d411791fdc4c2 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 23:06:54 -0800 Subject: [PATCH 373/606] Delete an unneeded blank line --- up-core.el | 1 - 1 file changed, 1 deletion(-) diff --git a/up-core.el b/up-core.el index 652fecff8f5..06711c1fc31 100644 --- a/up-core.el +++ b/up-core.el @@ -99,7 +99,6 @@ declaration is incorrect." (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, From 8bf5de28c3c1061f9459de42ec8b04d9702382ae Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 23:22:25 -0800 Subject: [PATCH 374/606] Correction to a macro expansion --- up-core.el | 64 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/up-core.el b/up-core.el index 06711c1fc31..de88482d204 100644 --- a/up-core.el +++ b/up-core.el @@ -1328,47 +1328,49 @@ no keyword implies `:all'." (defsubst use-package-hush (context body) `((condition-case-unless-debug err ,(macroexp-progn body) - (error (,context err))))) + (error (funcall ,context err))))) (defun use-package-core (name args) (let* ((context (gensym "use-package--warning")) (args* (use-package-normalize-keywords name args)) - (use-package--hush-function #'identity) - (process `(use-package-process-keywords ',name ',args* - ',(and (plist-get args* :demand) - (list :demand t))))) + (use-package--hush-function #'identity)) (if use-package-expand-minimally - (eval process) - `((cl-flet + (use-package-process-keywords name args* + (and (plist-get args* :demand) + (list :demand t))) + `((let ((,context - (err) - (let ((msg (format "%s: %s" ',name - (error-message-string err)))) - ,(when (eq use-package-verbose 'debug) - `(progn - (setq msg (concat msg " (see the *use-package* buffer)")) - (with-current-buffer (get-buffer-create "*use-package*") - (goto-char (point-max)) - (insert - "-----\n" msg - ,(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)) - (eval process)))))) - (emacs-lisp-mode)))) - (ignore (display-warning 'use-package msg :error))))) + #'(lambda (err) + (let ((msg (format "%s: %s" ',name (error-message-string err)))) + ,(when (eq use-package-verbose 'debug) + `(progn + (with-current-buffer (get-buffer-create "*use-package*") + (goto-char (point-max)) + (insert + "-----\n" msg + ,(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)))))))) + (emacs-lisp-mode)) + (setq msg (concat msg " (see the *use-package* buffer)")))) + (ignore (display-warning 'use-package msg :error)))))) ,(let ((use-package--hush-function (apply-partially #'use-package-hush context))) (macroexp-progn (funcall use-package--hush-function - (eval process))))))))) + (use-package-process-keywords name args* + (and (plist-get args* :demand) + (list :demand t))))))))))) ;;;###autoload (defmacro use-package (name &rest args) From bd2589e4bea47e3ca94cfa5938f632bfa21bdb2c Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 23:33:22 -0800 Subject: [PATCH 375/606] Add notes to NEWS.md --- etc/USE-PACKAGE-NEWS | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index eeaf91bdb0a..805272f43e1 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -12,7 +12,7 @@ ``` elisp (use-package diminish :ensure t) ``` - + - Emacs 24.3 or higher is now a requirement. - The `:defer-install` keyword has been remove. It may reappear as an add-on @@ -28,6 +28,14 @@ - Upgrade license to GPL 3. +- If `use-package-verbose` is set to the symbol `debug`, any evaluation errors + during package configuration will cause a complete report to be written to a + `*use-package*` buffer, including: the text of the error, the `use-package` + declaration that caused the error, the post-normalized form of this + declaration, and the macro-expanded version (without verbosity-related + code). Note that this still does not help if there are parsing errors, which + will still cause Emacs to encounter a Lisp error at startup time. + - New `:hook` keyword. - New keywords `:custom (foo1 bar1) (foo2 bar2)` etc., and `:custom-face`. @@ -58,6 +66,12 @@ - Documentation added for the `:after`, `:defer-install`, `:delight`, `:requires`, `:when` and `:unless` keywords. +- New undocumented (and currently experimental) keyword `:load` may be used to + change the name of the actual package loaded, rather than the package name, + and may even add other names. For example: `(use-package auctex :load + tex-site)`. This keyword is used internally to generate the `require` for a + package, so that deferral is simply a matter of not generating this keyword. + - The source code is now broken into several files, so that certain optional features (diminish, delight, ensure) may be maintained separately from the core functionality. @@ -69,4 +83,3 @@ - Append to *use-package* when debugging, don't clear it. - Don't allow :commands, :bind, etc., to be given an empty list. - Explicit :defer t should override use-package-always-demand. - From f4f3e01044b6ed3aa55bc6bce19abbd72b8b35b6 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 23:33:28 -0800 Subject: [PATCH 376/606] Remove code from up-core.el that is now in up-diminish.el --- up-core.el | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/up-core.el b/up-core.el index de88482d204..e760443fef5 100644 --- a/up-core.el +++ b/up-core.el @@ -1282,44 +1282,6 @@ no keyword implies `:all'." body (list t))))))) -;;;; :diminish - -(defun use-package-normalize-diminish (name label arg &optional recursed) - "Normalize the arguments to diminish down to a list of one of two forms: - SYMBOL - (SYMBOL . STRING)" - (cond - ((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"))))) - -(defun use-package-normalize/:diminish (name keyword args) - (use-package-as-one (symbol-name keyword) args - (apply-partially #'use-package-normalize-diminish name) t)) - -(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))) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; The main macro From 49752db41b3bf5685324d78cd2457bfe9ad83231 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 23:36:52 -0800 Subject: [PATCH 377/606] up-ensure's customization variables are now in their own group --- up-ensure.el | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/up-ensure.el b/up-ensure.el index 2e3d4ec4116..fa19e1d5a8e 100644 --- a/up-ensure.el +++ b/up-ensure.el @@ -35,6 +35,10 @@ (require 'up-core) +(defgroup use-package-ensure nil + "Support for :ensure and :pin keywords in use-package declarations." + :group 'use-package) + (eval-when-compile (declare-function package-installed-p "package") (declare-function package-read-all-archive-contents "package" ())) @@ -43,13 +47,13 @@ "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) + :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) + :group 'use-package-ensure) (defcustom use-package-ensure-function 'use-package-ensure-elpa "Function that ensures a package is installed. @@ -67,7 +71,7 @@ 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) + :group 'use-package-ensure) ;;;; :pin From 6d51e52342e625188b3de21645332e26916a90e2 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Dec 2017 23:37:03 -0800 Subject: [PATCH 378/606] Minor comment change --- up-core.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/up-core.el b/up-core.el index e760443fef5..a00f2bf6ab2 100644 --- a/up-core.el +++ b/up-core.el @@ -585,7 +585,7 @@ next value for the STATE." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;;; Arguments +;;; Argument Processing ;; (defun use-package-only-one (label args f) From 0be575766c51b8b63febde70262895c439b54089 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 00:11:46 -0800 Subject: [PATCH 379/606] Add new customization variable `use-package-deferring-keywords' --- etc/USE-PACKAGE-NEWS | 4 ++++ up-core.el | 28 ++++++++++++++++++---------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index 805272f43e1..4e1a6e949e6 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -35,6 +35,10 @@ declaration, and the macro-expanded version (without verbosity-related code). Note that this still does not help if there are parsing errors, which will still cause Emacs to encounter a Lisp error at startup time. + +- New customization variable `use-package-deferring-keywords`, mainly intended + for use by extension packages, indicates keywords that, if used without + `:demand`, cause deferred loading (as if `:defer t` had been specified). - New `:hook` keyword. diff --git a/up-core.el b/up-core.el index a00f2bf6ab2..6e9daadb211 100644 --- a/up-core.el +++ b/up-core.el @@ -97,6 +97,21 @@ declaration is incorrect." :type '(repeat symbol) :group 'use-package) +(defcustom use-package-deferring-keywords + '(:bind + :bind* + :bind-keymap + :bind-keymap* + :interpreter + :mode + :magic + :magic-fallback + :commands + :hook) + "Unless `:demand' is used, keywords in this list imply deferred loading." + :type '(repeat symbol) + :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' @@ -499,16 +514,9 @@ This is in contrast to merely setting it to 0." ;; Certain keywords imply :defer, if :demand was not specified. (when (and (not (plist-member args :demand)) (not (plist-member args :defer)) - (or (plist-member args :bind) - (plist-member args :bind*) - (plist-member args :bind-keymap) - (plist-member args :bind-keymap*) - (plist-member args :interpreter) - (plist-member args :mode) - (plist-member args :magic) - (plist-member args :magic-fallback) - (plist-member args :commands) - (plist-member args :hook))) + (cl-some #'identity + (mapcar (apply-partially #'plist-member args) + use-package-deferring-keywords))) (setq args (append args '(:defer t)))) (when (and (plist-member args :load) From 20ea11b71a6fefdb53d253fcb1b2fc6d9fbeb2ac Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 00:41:05 -0800 Subject: [PATCH 380/606] Add further notes to NEWS.md, in light of recent breakages --- etc/USE-PACKAGE-NEWS | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index 4e1a6e949e6..de9de0e977d 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -15,15 +15,25 @@ - Emacs 24.3 or higher is now a requirement. -- The `:defer-install` keyword has been remove. It may reappear as an add-on +- The `:defer-install` keyword has been removed. It may reappear as an add-on module for use-package in a future release. See issue #442 for more details. -- The ordering of several elements of `use-package-keywords' have changed; if - you have this customized you will need to rework your changes. - - There is no longer a `use-package-debug` option, since `use-package-verbose` already has the possible value of `debug`. +- The ordering of several elements of `use-package-keywords` have changed; if + you had previously customized this (or were an extension author adding to + this list), you may need to rework your changes. + +- For extension authors, the way `:commands` are propagated down for + autoloading has changed. They used to be passed through the `state` + parameter, but are now done as an extension to `rest`. Please see + `use-package-handler/:bind` for a canonical example. + +- For extension authors, if you add a keyword to `use-package-keywords` whose + presence should indicate deferred loading, please also add it to + `use-package-deferring-keywords`. + ### Other changes - Upgrade license to GPL 3. @@ -34,8 +44,8 @@ declaration that caused the error, the post-normalized form of this declaration, and the macro-expanded version (without verbosity-related code). Note that this still does not help if there are parsing errors, which - will still cause Emacs to encounter a Lisp error at startup time. - + cause Emacs to register a Lisp error at startup time. + - New customization variable `use-package-deferring-keywords`, mainly intended for use by extension packages, indicates keywords that, if used without `:demand`, cause deferred loading (as if `:defer t` had been specified). From 05dfea96e5834bf8715e2e6f001502405c7cf14f Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 00:54:14 -0800 Subject: [PATCH 381/606] Change order of :defines and :functions within `use-package-keywords' --- up-core.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/up-core.el b/up-core.el index 6e9daadb211..d809970cdb7 100644 --- a/up-core.el +++ b/up-core.el @@ -60,7 +60,9 @@ :requires :load-path :no-require - :preface :defines :functions + :defines + :functions + :preface :after :custom :custom-face From 5d9c854a6cf12fff2326ee5653e87e2d3d550a8d Mon Sep 17 00:00:00 2001 From: Justin Talbott Date: Mon, 4 Dec 2017 10:57:23 -0500 Subject: [PATCH 382/606] Add `use-package-chords` and `use-package-ensure-system-package` Also update docs on usage connect to https://github.com/jwiegley/use-package/issues/516 --- lisp/use-package/bind-chord.el | 61 ++++++++++++++++ lisp/use-package/use-package-chords.el | 48 +++++++++++++ .../use-package-ensure-system-package.el | 70 +++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 lisp/use-package/bind-chord.el create mode 100644 lisp/use-package/use-package-chords.el create mode 100644 lisp/use-package/use-package-ensure-system-package.el diff --git a/lisp/use-package/bind-chord.el b/lisp/use-package/bind-chord.el new file mode 100644 index 00000000000..e0827a4230f --- /dev/null +++ b/lisp/use-package/bind-chord.el @@ -0,0 +1,61 @@ +;;; bind-chord.el --- key-chord binding helper for use-package-chords + +;; Copyright (C) 2015-2017 Justin Talbott + +;; Author: Justin Talbott +;; Keywords: convenience, tools, extensions +;; URL: https://github.com/waymondo/use-package-chords +;; Version: 0.2 +;; 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) + +;;;###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))))) + +;;;###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)." + (let* ((map (plist-get args :map)) + (maps (if (listp map) map (list map))) + (key-bindings (progn + (while (keywordp (car args)) + (pop args) + (pop args)) + args))) + (macroexp-progn + (apply + #'nconc + (mapcar (lambda (form) + (if maps + (mapcar + #'(lambda (m) + `(bind-chord ,(car form) ',(cdr form) ,m)) maps) + `((bind-chord ,(car form) ',(cdr form))))) + key-bindings))))) + +(provide 'bind-chord) +;;; bind-chord.el ends here diff --git a/lisp/use-package/use-package-chords.el b/lisp/use-package/use-package-chords.el new file mode 100644 index 00000000000..f3e85b4149a --- /dev/null +++ b/lisp/use-package/use-package-chords.el @@ -0,0 +1,48 @@ +;;; use-package-chords.el --- key-chord keyword for use-package + +;; Copyright (C) 2015-2017 Justin Talbott + +;; Author: Justin Talbott +;; Keywords: convenience, tools, extensions +;; URL: https://github.com/waymondo/use-package-chords +;; Version: 0.2 +;; Package-Requires: ((use-package "2.1") (bind-key "1.0") (bind-chord "0.2") (key-chord "0.6")) +;; Filename: use-package-chords.el +;; License: GNU General Public License version 3, or (at your option) any later version +;; + +;;; Commentary: +;; +;; The `:chords' keyword allows you to define `key-chord' bindings for +;; `use-package' declarations in the same manner as the `:bind' +;; keyword. +;; + +;;; Code: + +(require 'use-package) +(require 'bind-chord) + +(add-to-list 'use-package-keywords :chords t) + +(defalias 'use-package-normalize/:chords 'use-package-normalize-binder) + +(defun use-package-handler/:chords (name keyword arg rest state) + "Handler for `:chords' keyword in `use-package'." + (let* ((commands (remq nil (mapcar #'(lambda (arg) + (if (listp arg) + (cdr arg) + nil)) arg))) + (chord-binder + (use-package-concat + (use-package-process-keywords name + (use-package-sort-keywords + (use-package-plist-maybe-put rest :defer t)) + (use-package-plist-append state :commands commands)) + `((ignore + ,(macroexpand + `(bind-chords :package ,name ,@arg))))))) + (use-package-handler/:preface name keyword chord-binder rest state))) + +(provide 'use-package-chords) +;;; use-package-chords.el ends here diff --git a/lisp/use-package/use-package-ensure-system-package.el b/lisp/use-package/use-package-ensure-system-package.el new file mode 100644 index 00000000000..e34bb16d738 --- /dev/null +++ b/lisp/use-package/use-package-ensure-system-package.el @@ -0,0 +1,70 @@ +;;; use-package-ensure-system-package.el --- auto install system packages + +;; Copyright (C) 2017 Justin Talbott + +;; Author: Justin Talbott +;; Keywords: convenience, tools, extensions +;; URL: https://github.com/waymondo/use-package-ensure-system-package +;; Version: 0.1 +;; Package-Requires: ((use-package "2.1") (system-packages "0.1")) +;; Filename: use-package-ensure-system-package.el +;; License: GNU General Public License version 3, or (at your option) any later version +;; + +;;; Commentary: +;; +;; The `:ensure-system-package` keyword allows you to ensure system +;; binaries exist alongside your `use-package` declarations. +;; + +;;; Code: + +(require 'use-package) +(require 'system-packages) + +(add-to-list 'use-package-keywords :ensure-system-package t) + +(defun use-package-ensure-system-package-install-command (pack) + "Return the default install command for `pack'." + (let ((command + (cdr (assoc 'install (cdr (assoc system-packages-packagemanager + system-packages-supported-package-managers)))))) + (unless command + (error (format "%S not supported in %S" 'install system-packages-packagemanager))) + (unless (listp command) + (setq command (list command))) + (when system-packages-usesudo + (setq command (mapcar (lambda (part) (concat "sudo " part)) command))) + (setq command (mapconcat 'identity command " && ")) + (mapconcat 'identity (list command pack) " "))) + +(defun use-package-ensure-system-package-consify (arg) + "Turn `arg' into a cons of (`package-name' . `install-command')." + (cond + ((stringp arg) + (cons arg (use-package-ensure-system-package-install-command arg))) + ((symbolp arg) + (cons arg (use-package-ensure-system-package-install-command (symbol-name arg)))) + ((consp arg) arg))) + +(defun use-package-normalize/:ensure-system-package (name-symbol keyword args) + "Turn `arg' into a list of cons-es of (`package-name' . `install-command')." + (use-package-only-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-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 (executable-find (symbol-name ',(car cons))) + (async-shell-command ,(cdr cons)))) arg) + body))) + +(provide 'use-package-ensure-system-package) +;;; use-package-ensure-system-package.el ends here From 5d973a01882cbf252fb4f8f7e4b7412ae02213dc Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 09:03:13 -0800 Subject: [PATCH 383/606] Move :init back to happening after all autoloads have occurred Fixes https://github.com/jwiegley/use-package/issues/535 --- up-core.el | 2 +- up-tests.el | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/up-core.el b/up-core.el index d809970cdb7..b78c619c003 100644 --- a/up-core.el +++ b/up-core.el @@ -66,7 +66,6 @@ :after :custom :custom-face - :init :bind :bind* :bind-keymap @@ -79,6 +78,7 @@ ;; Any other keyword that also declares commands to be autoloaded (such as ;; :bind) must appear before this keyword. :commands + :init :defer :demand :load diff --git a/up-tests.el b/up-tests.el index 8de058c4512..33b43654313 100644 --- a/up-tests.el +++ b/up-tests.el @@ -662,6 +662,15 @@ (eval-when-compile (declare-function quux "foo")))))) +(ert-deftest use-package-test/:commands-4 () + (match-expansion + (use-package foo :commands bar :init (bar)) + `(progn + (unless + (fboundp 'bar) + (autoload #'bar "foo" nil t)) + (bar)))) + (ert-deftest use-package-test/:defines-1 () (match-expansion (use-package foo :defines bar) From 0239ee227a5d40a13430843f61eea4f57afc2c7e Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 09:03:13 -0800 Subject: [PATCH 384/606] Move :init back to happening after all autoloads have occurred Fixes https://github.com/jwiegley/use-package/issues/535 --- up-core.el | 2 +- up-tests.el | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/up-core.el b/up-core.el index d809970cdb7..b78c619c003 100644 --- a/up-core.el +++ b/up-core.el @@ -66,7 +66,6 @@ :after :custom :custom-face - :init :bind :bind* :bind-keymap @@ -79,6 +78,7 @@ ;; Any other keyword that also declares commands to be autoloaded (such as ;; :bind) must appear before this keyword. :commands + :init :defer :demand :load diff --git a/up-tests.el b/up-tests.el index 8de058c4512..33b43654313 100644 --- a/up-tests.el +++ b/up-tests.el @@ -662,6 +662,15 @@ (eval-when-compile (declare-function quux "foo")))))) +(ert-deftest use-package-test/:commands-4 () + (match-expansion + (use-package foo :commands bar :init (bar)) + `(progn + (unless + (fboundp 'bar) + (autoload #'bar "foo" nil t)) + (bar)))) + (ert-deftest use-package-test/:defines-1 () (match-expansion (use-package foo :defines bar) From ac906479a782c5eedd2662fe4f65aa3ac6d3489c Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 09:31:13 -0800 Subject: [PATCH 385/606] Normalize some whitespace and ordering in new code --- lisp/use-package/bind-chord.el | 1 + lisp/use-package/use-package-chords.el | 5 +++-- lisp/use-package/use-package-ensure-system-package.el | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/bind-chord.el b/lisp/use-package/bind-chord.el index e0827a4230f..35634b174a3 100644 --- a/lisp/use-package/bind-chord.el +++ b/lisp/use-package/bind-chord.el @@ -58,4 +58,5 @@ function symbol (unquoted)." key-bindings))))) (provide 'bind-chord) + ;;; bind-chord.el ends here diff --git a/lisp/use-package/use-package-chords.el b/lisp/use-package/use-package-chords.el index f3e85b4149a..023a9c6b2ad 100644 --- a/lisp/use-package/use-package-chords.el +++ b/lisp/use-package/use-package-chords.el @@ -23,8 +23,6 @@ (require 'use-package) (require 'bind-chord) -(add-to-list 'use-package-keywords :chords t) - (defalias 'use-package-normalize/:chords 'use-package-normalize-binder) (defun use-package-handler/:chords (name keyword arg rest state) @@ -44,5 +42,8 @@ `(bind-chords :package ,name ,@arg))))))) (use-package-handler/:preface name keyword chord-binder rest state))) +(add-to-list 'use-package-keywords :chords t) + (provide 'use-package-chords) + ;;; use-package-chords.el ends here diff --git a/lisp/use-package/use-package-ensure-system-package.el b/lisp/use-package/use-package-ensure-system-package.el index e34bb16d738..b8fd19d830b 100644 --- a/lisp/use-package/use-package-ensure-system-package.el +++ b/lisp/use-package/use-package-ensure-system-package.el @@ -22,8 +22,6 @@ (require 'use-package) (require 'system-packages) -(add-to-list 'use-package-keywords :ensure-system-package t) - (defun use-package-ensure-system-package-install-command (pack) "Return the default install command for `pack'." (let ((command @@ -66,5 +64,8 @@ (async-shell-command ,(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 From 1e560c514004747062276ca59ddf425a3edc44cd Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 09:33:10 -0800 Subject: [PATCH 386/606] Reduce some code duplication --- up-core.el | 26 +++++++++++++------------- up-ensure.el | 35 +++++++++++++---------------------- 2 files changed, 26 insertions(+), 35 deletions(-) diff --git a/up-core.el b/up-core.el index b78c619c003..73884196e7f 100644 --- a/up-core.el +++ b/up-core.el @@ -273,6 +273,16 @@ Must be set before loading use-package." "Report MSG as an error, so the user knows it came from this package." (error "use-package: %s" msg)) +(defun use-package-hush (f body) + (condition-case-unless-debug err + (macroexp-progn body) + (error + (if (stringp f) + (ignore (display-warning 'use-package + (format f (error-message-string err)) + :error)) + (funcall f err))))) + (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)))) @@ -1297,11 +1307,6 @@ no keyword implies `:all'." ;;; The main macro ;; -(defsubst use-package-hush (context body) - `((condition-case-unless-debug err - ,(macroexp-progn body) - (error (funcall ,context err))))) - (defun use-package-core (name args) (let* ((context (gensym "use-package--warning")) (args* (use-package-normalize-keywords name args)) @@ -1404,14 +1409,9 @@ this file. Usage: (macroexp-progn (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)))))))) + (use-package-hush + (format "Failed to parse package %s: %%s" name) + '((use-package-core name args))))))) (put 'use-package 'lisp-indent-function 'defun) diff --git a/up-ensure.el b/up-ensure.el index fa19e1d5a8e..cd6a8533992 100644 --- a/up-ensure.el +++ b/up-ensure.el @@ -143,31 +143,22 @@ manually updated package." "(an unquoted symbol name)"))))))) (defun use-package-ensure-elpa (name ensure state &optional no-refresh) - (let ((package - (or (and (eq ensure t) (use-package-as-symbol name)) - ensure))) + (let ((package (or (and (eq ensure t) (use-package-as-symbol name)) + ensure))) (when package (require '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 - (ignore - (display-warning 'use-package - (format "Failed to install %s: %s" - name (error-message-string err)) - :error)))))))) + (use-package-hush + (format "Failed to install %s: %%s" name) + '((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)))))) (defun use-package-handler/:ensure (name keyword ensure rest state) (let* ((body (use-package-process-keywords name rest state))) From 4efd35510871047b438241788be77c089ac78945 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 09:33:18 -0800 Subject: [PATCH 387/606] Add two new tests --- up-tests.el | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/up-tests.el b/up-tests.el index 33b43654313..063db98bbea 100644 --- a/up-tests.el +++ b/up-tests.el @@ -1219,6 +1219,38 @@ (if (fboundp 'delight) (delight '((foo "bar" foo))))))) +(ert-deftest use-package-test/538 () + (match-expansion + (use-package mu4e + :commands (mu4e) + :bind (("" . mu4e)) + :init + :config + (config)) + `(progn + (unless + (fboundp 'mu4e) + (autoload #'mu4e "mu4e" nil t)) + (eval-after-load 'mu4e + '(progn + (config) + t)) + (ignore + (bind-keys :package mu4e + ("" . mu4e)))))) + +(ert-deftest use-package-test/539 () + (match-expansion + (use-package foo + :requires bar + :after quux + :ensure bow) + `(progn + (use-package-ensure-elpa 'foo 'bow 'nil) + (when (featurep 'bar) + (eval-after-load 'quux + '(require 'foo nil nil)))))) + ;; Local Variables: ;; indent-tabs-mode: nil ;; no-byte-compile: t From fb9d1596326cf2d1c4472eabb36f50d40ca37cfb Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 09:39:54 -0800 Subject: [PATCH 388/606] Move :preface handling within the code --- up-core.el | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/up-core.el b/up-core.el index 73884196e7f..6994c632ec0 100644 --- a/up-core.el +++ b/up-core.el @@ -939,17 +939,6 @@ deferred until the prefix key sequence is pressed." (defun use-package-handler/:no-require (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 arg - `((eval-and-compile ,@arg))) - body))) - ;;;; :defines (defalias 'use-package-normalize/:defines 'use-package-normalize-symlist) @@ -964,6 +953,17 @@ deferred until the prefix key sequence is pressed." (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 arg + `((eval-and-compile ,@arg))) + body))) + ;;;; :bind, :bind* (defalias 'use-package-normalize/:bind 'use-package-normalize-binder) From 026433a8a03133b76f1d9db9d9a7b250a5d28a13 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 10:29:27 -0800 Subject: [PATCH 389/606] Revert "Reduce some code duplication" This reverts commit 1e560c514004747062276ca59ddf425a3edc44cd. --- up-core.el | 26 +++++++++++++------------- up-ensure.el | 35 ++++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/up-core.el b/up-core.el index 6994c632ec0..6fc8ae5a7ef 100644 --- a/up-core.el +++ b/up-core.el @@ -273,16 +273,6 @@ Must be set before loading use-package." "Report MSG as an error, so the user knows it came from this package." (error "use-package: %s" msg)) -(defun use-package-hush (f body) - (condition-case-unless-debug err - (macroexp-progn body) - (error - (if (stringp f) - (ignore (display-warning 'use-package - (format f (error-message-string err)) - :error)) - (funcall f err))))) - (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)))) @@ -1307,6 +1297,11 @@ no keyword implies `:all'." ;;; The main macro ;; +(defsubst use-package-hush (context body) + `((condition-case-unless-debug err + ,(macroexp-progn body) + (error (funcall ,context err))))) + (defun use-package-core (name args) (let* ((context (gensym "use-package--warning")) (args* (use-package-normalize-keywords name args)) @@ -1409,9 +1404,14 @@ this file. Usage: (macroexp-progn (if (eq use-package-verbose 'errors) (use-package-core name args) - (use-package-hush - (format "Failed to parse package %s: %%s" name) - '((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)))))))) (put 'use-package 'lisp-indent-function 'defun) diff --git a/up-ensure.el b/up-ensure.el index cd6a8533992..fa19e1d5a8e 100644 --- a/up-ensure.el +++ b/up-ensure.el @@ -143,22 +143,31 @@ manually updated package." "(an unquoted symbol name)"))))))) (defun use-package-ensure-elpa (name ensure state &optional no-refresh) - (let ((package (or (and (eq ensure t) (use-package-as-symbol name)) - ensure))) + (let ((package + (or (and (eq ensure t) (use-package-as-symbol name)) + ensure))) (when package (require 'package) (unless (package-installed-p package) - (use-package-hush - (format "Failed to install %s: %%s" name) - '((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)))))) + (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 + (ignore + (display-warning 'use-package + (format "Failed to install %s: %s" + name (error-message-string err)) + :error)))))))) (defun use-package-handler/:ensure (name keyword ensure rest state) (let* ((body (use-package-process-keywords name rest state))) From 4042b87c720f68d213eb4933c010820de99834d2 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 10:30:49 -0800 Subject: [PATCH 390/606] Add expand-maximally macro to up-tests.el --- up-tests.el | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/up-tests.el b/up-tests.el index 063db98bbea..2635c7df757 100644 --- a/up-tests.el +++ b/up-tests.el @@ -61,6 +61,11 @@ (use-package-expand-minimally t)) (macroexpand-1 ',form))) +(defmacro expand-maximally (form) + `(let ((use-package-verbose 'debug) + (use-package-expand-minimally nil)) + (macroexpand-1 ',form))) + (defmacro match-expansion (form &rest value) `(should (pcase (expand-minimally ,form) ,@(mapcar #'(lambda (x) (list x t)) value)))) From 8489206db4abe4edd2de6b54b09961d99111dba6 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 10:41:17 -0800 Subject: [PATCH 391/606] Fix duplication in an error message --- up-core.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/up-core.el b/up-core.el index 6fc8ae5a7ef..aa677e1ad80 100644 --- a/up-core.el +++ b/up-core.el @@ -851,7 +851,7 @@ deferred until the prefix key sequence is pressed." (setq unread-command-events (listify-key-sequence kv))) (use-package-error - (format "use-package: package.el %s failed to define keymap %s" + (format "package.el %s failed to define keymap %s" package keymap-symbol))))) (defun use-package-normalize-mode (name keyword args) From fe85f246b0cd22ec3d8915d47ec6798958cbeefd Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 11:00:05 -0800 Subject: [PATCH 392/606] Add a new :catch keyword, and move :preface before such handling Fixes https://github.com/jwiegley/use-package/issues/534 --- etc/USE-PACKAGE-NEWS | 6 +++ up-core.el | 121 +++++++++++++++++++++++++------------------ up-tests.el | 29 +++++++++++ 3 files changed, 107 insertions(+), 49 deletions(-) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index de9de0e977d..b5b5adc0be0 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -52,6 +52,12 @@ - New `:hook` keyword. +- New `:catch` keyword. If `t` or `nil`, it enables (the default, see + `use-package-defaults`) or disables catching errors at load time in + use-package expansions. 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`). + - New keywords `:custom (foo1 bar1) (foo2 bar2)` etc., and `:custom-face`. - New `:magic` and `:magic-fallback` keywords. diff --git a/up-core.el b/up-core.el index aa677e1ad80..deaead24e85 100644 --- a/up-core.el +++ b/up-core.el @@ -63,6 +63,7 @@ :defines :functions :preface + :catch :after :custom :custom-face @@ -148,6 +149,8 @@ See also `use-package-defaults', which uses this value." '(;; this '(t) has special meaning; see `use-package-handler/:config' (:config '(t) t) (:init nil t) + (:catch t (lambda (args) + (not use-package-expand-minimally))) (:defer use-package-always-defer (lambda (args) (and use-package-always-defer @@ -262,8 +265,6 @@ Must be set before loading use-package." (font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords) -(defvar use-package--hush-function) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Utility functions @@ -954,6 +955,56 @@ deferred until the prefix key sequence is pressed." `((eval-and-compile ,@arg))) body))) +;;;; :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 (gensym "use-package--warning"))) + (cond + ((not arg) + (use-package-process-keywords name rest state)) + ((eq arg t) + `((let ((,context + #'(lambda (keyword err) + (let ((msg (format "%s/%s: %s" ',name keyword + (error-message-string err)))) + ,(when (eq use-package-verbose 'debug) + `(progn + (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)")))) + (ignore (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) + `((let ((,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"))))) + ;;;; :bind, :bind* (defalias 'use-package-normalize/:bind 'use-package-normalize-binder) @@ -1253,7 +1304,7 @@ no keyword implies `:all'." (use-package-hook-injector (use-package-as-string name) :init arg))) (when init-body - (funcall use-package--hush-function + (funcall use-package--hush-function :init (if use-package-check-before-init `((when (locate-library ,(use-package-as-string name)) ,@init-body)) @@ -1285,7 +1336,7 @@ no keyword implies `:all'." body (use-package-with-elapsed-timer (format "Configuring package %s" name-symbol) - (funcall use-package--hush-function + (funcall use-package--hush-function :config (use-package-concat (use-package-hook-injector (symbol-name name-symbol) :config arg) @@ -1297,52 +1348,24 @@ no keyword implies `:all'." ;;; The main macro ;; -(defsubst use-package-hush (context body) - `((condition-case-unless-debug err - ,(macroexp-progn body) - (error (funcall ,context err))))) - (defun use-package-core (name args) - (let* ((context (gensym "use-package--warning")) - (args* (use-package-normalize-keywords name args)) - (use-package--hush-function #'identity)) - (if use-package-expand-minimally - (use-package-process-keywords name args* - (and (plist-get args* :demand) - (list :demand t))) - `((let - ((,context - #'(lambda (err) - (let ((msg (format "%s: %s" ',name (error-message-string err)))) - ,(when (eq use-package-verbose 'debug) - `(progn - (with-current-buffer (get-buffer-create "*use-package*") - (goto-char (point-max)) - (insert - "-----\n" msg - ,(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)))))))) - (emacs-lisp-mode)) - (setq msg (concat msg " (see the *use-package* buffer)")))) - (ignore (display-warning 'use-package msg :error)))))) - ,(let ((use-package--hush-function - (apply-partially #'use-package-hush context))) - (macroexp-progn - (funcall use-package--hush-function - (use-package-process-keywords name args* - (and (plist-get args* :demand) - (list :demand t))))))))))) + (let* ((args* (use-package-normalize-keywords name args)) + (use-package--form + (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) diff --git a/up-tests.el b/up-tests.el index 2635c7df757..c23d706c32c 100644 --- a/up-tests.el +++ b/up-tests.el @@ -866,6 +866,35 @@ (init) (require 'foo nil nil))))) +(ert-deftest use-package-test/:catch-1 () + (match-expansion + (use-package foo :catch t) + `(let + ((,_ #'(lambda (keyword err) + (let ((msg (format "%s/%s: %s" 'foo keyword + (error-message-string err)))) + nil + (ignore (display-warning 'use-package msg :error)))))) + (condition-case-unless-debug err + (require 'foo nil nil) + (error + (funcall ,_ :catch err)))))) + +(ert-deftest use-package-test/:catch-2 () + (match-expansion + (use-package foo :catch nil) + `(require 'foo nil nil))) + +(ert-deftest use-package-test/:catch-3 () + (match-expansion + (use-package foo :catch (lambda (keyword error))) + `(let + ((,_ (lambda (keyword error)))) + (condition-case-unless-debug err + (require 'foo nil nil) + (error + (funcall ,_ :catch err)))))) + (ert-deftest use-package-test/:after-1 () (match-expansion (use-package foo :after bar) From 101dc9793bfd7ac0d9f2ec1f857bf1cef54ca679 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 11:05:11 -0800 Subject: [PATCH 393/606] Ensure that :commands always declare-function at compile time --- up-core.el | 26 +++++++++++++------------- up-tests.el | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/up-core.el b/up-core.el index deaead24e85..d1732c3b2a2 100644 --- a/up-core.el +++ b/up-core.el @@ -1147,20 +1147,20 @@ deferred until the prefix key sequence is pressed." (defun use-package-handler/:commands (name keyword arg rest state) (use-package-concat - (unless (plist-get state :demand) - ;; 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 + ;; 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)))) + (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))) ;;;; :defer diff --git a/up-tests.el b/up-tests.el index c23d706c32c..3bcc340eaca 100644 --- a/up-tests.el +++ b/up-tests.el @@ -676,6 +676,52 @@ (autoload #'bar "foo" nil t)) (bar)))) +(ert-deftest use-package-test/:commands-5 () + (match-expansion + (use-package gnus-harvest + :load-path "lisp/gnus-harvest" + :commands gnus-harvest-install + :demand t + :config + (if (featurep 'message-x) + (gnus-harvest-install 'message-x) + (gnus-harvest-install))) + `(progn + (eval-and-compile + (add-to-list 'load-path "/Users/johnw/.emacs.d/lisp/gnus-harvest")) + (require 'gnus-harvest nil nil) + (if (featurep 'message-x) + (gnus-harvest-install 'message-x) + (gnus-harvest-install)) + t))) + +(ert-deftest use-package-test/:commands-6 () + (let ((byte-compile-current-file t)) + (match-expansion + (use-package gnus-harvest + :load-path "lisp/gnus-harvest" + :commands gnus-harvest-install + :demand t + :config + (if (featurep 'message-x) + (gnus-harvest-install 'message-x) + (gnus-harvest-install))) + `(progn + (eval-and-compile + (add-to-list 'load-path "/Users/johnw/.emacs.d/lisp/gnus-harvest")) + (eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load gnus-harvest: %S" nil + (load "gnus-harvest" nil t)))) + (eval-when-compile + (declare-function gnus-harvest-install "gnus-harvest")) + (require 'gnus-harvest nil nil) + (if + (featurep 'message-x) + (gnus-harvest-install 'message-x) + (gnus-harvest-install)) + t)))) + (ert-deftest use-package-test/:defines-1 () (match-expansion (use-package foo :defines bar) From 01c3d756061b5f558895d674acc6d9a199707b43 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 11:26:19 -0800 Subject: [PATCH 394/606] :ensure can be a list; correct handling of multiple :ensure keywords Fixes https://github.com/jwiegley/use-package/issues/539 --- up-ensure.el | 66 ++++++++++++++++++++++++++++------------------------ up-tests.el | 58 +++++++++++++++++++++++++++------------------ 2 files changed, 71 insertions(+), 53 deletions(-) diff --git a/up-ensure.el b/up-ensure.el index fa19e1d5a8e..30f2190e922 100644 --- a/up-ensure.el +++ b/up-ensure.el @@ -33,6 +33,7 @@ ;;; Code: +(require 'cl-lib) (require 'up-core) (defgroup use-package-ensure nil @@ -58,9 +59,9 @@ See also `use-package-defaults', which uses this value." (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 argument passed -to `:ensure'; and the current `state' plist created by previous -handlers. +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 @@ -136,38 +137,43 @@ manually updated package." t (use-package-only-one (symbol-name keyword) args #'(lambda (label arg) - (if (symbolp arg) - arg + (cond + ((symbolp arg) + (list arg)) + ((and (listp arg) (cl-every #'symbolp arg)) + arg) + (t (use-package-error (concat ":ensure wants an optional package name " - "(an unquoted symbol name)"))))))) + "(an unquoted symbol name)")))))))) -(defun use-package-ensure-elpa (name ensure state &optional no-refresh) - (let ((package - (or (and (eq ensure t) (use-package-as-symbol name)) - ensure))) - (when package - (require '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) +(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) + (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)) - (package-install package)) - t) - (error - (ignore - (display-warning 'use-package - (format "Failed to install %s: %s" - name (error-message-string err)) - :error)))))))) + (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 + (ignore + (display-warning 'use-package + (format "Failed to install %s: %s" + name (error-message-string err)) + :error))))))))) (defun use-package-handler/:ensure (name keyword ensure rest state) (let* ((body (use-package-process-keywords name rest state))) @@ -184,7 +190,7 @@ manually updated package." body)) (add-to-list 'use-package-defaults - '(:ensure use-package-always-ensure + '(:ensure (list use-package-always-ensure) (lambda (args) (and use-package-always-ensure (not (plist-member args :load-path))))) t) diff --git a/up-tests.el b/up-tests.el index 3bcc340eaca..efefd07612c 100644 --- a/up-tests.el +++ b/up-tests.el @@ -219,9 +219,9 @@ (flet ((norm (&rest args) (apply #'use-package-normalize/:ensure 'foopkg :ensure args))) - (should (equal (norm '(t)) t)) - (should (equal (norm '(nil)) nil)) - (should (equal (norm '(sym)) 'sym)) + (should (equal (norm '(t)) '(t))) + (should (equal (norm '(nil)) '(nil))) + (should (equal (norm '(sym)) '(sym))) (should-error (norm '(1))) (should-error (norm '("Hello"))))) @@ -230,7 +230,7 @@ (match-expansion (use-package foo :ensure t) `(progn - (use-package-ensure-elpa 'foo 't 'nil) + (use-package-ensure-elpa 'foo '(t) 'nil) (require 'foo nil nil))))) (ert-deftest use-package-test/:ensure-2 () @@ -238,7 +238,7 @@ (match-expansion (use-package foo :ensure t) `(progn - (use-package-ensure-elpa 'foo 't 'nil) + (use-package-ensure-elpa 'foo '(t) 'nil) (require 'foo nil nil))))) (ert-deftest use-package-test/:ensure-3 () @@ -246,7 +246,7 @@ (match-expansion (use-package foo :ensure nil) `(progn - (use-package-ensure-elpa 'foo 'nil 'nil) + (use-package-ensure-elpa 'foo '(nil) 'nil) (require 'foo nil nil))))) (ert-deftest use-package-test/:ensure-4 () @@ -254,7 +254,7 @@ (match-expansion (use-package foo :ensure nil) `(progn - (use-package-ensure-elpa 'foo 'nil 'nil) + (use-package-ensure-elpa 'foo '(nil) 'nil) (require 'foo nil nil))))) (ert-deftest use-package-test/:ensure-5 () @@ -280,7 +280,7 @@ (match-expansion (use-package foo :ensure nil :load-path "foo") `(progn - (use-package-ensure-elpa 'foo 'nil 'nil) + (use-package-ensure-elpa 'foo '(nil) 'nil) (eval-and-compile (add-to-list 'load-path ,(pred stringp))) (require 'foo nil nil))))) @@ -290,7 +290,7 @@ (match-expansion (use-package foo :ensure nil :load-path "foo") `(progn - (use-package-ensure-elpa 'foo 'nil 'nil) + (use-package-ensure-elpa 'foo '(nil) 'nil) (eval-and-compile (add-to-list 'load-path ,(pred stringp))) (require 'foo nil nil))))) @@ -300,7 +300,7 @@ (match-expansion (use-package foo :ensure t :load-path "foo") `(progn - (use-package-ensure-elpa 'foo 't 'nil) + (use-package-ensure-elpa 'foo '(t) 'nil) (eval-and-compile (add-to-list 'load-path ,(pred stringp))) (require 'foo nil nil))))) @@ -310,7 +310,7 @@ (match-expansion (use-package foo :ensure t :load-path "foo") `(progn - (use-package-ensure-elpa 'foo 't 'nil) + (use-package-ensure-elpa 'foo '(t) 'nil) (eval-and-compile (add-to-list 'load-path ,(pred stringp))) (require 'foo nil nil))))) @@ -325,6 +325,30 @@ (use-package foo :ensure t) (should (eq tried-to-install 'foo))))) +(ert-deftest use-package-test/:ensure-12 () + (let ((use-package-always-ensure t)) + (match-expansion + (use-package foo :ensure bar) + `(progn + (use-package-ensure-elpa 'foo '(bar) 'nil) + (require 'foo nil nil))))) + +(ert-deftest use-package-test/:ensure-13 () + (let ((use-package-always-ensure t)) + (match-expansion + (use-package foo :ensure bar :ensure quux) + `(progn + (use-package-ensure-elpa 'foo '(bar quux) 'nil) + (require 'foo nil nil))))) + +(ert-deftest use-package-test/:ensure-14 () + (let ((use-package-always-ensure t)) + (match-expansion + (use-package foo :ensure bar :ensure (quux bow)) + `(progn + (use-package-ensure-elpa 'foo '(bar quux bow) 'nil) + (require 'foo nil nil))))) + (ert-deftest use-package-test/:if-1 () (match-expansion (use-package foo :if t) @@ -1319,18 +1343,6 @@ (bind-keys :package mu4e ("" . mu4e)))))) -(ert-deftest use-package-test/539 () - (match-expansion - (use-package foo - :requires bar - :after quux - :ensure bow) - `(progn - (use-package-ensure-elpa 'foo 'bow 'nil) - (when (featurep 'bar) - (eval-after-load 'quux - '(require 'foo nil nil)))))) - ;; Local Variables: ;; indent-tabs-mode: nil ;; no-byte-compile: t From e36d208c694153bfb195a2750405483ebe306d8a Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 11:32:27 -0800 Subject: [PATCH 395/606] Expand use-package-core as a macro, to avoid load time dependency --- up-core.el | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/up-core.el b/up-core.el index d1732c3b2a2..b4d86971b9b 100644 --- a/up-core.el +++ b/up-core.el @@ -1348,24 +1348,24 @@ no keyword implies `:all'." ;;; The main macro ;; -(defun use-package-core (name args) - (let* ((args* (use-package-normalize-keywords name args)) - (use-package--form - (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))))) +(defmacro use-package-core (name args) + `(let* ((args* (use-package-normalize-keywords ,name ,args)) + (use-package--form + (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) From 9245d08ebc9d123693437d00707d56e45fc5b9ec Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 11:53:18 -0800 Subject: [PATCH 396/606] Require cl for the use-package tests --- up-tests.el | 1 + 1 file changed, 1 insertion(+) diff --git a/up-tests.el b/up-tests.el index efefd07612c..c1daf0499b9 100644 --- a/up-tests.el +++ b/up-tests.el @@ -22,6 +22,7 @@ ;;; Code: +(require 'cl) (require 'ert) (require 'use-package) From d771e8d71931d2b9d8bf3d19b1e2a98d9b02c218 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 11:53:35 -0800 Subject: [PATCH 397/606] Please the byte-compiler --- lisp/use-package/bind-chord.el | 2 +- lisp/use-package/use-package-ensure-system-package.el | 7 ++++++- lisp/use-package/use-package.el | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/bind-chord.el b/lisp/use-package/bind-chord.el index 35634b174a3..e5184bff60e 100644 --- a/lisp/use-package/bind-chord.el +++ b/lisp/use-package/bind-chord.el @@ -17,7 +17,7 @@ ;;; Code: (require 'bind-key) -(require 'key-chord) +(require 'key-chord nil t) ;;;###autoload (defmacro bind-chord (chord command &optional keymap) diff --git a/lisp/use-package/use-package-ensure-system-package.el b/lisp/use-package/use-package-ensure-system-package.el index b8fd19d830b..36a614d47c3 100644 --- a/lisp/use-package/use-package-ensure-system-package.el +++ b/lisp/use-package/use-package-ensure-system-package.el @@ -20,7 +20,12 @@ ;;; Code: (require 'use-package) -(require 'system-packages) +(require 'system-packages nil t) + +(eval-when-compile + (defvar system-packages-packagemanager) + (defvar system-packages-supported-package-managers) + (defvar system-packages-usesudo)) (defun use-package-ensure-system-package-install-command (pack) "Return the default install command for `pack'." diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index ec459ab1662..c6ab7d742c6 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -45,6 +45,7 @@ (require 'up-diminish) (require 'up-delight) +(declare-function use-package-jump-to-package-form "up-jump") (autoload #'use-package-jump-to-package-form "up-jump" nil t) (provide 'use-package) From d5feff862a0d26f4a9df9246bbfee0576ebcec21 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 11:55:35 -0800 Subject: [PATCH 398/606] Split key binding functionality out into its own file --- lisp/use-package/use-package.el | 3 +- up-bind-key.el | 130 ++++++++++++++++++++++++++++++++ up-core.el | 106 +------------------------- 3 files changed, 133 insertions(+), 106 deletions(-) create mode 100644 up-bind-key.el diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index c6ab7d742c6..72a9e1a2250 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -41,9 +41,10 @@ (require 'up-core) -(require 'up-ensure) +(require 'up-bind-key) (require 'up-diminish) (require 'up-delight) +(require 'up-ensure) (declare-function use-package-jump-to-package-form "up-jump") (autoload #'use-package-jump-to-package-form "up-jump" nil t) diff --git a/up-bind-key.el b/up-bind-key.el new file mode 100644 index 00000000000..1ed760a96bb --- /dev/null +++ b/up-bind-key.el @@ -0,0 +1,130 @@ +;;; up-bind-key.el --- Support for the :bind/:bind-keymap keywords + +;; Copyright (C) 2012-2017 John Wiegley + +;; Author: John Wiegley +;; Maintainer: John Wiegley +;; Created: 17 Jun 2012 +;; Modified: 4 Dec 2017 +;; Version: 1.0 +;; Package-Requires: ((emacs "24.3") (use-package "2.4") (bind-key "2.4")) +;; Keywords: dotemacs startup speed config package +;; URL: https://github.com/jwiegley/use-package + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 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: + +;; 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. + +;;; Code: + +(require 'up-core) +(require 'bind-key) + +;;;###autoload +(defun use-package-autoload-keymap (keymap-symbol package override) + "Loads PACKAGE and then binds the key sequence used to invoke +this function to KEYMAP-SYMBOL. It then simulates pressing the +same key sequence a again, so that the next key pressed is routed +to the newly loaded keymap. + +This function supports use-package's :bind-keymap keyword. It +works by binding the given key sequence to an invocation of this +function for a particular keymap. The keymap is expected to be +defined by the package. In this way, loading the package is +deferred until the prefix key sequence is pressed." + (if (not (require package nil t)) + (use-package-error (format "Cannot load package.el: %s" package)) + (if (and (boundp keymap-symbol) + (keymapp (symbol-value keymap-symbol))) + (let* ((kv (this-command-keys-vector)) + (key (key-description kv)) + (keymap (symbol-value keymap-symbol))) + (if override + (bind-key* key keymap) + (bind-key key keymap)) + (setq unread-command-events + (listify-key-sequence kv))) + (use-package-error + (format "package.el %s failed to define keymap %s" + package keymap-symbol))))) + +(defun use-package-normalize-binder (name keyword args) + (use-package-as-one (symbol-name keyword) args + #'(lambda (label arg) + (unless (consp arg) + (use-package-error + (concat label " a ( . )" + " or list of these"))) + (use-package-normalize-pairs + #'(lambda (k) + (pcase k + ((pred stringp) t) + ((pred vectorp) t))) + #'(lambda (v) (use-package-recognize-function v t #'stringp)) + name label arg)))) + +;;;; :bind, :bind* + +(defalias 'use-package-normalize/:bind 'use-package-normalize-binder) +(defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) + +(defun use-package-handler/:bind + (name keyword args rest state &optional bind-macro) + (cl-destructuring-bind (nargs . commands) + (use-package-normalize-commands args) + (use-package-concat + (use-package-process-keywords name + (use-package-sort-keywords + (use-package-plist-append rest :commands commands)) + state) + `((ignore + (,(if bind-macro bind-macro 'bind-keys) + :package ,name ,@nargs)))))) + +(defun use-package-handler/:bind* (name keyword arg rest state) + (use-package-handler/:bind name keyword arg rest state 'bind-keys*)) + +;;;; :bind-keymap, :bind-keymap* + +(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder) +(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder) + +(defun use-package-handler/:bind-keymap + (name keyword arg rest state &optional override) + (use-package-concat + (use-package-process-keywords name rest state) + `((ignore + ,@(mapcar + #'(lambda (binding) + `(,(if override + 'bind-key* + 'bind-key) + ,(car binding) + #'(lambda () + (interactive) + (use-package-autoload-keymap + ',(cdr binding) ',(use-package-as-symbol name) + ,override)))) arg))))) + +(defun use-package-handler/:bind-keymap* (name keyword arg rest state) + (use-package-handler/:bind-keymap name keyword arg rest state t)) + +(provide 'up-bind-key) diff --git a/up-core.el b/up-core.el index b4d86971b9b..687aac21030 100644 --- a/up-core.el +++ b/up-core.el @@ -7,7 +7,7 @@ ;; Created: 17 Jun 2012 ;; Modified: 29 Nov 2017 ;; Version: 2.4 -;; Package-Requires: ((emacs "24.3") (bind-key "2.4")) +;; Package-Requires: ((emacs "24.3")) ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package @@ -39,7 +39,6 @@ ;;; Code: -(require 'bind-key) (require 'bytecomp) (require 'cl-lib) @@ -737,20 +736,6 @@ If RECURSED is non-nil, recurse into sublists." (prog1 (let ((ret (use-package-normalize-pairs key-pred val-pred name label x t))) - ;; Currently, the handling of keyword arguments by - ;; `use-package' and `bind-key' is non-uniform and - ;; undocumented. As a result, `use-package-normalize-pairs' - ;; (as it is currently implemented) does not correctly handle - ;; the keyword-argument syntax of `bind-keys'. A permanent - ;; solution to this problem will require a careful - ;; consideration of the desired keyword-argument interface - ;; for `use-package' and `bind-key'. However, in the - ;; meantime, we have a quick patch to fix a serious bug in - ;; the handling of keyword arguments. Namely, the code below - ;; would normally unwrap lists that were passed as keyword - ;; arguments (for example, the `:filter' argument in `:bind') - ;; without the (not (keywordp last-item)) clause. See #447 - ;; for further discussion. (if (and (listp ret) (not (keywordp last-item))) (car ret) @@ -812,49 +797,6 @@ representing symbols (that may need to be autloaded)." (use-package-non-nil-symbolp (cdr x)) (cdr x))) nargs))))) -(defun use-package-normalize-binder (name keyword args) - (use-package-as-one (symbol-name keyword) args - #'(lambda (label arg) - (unless (consp arg) - (use-package-error - (concat label " a ( . )" - " or list of these"))) - (use-package-normalize-pairs - #'(lambda (k) - (pcase k - ((pred stringp) t) - ((pred vectorp) t))) - #'(lambda (v) (use-package-recognize-function v t #'stringp)) - name label arg)))) - -;;;###autoload -(defun use-package-autoload-keymap (keymap-symbol package override) - "Loads PACKAGE and then binds the key sequence used to invoke -this function to KEYMAP-SYMBOL. It then simulates pressing the -same key sequence a again, so that the next key pressed is routed -to the newly loaded keymap. - -This function supports use-package's :bind-keymap keyword. It -works by binding the given key sequence to an invocation of this -function for a particular keymap. The keymap is expected to be -defined by the package. In this way, loading the package is -deferred until the prefix key sequence is pressed." - (if (not (require package nil t)) - (use-package-error (format "Cannot load package.el: %s" package)) - (if (and (boundp keymap-symbol) - (keymapp (symbol-value keymap-symbol))) - (let* ((kv (this-command-keys-vector)) - (key (key-description kv)) - (keymap (symbol-value keymap-symbol))) - (if override - (bind-key* key keymap) - (bind-key key keymap)) - (setq unread-command-events - (listify-key-sequence kv))) - (use-package-error - (format "package.el %s failed to define keymap %s" - package keymap-symbol))))) - (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 @@ -1005,52 +947,6 @@ deferred until the prefix key sequence is pressed." (t (use-package-error "The :catch keyword expects 't' or a function"))))) -;;;; :bind, :bind* - -(defalias 'use-package-normalize/:bind 'use-package-normalize-binder) -(defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) - -(defun use-package-handler/:bind - (name keyword args rest state &optional bind-macro) - (cl-destructuring-bind (nargs . commands) - (use-package-normalize-commands args) - (use-package-concat - (use-package-process-keywords name - (use-package-sort-keywords - (use-package-plist-append rest :commands commands)) - state) - `((ignore - (,(if bind-macro bind-macro 'bind-keys) - :package ,name ,@nargs)))))) - -(defun use-package-handler/:bind* (name keyword arg rest state) - (use-package-handler/:bind name keyword arg rest state 'bind-keys*)) - -;;;; :bind-keymap, :bind-keymap* - -(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder) -(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder) - -(defun use-package-handler/:bind-keymap - (name keyword arg rest state &optional override) - (use-package-concat - (use-package-process-keywords name rest state) - `((ignore - ,@(mapcar - #'(lambda (binding) - `(,(if override - 'bind-key* - 'bind-key) - ,(car binding) - #'(lambda () - (interactive) - (use-package-autoload-keymap - ',(cdr binding) ',(use-package-as-symbol name) - ,override)))) arg))))) - -(defun use-package-handler/:bind-keymap* (name keyword arg rest state) - (use-package-handler/:bind-keymap name keyword arg rest state t)) - ;;;; :interpreter (defun use-package-handle-mode (name alist args rest state) From 057814ae241e44f7550e5d485decb6f40e312d3c Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 12:04:20 -0800 Subject: [PATCH 399/606] Add new customization variables `use-package-hook-name-suffix' Fixes https://github.com/jwiegley/use-package/issues/530 --- etc/USE-PACKAGE-NEWS | 2 ++ up-core.el | 14 ++++++++++++-- up-tests.el | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index b5b5adc0be0..3bdd623adeb 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -66,6 +66,8 @@ - New customization variable `use-package-enable-imenu-support`. +- New customization variable `use-package-hook-name-suffix`. + - Allow `:diminish` to take no arguments. - Support multiple symbols passed to `:after`, and a mini-DSL using `:all` and diff --git a/up-core.el b/up-core.el index b4d86971b9b..fbaa862b066 100644 --- a/up-core.el +++ b/up-core.el @@ -180,6 +180,13 @@ be attempted." (choice :tag "Enable if non-nil" sexp 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 @@ -1136,8 +1143,11 @@ deferred until the prefix key sequence is pressed." (when fun (mapcar #'(lambda (sym) - `(add-hook (quote ,(intern (format "%s-hook" sym))) - (function ,fun))) + `(add-hook + (quote ,(intern + (concat (symbol-name sym) + use-package-hook-name-suffix))) + (function ,fun))) (if (use-package-non-nil-symbolp syms) (list syms) syms))))) nargs)))))) diff --git a/up-tests.el b/up-tests.el index c1daf0499b9..dcd3c8d308e 100644 --- a/up-tests.el +++ b/up-tests.el @@ -891,6 +891,38 @@ (ignore (bind-keys :package foo ("C-a" . key)))))))) +(ert-deftest use-package-test/:hook-2 () + (match-expansion + (use-package foo + :hook (hook . fun)) + `(progn + (unless (fboundp 'fun) + (autoload #'fun "foo" nil t)) + (ignore + (add-hook 'hook-hook #'fun))))) + +(ert-deftest use-package-test/:hook-3 () + (let ((use-package-hook-name-suffix nil)) + (match-expansion + (use-package foo + :hook (hook . fun)) + `(progn + (unless (fboundp 'fun) + (autoload #'fun "foo" nil t)) + (ignore + (add-hook 'hook #'fun)))))) + +(ert-deftest use-package-test/:hook-4 () + (let ((use-package-hook-name-suffix "-special")) + (match-expansion + (use-package foo + :hook (hook . fun)) + `(progn + (unless (fboundp 'fun) + (autoload #'fun "foo" nil t)) + (ignore + (add-hook 'hook-special #'fun)))))) + (ert-deftest use-package-test-normalize/:custom () (flet ((norm (&rest args) (apply #'use-package-normalize/:custom From 5382941ac3e57f6b930a0181be68d2a11a21eb9a Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 12:09:52 -0800 Subject: [PATCH 400/606] Add a test-in-progress for issue 506 --- up-tests.el | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/up-tests.el b/up-tests.el index dcd3c8d308e..bb22b344479 100644 --- a/up-tests.el +++ b/up-tests.el @@ -1356,6 +1356,18 @@ (if (fboundp 'delight) (delight '((foo "bar" foo))))))) +(ert-deftest use-package-test/506 () + (match-expansion + (use-package ess-site + :ensure ess + :pin melpa-stable) + `(progn + (use-package-pin-package 'ess-site "melpa-stable") + (use-package-ensure-elpa 'ess-site + '(ess) + 'nil) + (require 'ess-site nil nil)))) + (ert-deftest use-package-test/538 () (match-expansion (use-package mu4e From 1e42c867b61bee84a7c468ff632435e206d0fa36 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 12:11:59 -0800 Subject: [PATCH 401/606] Commit .texi file, as it requires several dependencies to generate --- doc/misc/use-package.texi | 1000 +++++++++++++++++++++++++++++++++++++ 1 file changed, 1000 insertions(+) create mode 100644 doc/misc/use-package.texi diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi new file mode 100644 index 00000000000..8ff40b03929 --- /dev/null +++ b/doc/misc/use-package.texi @@ -0,0 +1,1000 @@ +\input texinfo @c -*- texinfo -*- +@c %**start of header +@setfilename use-package.info +@settitle use-package User Manual +@documentencoding UTF-8 +@documentlanguage en +@c %**end of header + +@copying +@quotation +Copyright (C) 2012-2017 John Wiegley + +You can redistribute this document 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. + +This document 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. +@end quotation +@end copying + +@dircategory Emacs +@direntry +* use-package: (use-package). Declarative package configuration for Emacs. +@end direntry + +@finalout +@titlepage +@title use-package User Manual +@subtitle for version 2.4 +@author John Wiegley +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@contents + +@ifnottex +@node Top +@top use-package User Manual + +use-package is@dots{} + +@quotation +Copyright (C) 2012-2017 John Wiegley + +You can redistribute this document 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. + +This document 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. +@end quotation +@end ifnottex + +@menu +* Introduction:: +* Installation:: +* Getting Started:: +* Keywords:: +* FAQ:: +* Debugging Tools:: +* Command Index:: +* Function Index:: +* Variable Index:: + +@detailmenu +--- The Detailed Node Listing --- + + +Installation + +* Installing from an Elpa Archive:: +* Installing from the Git Repository:: +* Post-Installation Tasks:: + + + + +Keywords + +* @code{:after}: @code{after}. +* @code{:bind-keymap}, @code{:bind-keymap*}: @code{bind-keymap} @code{bind-keymap*}. +* @code{:bind}, @code{:bind*}: @code{bind} @code{bind*}. +* @code{:commands}: @code{commands}. +* @code{:preface}, @code{:init}, @code{:config}: @code{preface} @code{init} @code{config}. +* @code{:custom}: @code{custom}. +* @code{:custom-face}: @code{custom-face}. +* @code{:defer}, @code{:demand}: @code{defer} @code{demand}. +* @code{:defines}, @code{:functions}: @code{defines} @code{functions}. +* @code{:diminish}, @code{:delight}: @code{diminish} @code{delight}. +* @code{:disabled}: @code{disabled}. +* @code{:ensure}, @code{:pin}: @code{ensure} @code{pin}. +* @code{:hook}: @code{hook}. +* @code{:if}, @code{:when}, @code{:unless}: @code{if} @code{when} @code{unless}. +* @code{:load-path}: @code{load-path}. +* @code{:mode}, @code{:interpreter}: @code{mode} @code{interpreter}. +* @code{:magic}, @code{:magic-fallback}: @code{magic} @code{magic-fallback}. +* @code{:no-require}: @code{no-require}. +* @code{:requires}: @code{requires}. + + + +@code{:bind}, @code{:bind*} + +* Binding to local keymaps:: + +FAQ + +* FAQ - How to @dots{}?:: +* FAQ - Issues and Errors:: + +FAQ - How to @dots{}? + +* This is a question:: + + +FAQ - Issues and Errors + +* This is an issues:: +@end detailmenu +@end menu + +@node Introduction +@chapter Introduction + +TODO + +@node Installation +@chapter Installation + +use-package can be installed using Emacs' package manager or manually from +its development repository. + +@menu +* Installing from an Elpa Archive:: +* Installing from the Git Repository:: +* Post-Installation Tasks:: +@end menu + +@node Installing from an Elpa Archive +@section Installing from an Elpa Archive + +use-package is available from Melpa and Melpa-Stable. If you haven't used +Emacs' package manager before, then it is high time you familiarize yourself +with it by reading the documentation in the Emacs manual, see +@ref{Packages,,,emacs,}. Then add one of the archives to @code{package-archives}: + +@itemize +@item +To use Melpa: +@end itemize + +@lisp +(require 'package) +(add-to-list 'package-archives + '("melpa" . "http://melpa.org/packages/") t) +@end lisp + +@itemize +@item +To use Melpa-Stable: +@end itemize + +@lisp +(require 'package) +(add-to-list 'package-archives + '("melpa-stable" . "http://stable.melpa.org/packages/") t) +@end lisp + +Once you have added your preferred archive, you need to update the +local package list using: + +@example +M-x package-refresh-contents RET +@end example + +Once you have done that, you can install use-package and its dependencies +using: + +@example +M-x package-install RET use-package RET +@end example + +Now see @ref{Post-Installation Tasks}. + +@node Installing from the Git Repository +@section Installing from the Git Repository + +First, use Git to clone the use-package repository: + +@example +$ git clone https://github.com/jwiegley/use-package.git ~/.emacs.d/site-lisp/use-package +$ cd ~/.emacs.d/site-lisp/use-package +@end example + +Then compile the libraries and generate the info manuals: + +@example +$ make +@end example + +You may need to create @code{/path/to/use-package/config.mk} with the following +content before running @code{make}: + +@example +LOAD_PATH = -L /path/to/use-package +@end example + +Finally add this to your init file: + +@lisp +(add-to-list 'load-path "~/.emacs.d/site-lisp/use-package") +(require 'use-package) + +(with-eval-after-load 'info + (info-initialize) + (add-to-list 'Info-directory-list + "~/.emacs.d/site-lisp/use-package/")) +@end lisp + +Note that elements of @code{load-path} should not end with a slash, while those of +@code{Info-directory-list} should. + +Instead of running use-package directly from the repository by adding it to +the @code{load-path}, you might want to instead install it in some other directory +using @code{sudo make install} and setting @code{load-path} accordingly. + +To update use-package use: + +@example +$ git pull +$ make +@end example + +At times it might be necessary to run @code{make clean all} instead. + +To view all available targets use @code{make help}. + +Now see @ref{Post-Installation Tasks}. + +@node Post-Installation Tasks +@section Post-Installation Tasks + +After installing use-package you should verify that you are indeed using the +use-package release you think you are using. It's best to restart Emacs before +doing so, to make sure you are not using an outdated value for @code{load-path}. + +@example +C-h v use-package-version RET +@end example + +should display something like + +@example +use-package-version’s value is "2.4" +@end example + +If you are completely new to use-package then see @ref{Getting Started}. + +If you run into problems, then please see the @ref{FAQ}. Also see the +@ref{Debugging Tools}. + +@node Getting Started +@chapter Getting Started + +TODO. For now, see @code{README.md}. + +@node Keywords +@chapter Keywords + +@menu +* @code{:after}: @code{after}. +* @code{:bind-keymap}, @code{:bind-keymap*}: @code{bind-keymap} @code{bind-keymap*}. +* @code{:bind}, @code{:bind*}: @code{bind} @code{bind*}. +* @code{:commands}: @code{commands}. +* @code{:preface}, @code{:init}, @code{:config}: @code{preface} @code{init} @code{config}. +* @code{:custom}: @code{custom}. +* @code{:custom-face}: @code{custom-face}. +* @code{:defer}, @code{:demand}: @code{defer} @code{demand}. +* @code{:defines}, @code{:functions}: @code{defines} @code{functions}. +* @code{:diminish}, @code{:delight}: @code{diminish} @code{delight}. +* @code{:disabled}: @code{disabled}. +* @code{:ensure}, @code{:pin}: @code{ensure} @code{pin}. +* @code{:hook}: @code{hook}. +* @code{:if}, @code{:when}, @code{:unless}: @code{if} @code{when} @code{unless}. +* @code{:load-path}: @code{load-path}. +* @code{:mode}, @code{:interpreter}: @code{mode} @code{interpreter}. +* @code{:magic}, @code{:magic-fallback}: @code{magic} @code{magic-fallback}. +* @code{:no-require}: @code{no-require}. +* @code{:requires}: @code{requires}. +@end menu + +@node @code{after} +@section @code{:after} + +Sometimes it only makes sense to configure a package after another has been +loaded, because certain variables or functions are not in scope until that +time. This can achieved using an @code{:after} keyword that allows a fairly rich +description of the exact conditions when loading should occur. Here is an +example: + +@lisp +(use-package hydra + :load-path "site-lisp/hydra") + +(use-package ivy + :load-path "site-lisp/swiper") + +(use-package ivy-hydra + :after (ivy hydra)) +@end lisp + +In this case, because all of these packages are demand-loaded in the order +they occur, the use of @code{:after} is not strictly necessary. By using it, +however, the above code becomes order-independent, without an implicit +depedence on the nature of your init file. + +By default, @code{:after (foo bar)} is the same as @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: + +@lisp +: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 lisp + +When you nest selectors, such as @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 both @code{baz} and @code{quux} have been loaded. + +@node @code{bind-keymap} @code{bind-keymap*} +@section @code{:bind-keymap}, @code{: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 Emacs' @code{autoload} mechanism. + +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 +command 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 +(use-package projectile + :bind-keymap + ("C-c p" . projectile-command-map) +@end lisp + +@node @code{bind} @code{bind*} +@section @code{:bind}, @code{:bind*} + +Another common thing to do when loading a module is to bind a key to primary +commands within that module: + +@lisp +(use-package ace-jump-mode + :bind ("C-." . ace-jump-mode)) +@end lisp + +This does two things: first, it creates an autoload for the @code{ace-jump-mode} +command and defers loading of @code{ace-jump-mode} until you actually use it. +Second, it binds the key @code{C-.} to that command. After loading, you can use +@code{M-x describe-personal-keybindings} to see all such keybindings you've set +throughout your @code{.emacs} file. + +A more literal way to do the exact same thing is: + +@lisp +(use-package ace-jump-mode + :commands ace-jump-mode + :init + (bind-key "C-." 'ace-jump-mode)) +@end lisp + +When you use the @code{:commands} keyword, it creates autoloads for those commands +and defers loading of the module until they are used. Since the @code{:init} form +is always run---even if @code{ace-jump-mode} might not be on your system---remember +to restrict @code{:init} code to only what would succeed either way. + +The @code{:bind} keyword takes either a cons or a list of conses: + +@lisp +(use-package hi-lock + :bind (("M-o l" . highlight-lines-matching-regexp) + ("M-o r" . highlight-regexp) + ("M-o w" . highlight-phrase))) +@end lisp + +The @code{:commands} keyword likewise takes either a symbol or a list of symbols. + +NOTE: Special keys like @code{tab} or @code{F1}-@code{Fn} can be written in square brackets, +i.e. @code{[tab]} instead of @code{"tab"}. The syntax for the keybindings is similar to +the "kbd" syntax: see @uref{https://www.gnu.org/software/emacs/manual/html_node/emacs/Init-Rebinding.html, the Emacs Manual} for more information. + +Examples: + +@lisp +(use-package helm + :bind (("M-x" . helm-M-x) + ("M-" . helm-find-files) + ([f10] . helm-buffers-list) + ([S-f10] . helm-recentf))) +@end lisp + +@menu +* Binding to local keymaps:: +@end menu + +@node Binding to local keymaps +@subsection Binding to local keymaps + +Slightly different from binding a key to a keymap, is binding a key @strong{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 +(use-package helm + :bind (:map helm-command-map + ("C-c h" . helm-execute-persistent-action))) +@end lisp + +The effect of this statement is to wait until @code{helm} has loaded, and then to +bind the key @code{C-c h} to @code{helm-execute-persistent-action} within Helm's local +keymap, @code{helm-mode-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 +(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 lisp + +@node @code{commands} +@section @code{:commands} + +@node @code{preface} @code{init} @code{config} +@section @code{:preface}, @code{:init}, @code{:config} + +Here is the simplest @code{use-package} declaration: + +@lisp +;; This is only needed once, near the top of the file +(eval-when-compile + ;; Following line is not needed if use-package.el is in ~/.emacs.d + (add-to-list 'load-path "") + (require 'use-package)) + +(use-package foo) +@end lisp + +This loads in the package @code{foo}, but only if @code{foo} is available on your +system. If not, a warning is logged to the @code{*Messages*} buffer. If it +succeeds, a message about @code{"Loading foo"} is logged, along with the time it +took to load, if it took over 0.1 seconds. + +Use the @code{:init} keyword to execute code before a package is loaded. It +accepts one or more forms, up until the next keyword: + +@lisp +(use-package foo + :init + (setq foo-variable t)) +@end lisp + +Similarly, @code{:config} can be used to execute code after a package is loaded. +In cases where loading is done lazily (see more about autoloading below), this +execution is deferred until after the autoload occurs: + +@lisp +(use-package foo + :init + (setq foo-variable t) + :config + (foo-mode 1)) +@end lisp + +As you might expect, you can use @code{:init} and @code{:config} together: + +@lisp +(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 lisp + +In this case, I want to autoload the commands @code{isearch-moccur} and +@code{isearch-all} from @code{color-moccur.el}, and bind keys both at the global level +and within the @code{isearch-mode-map} (see next section). When the package is +actually loaded (by using one of these commands), @code{moccur-edit} is also +loaded, to allow editing of the @code{moccur} buffer. + +@node @code{custom} +@section @code{:custom} + +The @code{:custom} keyword allows customization of package custom variables. + +@lisp +(use-package comint + :custom + (comint-buffer-maximum-size 20000 "Increase comint buffer size.") + (comint-prompt-read-only t "Make the prompt read only.")) +@end lisp + +The documentation string is not mandatory. + +@node @code{custom-face} +@section @code{:custom-face} + +The @code{:custom-face} keyword allows customization of package custom faces. + +@lisp +(use-package eruby-mode + :custom-face + (eruby-standard-face ((t (:slant italic))))) +@end lisp + +@node @code{defer} @code{demand} +@section @code{:defer}, @code{:demand} + +In almost all cases you don't need to manually specify @code{:defer t}. This is +implied whenever @code{:bind} or @code{:mode} or @code{:interpreter} is used. Typically, you +only need to specify @code{:defer} if you know for a fact that some other package +will do something to cause your package to load at the appropriate time, and +thus you would like to defer loading even though use-package isn't creating +any autoloads for you. + +You can override package deferral with the @code{:demand} keyword. Thus, even if +you use @code{:bind}, using @code{:demand} will force loading to occur immediately and +not establish an autoload for the bound key. + +@node @code{defines} @code{functions} +@section @code{:defines}, @code{:functions} + +Another feature of @code{use-package} is that it always loads every file that it +can when @code{.emacs} is being byte-compiled. This helps to silence spurious +warnings about unknown variables and functions. + +However, there are times when this is just not enough. For those times, use +the @code{:defines} and @code{:functions} keywords to introduce dummy variable and +function declarations solely for the sake of the byte-compiler: + +@lisp +(use-package texinfo + :defines texinfo-section-list + :commands texinfo-mode + :init + (add-to-list 'auto-mode-alist '("\\.texi$" . texinfo-mode))) +@end lisp + +If you need to silence a missing function warning, you can use @code{:functions}: + +@lisp +(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 lisp + +@node @code{diminish} @code{delight} +@section @code{:diminish}, @code{:delight} + +@code{use-package} also provides built-in support for the diminish and delight +utilities---if you have them installed. Their purpose is to remove or change +minor mode strings in your mode-line. + +@uref{https://github.com/myrjola/diminish.el, diminish} is invoked with the @code{:diminish} keyword, which is passed 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: + +@lisp +(use-package abbrev + :diminish abbrev-mode + :config + (if (file-exists-p abbrev-file-name) + (quietly-read-abbrev-file))) +@end lisp + +@uref{https://elpa.gnu.org/packages/delight.html, delight} is invoked with the @code{:delight} keyword, which is passed a minor mode +symbol, a replacement string or quoted @uref{https://www.gnu.org/software/emacs/manual/html_node/elisp/Mode-Line-Data.html, mode-line data} (in which case the minor +mode symbol is guessed to be the package name with "-mode" appended at the +end), both of these, or several lists of both. If no arguments are provided, +the default mode name is hidden completely. + +@lisp +;; Don't show anything for rainbow-mode. +(use-package rainbow-mode + :delight) + +;; Don't show anything for auto-revert-mode, which doesn't match +;; its package name. +(use-package autorevert + :delight auto-revert-mode) + +;; Remove the mode name for projectile-mode, but show the project name. +(use-package projectile + :delight '(:eval (concat " " (projectile-project-name)))) + +;; Completely hide visual-line-mode and change auto-fill-mode to " AF". +(use-package emacs + :delight + (auto-fill-function " AF") + (visual-line-mode)) +@end lisp + +@node @code{disabled} +@section @code{:disabled} + +The @code{:disabled} keyword can turn off a module you're having difficulties with, +or stop loading something you're not using at the present time: + +@lisp +(use-package ess-site + :disabled + :commands R) +@end lisp + +When byte-compiling your @code{.emacs} file, disabled declarations are omitted +from the output entirely, to accelerate startup times. + +@node @code{ensure} @code{pin} +@section @code{:ensure}, @code{:pin} + +You can use @code{use-package} to load packages from ELPA with @code{package.el}. This +is particularly useful if you share your @code{.emacs} among several machines; the +relevant packages are downloaded automatically once declared in your @code{.emacs}. +The @code{:ensure} keyword causes the package(s) to be installed automatically if +not already present on your system (set @code{(setq use-package-always-ensure t)} +if you wish this behavior to be global for all packages): + +@lisp +(use-package magit + :ensure t) +@end lisp + +If you need to install a different package from the one named by +@code{use-package}, you can specify it like this: + +@lisp +(use-package tex + :ensure auctex) +@end lisp + +Lastly, when running on Emacs 24.4 or later, use-package can pin a package to +a specific archive, allowing you to mix and match packages from different +archives. The primary use-case for this is preferring packages from the +@code{melpa-stable} and @code{gnu} archives, but using specific packages from @code{melpa} +when you need to track newer versions than what is available in the @code{stable} +archives is also a valid use-case. + +By default @code{package.el} prefers @code{melpa} over @code{melpa-stable} due to the +versioning @code{(> evil-20141208.623 evil-1.0.9)}, so even if you are tracking +only a single package from @code{melpa}, you will need to tag all the non-@code{melpa} +packages with the appropriate archive. If this really annoys you, then you can +set @code{use-package-always-pin} to set a default. + +If you want to manually keep a package updated and ignore upstream updates, +you can pin it to @code{manual}, which as long as there is no repository by that +name, will Just Work(tm). + +@code{use-package} throws an error if you try to pin a package to an archive that +has not been configured using @code{package-archives} (apart from the magic +@code{manual} archive mentioned above): + +@example +Archive 'foo' requested for package 'bar' is not available. +@end example + +Example: + +@lisp +(use-package company + :ensure t + :pin melpa-stable) + +(use-package evil + :ensure t) + ;; no :pin needed, as package.el will choose the version in melpa + +(use-package adaptive-wrap + :ensure t + ;; as this package is available only in the gnu archive, this is + ;; technically not needed, but it helps to highlight where it + ;; comes from + :pin gnu) + +(use-package org + :ensure t + ;; ignore org-mode from upstream and use a manually installed version + :pin manual) +@end lisp + +@strong{NOTE}: the @code{:pin} argument has no effect on emacs versions < 24.4. + +@node @code{hook} +@section @code{:hook} + +The @code{:hook} keyword allows adding functions onto hooks, here only the basename +of the hook is required. Thus, all of the following are equivalent: + +@lisp +(use-package ace-jump-mode + :hook prog-mode) + +(use-package ace-jump-mode + :hook (prog-mode . ace-jump-mode)) + +(use-package ace-jump-mode + :commands ace-jump-mode + :init + (add-hook 'prog-mode-hook #'ace-jump-mode)) +@end lisp + +And likewise, when multiple hooks should be applied, the following are also +equivalent: + +@lisp +(use-package ace-jump-mode + :hook (prog-mode text-mode)) + +(use-package ace-jump-mode + :hook ((prog-mode text-mode) . ace-jump-mode)) + +(use-package ace-jump-mode + :hook ((prog-mode . ace-jump-mode) + (text-mode . ace-jump-mode))) + +(use-package ace-jump-mode + :commands ace-jump-mode + :init + (add-hook 'prog-mode-hook #'ace-jump-mode) + (add-hook 'text-mode-hook #'ace-jump-mode)) +@end lisp + +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} (meaning 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 @code{if} @code{when} @code{unless} +@section @code{:if}, @code{:when}, @code{:unless} + +You can use the @code{:if} keyword to predicate the loading and initialization of +modules. + +For example, I only want @code{edit-server} running for my main, graphical Emacs, +not for other Emacsen I may start at the command line: + +@lisp +(use-package edit-server + :if window-system + :init + (add-hook 'after-init-hook 'server-start t) + (add-hook 'after-init-hook 'edit-server-start t)) +@end lisp + +In another example, we can load things conditional on the operating system: + +@lisp +(use-package exec-path-from-shell + :if (memq window-system '(mac ns)) + :ensure t + :config + (exec-path-from-shell-initialize)) +@end lisp + +Note that @code{:when} is provided as an alias for @code{:if}, and @code{:unless foo} means +the same thing as @code{:if (not foo)}. + +@node @code{load-path} +@section @code{:load-path} + +If your package needs a directory added to the @code{load-path} in order to load, +use @code{:load-path}. This takes a symbol, a function, a string or a list of +strings. If the path is relative, it is expanded within +@code{user-emacs-directory}: + +@lisp +(use-package ess-site + :load-path "site-lisp/ess/lisp/" + :commands R) +@end lisp + +Note that when using a symbol or a function to provide a dynamically generated +list of paths, you must inform the byte-compiler of this definition so 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}). Further, this +value is fixed at whatever was determined during compilation, to avoid looking +up the same information again on each startup: + +@lisp +(eval-and-compile + (defun ess-site-load-path () + (shell-command "find ~ -path ess/lisp"))) + +(use-package ess-site + :load-path (lambda () (list (ess-site-load-path))) + :commands R) +@end lisp + +@node @code{mode} @code{interpreter} +@section @code{:mode}, @code{: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. The specifier to either keyword can be a cons cell, a list of cons +cells, or a string or regexp: + +@lisp +(use-package ruby-mode + :mode "\\.rb\\'" + :interpreter "ruby") + +;; The package is "python" but the mode is "python-mode": +(use-package python + :mode ("\\.py\\'" . python-mode) + :interpreter ("python" . python-mode)) +@end lisp + +If you aren't using @code{:commands}, @code{:bind}, @code{:bind*}, @code{:bind-keymap}, +@code{:bind-keymap*}, @code{:mode}, or @code{:interpreter} (all of which imply @code{:defer}; see +the docstring for @code{use-package} for a brief description of each), you can +still defer loading with the @code{:defer} keyword: + +@lisp +(use-package ace-jump-mode + :defer t + :init + (autoload 'ace-jump-mode "ace-jump-mode" nil t) + (bind-key "C-." 'ace-jump-mode)) +@end lisp + +This does exactly the same thing as the following: + +@lisp +(use-package ace-jump-mode + :bind ("C-." . ace-jump-mode)) +@end lisp + +@node @code{magic} @code{magic-fallback} +@section @code{:magic}, @code{:magic-fallback} + +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. The difference between the two is +that `:magic-fallback` has a lower priority than `:mode`. For example: + +``` elisp +(use-package pdf-tools + :load-path "site-lisp/pdf-tools/lisp" + :magic ("%PDF" . pdf-view-mode) + :config + (pdf-tools-install)) +``` + +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"`. + +@node @code{no-require} +@section @code{:no-require} + +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 +(use-package foo + :no-require t + :config + (message "This is evaluated when `foo' is loaded")) +@end lisp + +@node @code{requires} +@section @code{:requires} + +While the @code{:after} keyword delays loading until the dependencies are loaded, +the somewhat simpler @code{:requires} keyword simply never loads the package if the +dependencies are not available at the time the @code{use-package} declaration is +encountered. By "available" in this context it means that @code{foo} is available +of @code{(featurep 'foo)} evaulates to a non-nil value. For example: + +@lisp +(use-package abbrev + :requires foo) +@end lisp + +This is the same as: + +@lisp +(use-package abbrev + :if (featurep 'foo)) +@end lisp + +As a convenience, a list of such packages may be specified: + +@lisp +(use-package abbrev + :requires (foo bar baz)) +@end lisp + +For more complex logic, such as that supported by @code{:after}, simply use @code{:if} +and the appropriate Lisp expression. + +@node FAQ +@appendix FAQ + +The next two nodes lists frequently asked questions. + +Please also use the @ref{Debugging Tools}. + +@menu +* FAQ - How to @dots{}?:: +* FAQ - Issues and Errors:: +@end menu + +@node FAQ - How to @dots{}? +@appendixsec FAQ - How to @dots{}? + +@menu +* This is a question:: +@end menu + +@node This is a question +@appendixsubsec This is a question + +This is an answer. + +@node FAQ - Issues and Errors +@appendixsec FAQ - Issues and Errors + +@menu +* This is an issues:: +@end menu + +@node This is an issues +@appendixsubsec This is an issues + +This is a description. + +@node Debugging Tools +@chapter Debugging Tools + +TODO + +Please also see the @ref{FAQ}. + +@node Command Index +@appendix Command Index + +@printindex cp + +@node Function Index +@appendix Function Index + +@printindex fn + +@node Variable Index +@appendix Variable Index + +@printindex vr + +@bye From 4b83f9525ce6324eab2244a16f0d654a55a55fc3 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 21:21:54 +0000 Subject: [PATCH 402/606] Rename up-* files to use-package-* for consistency --- .../use-package/use-package-bind-key.el | 6 +++--- up-core.el => lisp/use-package/use-package-core.el | 4 ++-- .../use-package/use-package-delight.el | 6 +++--- .../use-package/use-package-diminish.el | 6 +++--- .../use-package/use-package-ensure.el | 6 +++--- up-jump.el => lisp/use-package/use-package-jump.el | 6 +++--- lisp/use-package/use-package.el | 14 +++++++------- .../lisp/use-package/use-package-tests.el | 2 +- 8 files changed, 25 insertions(+), 25 deletions(-) rename up-bind-key.el => lisp/use-package/use-package-bind-key.el (97%) rename up-core.el => lisp/use-package/use-package-core.el (99%) rename up-delight.el => lisp/use-package/use-package-delight.el (96%) rename up-diminish.el => lisp/use-package/use-package-diminish.el (95%) rename up-ensure.el => lisp/use-package/use-package-ensure.el (98%) rename up-jump.el => lisp/use-package/use-package-jump.el (95%) rename up-tests.el => test/lisp/use-package/use-package-tests.el (99%) diff --git a/up-bind-key.el b/lisp/use-package/use-package-bind-key.el similarity index 97% rename from up-bind-key.el rename to lisp/use-package/use-package-bind-key.el index 1ed760a96bb..4021bb432d6 100644 --- a/up-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -1,4 +1,4 @@ -;;; up-bind-key.el --- Support for the :bind/:bind-keymap keywords +;;; use-package-bind-key.el --- Support for the :bind/:bind-keymap keywords ;; Copyright (C) 2012-2017 John Wiegley @@ -35,7 +35,7 @@ ;;; Code: -(require 'up-core) +(require 'use-package-core) (require 'bind-key) ;;;###autoload @@ -127,4 +127,4 @@ deferred until the prefix key sequence is pressed." (defun use-package-handler/:bind-keymap* (name keyword arg rest state) (use-package-handler/:bind-keymap name keyword arg rest state t)) -(provide 'up-bind-key) +(provide 'use-package-bind-key) diff --git a/up-core.el b/lisp/use-package/use-package-core.el similarity index 99% rename from up-core.el rename to lisp/use-package/use-package-core.el index 527c8b19463..2e2fa945056 100644 --- a/up-core.el +++ b/lisp/use-package/use-package-core.el @@ -1,4 +1,4 @@ -;;; up-core.el --- A configuration macro for simplifying your .emacs +;;; use-package-core.el --- A configuration macro for simplifying your .emacs ;; Copyright (C) 2012-2017 John Wiegley @@ -1344,7 +1344,7 @@ this file. Usage: (put 'use-package 'lisp-indent-function 'defun) -(provide 'up-core) +(provide 'use-package-core) ;; Local Variables: ;; indent-tabs-mode: nil diff --git a/up-delight.el b/lisp/use-package/use-package-delight.el similarity index 96% rename from up-delight.el rename to lisp/use-package/use-package-delight.el index 2a2138a56db..9f0a93fb00f 100644 --- a/up-delight.el +++ b/lisp/use-package/use-package-delight.el @@ -1,4 +1,4 @@ -;;; up-delight.el --- Support for the :delight keyword +;;; use-package-delight.el --- Support for the :delight keyword ;; Copyright (C) 2012-2017 John Wiegley @@ -33,7 +33,7 @@ ;;; Code: -(require 'up-core) +(require 'use-package-core) (defun use-package-normalize-delight (name args) "Normalize ARGS for a single call to `delight'." @@ -84,4 +84,4 @@ (add-to-list 'use-package-keywords :delight t) -(provide 'up-delight) +(provide 'use-package-delight) diff --git a/up-diminish.el b/lisp/use-package/use-package-diminish.el similarity index 95% rename from up-diminish.el rename to lisp/use-package/use-package-diminish.el index f848531875a..d177a908839 100644 --- a/up-diminish.el +++ b/lisp/use-package/use-package-diminish.el @@ -1,4 +1,4 @@ -;;; up-diminish.el --- Support for the :diminish keyword +;;; use-package-diminish.el --- Support for the :diminish keyword ;; Copyright (C) 2012-2017 John Wiegley @@ -33,7 +33,7 @@ ;;; Code: -(require 'up-core) +(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: @@ -73,4 +73,4 @@ (add-to-list 'use-package-keywords :diminish t) -(provide 'up-diminish) +(provide 'use-package-diminish) diff --git a/up-ensure.el b/lisp/use-package/use-package-ensure.el similarity index 98% rename from up-ensure.el rename to lisp/use-package/use-package-ensure.el index 30f2190e922..5f728e36246 100644 --- a/up-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -1,4 +1,4 @@ -;;; up-ensure.el --- Support for the :ensure and :pin keywords +;;; use-package-ensure.el --- Support for the :ensure and :pin keywords ;; Copyright (C) 2012-2017 John Wiegley @@ -34,7 +34,7 @@ ;;; Code: (require 'cl-lib) -(require 'up-core) +(require 'use-package-core) (defgroup use-package-ensure nil "Support for :ensure and :pin keywords in use-package declarations." @@ -201,4 +201,4 @@ manually updated package." (add-to-list 'use-package-keywords :ensure) (add-to-list 'use-package-keywords :pin) -(provide 'up-ensure) +(provide 'use-package-ensure) diff --git a/up-jump.el b/lisp/use-package/use-package-jump.el similarity index 95% rename from up-jump.el rename to lisp/use-package/use-package-jump.el index 721c17c7100..000c6bc38b7 100644 --- a/up-jump.el +++ b/lisp/use-package/use-package-jump.el @@ -1,4 +1,4 @@ -;;; up-jump.el --- Attempt to jump to a use-package declaration +;;; use-package-jump.el --- Attempt to jump to a use-package declaration ;; Copyright (C) 2012-2017 John Wiegley @@ -35,7 +35,7 @@ ;;; Code: -(require 'up-core) +(require 'use-package-core) (defun use-package-find-require (package) "Find file that required PACKAGE by searching `load-history'. @@ -74,4 +74,4 @@ instead." (goto-char location) (beginning-of-line)))))) -(provide 'up-jump) +(provide 'use-package-jump) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 72a9e1a2250..a00957afe5a 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -39,15 +39,15 @@ ;;; Code: -(require 'up-core) +(require 'use-package-core) -(require 'up-bind-key) -(require 'up-diminish) -(require 'up-delight) -(require 'up-ensure) +(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 "up-jump") -(autoload #'use-package-jump-to-package-form "up-jump" nil t) +(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) diff --git a/up-tests.el b/test/lisp/use-package/use-package-tests.el similarity index 99% rename from up-tests.el rename to test/lisp/use-package/use-package-tests.el index bb22b344479..5c6f0fe92d9 100644 --- a/up-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -17,7 +17,7 @@ ;;; Commentary: -;; +;; ;;; Code: From a2ddc1806552e1df9ff56a9d21917b91c83d3376 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 13:27:57 -0800 Subject: [PATCH 403/606] Comment out two tests that break on Travis --- test/lisp/use-package/use-package-tests.el | 88 +++++++++++----------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 5c6f0fe92d9..ef6c52c583e 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -701,51 +701,51 @@ (autoload #'bar "foo" nil t)) (bar)))) -(ert-deftest use-package-test/:commands-5 () - (match-expansion - (use-package gnus-harvest - :load-path "lisp/gnus-harvest" - :commands gnus-harvest-install - :demand t - :config - (if (featurep 'message-x) - (gnus-harvest-install 'message-x) - (gnus-harvest-install))) - `(progn - (eval-and-compile - (add-to-list 'load-path "/Users/johnw/.emacs.d/lisp/gnus-harvest")) - (require 'gnus-harvest nil nil) - (if (featurep 'message-x) - (gnus-harvest-install 'message-x) - (gnus-harvest-install)) - t))) +;; (ert-deftest use-package-test/:commands-5 () +;; (match-expansion +;; (use-package gnus-harvest +;; :load-path "lisp/gnus-harvest" +;; :commands gnus-harvest-install +;; :demand t +;; :config +;; (if (featurep 'message-x) +;; (gnus-harvest-install 'message-x) +;; (gnus-harvest-install))) +;; `(progn +;; (eval-and-compile +;; (add-to-list 'load-path "/Users/johnw/.emacs.d/lisp/gnus-harvest")) +;; (require 'gnus-harvest nil nil) +;; (if (featurep 'message-x) +;; (gnus-harvest-install 'message-x) +;; (gnus-harvest-install)) +;; t))) -(ert-deftest use-package-test/:commands-6 () - (let ((byte-compile-current-file t)) - (match-expansion - (use-package gnus-harvest - :load-path "lisp/gnus-harvest" - :commands gnus-harvest-install - :demand t - :config - (if (featurep 'message-x) - (gnus-harvest-install 'message-x) - (gnus-harvest-install))) - `(progn - (eval-and-compile - (add-to-list 'load-path "/Users/johnw/.emacs.d/lisp/gnus-harvest")) - (eval-and-compile - (eval-when-compile - (with-demoted-errors "Cannot load gnus-harvest: %S" nil - (load "gnus-harvest" nil t)))) - (eval-when-compile - (declare-function gnus-harvest-install "gnus-harvest")) - (require 'gnus-harvest nil nil) - (if - (featurep 'message-x) - (gnus-harvest-install 'message-x) - (gnus-harvest-install)) - t)))) +;; (ert-deftest use-package-test/:commands-6 () +;; (let ((byte-compile-current-file t)) +;; (match-expansion +;; (use-package gnus-harvest +;; :load-path "lisp/gnus-harvest" +;; :commands gnus-harvest-install +;; :demand t +;; :config +;; (if (featurep 'message-x) +;; (gnus-harvest-install 'message-x) +;; (gnus-harvest-install))) +;; `(progn +;; (eval-and-compile +;; (add-to-list 'load-path "/Users/johnw/.emacs.d/lisp/gnus-harvest")) +;; (eval-and-compile +;; (eval-when-compile +;; (with-demoted-errors "Cannot load gnus-harvest: %S" nil +;; (load "gnus-harvest" nil t)))) +;; (eval-when-compile +;; (declare-function gnus-harvest-install "gnus-harvest")) +;; (require 'gnus-harvest nil nil) +;; (if +;; (featurep 'message-x) +;; (gnus-harvest-install 'message-x) +;; (gnus-harvest-install)) +;; t)))) (ert-deftest use-package-test/:defines-1 () (match-expansion From 6470eaf3d53d2596a7cc7bbe43ec7a47f6ea70ed Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 15:21:41 -0800 Subject: [PATCH 404/606] Fix an argument process problem with bind-key Fixes https://github.com/jwiegley/use-package/issues/334 --- lisp/use-package/bind-key.el | 55 ++++++++++------ test/lisp/use-package/use-package-tests.el | 77 +++++++++++++++++++++- 2 files changed, 110 insertions(+), 22 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index e5e06c7cd2a..1b11e6c8322 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -197,7 +197,7 @@ See `bind-key' for more details." "Similar to `bind-key', but overrides any mode-specific bindings." `(bind-key ,key-name ,command override-global-map ,predicate)) -(defun bind-keys-form (args) +(defun bind-keys-form (args keymap) "Bind multiple keys at once. Accepts keyword arguments: @@ -217,25 +217,37 @@ function symbol (unquoted)." (if (and (eq (car args) :package) (not (eq (car (cdr (cdr args))) :map))) (setq args (cons :map (cons 'global-map args)))) - (let* ((map (plist-get args :map)) - (doc (plist-get args :prefix-docstring)) - (prefix-map (plist-get args :prefix-map)) - (prefix (plist-get args :prefix)) - (filter (plist-get args :filter)) - (menu-name (plist-get args :menu-name)) - (pkg (plist-get args :package)) - (key-bindings (progn - (while (keywordp (car args)) - (pop args) - (pop args)) - args))) + (let ((map keymap) + doc + prefix-map + prefix + filter + menu-name + pkg) + + ;; Process any initial keyword arguments + (let ((cont t)) + (while (and cont args) + (if (pcase (car args) + (`:map (setq map (cadr args))) + (`:prefix-docstring (setq doc (cadr args))) + (`:prefix-map (setq prefix-map (cadr args))) + (`:prefix (setq prefix (cadr args))) + (`:filter (setq filter (cadr args)) t) + (`:menu-name (setq menu-name (cadr args))) + (`:package (setq pkg (cadr args)))) + (setq args (cddr 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 (and menu-name (not prefix)) (error "If :menu-name is supplied, :prefix must be too")) - (let ((args key-bindings) - saw-map first next) + + ;; Process key binding arguments + (let (first next) (while args (if (keywordp (car args)) (progn @@ -245,6 +257,7 @@ function symbol (unquoted)." (nconc first (list (car args))) (setq first (list (car args)))) (setq args (cdr args)))) + (cl-flet ((wrap (map bindings) (if (and map pkg (not (eq map 'global-map))) @@ -254,6 +267,7 @@ function symbol (unquoted)." ,(if (symbolp pkg) `',pkg pkg) '(progn ,@bindings)))) bindings))) + (append (when prefix-map `((defvar ,prefix-map) @@ -275,10 +289,9 @@ function symbol (unquoted)." `((bind-key ,(car form) ,fun nil ,filter)))))) first)) (when next - (bind-keys-form - (if pkg - (cons :package (cons pkg next)) - next)))))))) + (bind-keys-form (if pkg + (cons :package (cons pkg next)) + next) map))))))) ;;;###autoload (defmacro bind-keys (&rest args) @@ -296,12 +309,12 @@ Accepts keyword arguments: The rest of the arguments are conses of keybinding string and a function symbol (unquoted)." - (macroexp-progn (bind-keys-form args))) + (macroexp-progn (bind-keys-form args nil))) ;;;###autoload (defmacro bind-keys* (&rest args) (macroexp-progn - (bind-keys-form `(:map override-global-map ,@args)))) + (bind-keys-form args 'override-global-map))) (defun get-binding-description (elem) (cond diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index ef6c52c583e..80bbb728675 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -77,7 +77,7 @@ (unless (looking-at "(match-expansion") (backward-up-list)) (when (looking-at "(match-expansion") - (search-forward "(use-package") + (re-search-forward "(\\(use-package\\|bind-key\\)") (goto-char (match-beginning 0)) (let ((decl (read (current-buffer)))) (kill-sexp) @@ -1356,6 +1356,81 @@ (if (fboundp 'delight) (delight '((foo "bar" foo))))))) +(ert-deftest use-package-test/334-1 () + (let (foo1-map foo2-map + bar1-func1 + bar1-func2 + bar2-func1 + bar2-func2 + bar3-func1 + bar3-func2 + bar4-func1 + bar4-func2) + (match-expansion + (bind-keys :map foo1-map + ("Y" . foo1) + :prefix "y" + :prefix-map bar1-prefix-map + ("y" . bar1-func1) + ("f" . bar1-func2) + :prefix "y" + :prefix-map bar2-prefix-map + ("y" . bar2-func1) + ("f" . bar2-func2) + :map foo2-map + ("Y" . foo2) + :prefix "y" + :prefix-map bar3-prefix-map + ("y" . bar3-func1) + ("f" . bar3-func2) + :prefix "y" + :prefix-map bar4-prefix-map + ("y" . bar4-func1) + ("f" . bar4-func2)) + `(progn + (bind-key "Y" #'foo1 foo1-map nil) + (defvar bar1-prefix-map) + (define-prefix-command 'bar1-prefix-map) + (bind-key "y" 'bar1-prefix-map foo1-map nil) + (bind-key "y" #'bar1-func1 bar1-prefix-map nil) + (bind-key "f" #'bar1-func2 bar1-prefix-map nil) + (defvar bar2-prefix-map) + (define-prefix-command 'bar2-prefix-map) + (bind-key "y" 'bar2-prefix-map foo1-map nil) + (bind-key "y" #'bar2-func1 bar2-prefix-map nil) + (bind-key "f" #'bar2-func2 bar2-prefix-map nil) + (bind-key "Y" #'foo2 foo2-map nil) + (defvar bar3-prefix-map) + (define-prefix-command 'bar3-prefix-map) + (bind-key "y" 'bar3-prefix-map foo2-map nil) + (bind-key "y" #'bar3-func1 bar3-prefix-map nil) + (bind-key "f" #'bar3-func2 bar3-prefix-map nil) + (defvar bar4-prefix-map) + (define-prefix-command 'bar4-prefix-map) + (bind-key "y" 'bar4-prefix-map foo2-map nil) + (bind-key "y" #'bar4-func1 bar4-prefix-map nil) + (bind-key "f" #'bar4-func2 bar4-prefix-map nil))))) + +(ert-deftest use-package-test/334-2 () + (let (w3m-lnum-mode-map + w3m-print-current-url + w3m-lnum-print-this-url + w3m-print-this-url) + (match-expansion + (bind-keys :map w3m-lnum-mode-map + :prefix "y" + :prefix-map w3m-y-prefix-map + ("y" . w3m-print-current-url) + ("f" . w3m-lnum-print-this-url) + ("t" . w3m-print-this-url)) + `(progn + (defvar w3m-y-prefix-map) + (define-prefix-command 'w3m-y-prefix-map) + (bind-key "y" 'w3m-y-prefix-map w3m-lnum-mode-map nil) + (bind-key "y" #'w3m-print-current-url w3m-y-prefix-map nil) + (bind-key "f" #'w3m-lnum-print-this-url w3m-y-prefix-map nil) + (bind-key "t" #'w3m-print-this-url w3m-y-prefix-map nil))))) + (ert-deftest use-package-test/506 () (match-expansion (use-package ess-site From 6c836985b181084123ffeaac463a320cdf96ff90 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 15:22:08 -0800 Subject: [PATCH 405/606] Swap the order of two definitions --- lisp/use-package/use-package-core.el | 90 ++++++++++++++-------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 2e2fa945056..a82609dcfd9 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -452,20 +452,36 @@ This is in contrast to merely setting it to 0." (return-from outer index)) (incf index))) -(defun use-package-sort-keywords (plist) - (let (plist-grouped) - (while plist - (push (cons (car plist) (cadr plist)) - plist-grouped) - (setq plist (cddr plist))) - (let (result) - (dolist (x - (nreverse - (sort plist-grouped - #'(lambda (l r) (< (use-package-keyword-index (car l)) - (use-package-keyword-index (car r))))))) - (setq result (cons (car x) (cons (cdr x) result)))) - result))) +(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." + (when input + (let* ((keyword (car input)) + (xs (use-package-split-list #'keywordp (cdr input))) + (args (car xs)) + (tail (cdr xs)) + (normalizer (intern (concat "use-package-normalize/" + (symbol-name keyword)))) + (arg (cond ((functionp normalizer) + (funcall normalizer name keyword args)) + ((= (length args) 1) + (car args)) + (t + args)))) + (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))) + (ignore + (display-warning 'use-package + (format "Unrecognized keyword: %s" keyword) + :warning)))))) (defun use-package-unalias-keywords (name args) (setq args (cl-nsubstitute :if :when args)) @@ -482,6 +498,21 @@ This is in contrast to merely setting it to 0." (`:defer 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) + (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))) @@ -540,37 +571,6 @@ This is in contrast to merely setting it to 0." ;; Sort the list of keywords based on the order of `use-package-keywords'. (use-package-sort-keywords args))) -(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." - (when input - (let* ((keyword (car input)) - (xs (use-package-split-list #'keywordp (cdr input))) - (args (car xs)) - (tail (cdr xs)) - (normalizer (intern (concat "use-package-normalize/" - (symbol-name keyword)))) - (arg (cond ((functionp normalizer) - (funcall normalizer name keyword args)) - ((= (length args) 1) - (car args)) - (t - args)))) - (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))) - (ignore - (display-warning 'use-package - (format "Unrecognized keyword: %s" keyword) - :warning)))))) - (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 From e34fdb580a73d3e79e14cbc3b32d9219f30cdc2f Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 15:24:31 -0800 Subject: [PATCH 406/606] Add several missing comments --- lisp/use-package/use-package-bind-key.el | 2 ++ lisp/use-package/use-package-core.el | 2 +- lisp/use-package/use-package-delight.el | 2 ++ lisp/use-package/use-package-diminish.el | 2 ++ lisp/use-package/use-package-ensure.el | 2 ++ lisp/use-package/use-package-jump.el | 2 ++ lisp/use-package/use-package.el | 4 ---- 7 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index 4021bb432d6..5d1860b4e13 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -128,3 +128,5 @@ deferred until the prefix key sequence is pressed." (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/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index a82609dcfd9..f5f1f7e6bd8 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1350,4 +1350,4 @@ this file. Usage: ;; indent-tabs-mode: nil ;; End: -;;; use-package.el ends here +;;; use-package-core.el ends here diff --git a/lisp/use-package/use-package-delight.el b/lisp/use-package/use-package-delight.el index 9f0a93fb00f..3617f9aac58 100644 --- a/lisp/use-package/use-package-delight.el +++ b/lisp/use-package/use-package-delight.el @@ -85,3 +85,5 @@ (add-to-list 'use-package-keywords :delight t) (provide 'use-package-delight) + +;;; use-package-delight.el ends here diff --git a/lisp/use-package/use-package-diminish.el b/lisp/use-package/use-package-diminish.el index d177a908839..089c62ddeb3 100644 --- a/lisp/use-package/use-package-diminish.el +++ b/lisp/use-package/use-package-diminish.el @@ -74,3 +74,5 @@ (add-to-list 'use-package-keywords :diminish t) (provide 'use-package-diminish) + +;;; use-package-diminish.el ends here diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index 5f728e36246..2ed34e4071e 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -202,3 +202,5 @@ manually updated package." (add-to-list 'use-package-keywords :pin) (provide 'use-package-ensure) + +;;; use-package-ensure.el ends here diff --git a/lisp/use-package/use-package-jump.el b/lisp/use-package/use-package-jump.el index 000c6bc38b7..31d1b054060 100644 --- a/lisp/use-package/use-package-jump.el +++ b/lisp/use-package/use-package-jump.el @@ -75,3 +75,5 @@ instead." (beginning-of-line)))))) (provide 'use-package-jump) + +;;; use-package-jump.el ends here diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index a00957afe5a..5f98db1bed7 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -51,8 +51,4 @@ (provide 'use-package) -;; Local Variables: -;; indent-tabs-mode: nil -;; End: - ;;; use-package.el ends here From 62d33b2143018e5ad23f0f34c84250c950f0d71b Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 15:39:31 -0800 Subject: [PATCH 407/606] Support :ensure (pkg :pin archive) Fixes https://github.com/jwiegley/use-package/issues/506 --- etc/USE-PACKAGE-NEWS | 20 +++++++++ lisp/use-package/use-package-ensure.el | 23 +++++++---- test/lisp/use-package/use-package-tests.el | 48 ++++++++++++---------- 3 files changed, 61 insertions(+), 30 deletions(-) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index 3bdd623adeb..28f76b942ea 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -50,6 +50,26 @@ for use by extension packages, indicates keywords that, if used without `:demand`, cause deferred loading (as if `:defer t` had been specified). +- The `:ensure` keyword now accepts a specific pinning sub-keyword. For + example: + + ``` elisp + (use-package foo + :pin "elpa") + ``` + + This ensure the package `foo` is installed from `"elpa"`. + + ``` elisp + (use-package foo + :ensure bar + :ensure (quux :pin "melpa")) + ``` + + This says that `foo` ensures that `bar` is installed, as well as `quux` from + `"melpa"`. It does *not* ensure that `foo` is installed, because explicit + `:ensure` keywords were given. + - New `:hook` keyword. - New `:catch` keyword. If `t` or `nil`, it enables (the default, see diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index 2ed34e4071e..083350edf9e 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -137,15 +137,17 @@ manually updated package." t (use-package-only-one (symbol-name keyword) args #'(lambda (label arg) - (cond - ((symbolp arg) - (list arg)) - ((and (listp arg) (cl-every #'symbolp arg)) - arg) - (t - (use-package-error - (concat ":ensure wants an optional package name " - "(an unquoted symbol name)")))))))) + (pcase arg + ((pred symbolp) + (list arg)) + (`(,(and pkg (pred symbolp)) + :pin ,(and repo (or (pred stringp) + (pred symbolp)))) + (list (cons pkg repo))) + (_ + (use-package-error + (concat ":ensure wants an optional package name " + "(an unquoted symbol name), or ( :pin )")))))))) (defun use-package-ensure-elpa (name args state &optional no-refresh) (dolist (ensure args) @@ -154,6 +156,9 @@ manually updated package." 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 diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 80bbb728675..51a57edb7d2 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -343,11 +343,33 @@ (require 'foo nil nil))))) (ert-deftest use-package-test/:ensure-14 () + (match-expansion + (use-package ess-site + :ensure ess1 + :ensure ess2 + :ensure (ess3 :pin "melpa-unstable") + :pin melpa-stable) + `(progn + (use-package-pin-package 'ess-site "melpa-stable") + (use-package-ensure-elpa 'ess-site + '(ess1 ess2 + (ess3 . "melpa-unstable")) + 'nil) + (require 'ess-site nil nil)))) + +(ert-deftest use-package-test/:ensure-15 () (let ((use-package-always-ensure t)) (match-expansion - (use-package foo :ensure bar :ensure (quux bow)) + (use-package foo + :pin "elpa" + :ensure bar + :ensure (quux :pin "melpa")) `(progn - (use-package-ensure-elpa 'foo '(bar quux bow) 'nil) + (use-package-pin-package 'foo "elpa") + (use-package-ensure-elpa 'foo + '(bar + (quux . "melpa")) + 'nil) (require 'foo nil nil))))) (ert-deftest use-package-test/:if-1 () @@ -1431,18 +1453,6 @@ (bind-key "f" #'w3m-lnum-print-this-url w3m-y-prefix-map nil) (bind-key "t" #'w3m-print-this-url w3m-y-prefix-map nil))))) -(ert-deftest use-package-test/506 () - (match-expansion - (use-package ess-site - :ensure ess - :pin melpa-stable) - `(progn - (use-package-pin-package 'ess-site "melpa-stable") - (use-package-ensure-elpa 'ess-site - '(ess) - 'nil) - (require 'ess-site nil nil)))) - (ert-deftest use-package-test/538 () (match-expansion (use-package mu4e @@ -1452,16 +1462,12 @@ :config (config)) `(progn - (unless - (fboundp 'mu4e) + (unless (fboundp 'mu4e) (autoload #'mu4e "mu4e" nil t)) (eval-after-load 'mu4e - '(progn - (config) - t)) + '(progn (config) t)) (ignore - (bind-keys :package mu4e - ("" . mu4e)))))) + (bind-keys :package mu4e ("" . mu4e)))))) ;; Local Variables: ;; indent-tabs-mode: nil From 2790bfc00618046d44a9c4817f1128ad2986fc10 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 15:43:10 -0800 Subject: [PATCH 408/606] Add a bind-key test --- test/lisp/use-package/use-package-tests.el | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 51a57edb7d2..76e0be5105b 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1469,6 +1469,15 @@ (ignore (bind-keys :package mu4e ("" . mu4e)))))) +(ert-deftest bind-key/:prefix-map () + (match-expansion + (bind-keys :prefix "" + :prefix-map my/map) + `(progn + (defvar my/map) + (define-prefix-command 'my/map) + (bind-key "" 'my/map nil nil)))) + ;; Local Variables: ;; indent-tabs-mode: nil ;; no-byte-compile: t From 277384d1512141b4577070f2dc50cd1560868272 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 15:55:41 -0800 Subject: [PATCH 409/606] Add a note to `bind-key` on the usage of the KEYMAP argument Fixes https://github.com/jwiegley/use-package/issues/542 --- lisp/use-package/bind-key.el | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 1b11e6c8322..54961ecd96e 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -146,6 +146,13 @@ KEY-NAME may be a vector, in which case it is passed straight to 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 and not a quoted symbol. +For example: + + (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 From 2892c026f469706cfbb30bf737625902b2d3cdc2 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 16:36:40 -0800 Subject: [PATCH 410/606] Add note in NEWS.md about :after and autoloaded keybindings --- etc/USE-PACKAGE-NEWS | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index 28f76b942ea..5873d699089 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -118,6 +118,24 @@ features (diminish, delight, ensure) may be maintained separately from the core functionality. +- When using the `:after` keyword, now even autoloadeds keybinding are + deferred until after that other package has loaded, in order to allow + convenient `:bind` to maps only present in that other package. Consider the + following: + + ``` elisp + (use-package helm-descbinds + :load-path "site-lisp/helm-descbinds" + :after helm + :bind ("C-h b" . helm-descbinds) + :init + (fset 'describe-bindings 'helm-descbinds)) + ``` + + The binding of `C-h b` here will not occur until helm is loaded; and after + it is loaded, `helm-descbinds` itself is not loaded until the user presses + `C-h b`. + ### Bug fixes - Repeating a bind no longer causes duplicates in personal-keybindings. From afdf1c363809e721a838f8e7d0b9b791f3138b52 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 16:42:56 -0800 Subject: [PATCH 411/606] Some Emacsen don't have gensym Fixes https://github.com/jwiegley/use-package/issues/544 --- lisp/use-package/use-package-core.el | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index f5f1f7e6bd8..727e0d647fa 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -276,6 +276,19 @@ Must be set before loading use-package." ;;; Utility functions ;; +(defvar use-package-gensym-counter 0 + "Number used to construct the name of the next symbol created +by `use-package-gensym'.") + +(defun use-package-gensym (&optional prefix) + "Return a new uninterned symbol. +The name is made by appending `gensym-counter' to PREFIX. +PREFIX is a string, and defaults to \"g\"." + (let ((num (prog1 use-package-gensym-counter + (setq use-package-gensym-counter + (1+ use-package-gensym-counter))))) + (make-symbol (format "%s%d" (or prefix "g") num)))) + (defsubst use-package-error (msg) "Report MSG as an error, so the user knows it came from this package." (error "use-package: %s" msg)) @@ -636,9 +649,9 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." (defun use-package-memoize (f arg) "Ensure the macro-expansion of F applied to ARG evaluates ARG no more than once." - (let ((loaded (gensym "use-package--loaded")) - (result (gensym "use-package--result")) - (next (gensym "use-package--next"))) + (let ((loaded (use-package-gensym "use-package--loaded")) + (result (use-package-gensym "use-package--result")) + (next (use-package-gensym "use-package--next"))) `((lexical-let (,loaded ,result) (lexical-let ((,next (lambda () (if ,loaded @@ -921,7 +934,7 @@ representing symbols (that may need to be autloaded)." use-package--hush-function))) (defun use-package-handler/:catch (name keyword arg rest state) - (let* ((context (gensym "use-package--warning"))) + (let* ((context (use-package-gensym "use-package--warning"))) (cond ((not arg) (use-package-process-keywords name rest state)) From ee07e709eadc85479c06db9ca40e6f18bcb41463 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 16:46:46 -0800 Subject: [PATCH 412/606] Fix the case where :ensure is given no arguments Fixes https://github.com/jwiegley/use-package/issues/543 --- lisp/use-package/use-package-ensure.el | 2 +- test/lisp/use-package/use-package-tests.el | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index 083350edf9e..9cf94419d8a 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -134,7 +134,7 @@ manually updated package." (defun use-package-normalize/:ensure (name keyword args) (if (null args) - t + (list t) (use-package-only-one (symbol-name keyword) args #'(lambda (label arg) (pcase arg diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 76e0be5105b..938e990b856 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1469,6 +1469,14 @@ (ignore (bind-keys :package mu4e ("" . mu4e)))))) +(ert-deftest use-package-test/543 () + (match-expansion + (use-package hydra + :ensure) + `(progn + (use-package-ensure-elpa 'hydra '(t) 'nil) + (require 'hydra nil nil)))) + (ert-deftest bind-key/:prefix-map () (match-expansion (bind-keys :prefix "" From 43f1be12b770171a1dd396d0b386322c7c88926e Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 4 Dec 2017 17:03:59 -0800 Subject: [PATCH 413/606] Use cl-gensym --- lisp/use-package/use-package-core.el | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 727e0d647fa..acf053baf52 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -276,19 +276,6 @@ Must be set before loading use-package." ;;; Utility functions ;; -(defvar use-package-gensym-counter 0 - "Number used to construct the name of the next symbol created -by `use-package-gensym'.") - -(defun use-package-gensym (&optional prefix) - "Return a new uninterned symbol. -The name is made by appending `gensym-counter' to PREFIX. -PREFIX is a string, and defaults to \"g\"." - (let ((num (prog1 use-package-gensym-counter - (setq use-package-gensym-counter - (1+ use-package-gensym-counter))))) - (make-symbol (format "%s%d" (or prefix "g") num)))) - (defsubst use-package-error (msg) "Report MSG as an error, so the user knows it came from this package." (error "use-package: %s" msg)) @@ -649,9 +636,9 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." (defun use-package-memoize (f arg) "Ensure the macro-expansion of F applied to ARG evaluates ARG no more than once." - (let ((loaded (use-package-gensym "use-package--loaded")) - (result (use-package-gensym "use-package--result")) - (next (use-package-gensym "use-package--next"))) + (let ((loaded (cl-gensym "use-package--loaded")) + (result (cl-gensym "use-package--result")) + (next (cl-gensym "use-package--next"))) `((lexical-let (,loaded ,result) (lexical-let ((,next (lambda () (if ,loaded @@ -934,7 +921,7 @@ representing symbols (that may need to be autloaded)." use-package--hush-function))) (defun use-package-handler/:catch (name keyword arg rest state) - (let* ((context (use-package-gensym "use-package--warning"))) + (let* ((context (cl-gensym "use-package--warning"))) (cond ((not arg) (use-package-process-keywords name rest state)) From f037c2daeb8146780cdd56f9e45c857d76a7bb06 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 4 Dec 2017 22:44:22 -0800 Subject: [PATCH 414/606] Fix function accidentally made interactive --- lisp/use-package/use-package-core.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index acf053baf52..15ca2649e5c 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -819,7 +819,9 @@ representing symbols (that may need to be autloaded)." ;;;; :disabled -(defalias 'use-package-normalize/:disabled 'ignore) +;; Don't alias this to `ignore', as that will cause the resulting +;; function to be interactive. +(defun use-package-normalize/:disabled (name keyword arg rest state)) (defun use-package-handler/:disabled (name keyword arg rest state) (use-package-process-keywords name rest state)) From 10fd4577d012789348a79c0e3ffedf54089e1ec4 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 5 Dec 2017 10:28:28 -0800 Subject: [PATCH 415/606] Add missing autoload cookies Fixes https://github.com/jwiegley/use-package/issues/555 --- lisp/use-package/use-package-bind-key.el | 7 +++++++ lisp/use-package/use-package-chords.el | 2 ++ lisp/use-package/use-package-delight.el | 2 ++ lisp/use-package/use-package-diminish.el | 2 ++ lisp/use-package/use-package-ensure-system-package.el | 2 ++ lisp/use-package/use-package-ensure.el | 2 ++ 6 files changed, 17 insertions(+) diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index 5d1860b4e13..54389faf346 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -83,9 +83,12 @@ deferred until the prefix key sequence is pressed." ;;;; :bind, :bind* +;;;###autoload (defalias 'use-package-normalize/:bind 'use-package-normalize-binder) +;;;###autoload (defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) +;;;###autoload (defun use-package-handler/:bind (name keyword args rest state &optional bind-macro) (cl-destructuring-bind (nargs . commands) @@ -104,9 +107,12 @@ deferred until the prefix key sequence is pressed." ;;;; :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 arg rest state &optional override) (use-package-concat @@ -124,6 +130,7 @@ deferred until the prefix key sequence is pressed." ',(cdr binding) ',(use-package-as-symbol name) ,override)))) arg))))) +;;;###autoload (defun use-package-handler/:bind-keymap* (name keyword arg rest state) (use-package-handler/:bind-keymap name keyword arg rest state t)) diff --git a/lisp/use-package/use-package-chords.el b/lisp/use-package/use-package-chords.el index 023a9c6b2ad..8cdd30990cb 100644 --- a/lisp/use-package/use-package-chords.el +++ b/lisp/use-package/use-package-chords.el @@ -23,8 +23,10 @@ (require 'use-package) (require 'bind-chord) +;;;###autoload (defalias 'use-package-normalize/:chords 'use-package-normalize-binder) +;;;###autoload (defun use-package-handler/:chords (name keyword arg rest state) "Handler for `:chords' keyword in `use-package'." (let* ((commands (remq nil (mapcar #'(lambda (arg) diff --git a/lisp/use-package/use-package-delight.el b/lisp/use-package/use-package-delight.el index 3617f9aac58..625cc5a5554 100644 --- a/lisp/use-package/use-package-delight.el +++ b/lisp/use-package/use-package-delight.el @@ -51,6 +51,7 @@ (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) @@ -75,6 +76,7 @@ (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 diff --git a/lisp/use-package/use-package-diminish.el b/lisp/use-package/use-package-diminish.el index 089c62ddeb3..77708ef396c 100644 --- a/lisp/use-package/use-package-diminish.el +++ b/lisp/use-package/use-package-diminish.el @@ -56,10 +56,12 @@ (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 diff --git a/lisp/use-package/use-package-ensure-system-package.el b/lisp/use-package/use-package-ensure-system-package.el index 36a614d47c3..0fae57aff76 100644 --- a/lisp/use-package/use-package-ensure-system-package.el +++ b/lisp/use-package/use-package-ensure-system-package.el @@ -50,6 +50,7 @@ (cons arg (use-package-ensure-system-package-install-command (symbol-name arg)))) ((consp arg) arg))) +;;;###autoload (defun use-package-normalize/:ensure-system-package (name-symbol keyword args) "Turn `arg' into a list of cons-es of (`package-name' . `install-command')." (use-package-only-one (symbol-name keyword) args @@ -60,6 +61,7 @@ (t (list (use-package-ensure-system-package-consify arg))))))) +;;;###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))) diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index 9cf94419d8a..1c9cd08ff19 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -132,6 +132,7 @@ manually updated package." (defvar package-archive-contents) +;;;###autoload (defun use-package-normalize/:ensure (name keyword args) (if (null args) (list t) @@ -180,6 +181,7 @@ manually updated package." 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))) ;; We want to avoid installing packages when the `use-package' macro is From a090961f105595b6c9b56c0e5cda567c76687b06 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 5 Dec 2017 10:29:04 -0800 Subject: [PATCH 416/606] Fix bad interaction between bind-keys* and the :package keyword Fixes https://github.com/jwiegley/use-package/issues/558 --- lisp/use-package/bind-key.el | 9 +++++---- test/lisp/use-package/use-package-tests.el | 6 ++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 54961ecd96e..f5477945b4b 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -222,8 +222,10 @@ function symbol (unquoted)." ;; jww (2016-02-26): This is a hack; this whole function needs to be ;; rewritten to normalize arguments the way that use-package.el does. (if (and (eq (car args) :package) - (not (eq (car (cdr (cdr args))) :map))) + (not (eq (car (cdr (cdr args))) :map)) + (not keymap)) (setq args (cons :map (cons 'global-map args)))) + (let ((map keymap) doc prefix-map @@ -267,7 +269,7 @@ function symbol (unquoted)." (cl-flet ((wrap (map bindings) - (if (and map pkg (not (eq map 'global-map))) + (if (and map pkg (not (memq map '(global-map override-global-map)))) `((if (boundp ',map) (progn ,@bindings) (eval-after-load @@ -320,8 +322,7 @@ function symbol (unquoted)." ;;;###autoload (defmacro bind-keys* (&rest args) - (macroexp-progn - (bind-keys-form args 'override-global-map))) + (macroexp-progn (bind-keys-form args 'override-global-map))) (defun get-binding-description (elem) (cond diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 938e990b856..67d7c6f7e4d 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1477,6 +1477,12 @@ (use-package-ensure-elpa 'hydra '(t) 'nil) (require 'hydra nil nil)))) +(ert-deftest use-package-test/558 () + (match-expansion + (bind-keys* :package org-ref + ("C-c C-r" . org-ref-helm-insert-cite-link)) + `(bind-key "C-c C-r" #'org-ref-helm-insert-cite-link override-global-map nil))) + (ert-deftest bind-key/:prefix-map () (match-expansion (bind-keys :prefix "" From 0a628a27675491bbf154b4c641876ec1124a59ae Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 5 Dec 2017 11:10:16 -0800 Subject: [PATCH 417/606] Avoid using pcase and many other macros in macro-expanded forms This is related to https://github.com/jwiegley/use-package/issues/550 --- lisp/use-package/bind-key.el | 22 +- lisp/use-package/use-package-bind-key.el | 11 +- lisp/use-package/use-package-core.el | 222 +++++++++++---------- lisp/use-package/use-package-ensure.el | 24 ++- test/lisp/use-package/use-package-tests.el | 177 ++++++++++------ 5 files changed, 263 insertions(+), 193 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index f5477945b4b..70a83e8a6e4 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -237,14 +237,20 @@ function symbol (unquoted)." ;; Process any initial keyword arguments (let ((cont t)) (while (and cont args) - (if (pcase (car args) - (`:map (setq map (cadr args))) - (`:prefix-docstring (setq doc (cadr args))) - (`:prefix-map (setq prefix-map (cadr args))) - (`:prefix (setq prefix (cadr args))) - (`:filter (setq filter (cadr args)) t) - (`:menu-name (setq menu-name (cadr args))) - (`:package (setq pkg (cadr args)))) + (if (cond ((eq :map (car args)) + (setq map (cadr args))) + ((eq :prefix-docstring (car args)) + (setq doc (cadr args))) + ((eq :prefix-map (car args)) + (setq prefix-map (cadr args))) + ((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 (cddr args)) (setq cont nil)))) diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index 54389faf346..09229153f0c 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -74,10 +74,8 @@ deferred until the prefix key sequence is pressed." (concat label " a ( . )" " or list of these"))) (use-package-normalize-pairs - #'(lambda (k) - (pcase k - ((pred stringp) t) - ((pred vectorp) t))) + #'(lambda (k) (cond ((stringp k) t) + ((vectorp k) t))) #'(lambda (v) (use-package-recognize-function v t #'stringp)) name label arg)))) @@ -91,8 +89,9 @@ deferred until the prefix key sequence is pressed." ;;;###autoload (defun use-package-handler/:bind (name keyword args rest state &optional bind-macro) - (cl-destructuring-bind (nargs . commands) - (use-package-normalize-commands args) + (let* ((result (use-package-normalize-commands args)) + (nargs (car result)) + (commands (cdr result))) (use-package-concat (use-package-process-keywords name (use-package-sort-keywords diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 15ca2649e5c..9705a48c603 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -429,7 +429,7 @@ This is in contrast to merely setting it to 0." (defun use-package-split-list (pred xs) (let ((ys (list nil)) (zs (list nil)) flip) - (dolist (x xs) + (cl-dolist (x xs) (if flip (nconc zs (list x)) (if (funcall pred x) @@ -445,12 +445,12 @@ This is in contrast to merely setting it to 0." ;; (defun use-package-keyword-index (keyword) - (loop named outer - with index = 0 - for k in use-package-keywords do - (if (eq k keyword) - (return-from outer index)) - (incf index))) + (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. @@ -492,11 +492,10 @@ extending any keys already present." args) (defun use-package-merge-keys (key new old) - (pcase key - (`:if `(and ,new ,old)) - (`:after `(:all ,new ,old)) - (`:defer old) - (_ (append new old)))) + (cond ((eq :if key) `(and ,new ,old)) + ((eq :after key) `(:all ,new ,old)) + ((eq :defer key) old) + (t (append new old)))) (defun use-package-sort-keywords (plist) (let (plist-grouped) @@ -505,11 +504,12 @@ extending any keys already present." plist-grouped) (setq plist (cddr plist))) (let (result) - (dolist (x - (nreverse - (sort plist-grouped - #'(lambda (l r) (< (use-package-keyword-index (car l)) - (use-package-keyword-index (car r))))))) + (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))) @@ -525,10 +525,11 @@ extending any keys already present." #'use-package-merge-keys)) ;; Add default values for keywords not specified, when applicable. - (dolist (spec use-package-defaults) - (when (pcase (nth 2 spec) - ((and func (pred functionp)) (funcall func args)) - (sexp (eval sexp))) + (cl-dolist (spec use-package-defaults) + (when (let ((func (nth 2 spec))) + (if (and func (functionp func)) + (funcall func args) + (eval func))) (setq args (use-package-plist-maybe-put args (nth 0 spec) (eval (nth 1 spec)))))) @@ -639,13 +640,14 @@ no more than once." (let ((loaded (cl-gensym "use-package--loaded")) (result (cl-gensym "use-package--result")) (next (cl-gensym "use-package--next"))) - `((lexical-let (,loaded ,result) - (lexical-let ((,next (lambda () - (if ,loaded - ,result - (setq ,loaded t) - (setq ,result ,arg))))) - ,(funcall f ``(funcall ,,next))))))) + `((defvar ,loaded nil) + (defvar ,result nil) + (defvar ,next #'(lambda () + (if ,loaded + ,result + (setq ,loaded t) + (setq ,result ,arg)))) + ,(funcall f `(funcall ,next))))) (defsubst use-package-normalize-value (label arg) "Normalize a value." @@ -718,7 +720,9 @@ no more than once." (use-package-error (concat label " wants a sexp or list of sexps"))) (mapcar #'(lambda (form) (if (and (consp form) - (eq (car form) 'use-package)) + (memq (car form) + '(use-package bind-key bind-key* + unbind-key bind-keys bind-keys*))) (macroexpand form) form)) args)) @@ -763,28 +767,33 @@ If RECURSED is non-nil, recurse into sublists." (quote (lambda () ...)) #'(lambda () ...) (function (lambda () ...))" - (pcase v - ((and x (guard (if binding - (symbolp x) - (use-package-non-nil-symbolp x)))) t) - (`(,(or `quote `function) - ,(pred use-package-non-nil-symbolp)) t) - ((and x (guard (if binding (commandp x) (functionp x)))) t) - (_ (and additional-pred - (funcall additional-pred v))))) + (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 () ...)" - (pcase v - ((pred symbolp) v) - (`(,(or `quote `function) - ,(and sym (pred symbolp))) sym) - (`(lambda . ,_) v) - (`(quote ,(and lam `(lambda . ,_))) lam) - (`(function ,(and lam `(lambda . ,_))) lam) - (_ v))) + (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 '(quote function) (car v)) + (eq 'lambda (car (cadr v)))) + (cadr v)) + (t v))) (defun use-package-normalize-commands (args) "Map over ARGS of the form ((_ . F) ...). @@ -928,31 +937,31 @@ representing symbols (that may need to be autloaded)." ((not arg) (use-package-process-keywords name rest state)) ((eq arg t) - `((let ((,context - #'(lambda (keyword err) - (let ((msg (format "%s/%s: %s" ',name keyword - (error-message-string err)))) - ,(when (eq use-package-verbose 'debug) - `(progn - (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)")))) - (ignore (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)))))) + `((defvar ,context + #'(lambda (keyword err) + (let ((msg (format "%s/%s: %s" ',name keyword + (error-message-string err)))) + ,(when (eq use-package-verbose 'debug) + `(progn + (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)")))) + (ignore (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) - `((let ((,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)))))) + `((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"))))) @@ -960,8 +969,9 @@ representing symbols (that may need to be autloaded)." (defun use-package-handle-mode (name alist args rest state) "Handle keywords which add regexp/mode pairs to an alist." - (cl-destructuring-bind (nargs . commands) - (use-package-normalize-commands args) + (let* ((result (use-package-normalize-commands args)) + (nargs (car result)) + (commands (cdr result))) (use-package-concat (use-package-process-keywords name (use-package-sort-keywords @@ -1026,8 +1036,9 @@ representing symbols (that may need to be autloaded)." (defun use-package-handler/:hook (name keyword args rest state) "Generate use-package custom keyword code." - (cl-destructuring-bind (nargs . commands) - (use-package-normalize-commands args) + (let* ((result (use-package-normalize-commands args)) + (nargs (car result)) + (commands (cdr result))) (use-package-concat (use-package-process-keywords name (use-package-sort-keywords @@ -1097,38 +1108,43 @@ representing symbols (that may need to be autloaded)." (defun use-package-after-count-uses (features) "Count the number of time the body would appear in the result." - (pcase features - ((and (pred use-package-non-nil-symbolp) feat) - 1) - (`(,(or `:or `:any) . ,rest) - (let ((num 0)) - (dolist (next rest) - (setq num (+ num (use-package-after-count-uses next)))) - num)) - (`(,(or `:and `:all) . ,rest) - (apply #'max (mapcar #'use-package-after-count-uses rest))) - (`(,feat . ,rest) - (use-package-after-count-uses (cons :all (cons feat rest)))))) + (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'." - (pcase features - ((and (pred use-package-non-nil-symbolp) feat) - `(eval-after-load ',feat - ,(if (member (car body) '(quote backquote \' \`)) - body - (list 'quote body)))) - (`(,(or `:or `:any) . ,rest) - (macroexp-progn - (mapcar #'(lambda (x) (use-package-require-after-load x body)) rest))) - (`(,(or `:and `:all) . ,rest) - (dolist (next rest) - (setq body (use-package-require-after-load next body))) - body) - (`(,feat . ,rest) - (use-package-require-after-load (cons :all (cons feat rest)) body)))) + (cond + ((use-package-non-nil-symbolp features) + `(eval-after-load ',features + ,(if (member (car body) '(quote backquote \' \`)) + body + (list 'quote body)))) + ((and (consp features) + (memq (car features) '(:or :any))) + (macroexp-progn + (mapcar #'(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)) @@ -1186,7 +1202,7 @@ no keyword implies `:all'." name-symbol))) (unless (listp arg) (use-package-error error-msg)) - (dolist (def arg arg) + (cl-dolist (def arg arg) (unless (listp def) (use-package-error error-msg)) (let ((face (nth 0 def)) @@ -1229,7 +1245,7 @@ no keyword implies `:all'." (defun use-package-handler/:load (name keyword arg rest state) (let ((body (use-package-process-keywords name rest state))) - (dolist (pkg arg) + (cl-dolist (pkg arg) (setq body (use-package-require pkg nil body))) body)) diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index 1c9cd08ff19..46de5a8a3a4 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -138,17 +138,19 @@ manually updated package." (list t) (use-package-only-one (symbol-name keyword) args #'(lambda (label arg) - (pcase arg - ((pred symbolp) - (list arg)) - (`(,(and pkg (pred symbolp)) - :pin ,(and repo (or (pred stringp) - (pred symbolp)))) - (list (cons pkg repo))) - (_ - (use-package-error - (concat ":ensure wants an optional package name " - "(an unquoted symbol name), or ( :pin )")))))))) + (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 ( :pin )")))))))) (defun use-package-ensure-elpa (name args state &optional no-refresh) (dolist (ensure args) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 67d7c6f7e4d..4e65de082c1 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -994,12 +994,17 @@ (ert-deftest use-package-test/:catch-1 () (match-expansion (use-package foo :catch t) - `(let - ((,_ #'(lambda (keyword err) - (let ((msg (format "%s/%s: %s" 'foo keyword - (error-message-string err)))) - nil - (ignore (display-warning 'use-package msg :error)))))) + `(progn + (defvar ,_ + #'(lambda + (keyword err) + (let + ((msg + (format "%s/%s: %s" 'foo keyword + (error-message-string err)))) + nil + (ignore + (display-warning 'use-package msg :error))))) (condition-case-unless-debug err (require 'foo nil nil) (error @@ -1013,8 +1018,8 @@ (ert-deftest use-package-test/:catch-3 () (match-expansion (use-package foo :catch (lambda (keyword error))) - `(let - ((,_ (lambda (keyword error)))) + `(progn + (defvar ,_ (lambda (keyword error))) (condition-case-unless-debug err (require 'foo nil nil) (error @@ -1055,84 +1060,126 @@ (ert-deftest use-package-test/:after-5 () (match-expansion (use-package foo :after (:any bar quux)) - `(lexical-let ,_ - (lexical-let ,_ - (progn - (eval-after-load 'bar - `(funcall ,_)) - (eval-after-load 'quux - `(funcall ,_))))))) + `(progn + (defvar ,_ nil) + (defvar ,_ nil) + (defvar ,_ + #'(lambda nil + (if ,_ ,_ + (setq ,_ t) + (setq ,_ + (require 'foo nil nil))))) + (progn + (eval-after-load 'bar + '(funcall ,_)) + (eval-after-load 'quux + '(funcall ,_)))))) (ert-deftest use-package-test/:after-6 () (match-expansion (use-package foo :after (:all (:any bar quux) bow)) - `(lexical-let ,_ - (lexical-let ,_ - (eval-after-load 'bow - '(progn - (eval-after-load 'bar - `(funcall ,_)) - (eval-after-load 'quux - `(funcall ,_)))))))) + `(progn + (defvar ,_ nil) + (defvar ,_ nil) + (defvar ,_ + #'(lambda nil + (if ,_ ,_ + (setq ,_ t) + (setq ,_ + (require 'foo nil nil))))) + (eval-after-load 'bow + '(progn + (eval-after-load 'bar + '(funcall ,_)) + (eval-after-load 'quux + '(funcall ,_))))))) (ert-deftest use-package-test/:after-7 () (match-expansion (use-package foo :after (:any (:all bar quux) bow)) - `(lexical-let ,_ - (lexical-let ,_ - (progn - (eval-after-load 'quux - '(eval-after-load 'bar - `(funcall ,_))) - (eval-after-load 'bow - `(funcall ,_))))))) + `(progn + (defvar ,_ nil) + (defvar ,_ nil) + (defvar ,_ + #'(lambda nil + (if ,_ ,_ + (setq ,_ t) + (setq ,_ + (require 'foo nil nil))))) + (progn + (eval-after-load 'quux + '(eval-after-load 'bar + '(funcall ,_))) + (eval-after-load 'bow + '(funcall ,_)))))) (ert-deftest use-package-test/:after-8 () (match-expansion (use-package foo :after (:all (:any bar quux) (:any bow baz))) - `(lexical-let ,_ - (lexical-let ,_ - (progn - (eval-after-load 'bow - '(progn - (eval-after-load 'bar - `(funcall ,_)) - (eval-after-load 'quux - `(funcall ,_)))) - (eval-after-load 'baz - '(progn - (eval-after-load 'bar - `(funcall ,_)) - (eval-after-load 'quux - `(funcall ,_))))))))) + `(progn + (defvar ,_ nil) + (defvar ,_ nil) + (defvar ,_ + #'(lambda nil + (if ,_ ,_ + (setq ,_ t) + (setq ,_ + (require 'foo nil nil))))) + (progn + (eval-after-load 'bow + '(progn + (eval-after-load 'bar + '(funcall ,_)) + (eval-after-load 'quux + '(funcall ,_)))) + (eval-after-load 'baz + '(progn + (eval-after-load 'bar + '(funcall ,_)) + (eval-after-load 'quux + '(funcall ,_)))))))) (ert-deftest use-package-test/:after-9 () (match-expansion (use-package foo :after (:any (:all bar quux) (:all bow baz))) - `(lexical-let ,_ - (lexical-let ,_ - (progn - (eval-after-load 'quux - '(eval-after-load 'bar - `(funcall ,_))) - (eval-after-load 'baz - '(eval-after-load 'bow - `(funcall ,_)))))))) + `(progn + (defvar ,_ nil) + (defvar ,_ nil) + (defvar ,_ + #'(lambda nil + (if ,_ ,_ + (setq ,_ t) + (setq ,_ + (require 'foo nil nil))))) + (progn + (eval-after-load 'quux + '(eval-after-load 'bar + '(funcall ,_))) + (eval-after-load 'baz + '(eval-after-load 'bow + '(funcall ,_))))))) (ert-deftest use-package-test/:after-10 () (match-expansion (use-package foo :after (:any (:all bar quux) (:any bow baz))) - `(lexical-let ,_ - (lexical-let ,_ + `(progn + (defvar ,_ nil) + (defvar ,_ nil) + (defvar ,_ + #'(lambda nil + (if ,_ ,_ + (setq ,_ t) + (setq ,_ + (require 'foo nil nil))))) + (progn + (eval-after-load 'quux + '(eval-after-load 'bar + '(funcall ,_))) (progn - (eval-after-load 'quux - '(eval-after-load 'bar - `(funcall ,_))) - (progn - (eval-after-load 'bow - `(funcall ,_)) - (eval-after-load 'baz - `(funcall ,_)))))))) + (eval-after-load 'bow + '(funcall ,_)) + (eval-after-load 'baz + '(funcall ,_))))))) (ert-deftest use-package-test/:demand-1 () (match-expansion From 725d749b7c76f2a8c786922dc72cca5ae5e56e50 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 5 Dec 2017 13:11:17 -0800 Subject: [PATCH 418/606] Normalize errors should be errors, that are then caught by :catch --- lisp/use-package/use-package-core.el | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 9705a48c603..c1d5233e1ed 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -478,10 +478,7 @@ extending any keys already present." (funcall merge-function keyword arg (plist-get plist keyword)) arg))) - (ignore - (display-warning 'use-package - (format "Unrecognized keyword: %s" keyword) - :warning)))))) + (use-package-error (format "Unrecognized keyword: %s" keyword)))))) (defun use-package-unalias-keywords (name args) (setq args (cl-nsubstitute :if :when args)) From 65caa3b423e9a535568d3a60551f412916ce4c1f Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 5 Dec 2017 13:11:30 -0800 Subject: [PATCH 419/606] Rewrite normalization of :bind and :bind* Fixes https://github.com/jwiegley/use-package/issues/550 --- lisp/use-package/use-package-bind-key.el | 47 +++++-- test/lisp/use-package/use-package-tests.el | 153 +++++++++++++++++++-- 2 files changed, 175 insertions(+), 25 deletions(-) diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index 09229153f0c..7c5d2725301 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -67,17 +67,44 @@ deferred until the prefix key sequence is pressed." package keymap-symbol))))) (defun use-package-normalize-binder (name keyword args) - (use-package-as-one (symbol-name keyword) args - #'(lambda (label arg) - (unless (consp arg) + (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 + ;; :filter SEXP + ;; :menu-name STRING + ((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))) + (eq x :filter) + (and (eq x :menu-name) (stringp (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 label " a ( . )" - " or list of these"))) - (use-package-normalize-pairs - #'(lambda (k) (cond ((stringp k) t) - ((vectorp k) t))) - #'(lambda (v) (use-package-recognize-function v t #'stringp)) - name label arg)))) + (concat (symbol-name name) + " wants arguments acceptable to the `bind-keys' macro," + " or a list of such values")))))) + args*)) ;;;; :bind, :bind* diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 4e65de082c1..966c1221ba4 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -546,26 +546,115 @@ (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil nil)))))) -(ert-deftest use-package-test-normalize/:bind () - (flet ((norm (&rest args) - (apply #'use-package-normalize-binder - 'foopkg :bind args))) - (let ((good-values '(:map map-sym - ("str" . sym) ("str" . "str") - ([vec] . sym) ([vec] . "str")))) - (should (equal (norm good-values) good-values))) - (should-error (norm '("foo"))) - (should-error (norm '("foo" . 99))) - (should-error (norm '(99 . sym))))) +(defun use-package-test-normalize-bind (&rest args) + (apply #'use-package-normalize-binder 'foo :bind args)) + +(ert-deftest use-package-test-normalize/:bind-1 () + (should (equal (use-package-test-normalize-bind + '(("C-a" . alpha))) + '(("C-a" . alpha))))) + +(ert-deftest use-package-test-normalize/:bind-2 () + (should (equal (use-package-test-normalize-bind + '(("C-a" . alpha) + :map foo-map + ("C-b" . beta))) + '(("C-a" . alpha) + :map foo-map + ("C-b" . beta))))) + +(ert-deftest use-package-test-normalize/:bind-3 () + (should (equal (use-package-test-normalize-bind + '(:map foo-map + ("C-a" . alpha) + ("C-b" . beta))) + '(:map foo-map + ("C-a" . alpha) + ("C-b" . beta))))) (ert-deftest use-package-test/:bind-1 () (match-expansion - (use-package foo :bind ("C-k" . key)) + (use-package foo :bind ("C-k" . key1) ("C-u" . key2)) `(progn - (unless (fboundp 'key) - (autoload #'key "foo" nil t)) + (unless + (fboundp 'key1) + (autoload #'key1 "foo" nil t)) + (unless + (fboundp 'key2) + (autoload #'key2 "foo" nil t)) (ignore - (bind-keys :package foo ("C-k" . key)))))) + (bind-keys :package foo + ("C-k" . key1) + ("C-u" . key2)))))) + +(ert-deftest use-package-test/:bind-2 () + (match-expansion + (use-package foo :bind (("C-k" . key1) ("C-u" . key2))) + `(progn + (unless (fboundp 'key1) + (autoload #'key1 "foo" nil t)) + (unless (fboundp 'key2) + (autoload #'key2 "foo" nil t)) + (ignore + (bind-keys :package foo + ("C-k" . key1) + ("C-u" . key2)))))) + +(ert-deftest use-package-test/:bind-3 () + (match-expansion + (use-package foo :bind (:map my-map ("C-k" . key1) ("C-u" . key2))) + `(progn + (unless + (fboundp 'key1) + (autoload #'key1 "foo" nil t)) + (unless + (fboundp 'key2) + (autoload #'key2 "foo" nil t)) + (ignore + (bind-keys :package foo :map my-map + ("C-k" . key1) + ("C-u" . key2)))))) + +(ert-deftest use-package-test/:bind-4 () + (should-error + (match-expansion + (use-package foo :bind :map my-map ("C-k" . key1) ("C-u" . key2)) + `(ignore + (bind-keys :package foo))))) + +(ert-deftest use-package-test/:bind-5 () + (match-expansion + (use-package foo :bind ("C-k" . key1) (:map my-map ("C-u" . key2))) + `(progn + (unless (fboundp 'key1) + (autoload #'key1 "foo" nil t)) + (unless (fboundp 'key2) + (autoload #'key2 "foo" nil t)) + (ignore + (bind-keys :package foo + ("C-k" . key1) + :map my-map + ("C-u" . key2)))))) + +(ert-deftest use-package-test/:bind-6 () + (match-expansion + (use-package foo + :bind + ("C-k" . key1) + (:map my-map ("C-u" . key2)) + (:map my-map2 ("C-u" . key3))) + `(progn + (unless (fboundp 'key1) + (autoload #'key1 "foo" nil t)) + (unless (fboundp 'key2) + (autoload #'key2 "foo" nil t)) + (unless (fboundp 'key3) + (autoload #'key3 "foo" nil t)) + (ignore + (bind-keys :package foo + ("C-k" . key1) + :map my-map ("C-u" . key2) + :map my-map2 ("C-u" . key3)))))) (ert-deftest use-package-test/:bind*-1 () (match-expansion @@ -1524,6 +1613,40 @@ (use-package-ensure-elpa 'hydra '(t) 'nil) (require 'hydra nil nil)))) +(ert-deftest use-package-test/545 () + (match-expansion + (use-package spacemacs-theme + :ensure t + :init ; or :config + (load-theme 'spacemacs-dark t) + ) + `(progn + (use-package-ensure-elpa 'spacemacs-theme '(t) 'nil) + (load-theme 'spacemacs-dark t) + (require 'spacemacs-theme nil nil)) + )) + +(ert-deftest use-package-test/550 () + (match-expansion + (use-package company-try-hard + :ensure t + :bind + ("C-c M-/" . company-try-hard) + (:map company-active-map + ("C-c M-/" . company-try-hard))) + `(progn + (use-package-ensure-elpa 'company-try-hard + '(t) + 'nil) + (unless + (fboundp 'company-try-hard) + (autoload #'company-try-hard "company-try-hard" nil t)) + (ignore + (bind-keys :package company-try-hard + ("C-c M-/" . company-try-hard) + :map company-active-map + ("C-c M-/" . company-try-hard)))))) + (ert-deftest use-package-test/558 () (match-expansion (bind-keys* :package org-ref From 64ffdb68631b349de6083677210ab9aec2768fd9 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 5 Dec 2017 13:26:03 -0800 Subject: [PATCH 420/606] Enhance fix-expansion to take surrounding let bindings into account --- test/lisp/use-package/use-package-tests.el | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 966c1221ba4..7109d58ea1f 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -81,9 +81,19 @@ (goto-char (match-beginning 0)) (let ((decl (read (current-buffer)))) (kill-sexp) - (let ((use-package-verbose 'errors) - (use-package-expand-minimally t)) - (insert ?\n ?\` (pp-to-string (macroexpand-1 decl)))))))) + (let (vars) + (catch 'exit + (save-excursion + (while (ignore-errors (backward-up-list) t) + (when (looking-at "(let\\s-+") + (goto-char (match-end 0)) + (setq vars (read (current-buffer))) + (throw 'exit t))))) + (eval + `(let (,@ (append vars + '((use-package-verbose 'errors) + (use-package-expand-minimally t)))) + (insert ?\n ?\` (pp-to-string (macroexpand-1 decl)))))))))) (bind-key "C-c C-u" #'fix-expansion emacs-lisp-mode-map) From b25a305c588744b51276d2c4245d0a268f4d42f9 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 5 Dec 2017 13:26:32 -0800 Subject: [PATCH 421/606] Lower the priority of :if/:when/:unless in use-package-keywords Fixes https://github.com/jwiegley/use-package/issues/560 --- lisp/use-package/use-package-core.el | 6 +++--- test/lisp/use-package/use-package-tests.el | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index c1d5233e1ed..b46bdfa8651 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -55,13 +55,13 @@ (defcustom use-package-keywords '(:disabled - :if :when :unless - :requires :load-path - :no-require + :requires :defines :functions :preface + :if :when :unless + :no-require :catch :after :custom diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 7109d58ea1f..a47188f8ecc 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1663,6 +1663,24 @@ ("C-c C-r" . org-ref-helm-insert-cite-link)) `(bind-key "C-c C-r" #'org-ref-helm-insert-cite-link override-global-map nil))) +(ert-deftest use-package-test/560 () + (match-expansion + (use-package notmuch + :preface (setq-default notmuch-command (executable-find "notmuch")) + :if notmuch-command + :requires foo + :load-path "my-load-path" + :defines var) + `(progn + (eval-and-compile + (add-to-list 'load-path "/Users/johnw/.emacs.d/my-load-path")) + (when (featurep 'foo) + (eval-and-compile + (setq-default notmuch-command + (executable-find "notmuch"))) + (when (symbol-value 'notmuch-command) + (require 'notmuch nil nil)))))) + (ert-deftest bind-key/:prefix-map () (match-expansion (bind-keys :prefix "" From b5a0cd4f30798a535b4a71241ed86e3c2b22fb4a Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 5 Dec 2017 13:33:11 -0800 Subject: [PATCH 422/606] Add note in NEWS.md about :requires vs. :if --- etc/USE-PACKAGE-NEWS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index 5873d699089..b959a7578e7 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -108,6 +108,14 @@ - Documentation added for the `:after`, `:defer-install`, `:delight`, `:requires`, `:when` and `:unless` keywords. +- `:requires SYM` is subtly different from `:if (featurep SYM)`, in that it + happens before the `:preface`. This means that using `:requires` will cause + definitions in the `:preface` to not be visible to the byte-compiler, + leading to possible warnings about unknown functions, or functions that may + not be available at run-time (which can generally be ignored, since + `:requires` is intended as a check for basic system functionality; `:after` + should be used to check for the presence of other modules). + - New undocumented (and currently experimental) keyword `:load` may be used to change the name of the actual package loaded, rather than the package name, and may even add other names. For example: `(use-package auctex :load From 7c3a6cd70b4ad73852eed7c59077d96762637930 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 5 Dec 2017 14:27:49 -0800 Subject: [PATCH 423/606] Stub some referenced variables, for Travis --- test/lisp/use-package/use-package-tests.el | 34 ++++++++++++---------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index a47188f8ecc..c040c89654e 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1664,22 +1664,24 @@ `(bind-key "C-c C-r" #'org-ref-helm-insert-cite-link override-global-map nil))) (ert-deftest use-package-test/560 () - (match-expansion - (use-package notmuch - :preface (setq-default notmuch-command (executable-find "notmuch")) - :if notmuch-command - :requires foo - :load-path "my-load-path" - :defines var) - `(progn - (eval-and-compile - (add-to-list 'load-path "/Users/johnw/.emacs.d/my-load-path")) - (when (featurep 'foo) - (eval-and-compile - (setq-default notmuch-command - (executable-find "notmuch"))) - (when (symbol-value 'notmuch-command) - (require 'notmuch nil nil)))))) + (flet ((executable-find (name))) + (let (notmuch-command) + (match-expansion + (use-package notmuch + :preface (setq-default notmuch-command (executable-find "notmuch")) + :if notmuch-command + :requires foo + :load-path "my-load-path" + :defines var) + `(progn + (eval-and-compile + (add-to-list 'load-path "/Users/johnw/.emacs.d/my-load-path")) + (when (featurep 'foo) + (eval-and-compile + (setq-default notmuch-command + (executable-find "notmuch"))) + (when (symbol-value 'notmuch-command) + (require 'notmuch nil nil)))))))) (ert-deftest bind-key/:prefix-map () (match-expansion From cdb250e766c3e88a5da6061e63cdcf8eb5fbbc02 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 5 Dec 2017 14:34:15 -0800 Subject: [PATCH 424/606] For now, stub out test that breaks Travis --- test/lisp/use-package/use-package-tests.el | 38 +++++++++++----------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index c040c89654e..7d13ec16202 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1663,25 +1663,25 @@ ("C-c C-r" . org-ref-helm-insert-cite-link)) `(bind-key "C-c C-r" #'org-ref-helm-insert-cite-link override-global-map nil))) -(ert-deftest use-package-test/560 () - (flet ((executable-find (name))) - (let (notmuch-command) - (match-expansion - (use-package notmuch - :preface (setq-default notmuch-command (executable-find "notmuch")) - :if notmuch-command - :requires foo - :load-path "my-load-path" - :defines var) - `(progn - (eval-and-compile - (add-to-list 'load-path "/Users/johnw/.emacs.d/my-load-path")) - (when (featurep 'foo) - (eval-and-compile - (setq-default notmuch-command - (executable-find "notmuch"))) - (when (symbol-value 'notmuch-command) - (require 'notmuch nil nil)))))))) +;; (ert-deftest use-package-test/560 () +;; (flet ((executable-find (name))) +;; (let (notmuch-command) +;; (match-expansion +;; (use-package notmuch +;; :preface (setq-default notmuch-command (executable-find "notmuch")) +;; :if notmuch-command +;; :requires foo +;; :load-path "my-load-path" +;; :defines var) +;; `(progn +;; (eval-and-compile +;; (add-to-list 'load-path "/Users/johnw/.emacs.d/my-load-path")) +;; (when (featurep 'foo) +;; (eval-and-compile +;; (setq-default notmuch-command +;; (executable-find "notmuch"))) +;; (when (symbol-value 'notmuch-command) +;; (require 'notmuch nil nil)))))))) (ert-deftest bind-key/:prefix-map () (match-expansion From 5f1392488536ed3826ee7c40125bd6e952a61ec4 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 5 Dec 2017 14:36:56 -0800 Subject: [PATCH 425/606] Enable 4 tests that work when not run on Travis --- test/lisp/use-package/use-package-tests.el | 197 +++++++++++---------- 1 file changed, 101 insertions(+), 96 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 7d13ec16202..d35f8e755ce 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -26,6 +26,8 @@ (require 'ert) (require 'use-package) +(defvar running-on-travis nil) + (setq use-package-always-ensure nil use-package-verbose 'errors use-package-expand-minimally t @@ -822,51 +824,52 @@ (autoload #'bar "foo" nil t)) (bar)))) -;; (ert-deftest use-package-test/:commands-5 () -;; (match-expansion -;; (use-package gnus-harvest -;; :load-path "lisp/gnus-harvest" -;; :commands gnus-harvest-install -;; :demand t -;; :config -;; (if (featurep 'message-x) -;; (gnus-harvest-install 'message-x) -;; (gnus-harvest-install))) -;; `(progn -;; (eval-and-compile -;; (add-to-list 'load-path "/Users/johnw/.emacs.d/lisp/gnus-harvest")) -;; (require 'gnus-harvest nil nil) -;; (if (featurep 'message-x) -;; (gnus-harvest-install 'message-x) -;; (gnus-harvest-install)) -;; t))) +(unless running-on-travis + (ert-deftest use-package-test/:commands-5 () + (match-expansion + (use-package gnus-harvest + :load-path "lisp/gnus-harvest" + :commands gnus-harvest-install + :demand t + :config + (if (featurep 'message-x) + (gnus-harvest-install 'message-x) + (gnus-harvest-install))) + `(progn + (eval-and-compile + (add-to-list 'load-path "/Users/johnw/.emacs.d/lisp/gnus-harvest")) + (require 'gnus-harvest nil nil) + (if (featurep 'message-x) + (gnus-harvest-install 'message-x) + (gnus-harvest-install)) + t))) -;; (ert-deftest use-package-test/:commands-6 () -;; (let ((byte-compile-current-file t)) -;; (match-expansion -;; (use-package gnus-harvest -;; :load-path "lisp/gnus-harvest" -;; :commands gnus-harvest-install -;; :demand t -;; :config -;; (if (featurep 'message-x) -;; (gnus-harvest-install 'message-x) -;; (gnus-harvest-install))) -;; `(progn -;; (eval-and-compile -;; (add-to-list 'load-path "/Users/johnw/.emacs.d/lisp/gnus-harvest")) -;; (eval-and-compile -;; (eval-when-compile -;; (with-demoted-errors "Cannot load gnus-harvest: %S" nil -;; (load "gnus-harvest" nil t)))) -;; (eval-when-compile -;; (declare-function gnus-harvest-install "gnus-harvest")) -;; (require 'gnus-harvest nil nil) -;; (if -;; (featurep 'message-x) -;; (gnus-harvest-install 'message-x) -;; (gnus-harvest-install)) -;; t)))) + (ert-deftest use-package-test/:commands-6 () + (let ((byte-compile-current-file t)) + (match-expansion + (use-package gnus-harvest + :load-path "lisp/gnus-harvest" + :commands gnus-harvest-install + :demand t + :config + (if (featurep 'message-x) + (gnus-harvest-install 'message-x) + (gnus-harvest-install))) + `(progn + (eval-and-compile + (add-to-list 'load-path "/Users/johnw/.emacs.d/lisp/gnus-harvest")) + (eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load gnus-harvest: %S" nil + (load "gnus-harvest" nil t)))) + (eval-when-compile + (declare-function gnus-harvest-install "gnus-harvest")) + (require 'gnus-harvest nil nil) + (if + (featurep 'message-x) + (gnus-harvest-install 'message-x) + (gnus-harvest-install)) + t))))) (ert-deftest use-package-test/:defines-1 () (match-expansion @@ -1336,39 +1339,40 @@ (eval-after-load 'bar '(require 'foo nil nil)))))) -;; (ert-deftest use-package-test/:demand-7 () -;; (match-expansion -;; (use-package counsel -;; :load-path "site-lisp/swiper" -;; :after ivy -;; :demand t -;; :diminish -;; :bind (("C-*" . counsel-org-agenda-headlines) -;; ("M-x" . counsel-M-x)) -;; :commands (counsel-minibuffer-history -;; counsel-find-library -;; counsel-unicode-char) -;; :preface (preface-code) -;; :init -;; ;; This is actually wrong, but it's just part of the example. -;; (define-key minibuffer-local-map (kbd "M-r") -;; 'counsel-minibuffer-history)) -;; `(progn -;; (eval-and-compile -;; (add-to-list 'load-path "/Users/johnw/.emacs.d/site-lisp/swiper")) -;; (eval-and-compile -;; (preface-code)) -;; (eval-after-load 'ivy -;; '(progn -;; (define-key minibuffer-local-map (kbd "M-r") -;; 'counsel-minibuffer-history) -;; (require 'counsel nil nil) -;; (if (fboundp 'diminish) -;; (diminish 'counsel-mode)) -;; (ignore -;; (bind-keys :package counsel -;; ("C-*" . counsel-org-agenda-headlines) -;; ("M-x" . counsel-M-x)))))))) +(unless running-on-travis + (ert-deftest use-package-test/:demand-7 () + (match-expansion + (use-package counsel + :load-path "site-lisp/swiper" + :after ivy + :demand t + :diminish + :bind (("C-*" . counsel-org-agenda-headlines) + ("M-x" . counsel-M-x)) + :commands (counsel-minibuffer-history + counsel-find-library + counsel-unicode-char) + :preface (preface-code) + :init + ;; This is actually wrong, but it's just part of the example. + (define-key minibuffer-local-map (kbd "M-r") + 'counsel-minibuffer-history)) + `(progn + (eval-and-compile + (add-to-list 'load-path "/Users/johnw/.emacs.d/site-lisp/swiper")) + (eval-and-compile + (preface-code)) + (eval-after-load 'ivy + '(progn + (define-key minibuffer-local-map (kbd "M-r") + 'counsel-minibuffer-history) + (require 'counsel nil nil) + (if (fboundp 'diminish) + (diminish 'counsel-mode)) + (ignore + (bind-keys :package counsel + ("C-*" . counsel-org-agenda-headlines) + ("M-x" . counsel-M-x))))))))) (ert-deftest use-package-test/:config-1 () (match-expansion @@ -1663,25 +1667,26 @@ ("C-c C-r" . org-ref-helm-insert-cite-link)) `(bind-key "C-c C-r" #'org-ref-helm-insert-cite-link override-global-map nil))) -;; (ert-deftest use-package-test/560 () -;; (flet ((executable-find (name))) -;; (let (notmuch-command) -;; (match-expansion -;; (use-package notmuch -;; :preface (setq-default notmuch-command (executable-find "notmuch")) -;; :if notmuch-command -;; :requires foo -;; :load-path "my-load-path" -;; :defines var) -;; `(progn -;; (eval-and-compile -;; (add-to-list 'load-path "/Users/johnw/.emacs.d/my-load-path")) -;; (when (featurep 'foo) -;; (eval-and-compile -;; (setq-default notmuch-command -;; (executable-find "notmuch"))) -;; (when (symbol-value 'notmuch-command) -;; (require 'notmuch nil nil)))))))) +(unless running-on-travis + (ert-deftest use-package-test/560 () + (flet ((executable-find (name))) + (let (notmuch-command) + (match-expansion + (use-package notmuch + :preface (setq-default notmuch-command (executable-find "notmuch")) + :if notmuch-command + :requires foo + :load-path "my-load-path" + :defines var) + `(progn + (eval-and-compile + (add-to-list 'load-path "/Users/johnw/.emacs.d/my-load-path")) + (when (featurep 'foo) + (eval-and-compile + (setq-default notmuch-command + (executable-find "notmuch"))) + (when (symbol-value 'notmuch-command) + (require 'notmuch nil nil))))))))) (ert-deftest bind-key/:prefix-map () (match-expansion From 7b8e94a61a2f5f51a62df2044f24345618440325 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 5 Dec 2017 14:51:44 -0800 Subject: [PATCH 426/606] Default running-on-travis to t --- test/lisp/use-package/use-package-tests.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index d35f8e755ce..21890d7400f 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -26,7 +26,7 @@ (require 'ert) (require 'use-package) -(defvar running-on-travis nil) +(defvar running-on-travis t) (setq use-package-always-ensure nil use-package-verbose 'errors From 4882df8285351a30f804e4129aec1be8870bb608 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 5 Dec 2017 15:46:44 -0800 Subject: [PATCH 427/606] Whitespace change --- lisp/use-package/use-package-core.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index b46bdfa8651..649779bb271 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -877,7 +877,8 @@ representing symbols (that may need to be autloaded)." (let ((body (use-package-process-keywords name rest state))) (use-package-concat (mapcar #'(lambda (path) - `(eval-and-compile (add-to-list 'load-path ,path))) arg) + `(eval-and-compile (add-to-list 'load-path ,path))) + arg) body))) ;;;; :no-require From 0c110ebd67b2372263a7cb668e03047905b60ec2 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 5 Dec 2017 15:46:55 -0800 Subject: [PATCH 428/606] Allow `:load t' to mean the same as :load of the package name --- lisp/use-package/use-package-core.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 649779bb271..9d55074b19d 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1244,7 +1244,7 @@ no keyword implies `:all'." (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 pkg nil body))) + (setq body (use-package-require (if (eq t pkg) name pkg) nil body))) body)) ;;;; :config From 2a9904b9e8793b66145723a13634d41edf49fed9 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 5 Dec 2017 15:47:41 -0800 Subject: [PATCH 429/606] Enable all tests on Travis --- test/lisp/use-package/use-package-tests.el | 171 ++++++++++----------- 1 file changed, 83 insertions(+), 88 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 21890d7400f..1169de5147a 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -26,8 +26,6 @@ (require 'ert) (require 'use-package) -(defvar running-on-travis t) - (setq use-package-always-ensure nil use-package-verbose 'errors use-package-expand-minimally t @@ -824,11 +822,30 @@ (autoload #'bar "foo" nil t)) (bar)))) -(unless running-on-travis - (ert-deftest use-package-test/:commands-5 () +(ert-deftest use-package-test/:commands-5 () + (match-expansion + (use-package gnus-harvest + :load-path "foo" + :commands gnus-harvest-install + :demand t + :config + (if (featurep 'message-x) + (gnus-harvest-install 'message-x) + (gnus-harvest-install))) + `(progn + (eval-and-compile + (add-to-list 'load-path ,(pred stringp))) + (require 'gnus-harvest nil nil) + (if (featurep 'message-x) + (gnus-harvest-install 'message-x) + (gnus-harvest-install)) + t))) + +(ert-deftest use-package-test/:commands-6 () + (let ((byte-compile-current-file t)) (match-expansion (use-package gnus-harvest - :load-path "lisp/gnus-harvest" + :load-path "foo" :commands gnus-harvest-install :demand t :config @@ -837,39 +854,19 @@ (gnus-harvest-install))) `(progn (eval-and-compile - (add-to-list 'load-path "/Users/johnw/.emacs.d/lisp/gnus-harvest")) + (add-to-list 'load-path ,(pred stringp))) + (eval-and-compile + (eval-when-compile + (with-demoted-errors "Cannot load gnus-harvest: %S" nil + (load "gnus-harvest" nil t)))) + (eval-when-compile + (declare-function gnus-harvest-install "gnus-harvest")) (require 'gnus-harvest nil nil) - (if (featurep 'message-x) + (if + (featurep 'message-x) (gnus-harvest-install 'message-x) (gnus-harvest-install)) - t))) - - (ert-deftest use-package-test/:commands-6 () - (let ((byte-compile-current-file t)) - (match-expansion - (use-package gnus-harvest - :load-path "lisp/gnus-harvest" - :commands gnus-harvest-install - :demand t - :config - (if (featurep 'message-x) - (gnus-harvest-install 'message-x) - (gnus-harvest-install))) - `(progn - (eval-and-compile - (add-to-list 'load-path "/Users/johnw/.emacs.d/lisp/gnus-harvest")) - (eval-and-compile - (eval-when-compile - (with-demoted-errors "Cannot load gnus-harvest: %S" nil - (load "gnus-harvest" nil t)))) - (eval-when-compile - (declare-function gnus-harvest-install "gnus-harvest")) - (require 'gnus-harvest nil nil) - (if - (featurep 'message-x) - (gnus-harvest-install 'message-x) - (gnus-harvest-install)) - t))))) + t)))) (ert-deftest use-package-test/:defines-1 () (match-expansion @@ -1339,40 +1336,39 @@ (eval-after-load 'bar '(require 'foo nil nil)))))) -(unless running-on-travis - (ert-deftest use-package-test/:demand-7 () - (match-expansion - (use-package counsel - :load-path "site-lisp/swiper" - :after ivy - :demand t - :diminish - :bind (("C-*" . counsel-org-agenda-headlines) - ("M-x" . counsel-M-x)) - :commands (counsel-minibuffer-history - counsel-find-library - counsel-unicode-char) - :preface (preface-code) - :init - ;; This is actually wrong, but it's just part of the example. - (define-key minibuffer-local-map (kbd "M-r") - 'counsel-minibuffer-history)) - `(progn - (eval-and-compile - (add-to-list 'load-path "/Users/johnw/.emacs.d/site-lisp/swiper")) - (eval-and-compile - (preface-code)) - (eval-after-load 'ivy - '(progn - (define-key minibuffer-local-map (kbd "M-r") - 'counsel-minibuffer-history) - (require 'counsel nil nil) - (if (fboundp 'diminish) - (diminish 'counsel-mode)) - (ignore - (bind-keys :package counsel - ("C-*" . counsel-org-agenda-headlines) - ("M-x" . counsel-M-x))))))))) +(ert-deftest use-package-test/:demand-7 () + (match-expansion + (use-package counsel + :load-path "foo" + :after ivy + :demand t + :diminish + :bind (("C-*" . counsel-org-agenda-headlines) + ("M-x" . counsel-M-x)) + :commands (counsel-minibuffer-history + counsel-find-library + counsel-unicode-char) + :preface (preface-code) + :init + ;; This is actually wrong, but it's just part of the example. + (define-key minibuffer-local-map (kbd "M-r") + 'counsel-minibuffer-history)) + `(progn + (eval-and-compile + (add-to-list 'load-path ,(pred stringp))) + (eval-and-compile + (preface-code)) + (eval-after-load 'ivy + '(progn + (define-key minibuffer-local-map (kbd "M-r") + 'counsel-minibuffer-history) + (require 'counsel nil nil) + (if (fboundp 'diminish) + (diminish 'counsel-mode)) + (ignore + (bind-keys :package counsel + ("C-*" . counsel-org-agenda-headlines) + ("M-x" . counsel-M-x)))))))) (ert-deftest use-package-test/:config-1 () (match-expansion @@ -1667,26 +1663,25 @@ ("C-c C-r" . org-ref-helm-insert-cite-link)) `(bind-key "C-c C-r" #'org-ref-helm-insert-cite-link override-global-map nil))) -(unless running-on-travis - (ert-deftest use-package-test/560 () - (flet ((executable-find (name))) - (let (notmuch-command) - (match-expansion - (use-package notmuch - :preface (setq-default notmuch-command (executable-find "notmuch")) - :if notmuch-command - :requires foo - :load-path "my-load-path" - :defines var) - `(progn +(ert-deftest use-package-test/560 () + (flet ((executable-find (name))) + (let (notmuch-command) + (match-expansion + (use-package notmuch + :preface (setq-default notmuch-command (executable-find "notmuch")) + :if notmuch-command + :requires foo + :load-path "foo" + :defines var) + `(progn + (eval-and-compile + (add-to-list 'load-path ,(pred stringp))) + (when (featurep 'foo) (eval-and-compile - (add-to-list 'load-path "/Users/johnw/.emacs.d/my-load-path")) - (when (featurep 'foo) - (eval-and-compile - (setq-default notmuch-command - (executable-find "notmuch"))) - (when (symbol-value 'notmuch-command) - (require 'notmuch nil nil))))))))) + (setq-default notmuch-command + (executable-find "notmuch"))) + (when (symbol-value 'notmuch-command) + (require 'notmuch nil nil)))))))) (ert-deftest bind-key/:prefix-map () (match-expansion From 3343cca33bd7b167cb01471be278bb9b5e6c910a Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 5 Dec 2017 15:47:53 -0800 Subject: [PATCH 430/606] Don't auto-defer if the package itself was given to :load Otherwise, we'd be senselessly waiting for the package to load. --- lisp/use-package/use-package-core.el | 4 ++++ test/lisp/use-package/use-package-tests.el | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 9d55074b19d..729696abf89 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -552,6 +552,10 @@ extending any keys already present." ;; 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))) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 1169de5147a..cbfb98da0c0 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1044,6 +1044,27 @@ (ignore (add-hook 'hook-special #'fun)))))) +(ert-deftest use-package-test/:hook-5 () + (match-expansion + (use-package erefactor + :load-path "foo" + :after elisp-mode + :load t + :hook (emacs-lisp-mode + . (lambda () + (bind-key "\C-c\C-v" erefactor-map emacs-lisp-mode-map)))) + `(progn + (eval-and-compile + (add-to-list 'load-path ,(pred stringp))) + (eval-after-load 'elisp-mode + '(progn + (require 'erefactor nil nil) + (ignore + (add-hook + 'emacs-lisp-mode-hook + #'(lambda nil + (bind-key "" erefactor-map emacs-lisp-mode-map))))))))) + (ert-deftest use-package-test-normalize/:custom () (flet ((norm (&rest args) (apply #'use-package-normalize/:custom From de12a5ae86c90e20e11eaeea760e20bc46277c6b Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 5 Dec 2017 16:13:03 -0800 Subject: [PATCH 431/606] Several changes as suggested by flycheck --- lisp/use-package/use-package-core.el | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 729696abf89..01b3ac3c149 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -181,7 +181,7 @@ be attempted." (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 +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) @@ -214,8 +214,8 @@ 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." +return t if you only wish to add behavior to what the user had +specified." :type 'boolean :group 'use-package) @@ -248,8 +248,9 @@ This is used by `use-package-jump-to-package-form' and :group 'use-package) (defcustom use-package-enable-imenu-support nil - "If non-nil, adjust `lisp-imenu-generic-expression' to include -support for finding `use-package' and `require' forms. + "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 @@ -305,7 +306,7 @@ convert it to a string and return that." (stringp re))) (defun use-package-normalize-regex (re) - "Given some regexp-like thing, resolve it down to a regular expression." + "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) @@ -329,15 +330,16 @@ appended." (concat string "-mode"))))) (defsubst use-package-load-name (name &optional noerror) - "Return a form which will load or require NAME depending on -whether it's a string or symbol." + "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 a given keyword form. -ARGS is a list of forms, so `((foo))' if only `foo' is being called." + "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))) @@ -651,7 +653,8 @@ no more than once." ,(funcall f `(funcall ,next))))) (defsubst use-package-normalize-value (label arg) - "Normalize a value." + "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) From b2b91af2e5479a7959630cb1869241f8615a940a Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 6 Dec 2017 05:50:16 +0000 Subject: [PATCH 432/606] Make the expanded text for :after cleaner --- lisp/use-package/use-package-core.el | 34 +++--- test/lisp/use-package/use-package-tests.el | 129 ++++++++++----------- 2 files changed, 73 insertions(+), 90 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 01b3ac3c149..cacd74b256f 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -643,14 +643,14 @@ no more than once." (let ((loaded (cl-gensym "use-package--loaded")) (result (cl-gensym "use-package--result")) (next (cl-gensym "use-package--next"))) - `((defvar ,loaded nil) - (defvar ,result nil) - (defvar ,next #'(lambda () - (if ,loaded - ,result - (setq ,loaded t) - (setq ,result ,arg)))) - ,(funcall f `(funcall ,next))))) + `((defconst ,loaded nil) + (defconst ,result nil) + (defconst ,next #'(lambda () + (if ,loaded + ,result + (setq ,loaded t) + (setq ,result ,arg)))) + ,@(funcall f `((funcall ,next)))))) (defsubst use-package-normalize-value (label arg) "Normalize the Lisp value given by ARG. @@ -946,9 +946,8 @@ representing symbols (that may need to be autloaded)." #'(lambda (keyword err) (let ((msg (format "%s/%s: %s" ',name keyword (error-message-string err)))) - ,(when (eq use-package-verbose 'debug) - `(progn - (with-current-buffer + ,@(when (eq use-package-verbose 'debug) + `((with-current-buffer (get-buffer-create "*use-package*") (goto-char (point-max)) (insert "-----\n" msg ,use-package--form) @@ -1134,15 +1133,11 @@ 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 - ,(if (member (car body) '(quote backquote \' \`)) - body - (list 'quote body)))) + `((eval-after-load ',features ',(macroexp-progn body)))) ((and (consp features) (memq (car features) '(:or :any))) - (macroexp-progn - (mapcar #'(lambda (x) (use-package-require-after-load x body)) - (cdr features)))) + (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)) @@ -1157,8 +1152,7 @@ no keyword implies `:all'." (if (or (null uses) (null body)) body (if (<= uses 1) - (list (use-package-require-after-load - arg (list 'quote (macroexp-progn body)))) + (use-package-require-after-load arg body) (use-package-memoize (apply-partially #'use-package-require-after-load arg) (macroexp-progn body)))))) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index cbfb98da0c0..4ce0cbc6eb4 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1116,13 +1116,9 @@ (use-package foo :catch t) `(progn (defvar ,_ - #'(lambda - (keyword err) - (let - ((msg - (format "%s/%s: %s" 'foo keyword - (error-message-string err)))) - nil + #'(lambda (keyword err) + (let ((msg (format "%s/%s: %s" 'foo keyword + (error-message-string err)))) (ignore (display-warning 'use-package msg :error))))) (condition-case-unless-debug err @@ -1181,27 +1177,26 @@ (match-expansion (use-package foo :after (:any bar quux)) `(progn - (defvar ,_ nil) - (defvar ,_ nil) - (defvar ,_ + (defconst ,_ nil) + (defconst ,_ nil) + (defconst ,_ #'(lambda nil (if ,_ ,_ (setq ,_ t) (setq ,_ (require 'foo nil nil))))) - (progn - (eval-after-load 'bar - '(funcall ,_)) - (eval-after-load 'quux - '(funcall ,_)))))) + (eval-after-load 'bar + '(funcall ,_)) + (eval-after-load 'quux + '(funcall ,_))))) (ert-deftest use-package-test/:after-6 () (match-expansion (use-package foo :after (:all (:any bar quux) bow)) `(progn - (defvar ,_ nil) - (defvar ,_ nil) - (defvar ,_ + (defconst ,_ nil) + (defconst ,_ nil) + (defconst ,_ #'(lambda nil (if ,_ ,_ (setq ,_ t) @@ -1218,88 +1213,82 @@ (match-expansion (use-package foo :after (:any (:all bar quux) bow)) `(progn - (defvar ,_ nil) - (defvar ,_ nil) - (defvar ,_ + (defconst ,_ nil) + (defconst ,_ nil) + (defconst ,_ #'(lambda nil (if ,_ ,_ (setq ,_ t) (setq ,_ (require 'foo nil nil))))) - (progn - (eval-after-load 'quux - '(eval-after-load 'bar - '(funcall ,_))) - (eval-after-load 'bow - '(funcall ,_)))))) + (eval-after-load 'quux + '(eval-after-load 'bar + '(funcall ,_))) + (eval-after-load 'bow + '(funcall ,_))))) (ert-deftest use-package-test/:after-8 () (match-expansion (use-package foo :after (:all (:any bar quux) (:any bow baz))) `(progn - (defvar ,_ nil) - (defvar ,_ nil) - (defvar ,_ + (defconst ,_ nil) + (defconst ,_ nil) + (defconst ,_ #'(lambda nil (if ,_ ,_ (setq ,_ t) (setq ,_ (require 'foo nil nil))))) - (progn - (eval-after-load 'bow - '(progn - (eval-after-load 'bar - '(funcall ,_)) - (eval-after-load 'quux - '(funcall ,_)))) - (eval-after-load 'baz - '(progn - (eval-after-load 'bar - '(funcall ,_)) - (eval-after-load 'quux - '(funcall ,_)))))))) + (eval-after-load 'bow + '(progn + (eval-after-load 'bar + '(funcall ,_)) + (eval-after-load 'quux + '(funcall ,_)))) + (eval-after-load 'baz + '(progn + (eval-after-load 'bar + '(funcall ,_)) + (eval-after-load 'quux + '(funcall ,_))))))) (ert-deftest use-package-test/:after-9 () (match-expansion (use-package foo :after (:any (:all bar quux) (:all bow baz))) `(progn - (defvar ,_ nil) - (defvar ,_ nil) - (defvar ,_ + (defconst ,_ nil) + (defconst ,_ nil) + (defconst ,_ #'(lambda nil (if ,_ ,_ (setq ,_ t) (setq ,_ (require 'foo nil nil))))) - (progn - (eval-after-load 'quux - '(eval-after-load 'bar - '(funcall ,_))) - (eval-after-load 'baz - '(eval-after-load 'bow - '(funcall ,_))))))) + (eval-after-load 'quux + '(eval-after-load 'bar + '(funcall ,_))) + (eval-after-load 'baz + '(eval-after-load 'bow + '(funcall ,_)))))) (ert-deftest use-package-test/:after-10 () (match-expansion (use-package foo :after (:any (:all bar quux) (:any bow baz))) `(progn - (defvar ,_ nil) - (defvar ,_ nil) - (defvar ,_ - #'(lambda nil - (if ,_ ,_ - (setq ,_ t) - (setq ,_ - (require 'foo nil nil))))) - (progn - (eval-after-load 'quux - '(eval-after-load 'bar - '(funcall ,_))) - (progn - (eval-after-load 'bow - '(funcall ,_)) - (eval-after-load 'baz - '(funcall ,_))))))) + (defconst ,_ nil) + (defconst ,_ nil) + (defconst ,_ + #'(lambda nil (if ,_ ,_ + (setq ,_ t) + (setq ,_ + (require 'foo nil nil))))) + (eval-after-load 'quux + '(eval-after-load 'bar + '(funcall ,_))) + (eval-after-load 'bow + '(funcall ,_)) + (eval-after-load 'baz + '(funcall ,_))))) (ert-deftest use-package-test/:demand-1 () (match-expansion From 2cd3ebd5d5940b10e6eb17b27af155c4368f6dbd Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 6 Dec 2017 06:01:49 +0000 Subject: [PATCH 433/606] Allow the expansion of :after (:or foo bar) to be byte-compiled --- lisp/use-package/use-package-core.el | 13 +-- test/lisp/use-package/use-package-tests.el | 124 ++++++++++----------- 2 files changed, 61 insertions(+), 76 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index cacd74b256f..7ed5b7482e1 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -643,14 +643,11 @@ no more than once." (let ((loaded (cl-gensym "use-package--loaded")) (result (cl-gensym "use-package--result")) (next (cl-gensym "use-package--next"))) - `((defconst ,loaded nil) - (defconst ,result nil) - (defconst ,next #'(lambda () - (if ,loaded - ,result - (setq ,loaded t) - (setq ,result ,arg)))) - ,@(funcall f `((funcall ,next)))))) + `((lexical-let (,loaded ,result) + ,@(funcall f `((if ,loaded + ,result + (setq ,loaded t) + (setq ,result ,arg)))))))) (defsubst use-package-normalize-value (label arg) "Normalize the Lisp value given by ARG. diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 4ce0cbc6eb4..73c269abf14 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1176,119 +1176,107 @@ (ert-deftest use-package-test/:after-5 () (match-expansion (use-package foo :after (:any bar quux)) - `(progn - (defconst ,_ nil) - (defconst ,_ nil) - (defconst ,_ - #'(lambda nil - (if ,_ ,_ - (setq ,_ t) - (setq ,_ - (require 'foo nil nil))))) + `(lexical-let (,_ ,_) (eval-after-load 'bar - '(funcall ,_)) + '(if ,_ ,_ + (setq ,_ t) + (setq ,_ (require 'foo nil nil)))) (eval-after-load 'quux - '(funcall ,_))))) + '(if ,_ ,_ + (setq ,_ t) + (setq ,_ (require 'foo nil nil))))))) (ert-deftest use-package-test/:after-6 () (match-expansion (use-package foo :after (:all (:any bar quux) bow)) - `(progn - (defconst ,_ nil) - (defconst ,_ nil) - (defconst ,_ - #'(lambda nil - (if ,_ ,_ - (setq ,_ t) - (setq ,_ - (require 'foo nil nil))))) + `(lexical-let (,_ ,_) (eval-after-load 'bow '(progn (eval-after-load 'bar - '(funcall ,_)) + '(if ,_ ,_ + (setq ,_ t) + (setq ,_ (require 'foo nil nil)))) (eval-after-load 'quux - '(funcall ,_))))))) + '(if ,_ ,_ + (setq ,_ t) + (setq ,_ (require 'foo nil nil))))))) + )) (ert-deftest use-package-test/:after-7 () (match-expansion (use-package foo :after (:any (:all bar quux) bow)) - `(progn - (defconst ,_ nil) - (defconst ,_ nil) - (defconst ,_ - #'(lambda nil - (if ,_ ,_ - (setq ,_ t) - (setq ,_ - (require 'foo nil nil))))) + `(lexical-let (,_ ,_) (eval-after-load 'quux '(eval-after-load 'bar - '(funcall ,_))) + '(if ,_ ,_ + (setq ,_ t) + (setq ,_ (require 'foo nil nil))))) (eval-after-load 'bow - '(funcall ,_))))) + '(if ,_ ,_ + (setq ,_ t) + (setq ,_ (require 'foo nil nil))))) + )) (ert-deftest use-package-test/:after-8 () (match-expansion (use-package foo :after (:all (:any bar quux) (:any bow baz))) - `(progn - (defconst ,_ nil) - (defconst ,_ nil) - (defconst ,_ - #'(lambda nil - (if ,_ ,_ - (setq ,_ t) - (setq ,_ - (require 'foo nil nil))))) + `(lexical-let (,_ ,_) (eval-after-load 'bow '(progn (eval-after-load 'bar - '(funcall ,_)) + '(if ,_ ,_ + (setq ,_ t) + (setq ,_ (require 'foo nil nil)))) (eval-after-load 'quux - '(funcall ,_)))) + '(if ,_ ,_ + (setq ,_ t) + (setq ,_ (require 'foo nil nil)))))) (eval-after-load 'baz '(progn (eval-after-load 'bar - '(funcall ,_)) + '(if ,_ ,_ + (setq ,_ t) + (setq ,_ (require 'foo nil nil)))) (eval-after-load 'quux - '(funcall ,_))))))) + '(if ,_ ,_ + (setq ,_ t) + (setq ,_ (require 'foo nil nil))))))) + )) (ert-deftest use-package-test/:after-9 () (match-expansion (use-package foo :after (:any (:all bar quux) (:all bow baz))) - `(progn - (defconst ,_ nil) - (defconst ,_ nil) - (defconst ,_ - #'(lambda nil - (if ,_ ,_ - (setq ,_ t) - (setq ,_ - (require 'foo nil nil))))) + `(lexical-let (,_ ,_) (eval-after-load 'quux '(eval-after-load 'bar - '(funcall ,_))) + '(if ,_ ,_ + (setq ,_ t) + (setq ,_ (require 'foo nil nil))))) (eval-after-load 'baz '(eval-after-load 'bow - '(funcall ,_)))))) + '(if ,_ ,_ + (setq ,_ t) + (setq ,_ (require 'foo nil nil)))))) + )) (ert-deftest use-package-test/:after-10 () (match-expansion (use-package foo :after (:any (:all bar quux) (:any bow baz))) - `(progn - (defconst ,_ nil) - (defconst ,_ nil) - (defconst ,_ - #'(lambda nil (if ,_ ,_ - (setq ,_ t) - (setq ,_ - (require 'foo nil nil))))) + `(lexical-let (,_ ,_) (eval-after-load 'quux '(eval-after-load 'bar - '(funcall ,_))) + '(if ,_ ,_ + (setq ,_ t) + (setq ,_ (require 'foo nil nil))))) (eval-after-load 'bow - '(funcall ,_)) + '(if ,_ ,_ + (setq ,_ t) + (setq ,_ (require 'foo nil nil)))) (eval-after-load 'baz - '(funcall ,_))))) + '(if ,_ ,_ + (setq ,_ t) + (setq ,_ (require 'foo nil nil))))) + )) (ert-deftest use-package-test/:demand-1 () (match-expansion From c272c6b56b24623ea540324aec277ec1d0caf98b Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 6 Dec 2017 06:19:15 -0800 Subject: [PATCH 434/606] Update some GPL version references Fixes https://github.com/jwiegley/use-package/issues/563 --- lisp/use-package/bind-key.el | 2 +- test/lisp/use-package/use-package-tests.el | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 70a83e8a6e4..223a12c21fb 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -12,7 +12,7 @@ ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the gnu general public license as -;; published by the free software foundation; either version 2, or (at +;; 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 diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 73c269abf14..fa765ac6634 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -2,7 +2,7 @@ ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 2, or (at +;; 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 From 0939993935603a7ad171e1a86083ef3afe210919 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 6 Dec 2017 06:22:52 -0800 Subject: [PATCH 435/606] Clarify :config with setq versus :custom Fixes https://github.com/jwiegley/use-package/issues/564 --- etc/USE-PACKAGE-NEWS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index b959a7578e7..1cc64d12342 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -80,6 +80,12 @@ - New keywords `:custom (foo1 bar1) (foo2 bar2)` etc., and `:custom-face`. + NOTE: These are only for people who wish to keep customizations with their + accompanying use-package declarations. Functionally, the only benefit over + using `setq` in a `:config` block is that customizations might execute code + when values are assigned. If you currently use `M-x customize-option` and + save to a settings file, you do not want to use this option. + - New `:magic` and `:magic-fallback` keywords. - New `:defer-install` keyword. From 894e95aa4bc7248364c67b4f4ea3c6edbd027e84 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 6 Dec 2017 06:37:07 -0800 Subject: [PATCH 436/606] Respect keyword ordering in use-package-deferring-keywords Relates to https://github.com/jwiegley/use-package/issues/565 --- lisp/use-package/use-package-core.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 7ed5b7482e1..364ea90ef81 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -108,8 +108,8 @@ declaration is incorrect." :mode :magic :magic-fallback - :commands - :hook) + :hook + :commands) "Unless `:demand' is used, keywords in this list imply deferred loading." :type '(repeat symbol) :group 'use-package) From 2a85d81c47ad330ab5c5aea86b4ed02907150f56 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 6 Dec 2017 08:27:31 -0800 Subject: [PATCH 437/606] Add support for gathering statistics on use-package declarations --- etc/USE-PACKAGE-NEWS | 4 + lisp/use-package/use-package-core.el | 142 ++++++++++++++++++++++----- 2 files changed, 124 insertions(+), 22 deletions(-) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index 1cc64d12342..265e98f2094 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -94,6 +94,10 @@ - New customization variable `use-package-hook-name-suffix`. +- New customization variable `use-package-compute-statistics`, and an + accompanying command `M-x use-package-report`. See the README for more + details. + - Allow `:diminish` to take no arguments. - Support multiple symbols passed to `:after`, and a mini-DSL using `:all` and diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 364ea90ef81..5ff33402c86 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -272,6 +272,17 @@ Must be set before loading use-package." (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) + +(defvar use-package-statistics (make-hash-table)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Utility functions @@ -604,6 +615,30 @@ next value for the STATE." (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 @@ -822,6 +857,51 @@ representing symbols (that may need to be autloaded)." #'use-package-recognize-function name))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Statistics +;; + +(defun use-package-reset-statistics () + (interactive) + (setq use-package-statistics (make-hash-table))) + +(defun use-package-report () + (interactive) + (with-current-buffer (get-buffer-create "*use-package statistics*") + (delete-region (point-min) (point-max)) + (insert "|Package|Status|Last Event|Time|\n") + (insert "|-\n") + (maphash + #'(lambda (key hash) + (insert + (format "|%s |%s|%s |%.2f|\n" key + (cond ((gethash :config hash) "Configured") + ((gethash :init hash) "Initialized") + ((gethash :preface hash) "Prefaced") + ((gethash :use-package hash) "Declared")) + (format-time-string "[%Y-%m-%d %a %H:%M]" + (or (gethash :config hash) + (gethash :init hash) + (gethash :preface hash) + (gethash :use-package hash))) + (+ (float-time (gethash :config-secs hash 0)) + (float-time (gethash :init-secs hash 0)) + (float-time (gethash :preface-secs hash 0)) + (float-time (gethash :use-package-secs hash 0)))))) + use-package-statistics) + (display-buffer (current-buffer)))) + +(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 @@ -913,9 +993,13 @@ representing symbols (that may need to be autloaded)." (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))) + body + (when use-package-compute-statistics + `((use-package-statistics-gather :preface ',name t)))))) ;;;; :catch @@ -1220,6 +1304,8 @@ no keyword implies `:all'." (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))) @@ -1229,7 +1315,9 @@ no keyword implies `:all'." `((when (locate-library ,(use-package-as-string name)) ,@init-body)) init-body)))) - (use-package-process-keywords name rest state))) + (use-package-process-keywords name rest state) + (when use-package-compute-statistics + `((use-package-statistics-gather :init ',name t))))) ;;;; :load @@ -1252,16 +1340,21 @@ no keyword implies `:all'." (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))) - (if (or (null arg) (equal arg '(t))) - 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))))))) + (use-package-concat + (when use-package-compute-statistics + `((use-package-statistics-gather :config ',name nil))) + (if (or (null arg) (equal arg '(t))) + 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)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -1345,16 +1438,21 @@ this file. Usage: (declare (indent 1)) (unless (memq :disabled args) (macroexp-progn - (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)))))))) + (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))))))) (put 'use-package 'lisp-indent-function 'defun) From e8a7ae1ea170f08a601e8f2028618816a91d9232 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 6 Dec 2017 08:30:47 -0800 Subject: [PATCH 438/606] Add :bind test for a single cons cell Relates to https://github.com/jwiegley/use-package/issues/566 --- test/lisp/use-package/use-package-tests.el | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index fa765ac6634..05b8f3207ac 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -666,6 +666,18 @@ :map my-map ("C-u" . key2) :map my-map2 ("C-u" . key3)))))) +(ert-deftest use-package-test/:bind-7 () + (match-expansion + (use-package foo + :ensure + :bind ("C-c r" . browse-at-remote)) + `(progn + (use-package-ensure-elpa 'foo '(t) 'nil) + (unless (fboundp 'browse-at-remote) + (autoload #'browse-at-remote "foo" nil t)) + (ignore + (bind-keys :package foo ("C-c r" . browse-at-remote)))))) + (ert-deftest use-package-test/:bind*-1 () (match-expansion (use-package foo :bind* ("C-k" . key)) From ce36e6881748935c747760bc96d322e71ba115c5 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 6 Dec 2017 09:37:00 -0800 Subject: [PATCH 439/606] Don't compute the verbose debug text unless it's requested --- lisp/use-package/use-package-core.el | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 5ff33402c86..7711806d195 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1364,18 +1364,20 @@ no keyword implies `:all'." (defmacro use-package-core (name args) `(let* ((args* (use-package-normalize-keywords ,name ,args)) (use-package--form - (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))))))))) + (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))))) From b001edf1620151c307768046270478cadad39995 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 6 Dec 2017 10:20:51 -0800 Subject: [PATCH 440/606] Add missing autoload cookie, and make lack of a normalizer an error Fixes https://github.com/jwiegley/use-package/issues/566 --- lisp/use-package/use-package-bind-key.el | 1 + lisp/use-package/use-package-core.el | 8 ++------ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index 7c5d2725301..4a3d421522b 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -66,6 +66,7 @@ deferred until the prefix key sequence is pressed." (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*) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 7711806d195..4ab8a84a358 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -476,12 +476,8 @@ extending any keys already present." (tail (cdr xs)) (normalizer (intern (concat "use-package-normalize/" (symbol-name keyword)))) - (arg (cond ((functionp normalizer) - (funcall normalizer name keyword args)) - ((= (length args) 1) - (car args)) - (t - args)))) + (arg (and (functionp normalizer) + (funcall normalizer name keyword args)))) (if (memq keyword use-package-keywords) (progn (setq plist (use-package-normalize-plist From 9a6d8a4cf2a3cee0a1ff0def6651f44a793013e9 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 6 Dec 2017 10:31:47 -0800 Subject: [PATCH 441/606] Add a comment as to why max-lisp-eval-depth is set in -tests.el --- test/lisp/use-package/use-package-tests.el | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 05b8f3207ac..283758f5160 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -29,6 +29,8 @@ (setq use-package-always-ensure nil use-package-verbose 'errors use-package-expand-minimally t + ;; These are needed for certain tests below where the `pcase' match + ;; expression is large and contains holes, such as the :after tests. max-lisp-eval-depth 8000 max-specpdl-size 8000) From 75428f870ddfc260283f87534591b787dc242fd0 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 6 Dec 2017 10:45:34 -0800 Subject: [PATCH 442/606] Remove Package-Requires for diminish and delight, as these are optional --- lisp/use-package/use-package-delight.el | 2 +- lisp/use-package/use-package-diminish.el | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package-delight.el b/lisp/use-package/use-package-delight.el index 625cc5a5554..9d4f6acf2de 100644 --- a/lisp/use-package/use-package-delight.el +++ b/lisp/use-package/use-package-delight.el @@ -7,7 +7,7 @@ ;; Created: 17 Jun 2012 ;; Modified: 3 Dec 2017 ;; Version: 1.0 -;; Package-Requires: ((emacs "24.3") (use-package "2.4") (delight "1.5")) +;; Package-Requires: ((emacs "24.3") (use-package "2.4")) ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package diff --git a/lisp/use-package/use-package-diminish.el b/lisp/use-package/use-package-diminish.el index 77708ef396c..c2da62257e6 100644 --- a/lisp/use-package/use-package-diminish.el +++ b/lisp/use-package/use-package-diminish.el @@ -7,7 +7,7 @@ ;; Created: 17 Jun 2012 ;; Modified: 3 Dec 2017 ;; Version: 1.0 -;; Package-Requires: ((emacs "24.3") (use-package "2.4") (diminish "0.45")) +;; Package-Requires: ((emacs "24.3") (use-package "2.4")) ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package From beee6b8d4d9b77696adb0a66c71ae566f56c8941 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 6 Dec 2017 10:51:24 -0800 Subject: [PATCH 443/606] use-package-defaults predicate must also receive the package name --- lisp/use-package/use-package-core.el | 14 +++++++------- lisp/use-package/use-package-ensure.el | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 4ab8a84a358..fd7d56b271d 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -148,15 +148,15 @@ See also `use-package-defaults', which uses this value." '(;; this '(t) has special meaning; see `use-package-handler/:config' (:config '(t) t) (:init nil t) - (:catch t (lambda (args) + (:catch t (lambda (name args) (not use-package-expand-minimally))) (:defer use-package-always-defer - (lambda (args) + (lambda (name args) (and use-package-always-defer (not (plist-member args :defer)) (not (plist-member args :demand))))) (:demand use-package-always-demand - (lambda (args) + (lambda (name args) (and use-package-always-demand (not (plist-member args :defer)) (not (plist-member args :demand)))))) @@ -168,9 +168,9 @@ 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 list of keywords (in normalized form), -and should return nil or t according to whether defaulting should -be attempted." +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 +t according to whether defaulting should be attempted." :type `(repeat (list (choice :tag "Keyword" ,@(mapcar #'(lambda (k) (list 'const k)) @@ -534,7 +534,7 @@ extending any keys already present." (cl-dolist (spec use-package-defaults) (when (let ((func (nth 2 spec))) (if (and func (functionp func)) - (funcall func args) + (funcall func name args) (eval func))) (setq args (use-package-plist-maybe-put args (nth 0 spec) (eval (nth 1 spec)))))) diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index 46de5a8a3a4..3ae8201dc24 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -200,7 +200,7 @@ manually updated package." (add-to-list 'use-package-defaults '(:ensure (list use-package-always-ensure) - (lambda (args) + (lambda (name args) (and use-package-always-ensure (not (plist-member args :load-path))))) t) From 71fc224961510a56baff2e4686ccca484824f58d Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 6 Dec 2017 11:53:21 -0800 Subject: [PATCH 444/606] Add documentation for `use-package-report' --- lisp/use-package/use-package-core.el | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index fd7d56b271d..517671b87f1 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -863,6 +863,13 @@ representing symbols (that may need to be autloaded)." (setq use-package-statistics (make-hash-table))) (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" (interactive) (with-current-buffer (get-buffer-create "*use-package statistics*") (delete-region (point-min) (point-max)) From 7cc17cee8f8ae2093d98efebf429cd10e9b0b81c Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 6 Dec 2017 16:56:25 -0800 Subject: [PATCH 445/606] Pre-expand lexical-let, since otherwise it requires cl to be loaded Fixes https://github.com/jwiegley/use-package/issues/571 --- lisp/use-package/use-package-core.el | 19 +++++++++++-------- test/lisp/use-package/use-package-tests.el | 15 +++++---------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 517671b87f1..d2910ed5686 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -671,14 +671,17 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." (defun use-package-memoize (f arg) "Ensure the macro-expansion of F applied to ARG evaluates ARG no more than once." - (let ((loaded (cl-gensym "use-package--loaded")) - (result (cl-gensym "use-package--result")) - (next (cl-gensym "use-package--next"))) - `((lexical-let (,loaded ,result) - ,@(funcall f `((if ,loaded - ,result - (setq ,loaded t) - (setq ,result ,arg)))))))) + (let* ((loaded (cl-gensym "use-package--loaded")) + (result (cl-gensym "use-package--result")) + (next (cl-gensym "use-package--next")) + (body `(lexical-let (,loaded ,result) + ,@(funcall f `((if ,loaded + ,result + (setq ,loaded t) + (setq ,result ,arg))))))) + `(,(if (eq use-package-verbose 'errors) + body + (macroexpand body))))) (defsubst use-package-normalize-value (label arg) "Normalize the Lisp value given by ARG. diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 283758f5160..9dcab5fe63b 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1213,8 +1213,7 @@ (eval-after-load 'quux '(if ,_ ,_ (setq ,_ t) - (setq ,_ (require 'foo nil nil))))))) - )) + (setq ,_ (require 'foo nil nil))))))))) (ert-deftest use-package-test/:after-7 () (match-expansion @@ -1228,8 +1227,7 @@ (eval-after-load 'bow '(if ,_ ,_ (setq ,_ t) - (setq ,_ (require 'foo nil nil))))) - )) + (setq ,_ (require 'foo nil nil))))))) (ert-deftest use-package-test/:after-8 () (match-expansion @@ -1254,8 +1252,7 @@ (eval-after-load 'quux '(if ,_ ,_ (setq ,_ t) - (setq ,_ (require 'foo nil nil))))))) - )) + (setq ,_ (require 'foo nil nil))))))))) (ert-deftest use-package-test/:after-9 () (match-expansion @@ -1270,8 +1267,7 @@ '(eval-after-load 'bow '(if ,_ ,_ (setq ,_ t) - (setq ,_ (require 'foo nil nil)))))) - )) + (setq ,_ (require 'foo nil nil)))))))) (ert-deftest use-package-test/:after-10 () (match-expansion @@ -1289,8 +1285,7 @@ (eval-after-load 'baz '(if ,_ ,_ (setq ,_ t) - (setq ,_ (require 'foo nil nil))))) - )) + (setq ,_ (require 'foo nil nil))))))) (ert-deftest use-package-test/:demand-1 () (match-expansion From 20694696b2795e7743ef0c4e257c9783c41217eb Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 7 Dec 2017 04:53:10 +0000 Subject: [PATCH 446/606] Revert "Pre-expand lexical-let, since otherwise it requires cl to be loaded" This reverts commit 7cc17cee8f8ae2093d98efebf429cd10e9b0b81c. --- lisp/use-package/use-package-core.el | 19 ++++++++----------- test/lisp/use-package/use-package-tests.el | 15 ++++++++++----- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index d2910ed5686..517671b87f1 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -671,17 +671,14 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." (defun use-package-memoize (f arg) "Ensure the macro-expansion of F applied to ARG evaluates ARG no more than once." - (let* ((loaded (cl-gensym "use-package--loaded")) - (result (cl-gensym "use-package--result")) - (next (cl-gensym "use-package--next")) - (body `(lexical-let (,loaded ,result) - ,@(funcall f `((if ,loaded - ,result - (setq ,loaded t) - (setq ,result ,arg))))))) - `(,(if (eq use-package-verbose 'errors) - body - (macroexpand body))))) + (let ((loaded (cl-gensym "use-package--loaded")) + (result (cl-gensym "use-package--result")) + (next (cl-gensym "use-package--next"))) + `((lexical-let (,loaded ,result) + ,@(funcall f `((if ,loaded + ,result + (setq ,loaded t) + (setq ,result ,arg)))))))) (defsubst use-package-normalize-value (label arg) "Normalize the Lisp value given by ARG. diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 9dcab5fe63b..283758f5160 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1213,7 +1213,8 @@ (eval-after-load 'quux '(if ,_ ,_ (setq ,_ t) - (setq ,_ (require 'foo nil nil))))))))) + (setq ,_ (require 'foo nil nil))))))) + )) (ert-deftest use-package-test/:after-7 () (match-expansion @@ -1227,7 +1228,8 @@ (eval-after-load 'bow '(if ,_ ,_ (setq ,_ t) - (setq ,_ (require 'foo nil nil))))))) + (setq ,_ (require 'foo nil nil))))) + )) (ert-deftest use-package-test/:after-8 () (match-expansion @@ -1252,7 +1254,8 @@ (eval-after-load 'quux '(if ,_ ,_ (setq ,_ t) - (setq ,_ (require 'foo nil nil))))))))) + (setq ,_ (require 'foo nil nil))))))) + )) (ert-deftest use-package-test/:after-9 () (match-expansion @@ -1267,7 +1270,8 @@ '(eval-after-load 'bow '(if ,_ ,_ (setq ,_ t) - (setq ,_ (require 'foo nil nil)))))))) + (setq ,_ (require 'foo nil nil)))))) + )) (ert-deftest use-package-test/:after-10 () (match-expansion @@ -1285,7 +1289,8 @@ (eval-after-load 'baz '(if ,_ ,_ (setq ,_ t) - (setq ,_ (require 'foo nil nil))))))) + (setq ,_ (require 'foo nil nil))))) + )) (ert-deftest use-package-test/:demand-1 () (match-expansion From 7803571280be1596d46e41999fef7bd242d128aa Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 6 Dec 2017 20:59:10 -0800 Subject: [PATCH 447/606] Correctly fix the problem of unreferenced symbols after compilation Fixes https://github.com/jwiegley/use-package/issues/571 --- lisp/use-package/use-package-core.el | 16 +-- test/lisp/use-package/use-package-tests.el | 119 +++++++++++---------- 2 files changed, 71 insertions(+), 64 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 517671b87f1..81d45c03b2b 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -671,14 +671,14 @@ If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." (defun use-package-memoize (f arg) "Ensure the macro-expansion of F applied to ARG evaluates ARG no more than once." - (let ((loaded (cl-gensym "use-package--loaded")) - (result (cl-gensym "use-package--result")) - (next (cl-gensym "use-package--next"))) - `((lexical-let (,loaded ,result) - ,@(funcall f `((if ,loaded - ,result - (setq ,loaded t) - (setq ,result ,arg)))))))) + (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. diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 283758f5160..ffff7ced326 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1190,107 +1190,114 @@ (ert-deftest use-package-test/:after-5 () (match-expansion (use-package foo :after (:any bar quux)) - `(lexical-let (,_ ,_) + `(progn + (defvar ,_ nil) + (defvar ,_ nil) + (defvar ,_ + #'(lambda nil + (if ,_ ,_ + (setq ,_ t ,_ + (require 'foo nil nil))))) (eval-after-load 'bar - '(if ,_ ,_ - (setq ,_ t) - (setq ,_ (require 'foo nil nil)))) + '(funcall ,_)) (eval-after-load 'quux - '(if ,_ ,_ - (setq ,_ t) - (setq ,_ (require 'foo nil nil))))))) + '(funcall ,_))))) (ert-deftest use-package-test/:after-6 () (match-expansion (use-package foo :after (:all (:any bar quux) bow)) - `(lexical-let (,_ ,_) + `(progn + (defvar ,_ nil) + (defvar ,_ nil) + (defvar ,_ + #'(lambda nil + (if ,_ ,_ + (setq ,_ t ,_ + (require 'foo nil nil))))) (eval-after-load 'bow '(progn (eval-after-load 'bar - '(if ,_ ,_ - (setq ,_ t) - (setq ,_ (require 'foo nil nil)))) + '(funcall ,_)) (eval-after-load 'quux - '(if ,_ ,_ - (setq ,_ t) - (setq ,_ (require 'foo nil nil))))))) - )) + '(funcall ,_))))))) (ert-deftest use-package-test/:after-7 () (match-expansion (use-package foo :after (:any (:all bar quux) bow)) - `(lexical-let (,_ ,_) + `(progn + (defvar ,_ nil) + (defvar ,_ nil) + (defvar ,_ + #'(lambda nil + (if ,_ ,_ + (setq ,_ t ,_ + (require 'foo nil nil))))) (eval-after-load 'quux '(eval-after-load 'bar - '(if ,_ ,_ - (setq ,_ t) - (setq ,_ (require 'foo nil nil))))) + '(funcall ,_))) (eval-after-load 'bow - '(if ,_ ,_ - (setq ,_ t) - (setq ,_ (require 'foo nil nil))))) - )) + '(funcall ,_))))) (ert-deftest use-package-test/:after-8 () (match-expansion (use-package foo :after (:all (:any bar quux) (:any bow baz))) - `(lexical-let (,_ ,_) + `(progn + (defvar ,_ nil) + (defvar ,_ nil) + (defvar ,_ + #'(lambda nil + (if ,_ ,_ + (setq ,_ t ,_ + (require 'foo nil nil))))) (eval-after-load 'bow '(progn (eval-after-load 'bar - '(if ,_ ,_ - (setq ,_ t) - (setq ,_ (require 'foo nil nil)))) + '(funcall ,_)) (eval-after-load 'quux - '(if ,_ ,_ - (setq ,_ t) - (setq ,_ (require 'foo nil nil)))))) + '(funcall ,_)))) (eval-after-load 'baz '(progn (eval-after-load 'bar - '(if ,_ ,_ - (setq ,_ t) - (setq ,_ (require 'foo nil nil)))) + '(funcall ,_)) (eval-after-load 'quux - '(if ,_ ,_ - (setq ,_ t) - (setq ,_ (require 'foo nil nil))))))) - )) + '(funcall ,_))))))) (ert-deftest use-package-test/:after-9 () (match-expansion (use-package foo :after (:any (:all bar quux) (:all bow baz))) - `(lexical-let (,_ ,_) + `(progn + (defvar ,_ nil) + (defvar ,_ nil) + (defvar ,_ + #'(lambda nil + (if ,_ ,_ + (setq ,_ t ,_ + (require 'foo nil nil))))) (eval-after-load 'quux '(eval-after-load 'bar - '(if ,_ ,_ - (setq ,_ t) - (setq ,_ (require 'foo nil nil))))) + '(funcall ,_))) (eval-after-load 'baz '(eval-after-load 'bow - '(if ,_ ,_ - (setq ,_ t) - (setq ,_ (require 'foo nil nil)))))) - )) + '(funcall ,_)))))) (ert-deftest use-package-test/:after-10 () (match-expansion (use-package foo :after (:any (:all bar quux) (:any bow baz))) - `(lexical-let (,_ ,_) + `(progn + (defvar ,_ nil) + (defvar ,_ nil) + (defvar ,_ + #'(lambda nil + (if ,_ ,_ + (setq ,_ t ,_ + (require 'foo nil nil))))) (eval-after-load 'quux '(eval-after-load 'bar - '(if ,_ ,_ - (setq ,_ t) - (setq ,_ (require 'foo nil nil))))) + '(funcall ,_))) (eval-after-load 'bow - '(if ,_ ,_ - (setq ,_ t) - (setq ,_ (require 'foo nil nil)))) + '(funcall ,_)) (eval-after-load 'baz - '(if ,_ ,_ - (setq ,_ t) - (setq ,_ (require 'foo nil nil))))) - )) + '(funcall ,_))))) (ert-deftest use-package-test/:demand-1 () (match-expansion From 96ecfab9e4e219eb525d945ad14f6742562b11b1 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 6 Dec 2017 22:52:34 -0800 Subject: [PATCH 448/606] Use cl-gentemp in another place This avoids "Variable unknown" errors if a byte-compiled init.elc happening to encounter an error while evaluating an :init or :config block. --- lisp/use-package/use-package-core.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 81d45c03b2b..82163d01514 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1021,7 +1021,7 @@ meaning: use-package--hush-function))) (defun use-package-handler/:catch (name keyword arg rest state) - (let* ((context (cl-gensym "use-package--warning"))) + (let* ((context (cl-gentemp "use-package--warning"))) (cond ((not arg) (use-package-process-keywords name rest state)) From 80e8a599b4392bbb45a6263c8e750db267b8e4e9 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 7 Dec 2017 13:13:49 -0800 Subject: [PATCH 449/606] Introduce new customization variable `use-package-merge-key-alist' --- etc/USE-PACKAGE-NEWS | 7 ++++++ lisp/use-package/use-package-core.el | 35 +++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index 265e98f2094..76556be9b2e 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -154,6 +154,13 @@ it is loaded, `helm-descbinds` itself is not loaded until the user presses `C-h b`. +- For extension authors, there is a new customization variable + `use-package-merge-key-alist` that specifies how values passed to multiple + occurences of the same key should be merged into a single value, during + normalization of the `use-package` declaration into a proper plist. The + default behavior is to simply append the values together (since they are + always normalized to lists). + ### Bug fixes - Repeating a bind no longer causes duplicates in personal-keybindings. diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 82163d01514..175e023a5a4 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -179,6 +179,29 @@ t according to whether defaulting should be attempted." (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))) + "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 @@ -484,8 +507,8 @@ extending any keys already present." name tail plist merge-function)) (plist-put plist keyword (if (plist-member plist keyword) - (funcall merge-function keyword - arg (plist-get plist keyword)) + (funcall merge-function keyword arg + (plist-get plist keyword)) arg))) (use-package-error (format "Unrecognized keyword: %s" keyword)))))) @@ -498,10 +521,10 @@ extending any keys already present." args) (defun use-package-merge-keys (key new old) - (cond ((eq :if key) `(and ,new ,old)) - ((eq :after key) `(:all ,new ,old)) - ((eq :defer key) old) - (t (append 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) From 8fefa49d39dde99dfd13ff9551723ec387a3bfba Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 7 Dec 2017 13:14:32 -0800 Subject: [PATCH 450/606] Changes to the way auto-deferral is indicated This change adds a new extension hook `use-package-autoloads/` for specifying exactly which autoloads a keyword should imply. This is the proper way to indicate autoloads, rather than adding to the `:commands` entry as was done before. Further, autoloading now must occur in order to cause implied deferred loading; if :bind is used with only lambda forms, for example, this will not cause deferred loading without `:defer t`. --- etc/USE-PACKAGE-NEWS | 26 +++- lisp/use-package/use-package-bind-key.el | 25 ++-- lisp/use-package/use-package-core.el | 160 ++++++++++++--------- test/lisp/use-package/use-package-tests.el | 79 ++++++---- 4 files changed, 181 insertions(+), 109 deletions(-) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index 76556be9b2e..c34376d3ffe 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -30,10 +30,6 @@ parameter, but are now done as an extension to `rest`. Please see `use-package-handler/:bind` for a canonical example. -- For extension authors, if you add a keyword to `use-package-keywords` whose - presence should indicate deferred loading, please also add it to - `use-package-deferring-keywords`. - ### Other changes - Upgrade license to GPL 3. @@ -154,6 +150,28 @@ it is loaded, `helm-descbinds` itself is not loaded until the user presses `C-h b`. +- For extension authors, if you add a keyword to `use-package-keywords` whose + presence should indicate deferred loading, please also add it to + `use-package-deferring-keywords`. Note that this is a bit of a sledgehammer, + in that the mere presence of these keywords implies deferred loading. For a + more subtle approach, see the new `use-package-autoloads/` support + mentioned in the next bullet. + +- For extension authors, if you wish deferred loading to possibly occur, + create functions named `use-package-autoloads/` for each keyword + that you define, returning an alist of the form `(SYMBOL . TYPE)` of symbols + to be autoloaded. `SYMBOL` should be an interactive function, and `TYPE` the + smybol `command`, but this functionality may be extended in future. These + autoloads are established if deferred loading is to happen. + +- If you specify a lambda form rather than a function symbol in any of the + constructs that *might* introduce autoloads: `:bind`, `:bind*`, + `:interpreter`, `:mode`, `:magic`, `:magic-fallback`, and `:hook`: then + deferred loading will no longer be implied, since there's nothing to + associate an autoload with that could later load the module. In these cases, + it will be as if you'd specified `:demand t`, in order to ensure the lambda + form is able to execute in the context of the loaded package. + - For extension authors, there is a new customization variable `use-package-merge-key-alist` that specifies how values passed to multiple occurences of the same key should be merged into a single value, during diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index 4a3d421522b..6a8e3fbe8eb 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -114,20 +114,23 @@ deferred until the prefix key sequence is pressed." ;;;###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) - (let* ((result (use-package-normalize-commands args)) - (nargs (car result)) - (commands (cdr result))) - (use-package-concat - (use-package-process-keywords name - (use-package-sort-keywords - (use-package-plist-append rest :commands commands)) - state) - `((ignore - (,(if bind-macro bind-macro 'bind-keys) - :package ,name ,@nargs)))))) + (use-package-concat + (use-package-process-keywords name rest state) + `((ignore + (,(if bind-macro bind-macro 'bind-keys) + :package ,name ,@(use-package-normalize-commands args)))))) (defun use-package-handler/:bind* (name keyword arg rest state) (use-package-handler/:bind name keyword arg rest state 'bind-keys*)) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 175e023a5a4..001ffde1534 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -100,17 +100,15 @@ declaration is incorrect." :group 'use-package) (defcustom use-package-deferring-keywords - '(:bind - :bind* - :bind-keymap + '(:bind-keymap :bind-keymap* - :interpreter - :mode - :magic - :magic-fallback - :hook :commands) - "Unless `:demand' is used, keywords in this list imply deferred loading." + "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) @@ -160,7 +158,7 @@ See also `use-package-defaults', which uses this value." (and use-package-always-demand (not (plist-member args :defer)) (not (plist-member args :demand)))))) - "Alist of default values for `use-package' keywords. + "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 and the second is a form that can be evaluated to get the default value. The third element @@ -497,8 +495,9 @@ extending any keys already present." (xs (use-package-split-list #'keywordp (cdr input))) (args (car xs)) (tail (cdr xs)) - (normalizer (intern (concat "use-package-normalize/" - (symbol-name keyword)))) + (normalizer + (intern-soft (concat "use-package-normalize/" + (symbol-name keyword)))) (arg (and (functionp normalizer) (funcall normalizer name keyword args)))) (if (memq keyword use-package-keywords) @@ -562,6 +561,32 @@ extending any keys already present." (setq args (use-package-plist-maybe-put args (nth 0 spec) (eval (nth 1 spec)))))) + ;; 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) @@ -593,10 +618,13 @@ extending any keys already present." 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-member args :load)) (not (plist-member args :defer)) (not (plist-member args :no-require))) @@ -851,22 +879,12 @@ If RECURSED is non-nil, recurse into sublists." (t v))) (defun use-package-normalize-commands (args) - "Map over ARGS of the form ((_ . F) ...). -Normalizing functional F's and returning a list of F's -representing symbols (that may need to be autloaded)." - (let ((nargs (mapcar - #'(lambda (x) - (if (consp x) - (cons (car x) - (use-package-normalize-function (cdr x))) - x)) args))) - (cons nargs - (delete - nil (mapcar - #'(lambda (x) - (and (consp x) - (use-package-non-nil-symbolp (cdr x)) - (cdr x))) nargs))))) + "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." @@ -876,6 +894,27 @@ representing symbols (that may need to be autloaded)." #'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) + `((ignore + ,@(mapcar + #'(lambda (thing) + `(add-to-list + ',alist + ',(cons (use-package-normalize-regex (car thing)) + (cdr thing)))) + (use-package-normalize-commands args)))))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Statistics @@ -1078,26 +1117,8 @@ meaning: ;;;; :interpreter -(defun use-package-handle-mode (name alist args rest state) - "Handle keywords which add regexp/mode pairs to an alist." - (let* ((result (use-package-normalize-commands args)) - (nargs (car result)) - (commands (cdr result))) - (use-package-concat - (use-package-process-keywords name - (use-package-sort-keywords - (use-package-plist-append rest :commands commands)) - state) - `((ignore - ,@(mapcar - #'(lambda (thing) - `(add-to-list - ',alist - ',(cons (use-package-normalize-regex (car thing)) - (cdr thing)))) - nargs)))))) - (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)) @@ -1105,6 +1126,7 @@ meaning: ;;;; :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)) @@ -1112,6 +1134,7 @@ meaning: ;;;; :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)) @@ -1119,6 +1142,7 @@ meaning: ;;;; :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)) @@ -1145,31 +1169,27 @@ meaning: #'use-package-recognize-function name 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." - (let* ((result (use-package-normalize-commands args)) - (nargs (car result)) - (commands (cdr result))) - (use-package-concat - (use-package-process-keywords name - (use-package-sort-keywords - (use-package-plist-append rest :commands commands)) - state) - `((ignore - ,@(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))) - (if (use-package-non-nil-symbolp syms) (list syms) syms))))) - nargs)))))) + (use-package-concat + (use-package-process-keywords name rest state) + `((ignore + ,@(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))) + (if (use-package-non-nil-symbolp syms) (list syms) syms))))) + (use-package-normalize-commands args)))))) ;;;; :commands diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index ffff7ced326..08ac5293a99 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1001,30 +1001,30 @@ (ert-deftest use-package-test/:hook-1 () (let ((byte-compile-current-file t)) - (should - (equal - (expand-minimally - (use-package foo - :bind (("C-a" . key)) - :hook (hook . fun))) - '(progn - (eval-and-compile - (eval-when-compile - (with-demoted-errors - "Cannot load foo: %S" nil - (load "foo" nil t)))) - (unless (fboundp 'fun) - (autoload #'fun "foo" nil t)) - (eval-when-compile - (declare-function fun "foo")) - (unless (fboundp 'key) - (autoload #'key "foo" nil t)) - (eval-when-compile - (declare-function key "foo")) - (ignore - (add-hook 'hook-hook #'fun)) - (ignore - (bind-keys :package foo ("C-a" . key)))))))) + (match-expansion + (use-package foo + :bind (("C-a" . key)) + :hook (hook . fun)) + `(progn + (eval-and-compile + (eval-when-compile + (with-demoted-errors + "Cannot load foo: %S" nil + (load "foo" nil t)))) + (unless + (fboundp 'key) + (autoload #'key "foo" nil t)) + (eval-when-compile + (declare-function key "foo")) + (unless + (fboundp 'fun) + (autoload #'fun "foo" nil t)) + (eval-when-compile + (declare-function fun "foo")) + (ignore + (add-hook 'hook-hook #'fun)) + (ignore + (bind-keys :package foo ("C-a" . key))))))) (ert-deftest use-package-test/:hook-2 () (match-expansion @@ -1079,6 +1079,37 @@ #'(lambda nil (bind-key "" erefactor-map emacs-lisp-mode-map))))))))) +(ert-deftest use-package-test/:hook-6 () + (match-expansion + (use-package erefactor + :load-path "foo" + :after elisp-mode + :hook (emacs-lisp-mode . function)) + `(progn + (eval-and-compile + (add-to-list 'load-path "/Users/johnw/.emacs.d/foo")) + (eval-after-load 'elisp-mode + '(progn + (unless (fboundp 'function) + (autoload #'function "erefactor" nil t)) + (ignore + (add-hook 'emacs-lisp-mode-hook #'function))))))) + +(ert-deftest use-package-test/:hook-7 () + (match-expansion + (use-package erefactor + :load-path "foo" + :after elisp-mode + :hook (emacs-lisp-mode . (lambda () (function)))) + `(progn + (eval-and-compile + (add-to-list 'load-path "/Users/johnw/.emacs.d/foo")) + (eval-after-load 'elisp-mode + '(progn + (require 'erefactor nil nil) + (ignore + (add-hook 'emacs-lisp-mode-hook #'(lambda nil (function))))))))) + (ert-deftest use-package-test-normalize/:custom () (flet ((norm (&rest args) (apply #'use-package-normalize/:custom From 8cf7b17dae39b8fe5739fc86f9f78c389ecc9590 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 7 Dec 2017 13:22:57 -0800 Subject: [PATCH 451/606] Clarify a note in NEWS.md --- etc/USE-PACKAGE-NEWS | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index c34376d3ffe..07b076e4129 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -25,10 +25,8 @@ you had previously customized this (or were an extension author adding to this list), you may need to rework your changes. -- For extension authors, the way `:commands` are propagated down for - autoloading has changed. They used to be passed through the `state` - parameter, but are now done as an extension to `rest`. Please see - `use-package-handler/:bind` for a canonical example. +- For extension authors, `:commands` should no longer be propagated down for + autoloading. See more below. ### Other changes From 93231ecbab5a3567fbc5fb3e0c75df6dee983a07 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 7 Dec 2017 13:23:36 -0800 Subject: [PATCH 452/606] Fix the tests --- test/lisp/use-package/use-package-tests.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 08ac5293a99..f1e6bb00165 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1087,7 +1087,7 @@ :hook (emacs-lisp-mode . function)) `(progn (eval-and-compile - (add-to-list 'load-path "/Users/johnw/.emacs.d/foo")) + (add-to-list 'load-path ,(pred stringp))) (eval-after-load 'elisp-mode '(progn (unless (fboundp 'function) @@ -1103,7 +1103,7 @@ :hook (emacs-lisp-mode . (lambda () (function)))) `(progn (eval-and-compile - (add-to-list 'load-path "/Users/johnw/.emacs.d/foo")) + (add-to-list 'load-path ,(pred stringp))) (eval-after-load 'elisp-mode '(progn (require 'erefactor nil nil) From 4714380696404cc2d12ca7fb35209e62844883a1 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 7 Dec 2017 14:34:51 -0800 Subject: [PATCH 453/606] Add tests for two more issues --- test/lisp/use-package/use-package-tests.el | 50 ++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index f1e6bb00165..2f4a7b897c4 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1733,6 +1733,56 @@ (when (symbol-value 'notmuch-command) (require 'notmuch nil nil)))))))) +(ert-deftest use-package-test/572 () + (let ((use-package-always-defer t)) + (match-expansion + (use-package auth-password-store + :after auth-source + :init + (setq auth-sources '(password-store))) + `(eval-after-load 'auth-source + '(setq auth-sources '(password-store)))))) + +(ert-deftest use-package-test/575-1 () + (match-expansion + (use-package helm + :defer t + :after (:any ido dired) + :config + (message "test. helm start")) + `(progn + (defvar ,_ nil) + (defvar ,_ nil) + (defvar ,_ + #'(lambda nil + (if ,_ ,_ + (setq ,_ t ,_ + (eval-after-load 'helm + '(progn + (message "test. helm start") + t)))))) + (eval-after-load 'ido + '(funcall ,_)) + (eval-after-load 'dired + '(funcall ,_))))) + +(ert-deftest use-package-test/575-2 () + (match-expansion + (use-package helm + :defer t + :bind ("C-c d" . helm-mini) + :config + (message "test. helm start")) + `(progn + (unless (fboundp 'helm-mini) + (autoload #'helm-mini "helm" nil t)) + (eval-after-load 'helm + '(progn + (message "test. helm start") + t)) + (ignore + (bind-keys :package helm ("C-c d" . helm-mini)))))) + (ert-deftest bind-key/:prefix-map () (match-expansion (bind-keys :prefix "" From e6c54b54ab3af7da52b0e3a1e24732b0e111eb3d Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 7 Dec 2017 15:50:07 -0800 Subject: [PATCH 454/606] Add further note to NEWS.md --- etc/USE-PACKAGE-NEWS | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index 07b076e4129..59366b9604c 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -86,7 +86,11 @@ - New customization variable `use-package-enable-imenu-support`. -- New customization variable `use-package-hook-name-suffix`. +- New customization variable `use-package-hook-name-suffix`. Any symbols named + in `:hook`, or in the CAR of cons cells passed to `:hook`, have this text + appended to them as a convenience. If you find yourself using this keyword + to add to hooks of different names, or just don't want such appending done, + you can change the text to an empty string. - New customization variable `use-package-compute-statistics`, and an accompanying command `M-x use-package-report`. See the README for more From ae0d24368189025379a249ee31b3999c25645934 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 7 Dec 2017 22:04:24 -0800 Subject: [PATCH 455/606] Add another :bind test --- test/lisp/use-package/use-package-tests.el | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 2f4a7b897c4..0b40fb582ad 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -680,6 +680,24 @@ (ignore (bind-keys :package foo ("C-c r" . browse-at-remote)))))) +(ert-deftest use-package-test/:bind-8 () + (match-expansion + (use-package foo + :ensure + :bind (:map foo-map + (("C-c r" . foo) + ("C-c r" . bar)))) + `(progn + (use-package-ensure-elpa 'foo '(t) 'nil) + (unless (fboundp 'foo) + (autoload #'foo "foo" nil t)) + (unless (fboundp 'bar) + (autoload #'bar "foo" nil t)) + (ignore + (bind-keys :package foo :map foo-map + ("C-c r" . foo) + ("C-c r" . bar)))))) + (ert-deftest use-package-test/:bind*-1 () (match-expansion (use-package foo :bind* ("C-k" . key)) From 0068501aa086efc1b01620ec5bd427ef57cb9f9d Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 7 Dec 2017 22:40:48 -0800 Subject: [PATCH 456/606] Remove several unnecessary calls to `ignore' --- lisp/use-package/use-package-bind-key.el | 29 ++-- lisp/use-package/use-package-chords.el | 5 +- lisp/use-package/use-package-core.el | 62 ++++----- lisp/use-package/use-package-ensure.el | 9 +- test/lisp/use-package/use-package-tests.el | 152 ++++++++------------- 5 files changed, 108 insertions(+), 149 deletions(-) diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index 6a8e3fbe8eb..b26c812bf58 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -128,9 +128,8 @@ deferred until the prefix key sequence is pressed." (name keyword args rest state &optional bind-macro) (use-package-concat (use-package-process-keywords name rest state) - `((ignore - (,(if bind-macro bind-macro 'bind-keys) - :package ,name ,@(use-package-normalize-commands args)))))) + `((,(if bind-macro bind-macro 'bind-keys) + :package ,name ,@(use-package-normalize-commands args))))) (defun use-package-handler/:bind* (name keyword arg rest state) (use-package-handler/:bind name keyword arg rest state 'bind-keys*)) @@ -144,21 +143,19 @@ deferred until the prefix key sequence is pressed." ;;;###autoload (defun use-package-handler/:bind-keymap - (name keyword arg rest state &optional override) + (name keyword args rest state &optional override) (use-package-concat (use-package-process-keywords name rest state) - `((ignore - ,@(mapcar - #'(lambda (binding) - `(,(if override - 'bind-key* - 'bind-key) - ,(car binding) - #'(lambda () - (interactive) - (use-package-autoload-keymap - ',(cdr binding) ',(use-package-as-symbol name) - ,override)))) arg))))) + (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) diff --git a/lisp/use-package/use-package-chords.el b/lisp/use-package/use-package-chords.el index 8cdd30990cb..63a9737109f 100644 --- a/lisp/use-package/use-package-chords.el +++ b/lisp/use-package/use-package-chords.el @@ -39,9 +39,8 @@ (use-package-sort-keywords (use-package-plist-maybe-put rest :defer t)) (use-package-plist-append state :commands commands)) - `((ignore - ,(macroexpand - `(bind-chords :package ,name ,@arg))))))) + `(,(macroexpand + `(bind-chords :package ,name ,@arg)))))) (use-package-handler/:preface name keyword chord-binder rest state))) (add-to-list 'use-package-keywords :chords t) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 001ffde1534..9e32fb477d3 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -414,10 +414,9 @@ The BODY is a list of forms, so `((foo))' if only `foo' is being called." (use-package-with-elapsed-timer (format "Loading package %s" name) `((if (not ,(use-package-load-name name t)) - (ignore - (display-warning 'use-package - (format "Cannot load %s" ',name) - :error)) + (display-warning 'use-package + (format "Cannot load %s" ',name) + :error) ,@body)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -906,14 +905,13 @@ If RECURSED is non-nil, recurse into sublists." "Handle keywords which add regexp/mode pairs to an alist." (use-package-concat (use-package-process-keywords name rest state) - `((ignore - ,@(mapcar - #'(lambda (thing) - `(add-to-list - ',alist - ',(cons (use-package-normalize-regex (car thing)) - (cdr thing)))) - (use-package-normalize-commands args)))))) + (mapcar + #'(lambda (thing) + `(add-to-list + ',alist + ',(cons (use-package-normalize-regex (car thing)) + (cdr thing)))) + (use-package-normalize-commands args)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -1101,7 +1099,7 @@ meaning: (setq msg (concat msg " (see the *use-package* buffer)")))) - (ignore (display-warning 'use-package msg :error))))) + (display-warning 'use-package msg :error)))) ,@(let ((use-package--hush-function (apply-partially #'use-package-hush context))) (funcall use-package--hush-function keyword @@ -1175,21 +1173,20 @@ meaning: "Generate use-package custom keyword code." (use-package-concat (use-package-process-keywords name rest state) - `((ignore - ,@(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))) - (if (use-package-non-nil-symbolp syms) (list syms) syms))))) - (use-package-normalize-commands args)))))) + (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))) + (if (use-package-non-nil-symbolp syms) (list syms) syms))))) + (use-package-normalize-commands args)))) ;;;; :commands @@ -1494,11 +1491,10 @@ this file. Usage: (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))))) + (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))))))) diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index 3ae8201dc24..1a76b883e1c 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -177,11 +177,10 @@ manually updated package." (package-install package)) t) (error - (ignore - (display-warning 'use-package - (format "Failed to install %s: %s" - name (error-message-string err)) - :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) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 0b40fb582ad..5ba6db8a4b5 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -594,10 +594,9 @@ (unless (fboundp 'key2) (autoload #'key2 "foo" nil t)) - (ignore - (bind-keys :package foo - ("C-k" . key1) - ("C-u" . key2)))))) + (bind-keys :package foo + ("C-k" . key1) + ("C-u" . key2))))) (ert-deftest use-package-test/:bind-2 () (match-expansion @@ -607,10 +606,9 @@ (autoload #'key1 "foo" nil t)) (unless (fboundp 'key2) (autoload #'key2 "foo" nil t)) - (ignore - (bind-keys :package foo - ("C-k" . key1) - ("C-u" . key2)))))) + (bind-keys :package foo + ("C-k" . key1) + ("C-u" . key2))))) (ert-deftest use-package-test/:bind-3 () (match-expansion @@ -622,17 +620,15 @@ (unless (fboundp 'key2) (autoload #'key2 "foo" nil t)) - (ignore - (bind-keys :package foo :map my-map - ("C-k" . key1) - ("C-u" . key2)))))) + (bind-keys :package foo :map my-map + ("C-k" . key1) + ("C-u" . key2))))) (ert-deftest use-package-test/:bind-4 () (should-error (match-expansion (use-package foo :bind :map my-map ("C-k" . key1) ("C-u" . key2)) - `(ignore - (bind-keys :package foo))))) + `(bind-keys :package foo)))) (ert-deftest use-package-test/:bind-5 () (match-expansion @@ -642,11 +638,10 @@ (autoload #'key1 "foo" nil t)) (unless (fboundp 'key2) (autoload #'key2 "foo" nil t)) - (ignore - (bind-keys :package foo - ("C-k" . key1) - :map my-map - ("C-u" . key2)))))) + (bind-keys :package foo + ("C-k" . key1) + :map my-map + ("C-u" . key2))))) (ert-deftest use-package-test/:bind-6 () (match-expansion @@ -662,11 +657,10 @@ (autoload #'key2 "foo" nil t)) (unless (fboundp 'key3) (autoload #'key3 "foo" nil t)) - (ignore - (bind-keys :package foo - ("C-k" . key1) - :map my-map ("C-u" . key2) - :map my-map2 ("C-u" . key3)))))) + (bind-keys :package foo + ("C-k" . key1) + :map my-map ("C-u" . key2) + :map my-map2 ("C-u" . key3))))) (ert-deftest use-package-test/:bind-7 () (match-expansion @@ -677,8 +671,7 @@ (use-package-ensure-elpa 'foo '(t) 'nil) (unless (fboundp 'browse-at-remote) (autoload #'browse-at-remote "foo" nil t)) - (ignore - (bind-keys :package foo ("C-c r" . browse-at-remote)))))) + (bind-keys :package foo ("C-c r" . browse-at-remote))))) (ert-deftest use-package-test/:bind-8 () (match-expansion @@ -693,10 +686,9 @@ (autoload #'foo "foo" nil t)) (unless (fboundp 'bar) (autoload #'bar "foo" nil t)) - (ignore - (bind-keys :package foo :map foo-map - ("C-c r" . foo) - ("C-c r" . bar)))))) + (bind-keys :package foo :map foo-map + ("C-c r" . foo) + ("C-c r" . bar))))) (ert-deftest use-package-test/:bind*-1 () (match-expansion @@ -704,26 +696,23 @@ `(progn (unless (fboundp 'key) (autoload #'key "foo" nil t)) - (ignore - (bind-keys* :package foo ("C-k" . key)))))) + (bind-keys* :package foo ("C-k" . key))))) (ert-deftest use-package-test/:bind-keymap-1 () (match-expansion (use-package foo :bind-keymap ("C-k" . key)) - `(ignore - (bind-key "C-k" - #'(lambda nil - (interactive) - (use-package-autoload-keymap 'key 'foo nil)))))) + `(bind-key "C-k" + #'(lambda nil + (interactive) + (use-package-autoload-keymap 'key 'foo nil))))) (ert-deftest use-package-test/:bind-keymap*-1 () (match-expansion (use-package foo :bind-keymap* ("C-k" . key)) - `(ignore - (bind-key* "C-k" - #'(lambda () - (interactive) - (use-package-autoload-keymap 'key 'foo t)))))) + `(bind-key* "C-k" + #'(lambda () + (interactive) + (use-package-autoload-keymap 'key 'foo t))))) (ert-deftest use-package-test/:interpreter-1 () (match-expansion @@ -731,8 +720,7 @@ `(progn (unless (fboundp 'foo) (autoload #'foo "foo" nil t)) - (ignore - (add-to-list 'interpreter-mode-alist '("interp" . foo)))))) + (add-to-list 'interpreter-mode-alist '("interp" . foo))))) (ert-deftest use-package-test/:interpreter-2 () (match-expansion @@ -740,8 +728,7 @@ `(progn (unless (fboundp 'fun) (autoload #'fun "foo" nil t)) - (ignore - (add-to-list 'interpreter-mode-alist '("interp" . fun)))))) + (add-to-list 'interpreter-mode-alist '("interp" . fun))))) (ert-deftest use-package-test-normalize/:mode () (flet ((norm (&rest args) @@ -764,8 +751,7 @@ `(progn (unless (fboundp 'foo) (autoload #'foo "foo" nil t)) - (ignore - (add-to-list 'auto-mode-alist '("interp" . foo)))))) + (add-to-list 'auto-mode-alist '("interp" . foo))))) (ert-deftest use-package-test/:mode-2 () (match-expansion @@ -773,8 +759,7 @@ `(progn (unless (fboundp 'fun) (autoload #'fun "foo" nil t)) - (ignore - (add-to-list 'auto-mode-alist '("interp" . fun)))))) + (add-to-list 'auto-mode-alist '("interp" . fun))))) (ert-deftest use-package-test/:magic-1 () (match-expansion @@ -782,8 +767,7 @@ `(progn (unless (fboundp 'foo) (autoload #'foo "foo" nil t)) - (ignore - (add-to-list 'magic-mode-alist '("interp" . foo)))))) + (add-to-list 'magic-mode-alist '("interp" . foo))))) (ert-deftest use-package-test/:magic-2 () (match-expansion @@ -791,8 +775,7 @@ `(progn (unless (fboundp 'fun) (autoload #'fun "foo" nil t)) - (ignore - (add-to-list 'magic-mode-alist '("interp" . fun)))))) + (add-to-list 'magic-mode-alist '("interp" . fun))))) (ert-deftest use-package-test/:magic-fallback-1 () (match-expansion @@ -800,8 +783,7 @@ `(progn (unless (fboundp 'foo) (autoload #'foo "foo" nil t)) - (ignore - (add-to-list 'magic-fallback-mode-alist '("interp" . foo)))))) + (add-to-list 'magic-fallback-mode-alist '("interp" . foo))))) (ert-deftest use-package-test/:magic-fallback-2 () (match-expansion @@ -809,8 +791,7 @@ `(progn (unless (fboundp 'fun) (autoload #'fun "foo" nil t)) - (ignore - (add-to-list 'magic-fallback-mode-alist '("interp" . fun)))))) + (add-to-list 'magic-fallback-mode-alist '("interp" . fun))))) (ert-deftest use-package-test/:commands-1 () (match-expansion @@ -1039,10 +1020,8 @@ (autoload #'fun "foo" nil t)) (eval-when-compile (declare-function fun "foo")) - (ignore - (add-hook 'hook-hook #'fun)) - (ignore - (bind-keys :package foo ("C-a" . key))))))) + (add-hook 'hook-hook #'fun) + (bind-keys :package foo ("C-a" . key)))))) (ert-deftest use-package-test/:hook-2 () (match-expansion @@ -1051,8 +1030,7 @@ `(progn (unless (fboundp 'fun) (autoload #'fun "foo" nil t)) - (ignore - (add-hook 'hook-hook #'fun))))) + (add-hook 'hook-hook #'fun)))) (ert-deftest use-package-test/:hook-3 () (let ((use-package-hook-name-suffix nil)) @@ -1062,8 +1040,7 @@ `(progn (unless (fboundp 'fun) (autoload #'fun "foo" nil t)) - (ignore - (add-hook 'hook #'fun)))))) + (add-hook 'hook #'fun))))) (ert-deftest use-package-test/:hook-4 () (let ((use-package-hook-name-suffix "-special")) @@ -1073,8 +1050,7 @@ `(progn (unless (fboundp 'fun) (autoload #'fun "foo" nil t)) - (ignore - (add-hook 'hook-special #'fun)))))) + (add-hook 'hook-special #'fun))))) (ert-deftest use-package-test/:hook-5 () (match-expansion @@ -1091,11 +1067,10 @@ (eval-after-load 'elisp-mode '(progn (require 'erefactor nil nil) - (ignore - (add-hook - 'emacs-lisp-mode-hook - #'(lambda nil - (bind-key "" erefactor-map emacs-lisp-mode-map))))))))) + (add-hook + 'emacs-lisp-mode-hook + #'(lambda nil + (bind-key "" erefactor-map emacs-lisp-mode-map)))))))) (ert-deftest use-package-test/:hook-6 () (match-expansion @@ -1110,8 +1085,7 @@ '(progn (unless (fboundp 'function) (autoload #'function "erefactor" nil t)) - (ignore - (add-hook 'emacs-lisp-mode-hook #'function))))))) + (add-hook 'emacs-lisp-mode-hook #'function)))))) (ert-deftest use-package-test/:hook-7 () (match-expansion @@ -1125,8 +1099,7 @@ (eval-after-load 'elisp-mode '(progn (require 'erefactor nil nil) - (ignore - (add-hook 'emacs-lisp-mode-hook #'(lambda nil (function))))))))) + (add-hook 'emacs-lisp-mode-hook #'(lambda nil (function)))))))) (ert-deftest use-package-test-normalize/:custom () (flet ((norm (&rest args) @@ -1182,8 +1155,7 @@ #'(lambda (keyword err) (let ((msg (format "%s/%s: %s" 'foo keyword (error-message-string err)))) - (ignore - (display-warning 'use-package msg :error))))) + (display-warning 'use-package msg :error)))) (condition-case-unless-debug err (require 'foo nil nil) (error @@ -1433,10 +1405,9 @@ (require 'counsel nil nil) (if (fboundp 'diminish) (diminish 'counsel-mode)) - (ignore - (bind-keys :package counsel - ("C-*" . counsel-org-agenda-headlines) - ("M-x" . counsel-M-x)))))))) + (bind-keys :package counsel + ("C-*" . counsel-org-agenda-headlines) + ("M-x" . counsel-M-x))))))) (ert-deftest use-package-test/:config-1 () (match-expansion @@ -1680,8 +1651,7 @@ (autoload #'mu4e "mu4e" nil t)) (eval-after-load 'mu4e '(progn (config) t)) - (ignore - (bind-keys :package mu4e ("" . mu4e)))))) + (bind-keys :package mu4e ("" . mu4e))))) (ert-deftest use-package-test/543 () (match-expansion @@ -1719,11 +1689,10 @@ (unless (fboundp 'company-try-hard) (autoload #'company-try-hard "company-try-hard" nil t)) - (ignore - (bind-keys :package company-try-hard - ("C-c M-/" . company-try-hard) - :map company-active-map - ("C-c M-/" . company-try-hard)))))) + (bind-keys :package company-try-hard + ("C-c M-/" . company-try-hard) + :map company-active-map + ("C-c M-/" . company-try-hard))))) (ert-deftest use-package-test/558 () (match-expansion @@ -1798,8 +1767,7 @@ '(progn (message "test. helm start") t)) - (ignore - (bind-keys :package helm ("C-c d" . helm-mini)))))) + (bind-keys :package helm ("C-c d" . helm-mini))))) (ert-deftest bind-key/:prefix-map () (match-expansion From 7e458c640ce3f725eadb3a91890b2095db1d872a Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 8 Dec 2017 00:28:14 -0800 Subject: [PATCH 457/606] use-package-normalize/:disabled has the wrong number of arguments --- lisp/use-package/use-package-core.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 9e32fb477d3..e700c1c110b 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -974,7 +974,7 @@ meaning: ;; Don't alias this to `ignore', as that will cause the resulting ;; function to be interactive. -(defun use-package-normalize/:disabled (name keyword arg rest state)) +(defun use-package-normalize/:disabled (name keyword arg)) (defun use-package-handler/:disabled (name keyword arg rest state) (use-package-process-keywords name rest state)) From 5a02d61ac61d52e55bf642006f75afce95270376 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 8 Dec 2017 00:44:29 -0800 Subject: [PATCH 458/606] Start building a use-package linter in use-package-lint.el --- lisp/use-package/use-package-lint.el | 84 ++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 lisp/use-package/use-package-lint.el diff --git a/lisp/use-package/use-package-lint.el b/lisp/use-package/use-package-lint.el new file mode 100644 index 00000000000..53c682842f9 --- /dev/null +++ b/lisp/use-package/use-package-lint.el @@ -0,0 +1,84 @@ +;;; use-package-lint.el --- Attempt to find errors in use-package declarations + +;; Copyright (C) 2012-2017 John Wiegley + +;; Author: John Wiegley +;; Maintainer: John Wiegley +;; Created: 17 Jun 2012 +;; Modified: 3 Dec 2017 +;; Version: 1.0 +;; Package-Requires: ((emacs "24.3") (use-package "2.4")) +;; Keywords: dotemacs startup speed config package +;; URL: https://github.com/jwiegley/use-package + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 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: + +;; Provides the command `M-x use-package-lint'. + +;;; 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 From ec84ed0dfbeebb8683330449aa4e476debd2f72c Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 9 Dec 2017 16:28:49 -0800 Subject: [PATCH 459/606] Fix a scoping issues with multiple occurrences of :bind Fixes https://github.com/jwiegley/use-package/issues/585 --- lisp/use-package/use-package-bind-key.el | 7 +++++-- lisp/use-package/use-package-core.el | 10 +++++++++- test/lisp/use-package/use-package-tests.el | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index b26c812bf58..d8fe56dfaa5 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -128,8 +128,11 @@ deferred until the prefix key sequence is pressed." (name keyword args rest state &optional bind-macro) (use-package-concat (use-package-process-keywords name rest state) - `((,(if bind-macro bind-macro 'bind-keys) - :package ,name ,@(use-package-normalize-commands args))))) + `(,@(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*)) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index e700c1c110b..df65e04b9a0 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -180,7 +180,8 @@ t according to whether defaulting should be attempted." (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))) + (: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: @@ -472,6 +473,13 @@ This is in contrast to merely setting it to 0." (nconc ys (list x))))) (cons (cdr ys) (cdr zs)))) +(defun use-package-split-list-at-keys (key lst) + (when lst + (let* ((xs (use-package-split-list (apply-partially #'eq key) lst)) + (args (car xs)) + (tail (cdr xs))) + (cons args (use-package-split-list-at-keys key (cdr tail)))))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Keywords diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 5ba6db8a4b5..5aab6bb1170 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1769,6 +1769,21 @@ t)) (bind-keys :package helm ("C-c d" . helm-mini))))) +(ert-deftest use-package-test/585 () + (match-expansion + (use-package bug + :bind (:map bug-map ("C-a" . alpha)) + :bind (("C-b" . beta))) + `(progn + (unless (fboundp 'alpha) + (autoload #'alpha "bug" nil t)) + (unless (fboundp 'beta) + (autoload #'beta "bug" nil t)) + (bind-keys :package bug :map bug-map + ("C-a" . alpha)) + (bind-keys :package bug + ("C-b" . beta))))) + (ert-deftest bind-key/:prefix-map () (match-expansion (bind-keys :prefix "" From 3850281f88d16f5356f4403dba95688f7b7cab0f Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 10 Dec 2017 09:53:13 -0800 Subject: [PATCH 460/606] Add a clarifying test for GitHub-reference: https://github.com/jwiegley/use-package/issues/482 --- test/lisp/use-package/use-package-tests.el | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 5aab6bb1170..067661abf89 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1638,6 +1638,22 @@ (bind-key "f" #'w3m-lnum-print-this-url w3m-y-prefix-map nil) (bind-key "t" #'w3m-print-this-url w3m-y-prefix-map nil))))) +(ert-deftest use-package-test/482 () + (match-expansion + (use-package simple + :bind-keymap ("C-t " . my/transpose-map) + :bind (:map my/transpose-map + ("w" . transpose-words))) + `(progn + (unless (fboundp 'transpose-words) + (autoload #'transpose-words "simple" nil t)) + (bind-key "C-t " + #'(lambda nil + (interactive) + (use-package-autoload-keymap 'my/transpose-map 'simple nil))) + (bind-keys :package simple :map my/transpose-map + ("w" . transpose-words))))) + (ert-deftest use-package-test/538 () (match-expansion (use-package mu4e From a4d2e779610d12303b86f3b7506eb38fbf6141f4 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 10 Dec 2017 21:25:37 -0800 Subject: [PATCH 461/606] bind-keys fixes related to GitHub-reference: https://github.com/jwiegley/use-package/issues/482 --- lisp/use-package/bind-key.el | 25 ++++++++++--------- test/lisp/use-package/use-package-tests.el | 28 +++++++++++++++++++++- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 223a12c21fb..e5cd73e9ea3 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -219,14 +219,7 @@ Accepts keyword arguments: The rest of the arguments are conses of keybinding string and a function symbol (unquoted)." - ;; jww (2016-02-26): This is a hack; this whole function needs to be - ;; rewritten to normalize arguments the way that use-package.el does. - (if (and (eq (car args) :package) - (not (eq (car (cdr (cdr args))) :map)) - (not keymap)) - (setq args (cons :map (cons 'global-map args)))) - - (let ((map keymap) + (let (map doc prefix-map prefix @@ -237,11 +230,14 @@ function symbol (unquoted)." ;; Process any initial keyword arguments (let ((cont t)) (while (and cont args) - (if (cond ((eq :map (car args)) + (if (cond ((and (eq :map (car args)) + (not prefix-map)) (setq map (cadr args))) ((eq :prefix-docstring (car args)) (setq doc (cadr args))) - ((eq :prefix-map (car args)) + ((and (eq :prefix-map (car args)) + (not (memq map '(global-map + override-global-map)))) (setq prefix-map (cadr args))) ((eq :prefix (car args)) (setq prefix (cadr args))) @@ -261,6 +257,8 @@ function symbol (unquoted)." (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 @@ -275,12 +273,13 @@ function symbol (unquoted)." (cl-flet ((wrap (map bindings) - (if (and map pkg (not (memq map '(global-map override-global-map)))) + (if (and map pkg (not (memq map '(global-map + override-global-map)))) `((if (boundp ',map) - (progn ,@bindings) + ,(macroexp-progn bindings) (eval-after-load ,(if (symbolp pkg) `',pkg pkg) - '(progn ,@bindings)))) + ',(macroexp-progn bindings)))) bindings))) (append diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 067661abf89..70654daa3ed 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1638,7 +1638,7 @@ (bind-key "f" #'w3m-lnum-print-this-url w3m-y-prefix-map nil) (bind-key "t" #'w3m-print-this-url w3m-y-prefix-map nil))))) -(ert-deftest use-package-test/482 () +(ert-deftest use-package-test/482-1 () (match-expansion (use-package simple :bind-keymap ("C-t " . my/transpose-map) @@ -1654,6 +1654,32 @@ (bind-keys :package simple :map my/transpose-map ("w" . transpose-words))))) +(ert-deftest use-package-test/482-2 () + (match-expansion + (use-package simple + :bind (:prefix-map my/transpose-map + :prefix "C-t" + ("w" . transpose-words))) + `(progn + (unless (fboundp 'transpose-words) + (autoload #'transpose-words "simple" nil t)) + (bind-keys :package simple + :prefix-map my/transpose-map + :prefix "C-t" + ("w" . transpose-words))))) + +(ert-deftest use-package-test/482-3 () + (match-expansion + (bind-keys :package simple + :prefix-map my/transpose-map + :prefix "C-t" + ("w" . transpose-words)) + `(progn + (defvar my/transpose-map) + (define-prefix-command 'my/transpose-map) + (bind-key "C-t" 'my/transpose-map nil nil) + (bind-key "w" #'transpose-words my/transpose-map nil)))) + (ert-deftest use-package-test/538 () (match-expansion (use-package mu4e From 4aa9b0cd6a1b3b1479a803052c1cc02db1fbd0eb Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 10 Dec 2017 21:36:41 -0800 Subject: [PATCH 462/606] Minor simplification of a function --- lisp/use-package/use-package-core.el | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index df65e04b9a0..b3dc3f95c08 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -474,11 +474,9 @@ This is in contrast to merely setting it to 0." (cons (cdr ys) (cdr zs)))) (defun use-package-split-list-at-keys (key lst) - (when lst - (let* ((xs (use-package-split-list (apply-partially #'eq key) lst)) - (args (car xs)) - (tail (cdr xs))) - (cons args (use-package-split-list-at-keys key (cdr tail)))))) + (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)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; From 31fa2f24a106f2e1fe433713c1e867d27788774e Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 13 Dec 2017 17:02:55 -0800 Subject: [PATCH 463/606] Add more tests related to issue GitHub-reference: https://github.com/jwiegley/use-package/issues/572 --- test/lisp/use-package/use-package-tests.el | 25 +++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 70654daa3ed..59a041789cb 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1762,7 +1762,7 @@ (when (symbol-value 'notmuch-command) (require 'notmuch nil nil)))))))) -(ert-deftest use-package-test/572 () +(ert-deftest use-package-test/572-1 () (let ((use-package-always-defer t)) (match-expansion (use-package auth-password-store @@ -1772,6 +1772,29 @@ `(eval-after-load 'auth-source '(setq auth-sources '(password-store)))))) +(ert-deftest use-package-test/572-2 () + (let ((use-package-always-defer t)) + (match-expansion + (use-package ivy-hydra :after ivy) + `nil))) + +(ert-deftest use-package-test/572-3 () + (let ((use-package-always-defer t) + (use-package-defaults + (let ((defaults (copy-alist use-package-defaults))) + (setcdr (assq :defer defaults) + '(use-package-always-defer + (lambda (name args) + (and use-package-always-defer + (not (plist-member args :after)) + (not (plist-member args :defer)) + (not (plist-member args :demand)))))) + defaults))) + (match-expansion + (use-package ivy-hydra :after ivy) + `(eval-after-load 'ivy + '(require 'ivy-hydra nil nil))))) + (ert-deftest use-package-test/575-1 () (match-expansion (use-package helm From 51eceb4238ac7b4ed48a454cc7cde67de599fe00 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 13 Dec 2017 17:03:05 -0800 Subject: [PATCH 464/606] Add a test related to GitHub-reference: https://github.com/jwiegley/use-package/issues/589 --- test/lisp/use-package/use-package-tests.el | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 59a041789cb..5039e21064c 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1849,6 +1849,19 @@ (bind-keys :package bug ("C-b" . beta))))) +(ert-deftest use-package-test/589 () + (let ((use-package-verbose t) + (use-package-expand-minimally t) + debug-on-error + warnings) + (flet ((display-warning (_ msg _) (push msg warnings))) + (progn + (macroexpand-1 + '(use-package ediff :defer t (setq my-var t))) + (should (= (and (> (length warnings) 0) + (string-match ":defer wants exactly one argument" + (car warnings))) 44)))))) + (ert-deftest bind-key/:prefix-map () (match-expansion (bind-keys :prefix "" From 2d226310f1fb053f9bba5abee101b31b38a919fc Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 15 Dec 2017 22:48:42 -0800 Subject: [PATCH 465/606] All the second argument in use-package-defaults lists to be a function Address the question raised in https://github.com/jwiegley/use-package/issues/591 --- lisp/use-package/use-package-core.el | 37 +++++++++++++++------- test/lisp/use-package/use-package-tests.el | 12 +++++++ 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index b3dc3f95c08..dad68591cb3 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -159,21 +159,30 @@ See also `use-package-defaults', which uses this value." (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 and the second is a form -that can be evaluated to get the default value. 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 -t according to whether defaulting should be attempted." +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 (choice :tag "Keyword" ,@(mapcar #'(lambda (k) (list 'const k)) use-package-keywords)) - (choice :tag "Default value" sexp) + (choice :tag "Default value" sexp function) (choice :tag "Enable if non-nil" sexp function))) :group 'use-package) @@ -564,7 +573,11 @@ extending any keys already present." (funcall func name args) (eval func))) (setq args (use-package-plist-maybe-put - args (nth 0 spec) (eval (nth 1 spec)))))) + 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) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 5039e21064c..fc86fa63f81 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1862,6 +1862,18 @@ (string-match ":defer wants exactly one argument" (car warnings))) 44)))))) +(ert-deftest use-package-test/591 () + (let ((use-package-defaults + (cons '(:if (lambda (name _) `(locate-library ,name)) t) + use-package-defaults))) + (match-expansion + (use-package nonexistent + :hook lisp-mode) + `(when (locate-library nonexistent) + (unless (fboundp 'nonexistent) + (autoload #'nonexistent "nonexistent" nil t)) + (add-hook 'lisp-mode-hook #'nonexistent))))) + (ert-deftest bind-key/:prefix-map () (match-expansion (bind-keys :prefix "" From cb15dffbd730af0617fec224289d53ea4682162e Mon Sep 17 00:00:00 2001 From: Nick McCurdy Date: Sat, 16 Dec 2017 14:52:14 -0500 Subject: [PATCH 466/606] Render the use-package-report table using Org I noticed that the "Gathering Statistics" instructions for rendering the Org table could be automated for convenience. Now the table is reformatted automatically, and you can still manually sort it. I'm not sorting it by default to maintain the same order of use-package forms for easier troubleshooting. --- lisp/use-package/use-package-core.el | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index dad68591cb3..d770be1d1c3 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -972,6 +972,9 @@ meaning: (float-time (gethash :preface-secs hash 0)) (float-time (gethash :use-package-secs hash 0)))))) use-package-statistics) + (goto-char (point-min)) + (orgtbl-mode) + (orgtbl-ctrl-c-ctrl-c nil) (display-buffer (current-buffer)))) (defun use-package-statistics-gather (keyword name after) From 13fb5f4f2e02ef08f8c87017a8eb03d69cd59910 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 17 Dec 2017 00:35:01 -0800 Subject: [PATCH 467/606] Guard a call to display-warning with ignore Fixes https://github.com/jwiegley/use-package/issues/589 --- lisp/use-package/use-package-core.el | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index dad68591cb3..80f1fe1f1d0 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1510,10 +1510,11 @@ this file. Usage: (condition-case-unless-debug err (use-package-core name args) (error - (display-warning - 'use-package - (format "Failed to parse package %s: %s" - name (error-message-string err)) :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))))))) From 9638870f53a895264cef748e7c2afb24f28b0cf1 Mon Sep 17 00:00:00 2001 From: Justin Burkett Date: Mon, 18 Dec 2017 15:15:28 -0500 Subject: [PATCH 468/606] Handle automatic macro expansion by elisp-completion-at-point The function `elisp--local-variables' inserts an unbound variable, `elisp--witness--lisp', 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. --- lisp/use-package/use-package-core.el | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 80f1fe1f1d0..1b5196a7b6d 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -559,6 +559,15 @@ extending any keys already present." (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)) From 1fdfd46fb2c27cb9018afe42e5268b7107ba528b Mon Sep 17 00:00:00 2001 From: wouter bolsterlee Date: Wed, 20 Dec 2017 08:31:56 +0100 Subject: [PATCH 469/606] Fix sanity check for correct :custom-face format Instead of testing the length of each form passed to :custom-face, the sanity check would test the number of forms passed to :custom-face, causing it to fail when more than 2 face customisations are used. Fixes https://github.com/jwiegley/use-package/issues/600. Copyright-paperwork-exempt: yes --- lisp/use-package/use-package-core.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 80f1fe1f1d0..1e52428f522 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1351,7 +1351,7 @@ no keyword implies `:all'." (spec (nth 1 def))) (when (or (not face) (not spec) - (> (length arg) 2)) + (> (length def) 2)) (use-package-error error-msg)))))) (defun use-package-handler/:custom-face (name keyword args rest state) From 8a6430835fa236c034c3a3ef4e915087299d9dc6 Mon Sep 17 00:00:00 2001 From: Alex Branham Date: Mon, 8 Jan 2018 19:21:46 -0600 Subject: [PATCH 470/606] Prefer org-table-align to orgtbl-ctrl-c-ctrl-c org-table-align is an autoloaded function so the byte compiler can find it. orgtbl-ctrl-c-ctrl-c isn't so we get a warning about undefined functions. --- lisp/use-package/use-package-core.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index c4c251e9a00..469b3f7b23c 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -983,7 +983,7 @@ meaning: use-package-statistics) (goto-char (point-min)) (orgtbl-mode) - (orgtbl-ctrl-c-ctrl-c nil) + (org-table-align) (display-buffer (current-buffer)))) (defun use-package-statistics-gather (keyword name after) From 46ee10032742963b9e04ad19e69877c8463750df Mon Sep 17 00:00:00 2001 From: Alex Branham Date: Fri, 26 Jan 2018 22:37:31 -0600 Subject: [PATCH 471/606] Prefer non-obsolete var names --- .../use-package/use-package-ensure-system-package.el | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lisp/use-package/use-package-ensure-system-package.el b/lisp/use-package/use-package-ensure-system-package.el index 0fae57aff76..d6f7956dcae 100644 --- a/lisp/use-package/use-package-ensure-system-package.el +++ b/lisp/use-package/use-package-ensure-system-package.el @@ -23,20 +23,20 @@ (require 'system-packages nil t) (eval-when-compile - (defvar system-packages-packagemanager) + (defvar system-packages-package-manager) (defvar system-packages-supported-package-managers) - (defvar system-packages-usesudo)) + (defvar system-packages-use-sudo)) (defun use-package-ensure-system-package-install-command (pack) - "Return the default install command for `pack'." + "Return the default install command for PACK." (let ((command - (cdr (assoc 'install (cdr (assoc system-packages-packagemanager + (cdr (assoc 'install (cdr (assoc system-packages-package-manager system-packages-supported-package-managers)))))) (unless command - (error (format "%S not supported in %S" 'install system-packages-packagemanager))) + (error (format "%S not supported in %S" 'install system-packages-package-manager))) (unless (listp command) (setq command (list command))) - (when system-packages-usesudo + (when system-packages-use-sudo (setq command (mapcar (lambda (part) (concat "sudo " part)) command))) (setq command (mapconcat 'identity command " && ")) (mapconcat 'identity (list command pack) " "))) From b7252f8e63a14bbc83d9db6431f5c5161300f212 Mon Sep 17 00:00:00 2001 From: Alex Branham Date: Fri, 26 Jan 2018 22:37:47 -0600 Subject: [PATCH 472/606] lexical binding --- lisp/use-package/use-package-ensure-system-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-ensure-system-package.el b/lisp/use-package/use-package-ensure-system-package.el index d6f7956dcae..48fbde2e20a 100644 --- a/lisp/use-package/use-package-ensure-system-package.el +++ b/lisp/use-package/use-package-ensure-system-package.el @@ -1,4 +1,4 @@ -;;; use-package-ensure-system-package.el --- auto install system packages +;;; use-package-ensure-system-package.el --- auto install system packages -*- lexical: t; -*- ;; Copyright (C) 2017 Justin Talbott From 88bcb8b96d6366ad2c801d6edb3ecc0d18618643 Mon Sep 17 00:00:00 2001 From: Alex Branham Date: Sat, 27 Jan 2018 09:56:15 -0600 Subject: [PATCH 473/606] Use lexical bindings and remove cl package --- lisp/use-package/use-package-bind-key.el | 2 +- lisp/use-package/use-package-chords.el | 2 +- lisp/use-package/use-package-core.el | 3 +-- lisp/use-package/use-package-delight.el | 2 +- lisp/use-package/use-package-diminish.el | 2 +- lisp/use-package/use-package-ensure.el | 2 +- lisp/use-package/use-package-jump.el | 2 +- lisp/use-package/use-package-lint.el | 2 +- lisp/use-package/use-package.el | 2 +- test/lisp/use-package/use-package-tests.el | 3 +-- 10 files changed, 10 insertions(+), 12 deletions(-) diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index d8fe56dfaa5..638aec45d7b 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -1,4 +1,4 @@ -;;; use-package-bind-key.el --- Support for the :bind/:bind-keymap keywords +;;; use-package-bind-key.el --- Support for the :bind/:bind-keymap keywords -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley diff --git a/lisp/use-package/use-package-chords.el b/lisp/use-package/use-package-chords.el index 63a9737109f..936ff228999 100644 --- a/lisp/use-package/use-package-chords.el +++ b/lisp/use-package/use-package-chords.el @@ -1,4 +1,4 @@ -;;; use-package-chords.el --- key-chord keyword for use-package +;;; use-package-chords.el --- key-chord keyword for use-package -*- lexical-binding: t; -*- ;; Copyright (C) 2015-2017 Justin Talbott diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 469b3f7b23c..198246eb3ee 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1,4 +1,4 @@ -;;; use-package-core.el --- A configuration macro for simplifying your .emacs +;;; use-package-core.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley @@ -43,7 +43,6 @@ (require 'cl-lib) (eval-when-compile - (require 'cl) (require 'regexp-opt)) (defgroup use-package nil diff --git a/lisp/use-package/use-package-delight.el b/lisp/use-package/use-package-delight.el index 9d4f6acf2de..4207993f811 100644 --- a/lisp/use-package/use-package-delight.el +++ b/lisp/use-package/use-package-delight.el @@ -1,4 +1,4 @@ -;;; use-package-delight.el --- Support for the :delight keyword +;;; use-package-delight.el --- Support for the :delight keyword -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley diff --git a/lisp/use-package/use-package-diminish.el b/lisp/use-package/use-package-diminish.el index c2da62257e6..4ff2b3505f6 100644 --- a/lisp/use-package/use-package-diminish.el +++ b/lisp/use-package/use-package-diminish.el @@ -1,4 +1,4 @@ -;;; use-package-diminish.el --- Support for the :diminish keyword +;;; use-package-diminish.el --- Support for the :diminish keyword -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index 1a76b883e1c..257e542d0af 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -1,4 +1,4 @@ -;;; use-package-ensure.el --- Support for the :ensure and :pin keywords +;;; use-package-ensure.el --- Support for the :ensure and :pin keywords -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley diff --git a/lisp/use-package/use-package-jump.el b/lisp/use-package/use-package-jump.el index 31d1b054060..4044ad16564 100644 --- a/lisp/use-package/use-package-jump.el +++ b/lisp/use-package/use-package-jump.el @@ -1,4 +1,4 @@ -;;; use-package-jump.el --- Attempt to jump to a use-package declaration +;;; use-package-jump.el --- Attempt to jump to a use-package declaration -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley diff --git a/lisp/use-package/use-package-lint.el b/lisp/use-package/use-package-lint.el index 53c682842f9..c6e7c3c0ce2 100644 --- a/lisp/use-package/use-package-lint.el +++ b/lisp/use-package/use-package-lint.el @@ -1,4 +1,4 @@ -;;; use-package-lint.el --- Attempt to find errors in use-package declarations +;;; use-package-lint.el --- Attempt to find errors in use-package declarations -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 5f98db1bed7..1a8fff895f6 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1,4 +1,4 @@ -;;; use-package.el --- A configuration macro for simplifying your .emacs +;;; use-package.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index fc86fa63f81..be017850cc2 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1,4 +1,4 @@ -;;; use-package-tests.el --- Tests for use-package.el +;;; use-package-tests.el --- Tests for use-package.el -*- lexical-binding: t; -*- ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as @@ -22,7 +22,6 @@ ;;; Code: -(require 'cl) (require 'ert) (require 'use-package) From 4c3abcf4ebd308e5356decedc6cb292804dba235 Mon Sep 17 00:00:00 2001 From: Alex Branham Date: Sat, 27 Jan 2018 10:19:42 -0600 Subject: [PATCH 474/606] Fix byte compiler warnings --- lisp/use-package/use-package-bind-key.el | 4 +- lisp/use-package/use-package-core.el | 77 ++++++++++++------------ lisp/use-package/use-package-delight.el | 4 +- lisp/use-package/use-package-diminish.el | 2 +- lisp/use-package/use-package-ensure.el | 52 ++++++++-------- 5 files changed, 70 insertions(+), 69 deletions(-) diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index 638aec45d7b..8c86ef5edfc 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -125,7 +125,7 @@ deferred until the prefix key sequence is pressed." ;;;###autoload (defun use-package-handler/:bind - (name keyword args rest state &optional bind-macro) + (name _keyword args rest state &optional bind-macro) (use-package-concat (use-package-process-keywords name rest state) `(,@(mapcar @@ -146,7 +146,7 @@ deferred until the prefix key sequence is pressed." ;;;###autoload (defun use-package-handler/:bind-keymap - (name keyword args rest state &optional override) + (name _keyword args rest state &optional override) (use-package-concat (use-package-process-keywords name rest state) (mapcar diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 198246eb3ee..9adebdf4bf0 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -285,7 +285,7 @@ include support for finding `use-package' and `require' forms. Must be set before loading use-package." :type 'boolean :set - #'(lambda (sym value) + #'(lambda (_sym value) (eval-after-load 'lisp-mode (if value `(add-to-list 'lisp-imenu-generic-expression @@ -524,7 +524,7 @@ extending any keys already present." arg))) (use-package-error (format "Unrecognized keyword: %s" keyword)))))) -(defun use-package-unalias-keywords (name args) +(defun use-package-unalias-keywords (_name args) (setq args (cl-nsubstitute :if :when args)) (let (temp) (while (setq temp (plist-get args :unless)) @@ -757,7 +757,7 @@ no more than once." (setq ,loaded t ,result ,arg)))) ,@(funcall f `((funcall ,next)))))) -(defsubst use-package-normalize-value (label arg) +(defsubst use-package-normalize-value (_label arg) "Normalize the Lisp value given by ARG. The argument LABEL is ignored." (cond ((null arg) nil) @@ -779,7 +779,7 @@ The argument LABEL is ignored." (use-package-error (concat label " wants a symbol, or list of symbols"))))) -(defun use-package-normalize-symlist (name keyword args) +(defun use-package-normalize-symlist (_name keyword args) (use-package-as-one (symbol-name keyword) args #'use-package-normalize-symbols)) @@ -795,7 +795,7 @@ The argument LABEL is ignored." (use-package-error (concat label " wants a symbol, or nested list of symbols"))))) -(defun use-package-normalize-recursive-symlist (name keyword args) +(defun use-package-normalize-recursive-symlist (_name keyword args) (use-package-as-one (symbol-name keyword) args #'use-package-normalize-recursive-symbols)) @@ -817,7 +817,7 @@ The argument LABEL is ignored." (use-package-error (concat label " wants a directory path, or list of paths"))))) -(defun use-package-normalize-predicate (name keyword args) +(defun use-package-normalize-predicate (_name keyword args) (if (null args) t (use-package-only-one (symbol-name keyword) args @@ -835,7 +835,7 @@ The argument LABEL is ignored." (macroexpand form) form)) args)) -(defun use-package-normalize-forms (name keyword args) +(defun use-package-normalize-forms (_name keyword args) (use-package-normalize-form (symbol-name keyword) args)) (defun use-package-normalize-pairs @@ -920,7 +920,7 @@ If RECURSED is non-nil, recurse into sublists." #'use-package-recognize-function name))) -(defun use-package-autoloads-mode (name keyword args) +(defun use-package-autoloads-mode (_name _keyword args) (mapcar #'(lambda (x) (cons (cdr x) 'command)) (cl-remove-if-not #'(lambda (x) @@ -1004,20 +1004,21 @@ meaning: ;; Don't alias this to `ignore', as that will cause the resulting ;; function to be interactive. -(defun use-package-normalize/:disabled (name keyword arg)) +(defun use-package-normalize/:disabled (_name _keyword _arg) + "Do nothing, return nil.") -(defun use-package-handler/:disabled (name keyword arg rest state) +(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) +(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) +(defun use-package-handler/:if (name _keyword pred rest state) (let ((body (use-package-process-keywords name rest state))) `((when ,pred ,@body)))) @@ -1027,7 +1028,7 @@ meaning: (defalias 'use-package-normalize/:unless 'use-package-normalize-test) -(defun use-package-handler/:unless (name keyword pred rest state) +(defun use-package-handler/:unless (name _keyword pred rest state) (let ((body (use-package-process-keywords name rest state))) `((unless ,pred ,@body)))) @@ -1035,7 +1036,7 @@ meaning: (defalias 'use-package-normalize/:requires 'use-package-normalize-symlist) -(defun use-package-handler/:requires (name keyword requires rest state) +(defun use-package-handler/:requires (name _keyword requires rest state) (let ((body (use-package-process-keywords name rest state))) (if (null requires) body @@ -1046,11 +1047,11 @@ meaning: ;;;; :load-path -(defun use-package-normalize/:load-path (name keyword args) +(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) +(defun use-package-handler/:load-path (name _keyword arg rest state) (let ((body (use-package-process-keywords name rest state))) (use-package-concat (mapcar #'(lambda (path) @@ -1062,28 +1063,28 @@ meaning: (defalias 'use-package-normalize/:no-require 'use-package-normalize-predicate) -(defun use-package-handler/:no-require (name keyword arg rest state) +(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) +(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) +(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) +(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 @@ -1097,14 +1098,14 @@ meaning: ;;;; :catch (defvar use-package--form) -(defvar use-package--hush-function #'(lambda (keyword body) body)) +(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) +(defun use-package-normalize/:catch (_name keyword args) (if (null args) t (use-package-only-one (symbol-name keyword) args @@ -1148,7 +1149,7 @@ meaning: (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) +(defun use-package-handler/:interpreter (name _keyword arg rest state) (use-package-handle-mode name 'interpreter-mode-alist arg rest state)) ;;;; :mode @@ -1156,7 +1157,7 @@ meaning: (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) +(defun use-package-handler/:mode (name _keyword arg rest state) (use-package-handle-mode name 'auto-mode-alist arg rest state)) ;;;; :magic @@ -1164,7 +1165,7 @@ meaning: (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) +(defun use-package-handler/:magic (name _keyword arg rest state) (use-package-handle-mode name 'magic-mode-alist arg rest state)) ;;;; :magic-fallback @@ -1172,7 +1173,7 @@ meaning: (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) +(defun use-package-handler/:magic-fallback (name _keyword arg rest state) (use-package-handle-mode name 'magic-fallback-mode-alist arg rest state)) ;;;; :hook @@ -1199,7 +1200,7 @@ meaning: (defalias 'use-package-autoloads/:hook 'use-package-autoloads-mode) -(defun use-package-handler/:hook (name keyword args rest state) +(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) @@ -1222,7 +1223,7 @@ meaning: (defalias 'use-package-normalize/:commands 'use-package-normalize-symlist) -(defun use-package-handler/:commands (name keyword arg rest state) +(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. @@ -1244,7 +1245,7 @@ meaning: (defalias 'use-package-normalize/:defer 'use-package-normalize-predicate) -(defun use-package-handler/:defer (name keyword arg rest state) +(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 @@ -1300,7 +1301,7 @@ no keyword implies `:all'." ((listp features) (use-package-require-after-load (cons :all features) body)))) -(defun use-package-handler/:after (name keyword arg rest state) +(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)) @@ -1315,12 +1316,12 @@ no keyword implies `:all'." (defalias 'use-package-normalize/:demand 'use-package-normalize-predicate) -(defun use-package-handler/:demand (name keyword arg rest state) +(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) +(defun use-package-normalize/:custom (_name keyword args) "Normalize use-package custom keyword." (use-package-as-one (symbol-name keyword) args #'(lambda (label arg) @@ -1332,7 +1333,7 @@ no keyword implies `:all'." (list arg) arg)))) -(defun use-package-handler/:custom (name keyword args rest state) +(defun use-package-handler/:custom (name _keyword args rest state) "Generate use-package custom keyword code." (use-package-concat (mapcar @@ -1348,7 +1349,7 @@ no keyword implies `:all'." ;;;; :custom-face -(defun use-package-normalize/:custom-face (name-symbol keyword arg) +(defun use-package-normalize/:custom-face (name-symbol _keyword arg) "Normalize use-package custom-face keyword." (let ((error-msg (format "%s wants a ( ) or list of these" @@ -1365,7 +1366,7 @@ no keyword implies `:all'." (> (length def) 2)) (use-package-error error-msg)))))) -(defun use-package-handler/:custom-face (name keyword args rest state) +(defun use-package-handler/:custom-face (name _keyword args rest state) "Generate use-package custom-face keyword code." (use-package-concat (mapcar #'(lambda (def) `(custom-set-faces (quote ,def))) args) @@ -1375,7 +1376,7 @@ no keyword implies `:all'." (defalias 'use-package-normalize/:init 'use-package-normalize-forms) -(defun use-package-handler/:init (name keyword arg rest state) +(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))) @@ -1400,7 +1401,7 @@ no keyword implies `:all'." args (list args))) -(defun use-package-handler/:load (name keyword arg rest state) +(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))) @@ -1410,7 +1411,7 @@ no keyword implies `:all'." (defalias 'use-package-normalize/:config 'use-package-normalize-forms) -(defun use-package-handler/:config (name keyword arg rest state) +(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 diff --git a/lisp/use-package/use-package-delight.el b/lisp/use-package/use-package-delight.el index 4207993f811..85d5c7cb4d6 100644 --- a/lisp/use-package/use-package-delight.el +++ b/lisp/use-package/use-package-delight.el @@ -52,7 +52,7 @@ ":delight expects `delight' arguments or a list of them")))) ;;;###autoload -(defun use-package-normalize/:delight (name keyword args) +(defun use-package-normalize/:delight (name _keyword args) "Normalize arguments to delight." (cond ((null args) `((,(use-package-as-mode name) nil ,name))) @@ -77,7 +77,7 @@ args))))) ;;;###autoload -(defun use-package-handler/:delight (name keyword args rest state) +(defun use-package-handler/:delight (name _keyword args rest state) (let ((body (use-package-process-keywords name rest state))) (use-package-concat body diff --git a/lisp/use-package/use-package-diminish.el b/lisp/use-package/use-package-diminish.el index 4ff2b3505f6..1f3895f42cd 100644 --- a/lisp/use-package/use-package-diminish.el +++ b/lisp/use-package/use-package-diminish.el @@ -62,7 +62,7 @@ (apply-partially #'use-package-normalize-diminish name) t)) ;;;###autoload -(defun use-package-handler/:diminish (name keyword arg rest state) +(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) diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index 257e542d0af..cea1b6d6b40 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -76,15 +76,15 @@ The default value uses package.el to install the package." ;;;; :pin -(defun use-package-normalize/:pin (name keyword args) +(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)")))))) + (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) @@ -116,7 +116,7 @@ manually updated package." (unless (bound-and-true-p package--initialized) (package-initialize t)))) -(defun use-package-handler/:pin (name keyword archive-name rest state) +(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) @@ -133,26 +133,26 @@ manually updated package." (defvar package-archive-contents) ;;;###autoload -(defun use-package-normalize/:ensure (name keyword args) +(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 ( :pin )")))))))) + (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 ( :pin )")))))))) -(defun use-package-ensure-elpa (name args state &optional no-refresh) +(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)) @@ -183,7 +183,7 @@ manually updated package." :error)))))))) ;;;###autoload -(defun use-package-handler/:ensure (name keyword ensure rest state) +(defun use-package-handler/:ensure (name _keyword ensure rest state) (let* ((body (use-package-process-keywords name rest state))) ;; We want to avoid installing packages when the `use-package' macro is ;; being macro-expanded by elisp completion (see `lisp--local-variables'), From 2274130b40ae8ac7f34ed5c0efc7e0af5c10ce99 Mon Sep 17 00:00:00 2001 From: Alex Branham Date: Sat, 27 Jan 2018 11:11:40 -0600 Subject: [PATCH 475/606] Test still requires cl --- test/lisp/use-package/use-package-tests.el | 1 + 1 file changed, 1 insertion(+) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index be017850cc2..55d9959fb10 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -22,6 +22,7 @@ ;;; Code: +(require 'cl) (require 'ert) (require 'use-package) From 109167e8f50c61472998f3eb800b95dcab904695 Mon Sep 17 00:00:00 2001 From: Alex Branham Date: Sat, 27 Jan 2018 15:17:26 -0600 Subject: [PATCH 476/606] Don't remove sharp quotes --- lisp/use-package/use-package-ensure.el | 42 +++++++++++++------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index cea1b6d6b40..50005a9e990 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -78,13 +78,13 @@ The default value uses package.el to install the package." (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)")))))) + #'(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) @@ -137,20 +137,20 @@ manually updated package." (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 ( :pin )")))))))) + #'(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 ( :pin )")))))))) (defun use-package-ensure-elpa (name args _state &optional _no-refresh) (dolist (ensure args) From c29193bf0724633adf7183dad2d0b6faf7d029ab Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 27 Jan 2018 14:07:11 -0800 Subject: [PATCH 477/606] Move variable bindings to the bottom of each file --- lisp/use-package/use-package-bind-key.el | 7 ++++++- lisp/use-package/use-package-chords.el | 7 ++++++- lisp/use-package/use-package-core.el | 7 ++++--- lisp/use-package/use-package-delight.el | 7 ++++++- lisp/use-package/use-package-diminish.el | 7 ++++++- lisp/use-package/use-package-ensure.el | 7 ++++++- lisp/use-package/use-package-jump.el | 7 ++++++- lisp/use-package/use-package-lint.el | 7 ++++++- lisp/use-package/use-package.el | 7 ++++++- test/lisp/use-package/use-package-tests.el | 3 ++- 10 files changed, 54 insertions(+), 12 deletions(-) diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index 8c86ef5edfc..0f286c51c68 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -1,4 +1,4 @@ -;;; use-package-bind-key.el --- Support for the :bind/:bind-keymap keywords -*- lexical-binding: t; -*- +;;; use-package-bind-key.el --- Support for the :bind/:bind-keymap keywords ;; Copyright (C) 2012-2017 John Wiegley @@ -166,4 +166,9 @@ deferred until the prefix key sequence is pressed." (provide 'use-package-bind-key) +;; Local Variables: +;; indent-tabs-mode: nil +;; lexical-binding: t +;; End: + ;;; use-package-bind-key.el ends here diff --git a/lisp/use-package/use-package-chords.el b/lisp/use-package/use-package-chords.el index 936ff228999..240da96eca1 100644 --- a/lisp/use-package/use-package-chords.el +++ b/lisp/use-package/use-package-chords.el @@ -1,4 +1,4 @@ -;;; use-package-chords.el --- key-chord keyword for use-package -*- lexical-binding: t; -*- +;;; use-package-chords.el --- key-chord keyword for use-package ;; Copyright (C) 2015-2017 Justin Talbott @@ -47,4 +47,9 @@ (provide 'use-package-chords) +;; Local Variables: +;; indent-tabs-mode: nil +;; lexical-binding: t +;; End: + ;;; use-package-chords.el ends here diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 9adebdf4bf0..9ec5d3b1422 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1,4 +1,4 @@ -;;; use-package-core.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*- +;;; use-package-core.el --- A configuration macro for simplifying your .emacs ;; Copyright (C) 2012-2017 John Wiegley @@ -550,7 +550,7 @@ extending any keys already present." (nreverse (sort plist-grouped #'(lambda (l r) (< (use-package-keyword-index (car l)) - (use-package-keyword-index (car r))))))) + (use-package-keyword-index (car r))))))) (setq result (cons (car x) (cons (cdr x) result)))) result))) @@ -754,7 +754,7 @@ no more than once." `((defvar ,loaded nil) (defvar ,result nil) (defvar ,next #'(lambda () (if ,loaded ,result - (setq ,loaded t ,result ,arg)))) + (setq ,loaded t ,result ,arg)))) ,@(funcall f `((funcall ,next)))))) (defsubst use-package-normalize-value (_label arg) @@ -1536,6 +1536,7 @@ this file. Usage: ;; Local Variables: ;; indent-tabs-mode: nil +;; lexical-binding: t ;; End: ;;; use-package-core.el ends here diff --git a/lisp/use-package/use-package-delight.el b/lisp/use-package/use-package-delight.el index 85d5c7cb4d6..ab2dad9bd0a 100644 --- a/lisp/use-package/use-package-delight.el +++ b/lisp/use-package/use-package-delight.el @@ -1,4 +1,4 @@ -;;; use-package-delight.el --- Support for the :delight keyword -*- lexical-binding: t; -*- +;;; use-package-delight.el --- Support for the :delight keyword ;; Copyright (C) 2012-2017 John Wiegley @@ -88,4 +88,9 @@ (provide 'use-package-delight) +;; Local Variables: +;; indent-tabs-mode: nil +;; lexical-binding: t +;; End: + ;;; use-package-delight.el ends here diff --git a/lisp/use-package/use-package-diminish.el b/lisp/use-package/use-package-diminish.el index 1f3895f42cd..69b8dafc4c3 100644 --- a/lisp/use-package/use-package-diminish.el +++ b/lisp/use-package/use-package-diminish.el @@ -1,4 +1,4 @@ -;;; use-package-diminish.el --- Support for the :diminish keyword -*- lexical-binding: t; -*- +;;; use-package-diminish.el --- Support for the :diminish keyword ;; Copyright (C) 2012-2017 John Wiegley @@ -77,4 +77,9 @@ (provide 'use-package-diminish) +;; Local Variables: +;; indent-tabs-mode: nil +;; lexical-binding: t +;; End: + ;;; use-package-diminish.el ends here diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index 50005a9e990..2d4e00e5c01 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -1,4 +1,4 @@ -;;; use-package-ensure.el --- Support for the :ensure and :pin keywords -*- lexical-binding: t; -*- +;;; use-package-ensure.el --- Support for the :ensure and :pin keywords ;; Copyright (C) 2012-2017 John Wiegley @@ -211,4 +211,9 @@ manually updated package." (provide 'use-package-ensure) +;; Local Variables: +;; indent-tabs-mode: nil +;; lexical-binding: t +;; End: + ;;; use-package-ensure.el ends here diff --git a/lisp/use-package/use-package-jump.el b/lisp/use-package/use-package-jump.el index 4044ad16564..60d3ef525bc 100644 --- a/lisp/use-package/use-package-jump.el +++ b/lisp/use-package/use-package-jump.el @@ -1,4 +1,4 @@ -;;; use-package-jump.el --- Attempt to jump to a use-package declaration -*- lexical-binding: t; -*- +;;; use-package-jump.el --- Attempt to jump to a use-package declaration ;; Copyright (C) 2012-2017 John Wiegley @@ -76,4 +76,9 @@ instead." (provide 'use-package-jump) +;; Local Variables: +;; indent-tabs-mode: nil +;; lexical-binding: t +;; End: + ;;; use-package-jump.el ends here diff --git a/lisp/use-package/use-package-lint.el b/lisp/use-package/use-package-lint.el index c6e7c3c0ce2..54f5b759406 100644 --- a/lisp/use-package/use-package-lint.el +++ b/lisp/use-package/use-package-lint.el @@ -1,4 +1,4 @@ -;;; use-package-lint.el --- Attempt to find errors in use-package declarations -*- lexical-binding: t; -*- +;;; use-package-lint.el --- Attempt to find errors in use-package declarations ;; Copyright (C) 2012-2017 John Wiegley @@ -81,4 +81,9 @@ with the specified `:load-path' the module cannot be found." (provide 'use-package-lint) +;; Local Variables: +;; indent-tabs-mode: nil +;; lexical-binding: t +;; End: + ;;; use-package-lint.el ends here diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 1a8fff895f6..4d1b56b6d6a 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1,4 +1,4 @@ -;;; use-package.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*- +;;; use-package.el --- A configuration macro for simplifying your .emacs ;; Copyright (C) 2012-2017 John Wiegley @@ -51,4 +51,9 @@ (provide 'use-package) +;; Local Variables: +;; indent-tabs-mode: nil +;; lexical-binding: t +;; End: + ;;; use-package.el ends here diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 55d9959fb10..ec9c59be916 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1,4 +1,4 @@ -;;; use-package-tests.el --- Tests for use-package.el -*- lexical-binding: t; -*- +;;; use-package-tests.el --- Tests for use-package.el ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as @@ -1885,6 +1885,7 @@ ;; Local Variables: ;; indent-tabs-mode: nil +;; lexical-binding: t ;; no-byte-compile: t ;; no-update-autoloads: t ;; End: From 566a2ea3a1f0fb1449e9c662924ed1d87e109284 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 27 Jan 2018 14:09:10 -0800 Subject: [PATCH 478/606] Revert "Move variable bindings to the bottom of each file" This reverts commit c29193bf0724633adf7183dad2d0b6faf7d029ab. --- lisp/use-package/use-package-bind-key.el | 7 +------ lisp/use-package/use-package-chords.el | 7 +------ lisp/use-package/use-package-core.el | 7 +++---- lisp/use-package/use-package-delight.el | 7 +------ lisp/use-package/use-package-diminish.el | 7 +------ lisp/use-package/use-package-ensure.el | 7 +------ lisp/use-package/use-package-jump.el | 7 +------ lisp/use-package/use-package-lint.el | 7 +------ lisp/use-package/use-package.el | 7 +------ test/lisp/use-package/use-package-tests.el | 3 +-- 10 files changed, 12 insertions(+), 54 deletions(-) diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index 0f286c51c68..8c86ef5edfc 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -1,4 +1,4 @@ -;;; use-package-bind-key.el --- Support for the :bind/:bind-keymap keywords +;;; use-package-bind-key.el --- Support for the :bind/:bind-keymap keywords -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley @@ -166,9 +166,4 @@ deferred until the prefix key sequence is pressed." (provide 'use-package-bind-key) -;; Local Variables: -;; indent-tabs-mode: nil -;; lexical-binding: t -;; End: - ;;; use-package-bind-key.el ends here diff --git a/lisp/use-package/use-package-chords.el b/lisp/use-package/use-package-chords.el index 240da96eca1..936ff228999 100644 --- a/lisp/use-package/use-package-chords.el +++ b/lisp/use-package/use-package-chords.el @@ -1,4 +1,4 @@ -;;; use-package-chords.el --- key-chord keyword for use-package +;;; use-package-chords.el --- key-chord keyword for use-package -*- lexical-binding: t; -*- ;; Copyright (C) 2015-2017 Justin Talbott @@ -47,9 +47,4 @@ (provide 'use-package-chords) -;; Local Variables: -;; indent-tabs-mode: nil -;; lexical-binding: t -;; End: - ;;; use-package-chords.el ends here diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 9ec5d3b1422..9adebdf4bf0 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1,4 +1,4 @@ -;;; use-package-core.el --- A configuration macro for simplifying your .emacs +;;; use-package-core.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley @@ -550,7 +550,7 @@ extending any keys already present." (nreverse (sort plist-grouped #'(lambda (l r) (< (use-package-keyword-index (car l)) - (use-package-keyword-index (car r))))))) + (use-package-keyword-index (car r))))))) (setq result (cons (car x) (cons (cdr x) result)))) result))) @@ -754,7 +754,7 @@ no more than once." `((defvar ,loaded nil) (defvar ,result nil) (defvar ,next #'(lambda () (if ,loaded ,result - (setq ,loaded t ,result ,arg)))) + (setq ,loaded t ,result ,arg)))) ,@(funcall f `((funcall ,next)))))) (defsubst use-package-normalize-value (_label arg) @@ -1536,7 +1536,6 @@ this file. Usage: ;; Local Variables: ;; indent-tabs-mode: nil -;; lexical-binding: t ;; End: ;;; use-package-core.el ends here diff --git a/lisp/use-package/use-package-delight.el b/lisp/use-package/use-package-delight.el index ab2dad9bd0a..85d5c7cb4d6 100644 --- a/lisp/use-package/use-package-delight.el +++ b/lisp/use-package/use-package-delight.el @@ -1,4 +1,4 @@ -;;; use-package-delight.el --- Support for the :delight keyword +;;; use-package-delight.el --- Support for the :delight keyword -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley @@ -88,9 +88,4 @@ (provide 'use-package-delight) -;; Local Variables: -;; indent-tabs-mode: nil -;; lexical-binding: t -;; End: - ;;; use-package-delight.el ends here diff --git a/lisp/use-package/use-package-diminish.el b/lisp/use-package/use-package-diminish.el index 69b8dafc4c3..1f3895f42cd 100644 --- a/lisp/use-package/use-package-diminish.el +++ b/lisp/use-package/use-package-diminish.el @@ -1,4 +1,4 @@ -;;; use-package-diminish.el --- Support for the :diminish keyword +;;; use-package-diminish.el --- Support for the :diminish keyword -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley @@ -77,9 +77,4 @@ (provide 'use-package-diminish) -;; Local Variables: -;; indent-tabs-mode: nil -;; lexical-binding: t -;; End: - ;;; use-package-diminish.el ends here diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index 2d4e00e5c01..50005a9e990 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -1,4 +1,4 @@ -;;; use-package-ensure.el --- Support for the :ensure and :pin keywords +;;; use-package-ensure.el --- Support for the :ensure and :pin keywords -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley @@ -211,9 +211,4 @@ manually updated package." (provide 'use-package-ensure) -;; Local Variables: -;; indent-tabs-mode: nil -;; lexical-binding: t -;; End: - ;;; use-package-ensure.el ends here diff --git a/lisp/use-package/use-package-jump.el b/lisp/use-package/use-package-jump.el index 60d3ef525bc..4044ad16564 100644 --- a/lisp/use-package/use-package-jump.el +++ b/lisp/use-package/use-package-jump.el @@ -1,4 +1,4 @@ -;;; use-package-jump.el --- Attempt to jump to a use-package declaration +;;; use-package-jump.el --- Attempt to jump to a use-package declaration -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley @@ -76,9 +76,4 @@ instead." (provide 'use-package-jump) -;; Local Variables: -;; indent-tabs-mode: nil -;; lexical-binding: t -;; End: - ;;; use-package-jump.el ends here diff --git a/lisp/use-package/use-package-lint.el b/lisp/use-package/use-package-lint.el index 54f5b759406..c6e7c3c0ce2 100644 --- a/lisp/use-package/use-package-lint.el +++ b/lisp/use-package/use-package-lint.el @@ -1,4 +1,4 @@ -;;; use-package-lint.el --- Attempt to find errors in use-package declarations +;;; use-package-lint.el --- Attempt to find errors in use-package declarations -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley @@ -81,9 +81,4 @@ with the specified `:load-path' the module cannot be found." (provide 'use-package-lint) -;; Local Variables: -;; indent-tabs-mode: nil -;; lexical-binding: t -;; End: - ;;; use-package-lint.el ends here diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 4d1b56b6d6a..1a8fff895f6 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1,4 +1,4 @@ -;;; use-package.el --- A configuration macro for simplifying your .emacs +;;; use-package.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley @@ -51,9 +51,4 @@ (provide 'use-package) -;; Local Variables: -;; indent-tabs-mode: nil -;; lexical-binding: t -;; End: - ;;; use-package.el ends here diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index ec9c59be916..55d9959fb10 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1,4 +1,4 @@ -;;; use-package-tests.el --- Tests for use-package.el +;;; use-package-tests.el --- Tests for use-package.el -*- lexical-binding: t; -*- ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as @@ -1885,7 +1885,6 @@ ;; Local Variables: ;; indent-tabs-mode: nil -;; lexical-binding: t ;; no-byte-compile: t ;; no-update-autoloads: t ;; End: From ab918196faff60300a8c9e3b7e1d825c42831b6e Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 27 Jan 2018 14:13:48 -0800 Subject: [PATCH 479/606] Revert "Merge pull request from jabranham/lexical-bindings" This reverts commit d21787f1d64a740c0e00899835d9200a0e4690df, reversing changes made to fd8a3510fd1a555b925f57b2870917e3c4ea0206. GitHub-reference: https://github.com/jwiegley/use-package/issues/617 --- lisp/use-package/use-package-bind-key.el | 6 +- lisp/use-package/use-package-chords.el | 2 +- lisp/use-package/use-package-core.el | 80 +++++++++++----------- lisp/use-package/use-package-delight.el | 6 +- lisp/use-package/use-package-diminish.el | 4 +- lisp/use-package/use-package-ensure.el | 16 ++--- lisp/use-package/use-package-jump.el | 2 +- lisp/use-package/use-package-lint.el | 2 +- lisp/use-package/use-package.el | 2 +- test/lisp/use-package/use-package-tests.el | 2 +- 10 files changed, 61 insertions(+), 61 deletions(-) diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index 8c86ef5edfc..d8fe56dfaa5 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -1,4 +1,4 @@ -;;; use-package-bind-key.el --- Support for the :bind/:bind-keymap keywords -*- lexical-binding: t; -*- +;;; use-package-bind-key.el --- Support for the :bind/:bind-keymap keywords ;; Copyright (C) 2012-2017 John Wiegley @@ -125,7 +125,7 @@ deferred until the prefix key sequence is pressed." ;;;###autoload (defun use-package-handler/:bind - (name _keyword args rest state &optional bind-macro) + (name keyword args rest state &optional bind-macro) (use-package-concat (use-package-process-keywords name rest state) `(,@(mapcar @@ -146,7 +146,7 @@ deferred until the prefix key sequence is pressed." ;;;###autoload (defun use-package-handler/:bind-keymap - (name _keyword args rest state &optional override) + (name keyword args rest state &optional override) (use-package-concat (use-package-process-keywords name rest state) (mapcar diff --git a/lisp/use-package/use-package-chords.el b/lisp/use-package/use-package-chords.el index 936ff228999..63a9737109f 100644 --- a/lisp/use-package/use-package-chords.el +++ b/lisp/use-package/use-package-chords.el @@ -1,4 +1,4 @@ -;;; use-package-chords.el --- key-chord keyword for use-package -*- lexical-binding: t; -*- +;;; use-package-chords.el --- key-chord keyword for use-package ;; Copyright (C) 2015-2017 Justin Talbott diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 9adebdf4bf0..469b3f7b23c 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1,4 +1,4 @@ -;;; use-package-core.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*- +;;; use-package-core.el --- A configuration macro for simplifying your .emacs ;; Copyright (C) 2012-2017 John Wiegley @@ -43,6 +43,7 @@ (require 'cl-lib) (eval-when-compile + (require 'cl) (require 'regexp-opt)) (defgroup use-package nil @@ -285,7 +286,7 @@ include support for finding `use-package' and `require' forms. Must be set before loading use-package." :type 'boolean :set - #'(lambda (_sym value) + #'(lambda (sym value) (eval-after-load 'lisp-mode (if value `(add-to-list 'lisp-imenu-generic-expression @@ -524,7 +525,7 @@ extending any keys already present." arg))) (use-package-error (format "Unrecognized keyword: %s" keyword)))))) -(defun use-package-unalias-keywords (_name args) +(defun use-package-unalias-keywords (name args) (setq args (cl-nsubstitute :if :when args)) (let (temp) (while (setq temp (plist-get args :unless)) @@ -757,7 +758,7 @@ no more than once." (setq ,loaded t ,result ,arg)))) ,@(funcall f `((funcall ,next)))))) -(defsubst use-package-normalize-value (_label arg) +(defsubst use-package-normalize-value (label arg) "Normalize the Lisp value given by ARG. The argument LABEL is ignored." (cond ((null arg) nil) @@ -779,7 +780,7 @@ The argument LABEL is ignored." (use-package-error (concat label " wants a symbol, or list of symbols"))))) -(defun use-package-normalize-symlist (_name keyword args) +(defun use-package-normalize-symlist (name keyword args) (use-package-as-one (symbol-name keyword) args #'use-package-normalize-symbols)) @@ -795,7 +796,7 @@ The argument LABEL is ignored." (use-package-error (concat label " wants a symbol, or nested list of symbols"))))) -(defun use-package-normalize-recursive-symlist (_name keyword args) +(defun use-package-normalize-recursive-symlist (name keyword args) (use-package-as-one (symbol-name keyword) args #'use-package-normalize-recursive-symbols)) @@ -817,7 +818,7 @@ The argument LABEL is ignored." (use-package-error (concat label " wants a directory path, or list of paths"))))) -(defun use-package-normalize-predicate (_name keyword args) +(defun use-package-normalize-predicate (name keyword args) (if (null args) t (use-package-only-one (symbol-name keyword) args @@ -835,7 +836,7 @@ The argument LABEL is ignored." (macroexpand form) form)) args)) -(defun use-package-normalize-forms (_name keyword args) +(defun use-package-normalize-forms (name keyword args) (use-package-normalize-form (symbol-name keyword) args)) (defun use-package-normalize-pairs @@ -920,7 +921,7 @@ If RECURSED is non-nil, recurse into sublists." #'use-package-recognize-function name))) -(defun use-package-autoloads-mode (_name _keyword args) +(defun use-package-autoloads-mode (name keyword args) (mapcar #'(lambda (x) (cons (cdr x) 'command)) (cl-remove-if-not #'(lambda (x) @@ -1004,21 +1005,20 @@ meaning: ;; 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-normalize/:disabled (name keyword arg)) -(defun use-package-handler/:disabled (name _keyword _arg rest state) +(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) +(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) +(defun use-package-handler/:if (name keyword pred rest state) (let ((body (use-package-process-keywords name rest state))) `((when ,pred ,@body)))) @@ -1028,7 +1028,7 @@ meaning: (defalias 'use-package-normalize/:unless 'use-package-normalize-test) -(defun use-package-handler/:unless (name _keyword pred rest state) +(defun use-package-handler/:unless (name keyword pred rest state) (let ((body (use-package-process-keywords name rest state))) `((unless ,pred ,@body)))) @@ -1036,7 +1036,7 @@ meaning: (defalias 'use-package-normalize/:requires 'use-package-normalize-symlist) -(defun use-package-handler/:requires (name _keyword requires rest state) +(defun use-package-handler/:requires (name keyword requires rest state) (let ((body (use-package-process-keywords name rest state))) (if (null requires) body @@ -1047,11 +1047,11 @@ meaning: ;;;; :load-path -(defun use-package-normalize/:load-path (_name keyword args) +(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) +(defun use-package-handler/:load-path (name keyword arg rest state) (let ((body (use-package-process-keywords name rest state))) (use-package-concat (mapcar #'(lambda (path) @@ -1063,28 +1063,28 @@ meaning: (defalias 'use-package-normalize/:no-require 'use-package-normalize-predicate) -(defun use-package-handler/:no-require (name _keyword _arg rest state) +(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) +(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) +(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) +(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 @@ -1098,14 +1098,14 @@ meaning: ;;;; :catch (defvar use-package--form) -(defvar use-package--hush-function #'(lambda (_keyword body) body)) +(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) +(defun use-package-normalize/:catch (name keyword args) (if (null args) t (use-package-only-one (symbol-name keyword) args @@ -1149,7 +1149,7 @@ meaning: (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) +(defun use-package-handler/:interpreter (name keyword arg rest state) (use-package-handle-mode name 'interpreter-mode-alist arg rest state)) ;;;; :mode @@ -1157,7 +1157,7 @@ meaning: (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) +(defun use-package-handler/:mode (name keyword arg rest state) (use-package-handle-mode name 'auto-mode-alist arg rest state)) ;;;; :magic @@ -1165,7 +1165,7 @@ meaning: (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) +(defun use-package-handler/:magic (name keyword arg rest state) (use-package-handle-mode name 'magic-mode-alist arg rest state)) ;;;; :magic-fallback @@ -1173,7 +1173,7 @@ meaning: (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) +(defun use-package-handler/:magic-fallback (name keyword arg rest state) (use-package-handle-mode name 'magic-fallback-mode-alist arg rest state)) ;;;; :hook @@ -1200,7 +1200,7 @@ meaning: (defalias 'use-package-autoloads/:hook 'use-package-autoloads-mode) -(defun use-package-handler/:hook (name _keyword args rest state) +(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) @@ -1223,7 +1223,7 @@ meaning: (defalias 'use-package-normalize/:commands 'use-package-normalize-symlist) -(defun use-package-handler/:commands (name _keyword arg rest state) +(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. @@ -1245,7 +1245,7 @@ meaning: (defalias 'use-package-normalize/:defer 'use-package-normalize-predicate) -(defun use-package-handler/:defer (name _keyword arg rest state) +(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 @@ -1301,7 +1301,7 @@ no keyword implies `:all'." ((listp features) (use-package-require-after-load (cons :all features) body)))) -(defun use-package-handler/:after (name _keyword arg rest state) +(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)) @@ -1316,12 +1316,12 @@ no keyword implies `:all'." (defalias 'use-package-normalize/:demand 'use-package-normalize-predicate) -(defun use-package-handler/:demand (name _keyword _arg rest state) +(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) +(defun use-package-normalize/:custom (name keyword args) "Normalize use-package custom keyword." (use-package-as-one (symbol-name keyword) args #'(lambda (label arg) @@ -1333,7 +1333,7 @@ no keyword implies `:all'." (list arg) arg)))) -(defun use-package-handler/:custom (name _keyword args rest state) +(defun use-package-handler/:custom (name keyword args rest state) "Generate use-package custom keyword code." (use-package-concat (mapcar @@ -1349,7 +1349,7 @@ no keyword implies `:all'." ;;;; :custom-face -(defun use-package-normalize/:custom-face (name-symbol _keyword arg) +(defun use-package-normalize/:custom-face (name-symbol keyword arg) "Normalize use-package custom-face keyword." (let ((error-msg (format "%s wants a ( ) or list of these" @@ -1366,7 +1366,7 @@ no keyword implies `:all'." (> (length def) 2)) (use-package-error error-msg)))))) -(defun use-package-handler/:custom-face (name _keyword args rest state) +(defun use-package-handler/:custom-face (name keyword args rest state) "Generate use-package custom-face keyword code." (use-package-concat (mapcar #'(lambda (def) `(custom-set-faces (quote ,def))) args) @@ -1376,7 +1376,7 @@ no keyword implies `:all'." (defalias 'use-package-normalize/:init 'use-package-normalize-forms) -(defun use-package-handler/:init (name _keyword arg rest state) +(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))) @@ -1401,7 +1401,7 @@ no keyword implies `:all'." args (list args))) -(defun use-package-handler/:load (name _keyword arg rest state) +(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))) @@ -1411,7 +1411,7 @@ no keyword implies `:all'." (defalias 'use-package-normalize/:config 'use-package-normalize-forms) -(defun use-package-handler/:config (name _keyword arg rest state) +(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 diff --git a/lisp/use-package/use-package-delight.el b/lisp/use-package/use-package-delight.el index 85d5c7cb4d6..9d4f6acf2de 100644 --- a/lisp/use-package/use-package-delight.el +++ b/lisp/use-package/use-package-delight.el @@ -1,4 +1,4 @@ -;;; use-package-delight.el --- Support for the :delight keyword -*- lexical-binding: t; -*- +;;; use-package-delight.el --- Support for the :delight keyword ;; Copyright (C) 2012-2017 John Wiegley @@ -52,7 +52,7 @@ ":delight expects `delight' arguments or a list of them")))) ;;;###autoload -(defun use-package-normalize/:delight (name _keyword args) +(defun use-package-normalize/:delight (name keyword args) "Normalize arguments to delight." (cond ((null args) `((,(use-package-as-mode name) nil ,name))) @@ -77,7 +77,7 @@ args))))) ;;;###autoload -(defun use-package-handler/:delight (name _keyword args rest state) +(defun use-package-handler/:delight (name keyword args rest state) (let ((body (use-package-process-keywords name rest state))) (use-package-concat body diff --git a/lisp/use-package/use-package-diminish.el b/lisp/use-package/use-package-diminish.el index 1f3895f42cd..c2da62257e6 100644 --- a/lisp/use-package/use-package-diminish.el +++ b/lisp/use-package/use-package-diminish.el @@ -1,4 +1,4 @@ -;;; use-package-diminish.el --- Support for the :diminish keyword -*- lexical-binding: t; -*- +;;; use-package-diminish.el --- Support for the :diminish keyword ;; Copyright (C) 2012-2017 John Wiegley @@ -62,7 +62,7 @@ (apply-partially #'use-package-normalize-diminish name) t)) ;;;###autoload -(defun use-package-handler/:diminish (name _keyword arg rest state) +(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) diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index 50005a9e990..1a76b883e1c 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -1,4 +1,4 @@ -;;; use-package-ensure.el --- Support for the :ensure and :pin keywords -*- lexical-binding: t; -*- +;;; use-package-ensure.el --- Support for the :ensure and :pin keywords ;; Copyright (C) 2012-2017 John Wiegley @@ -76,9 +76,9 @@ The default value uses package.el to install the package." ;;;; :pin -(defun use-package-normalize/:pin (_name keyword args) +(defun use-package-normalize/:pin (name keyword args) (use-package-only-one (symbol-name keyword) args - #'(lambda (_label arg) + #'(lambda (label arg) (cond ((stringp arg) arg) ((use-package-non-nil-symbolp arg) (symbol-name arg)) @@ -116,7 +116,7 @@ manually updated package." (unless (bound-and-true-p package--initialized) (package-initialize t)))) -(defun use-package-handler/:pin (name _keyword archive-name rest state) +(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) @@ -133,11 +133,11 @@ manually updated package." (defvar package-archive-contents) ;;;###autoload -(defun use-package-normalize/:ensure (_name keyword args) +(defun use-package-normalize/:ensure (name keyword args) (if (null args) (list t) (use-package-only-one (symbol-name keyword) args - #'(lambda (_label arg) + #'(lambda (label arg) (cond ((symbolp arg) (list arg)) @@ -152,7 +152,7 @@ manually updated package." (concat ":ensure wants an optional package name " "(an unquoted symbol name), or ( :pin )")))))))) -(defun use-package-ensure-elpa (name args _state &optional _no-refresh) +(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)) @@ -183,7 +183,7 @@ manually updated package." :error)))))))) ;;;###autoload -(defun use-package-handler/:ensure (name _keyword ensure rest state) +(defun use-package-handler/:ensure (name keyword ensure rest state) (let* ((body (use-package-process-keywords name rest state))) ;; We want to avoid installing packages when the `use-package' macro is ;; being macro-expanded by elisp completion (see `lisp--local-variables'), diff --git a/lisp/use-package/use-package-jump.el b/lisp/use-package/use-package-jump.el index 4044ad16564..31d1b054060 100644 --- a/lisp/use-package/use-package-jump.el +++ b/lisp/use-package/use-package-jump.el @@ -1,4 +1,4 @@ -;;; use-package-jump.el --- Attempt to jump to a use-package declaration -*- lexical-binding: t; -*- +;;; use-package-jump.el --- Attempt to jump to a use-package declaration ;; Copyright (C) 2012-2017 John Wiegley diff --git a/lisp/use-package/use-package-lint.el b/lisp/use-package/use-package-lint.el index c6e7c3c0ce2..53c682842f9 100644 --- a/lisp/use-package/use-package-lint.el +++ b/lisp/use-package/use-package-lint.el @@ -1,4 +1,4 @@ -;;; use-package-lint.el --- Attempt to find errors in use-package declarations -*- lexical-binding: t; -*- +;;; use-package-lint.el --- Attempt to find errors in use-package declarations ;; Copyright (C) 2012-2017 John Wiegley diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 1a8fff895f6..5f98db1bed7 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1,4 +1,4 @@ -;;; use-package.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*- +;;; use-package.el --- A configuration macro for simplifying your .emacs ;; Copyright (C) 2012-2017 John Wiegley diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 55d9959fb10..fc86fa63f81 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1,4 +1,4 @@ -;;; use-package-tests.el --- Tests for use-package.el -*- lexical-binding: t; -*- +;;; use-package-tests.el --- Tests for use-package.el ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as From 09266283b94502247b11ed4d948dfbe07b5702ac Mon Sep 17 00:00:00 2001 From: Justin Burkett Date: Tue, 6 Feb 2018 11:35:45 -0500 Subject: [PATCH 480/606] Add use-package-ignore-unknown-keywords option This option allows use-package to skip over keywords it doesn't recognize. --- lisp/use-package/use-package-core.el | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 469b3f7b23c..1ae35fe7335 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -112,6 +112,13 @@ otherwise requested." :type '(repeat symbol) :group 'use-package) +(defcustom use-package-ignore-unknown-keywords nil + "If non-nil, issue warning instead of error when unknown +keyword is encountered. The unknown keyword and its associated +arguments will be ignored in the `use-package' expansion." + :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' @@ -513,7 +520,8 @@ extending any keys already present." (intern-soft (concat "use-package-normalize/" (symbol-name keyword)))) (arg (and (functionp normalizer) - (funcall normalizer name keyword args)))) + (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 @@ -523,7 +531,12 @@ extending any keys already present." (funcall merge-function keyword arg (plist-get plist keyword)) arg))) - (use-package-error (format "Unrecognized keyword: %s" keyword)))))) + (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)) From 46503b194c2a1025e3e88f6e8cbd5750ccd5d855 Mon Sep 17 00:00:00 2001 From: Justin Burkett Date: Tue, 6 Feb 2018 12:48:51 -0500 Subject: [PATCH 481/606] Fix usage of plist argument in use-package-normalize-plist Previously the argument was never used. --- lisp/use-package/use-package-core.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 1ae35fe7335..a649d087fae 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -511,7 +511,8 @@ This is in contrast to merely setting it to 0." "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." - (when input + (if (null input) + plist (let* ((keyword (car input)) (xs (use-package-split-list #'keywordp (cdr input))) (args (car xs)) From 2250f89ac0b8d2c19875dab67e73ac1cfe6ca3df Mon Sep 17 00:00:00 2001 From: Matthew Justin Bauer Date: Sun, 25 Feb 2018 15:03:43 -0600 Subject: [PATCH 482/606] Support ":package" in use-package bind-key supports the keyword ":package" but use-package does not know that. Adding this should be helpful. In the future, maybe we could automatically fill in with the use-package package, but that could be a breaking change. --- lisp/use-package/use-package-bind-key.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index d8fe56dfaa5..d17ecb2cf75 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -87,12 +87,14 @@ deferred until the prefix key sequence is pressed." ;; :prefix STRING ;; :filter SEXP ;; :menu-name STRING + ;; :package SYMBOL ((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))) (eq x :filter) - (and (eq x :menu-name) (stringp (cadr arg)))) + (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) From ae22d74a166da46eb3ac689e75383508b17cb3f8 Mon Sep 17 00:00:00 2001 From: Damien Cassou Date: Thu, 8 Mar 2018 20:48:07 +0100 Subject: [PATCH 483/606] Use a tabulated-list to display package configuration statistics Fix https://github.com/jwiegley/use-package/issues/641 --- lisp/use-package/use-package-core.el | 78 +++++++++++++++++++--------- 1 file changed, 54 insertions(+), 24 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index a649d087fae..83630b80785 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -41,6 +41,7 @@ (require 'bytecomp) (require 'cl-lib) +(require 'tabulated-list) (eval-when-compile (require 'cl) @@ -964,6 +965,43 @@ If RECURSED is non-nil, recurse into sublists." (interactive) (setq use-package-statistics (make-hash-table))) +(defun use-package-statistics-status (package) + "Return loading configuration status of PACKAGE." + (cond ((gethash :config statistics) "Configured") + ((gethash :init statistics) "Initialized") + ((gethash :preface statistics) "Prefaced") + ((gethash :use-package statistics) "Declared"))) + +(defun use-package-statistics-last-event (package) + "Return the date when package's status last changed. +The date is returned as a string." + (format-time-string "%Y-%m-%d %a %H:%M" + (or (gethash :config statistics) + (gethash :init statistics) + (gethash :preface statistics) + (gethash :use-package statistics)))) + +(defun use-package-statistics-time (package) + "Return the time is took for package to load." + (+ (float-time (gethash :config-secs statistics 0)) + (float-time (gethash :init-secs statistics 0)) + (float-time (gethash :preface-secs statistics 0)) + (float-time (gethash :use-package-secs statistics 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 package) + (use-package-statistics-last-event package) + (format "%.2f" (use-package-statistics-time package)))))) + (defun use-package-report () "Show current statistics gathered about use-package declarations. In the table that's generated, the status field has the following @@ -974,32 +1012,24 @@ meaning: Declared the use-package declaration was seen" (interactive) (with-current-buffer (get-buffer-create "*use-package statistics*") - (delete-region (point-min) (point-max)) - (insert "|Package|Status|Last Event|Time|\n") - (insert "|-\n") - (maphash - #'(lambda (key hash) - (insert - (format "|%s |%s|%s |%.2f|\n" key - (cond ((gethash :config hash) "Configured") - ((gethash :init hash) "Initialized") - ((gethash :preface hash) "Prefaced") - ((gethash :use-package hash) "Declared")) - (format-time-string "[%Y-%m-%d %a %H:%M]" - (or (gethash :config hash) - (gethash :init hash) - (gethash :preface hash) - (gethash :use-package hash))) - (+ (float-time (gethash :config-secs hash 0)) - (float-time (gethash :init-secs hash 0)) - (float-time (gethash :preface-secs hash 0)) - (float-time (gethash :use-package-secs hash 0)))))) - use-package-statistics) - (goto-char (point-min)) - (orgtbl-mode) - (org-table-align) + (setq tabulated-list-entries + (mapcar #'use-package-statistics-convert + (hash-table-keys use-package-statistics))) + (use-package-statistics-mode) + (tabulated-list-print) (display-buffer (current-buffer)))) +(define-derived-mode use-package-statistics-mode tabulated-list-mode + "use-package statistics" + "Show current statistics gathered about use-package declarations." + (setq tabulated-list-format + ;; The sum of column width is 80 caracters: + #[("Package" 25 t) + ("Status" 13 t) + ("Last Event" 23 t) + ("Time" 10 t)]) + (tabulated-list-init-header)) + (defun use-package-statistics-gather (keyword name after) (let* ((hash (gethash name use-package-statistics (make-hash-table))) From bce655f6163decb6df9ae6f1ef815fb9763e3416 Mon Sep 17 00:00:00 2001 From: Damien Cassou Date: Sun, 11 Mar 2018 13:21:00 +0100 Subject: [PATCH 484/606] Add missing require This is used for `hash-table-keys`. Fix https://github.com/jwiegley/use-package/issues/644. --- lisp/use-package/use-package-core.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 83630b80785..84cdb83f48d 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -42,6 +42,7 @@ (require 'bytecomp) (require 'cl-lib) (require 'tabulated-list) +(require 'subr-x) (eval-when-compile (require 'cl) From b28efb484712a9c773ded037523b28a1ba688632 Mon Sep 17 00:00:00 2001 From: Damien Cassou Date: Sun, 11 Mar 2018 13:22:13 +0100 Subject: [PATCH 485/606] Fix compile-time warnings due to the statistics-reporting code The code worked because the file is using dynamic binding. --- lisp/use-package/use-package-core.el | 36 ++++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 84cdb83f48d..33b0e677cff 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -967,27 +967,27 @@ If RECURSED is non-nil, recurse into sublists." (setq use-package-statistics (make-hash-table))) (defun use-package-statistics-status (package) - "Return loading configuration status of PACKAGE." - (cond ((gethash :config statistics) "Configured") - ((gethash :init statistics) "Initialized") - ((gethash :preface statistics) "Prefaced") - ((gethash :use-package statistics) "Declared"))) + "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. + "Return the date when PACKAGE's status last changed. The date is returned as a string." (format-time-string "%Y-%m-%d %a %H:%M" - (or (gethash :config statistics) - (gethash :init statistics) - (gethash :preface statistics) - (gethash :use-package statistics)))) + (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 statistics 0)) - (float-time (gethash :init-secs statistics 0)) - (float-time (gethash :preface-secs statistics 0)) - (float-time (gethash :use-package-secs statistics 0)))) + "Return the time is took for PACKAGE to load." + (+ (float-time (gethash :config-secs package 0)) + (float-time (gethash :init-secs package 0)) + (float-time (gethash :preface-secs package 0)) + (float-time (gethash :use-package-secs package 0)))) (defun use-package-statistics-convert (package) "Return information about PACKAGE. @@ -999,9 +999,9 @@ The information is formatted in a way suitable for package (vector (symbol-name package) - (use-package-statistics-status package) - (use-package-statistics-last-event package) - (format "%.2f" (use-package-statistics-time package)))))) + (use-package-statistics-status statistics) + (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. From cba5a11368aa71521ce8d1a7b080a59ddaa04cbf Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 11 Mar 2018 21:37:02 -0700 Subject: [PATCH 486/606] Revert "Fix report" --- lisp/use-package/use-package-core.el | 37 ++++++++++++++-------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 33b0e677cff..83630b80785 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -42,7 +42,6 @@ (require 'bytecomp) (require 'cl-lib) (require 'tabulated-list) -(require 'subr-x) (eval-when-compile (require 'cl) @@ -967,27 +966,27 @@ If RECURSED is non-nil, recurse into sublists." (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"))) + "Return loading configuration status of PACKAGE." + (cond ((gethash :config statistics) "Configured") + ((gethash :init statistics) "Initialized") + ((gethash :preface statistics) "Prefaced") + ((gethash :use-package statistics) "Declared"))) (defun use-package-statistics-last-event (package) - "Return the date when PACKAGE's status last changed. + "Return the date when package's status last changed. The date is returned as a string." (format-time-string "%Y-%m-%d %a %H:%M" - (or (gethash :config package) - (gethash :init package) - (gethash :preface package) - (gethash :use-package package)))) + (or (gethash :config statistics) + (gethash :init statistics) + (gethash :preface statistics) + (gethash :use-package statistics)))) (defun use-package-statistics-time (package) - "Return the time is took for PACKAGE to load." - (+ (float-time (gethash :config-secs package 0)) - (float-time (gethash :init-secs package 0)) - (float-time (gethash :preface-secs package 0)) - (float-time (gethash :use-package-secs package 0)))) + "Return the time is took for package to load." + (+ (float-time (gethash :config-secs statistics 0)) + (float-time (gethash :init-secs statistics 0)) + (float-time (gethash :preface-secs statistics 0)) + (float-time (gethash :use-package-secs statistics 0)))) (defun use-package-statistics-convert (package) "Return information about PACKAGE. @@ -999,9 +998,9 @@ The information is formatted in a way suitable for package (vector (symbol-name package) - (use-package-statistics-status statistics) - (use-package-statistics-last-event statistics) - (format "%.2f" (use-package-statistics-time statistics)))))) + (use-package-statistics-status package) + (use-package-statistics-last-event package) + (format "%.2f" (use-package-statistics-time package)))))) (defun use-package-report () "Show current statistics gathered about use-package declarations. From 2a479988443c3264a2f67e643f2acf6055014c30 Mon Sep 17 00:00:00 2001 From: Damien Cassou Date: Sun, 11 Mar 2018 13:21:00 +0100 Subject: [PATCH 487/606] Add missing require This is used for `hash-table-keys`. Fix https://github.com/jwiegley/use-package/issues/644. --- lisp/use-package/use-package-core.el | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 83630b80785..2c27351d0bd 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -43,6 +43,12 @@ (require 'cl-lib) (require 'tabulated-list) +(if (and (eq emacs-major-version 24) (eq emacs-minor-version 3)) + (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)) + (require 'subr-x)) + (eval-when-compile (require 'cl) (require 'regexp-opt)) From 69a561b86b4d781de5294964176509b112d7a7bd Mon Sep 17 00:00:00 2001 From: Damien Cassou Date: Sun, 11 Mar 2018 13:22:13 +0100 Subject: [PATCH 488/606] Fix compile-time warnings due to the statistics-reporting code The code worked because the file is using dynamic binding. --- lisp/use-package/use-package-core.el | 36 ++++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 2c27351d0bd..bd18c972303 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -972,27 +972,27 @@ If RECURSED is non-nil, recurse into sublists." (setq use-package-statistics (make-hash-table))) (defun use-package-statistics-status (package) - "Return loading configuration status of PACKAGE." - (cond ((gethash :config statistics) "Configured") - ((gethash :init statistics) "Initialized") - ((gethash :preface statistics) "Prefaced") - ((gethash :use-package statistics) "Declared"))) + "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. + "Return the date when PACKAGE's status last changed. The date is returned as a string." (format-time-string "%Y-%m-%d %a %H:%M" - (or (gethash :config statistics) - (gethash :init statistics) - (gethash :preface statistics) - (gethash :use-package statistics)))) + (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 statistics 0)) - (float-time (gethash :init-secs statistics 0)) - (float-time (gethash :preface-secs statistics 0)) - (float-time (gethash :use-package-secs statistics 0)))) + "Return the time is took for PACKAGE to load." + (+ (float-time (gethash :config-secs package 0)) + (float-time (gethash :init-secs package 0)) + (float-time (gethash :preface-secs package 0)) + (float-time (gethash :use-package-secs package 0)))) (defun use-package-statistics-convert (package) "Return information about PACKAGE. @@ -1004,9 +1004,9 @@ The information is formatted in a way suitable for package (vector (symbol-name package) - (use-package-statistics-status package) - (use-package-statistics-last-event package) - (format "%.2f" (use-package-statistics-time package)))))) + (use-package-statistics-status statistics) + (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. From 8a27cd3a8b8dd9b1f34545bf6521f7d13dd64de8 Mon Sep 17 00:00:00 2001 From: Valentin Ignatev Date: Wed, 14 Mar 2018 21:27:09 +1000 Subject: [PATCH 489/606] Encourage installation via https instead of http --- doc/misc/use-package.texi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index 8ff40b03929..3af91dac9fd 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -159,7 +159,7 @@ To use Melpa: @lisp (require 'package) (add-to-list 'package-archives - '("melpa" . "http://melpa.org/packages/") t) + '("melpa" . "https://melpa.org/packages/") t) @end lisp @itemize @@ -170,7 +170,7 @@ To use Melpa-Stable: @lisp (require 'package) (add-to-list 'package-archives - '("melpa-stable" . "http://stable.melpa.org/packages/") t) + '("melpa-stable" . "https://stable.melpa.org/packages/") t) @end lisp Once you have added your preferred archive, you need to update the From e5d3826b625228ef61632273df374d775b429fca Mon Sep 17 00:00:00 2001 From: Justin Talbott Date: Fri, 16 Mar 2018 12:29:20 -0400 Subject: [PATCH 490/606] :ensure-system-package allow cdr of cons to be a package name symbol closes https://github.com/jwiegley/use-package/issues/652 --- lisp/use-package/use-package-ensure-system-package.el | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-ensure-system-package.el b/lisp/use-package/use-package-ensure-system-package.el index 48fbde2e20a..81beaec104f 100644 --- a/lisp/use-package/use-package-ensure-system-package.el +++ b/lisp/use-package/use-package-ensure-system-package.el @@ -48,7 +48,11 @@ (cons arg (use-package-ensure-system-package-install-command arg))) ((symbolp arg) (cons arg (use-package-ensure-system-package-install-command (symbol-name arg)))) - ((consp arg) arg))) + ((consp arg) + (if (stringp (cdr arg)) + arg + (cons (car arg) + (use-package-ensure-system-package-install-command (symbol-name (cdr arg)))))))) ;;;###autoload (defun use-package-normalize/:ensure-system-package (name-symbol keyword args) From c9f6cae60329e67686ba171be25c73487c315906 Mon Sep 17 00:00:00 2001 From: Russell Black Date: Fri, 23 Mar 2018 21:46:36 -0600 Subject: [PATCH 491/606] Update use-package-chords.el new style of auto-deferral for chords --- lisp/use-package/use-package-chords.el | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lisp/use-package/use-package-chords.el b/lisp/use-package/use-package-chords.el index 63a9737109f..361398cc8dc 100644 --- a/lisp/use-package/use-package-chords.el +++ b/lisp/use-package/use-package-chords.el @@ -23,6 +23,9 @@ (require 'use-package) (require 'bind-chord) +;;;###autoload +(defalias 'use-package-autoloads/:chords 'use-package-autoloads-mode) + ;;;###autoload (defalias 'use-package-normalize/:chords 'use-package-normalize-binder) From dc83e2f035033fa038888115a8a92f5df69b1732 Mon Sep 17 00:00:00 2001 From: Russell Black Date: Fri, 23 Mar 2018 22:04:48 -0600 Subject: [PATCH 492/606] Update use-package-chords.el --- lisp/use-package/use-package-chords.el | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/lisp/use-package/use-package-chords.el b/lisp/use-package/use-package-chords.el index 361398cc8dc..fbac4b59df6 100644 --- a/lisp/use-package/use-package-chords.el +++ b/lisp/use-package/use-package-chords.el @@ -32,19 +32,10 @@ ;;;###autoload (defun use-package-handler/:chords (name keyword arg rest state) "Handler for `:chords' keyword in `use-package'." - (let* ((commands (remq nil (mapcar #'(lambda (arg) - (if (listp arg) - (cdr arg) - nil)) arg))) - (chord-binder - (use-package-concat - (use-package-process-keywords name - (use-package-sort-keywords - (use-package-plist-maybe-put rest :defer t)) - (use-package-plist-append state :commands commands)) - `(,(macroexpand - `(bind-chords :package ,name ,@arg)))))) - (use-package-handler/:preface name keyword chord-binder rest state))) + (use-package-concat + (use-package-process-keywords name rest state) + `(,(macroexpand + `(bind-chords :package ,name ,@arg))))) (add-to-list 'use-package-keywords :chords t) From 9f034a0bcfdd8c4a6c691d159f3a333e9ca68912 Mon Sep 17 00:00:00 2001 From: Artyom Khramov Date: Thu, 26 Apr 2018 02:22:53 +0600 Subject: [PATCH 493/606] [] ensure-system-package: honor system-packages customizations ensure-system-package doesn't honor system-packages customizations (https://github.com/jwiegley/use-package/issues/661), because system-packages didn't provide an API to retrieve shell command to be executed. This change makes use of the new system-packages' `system-package-get-command` function and therefore fixes the issue. GitHub-reference: fix https://github.com/jwiegley/use-package/issues/661 Copyright-paperwork-exempt: yes --- .../use-package-ensure-system-package.el | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/lisp/use-package/use-package-ensure-system-package.el b/lisp/use-package/use-package-ensure-system-package.el index 81beaec104f..9f2a59ae5e6 100644 --- a/lisp/use-package/use-package-ensure-system-package.el +++ b/lisp/use-package/use-package-ensure-system-package.el @@ -6,7 +6,7 @@ ;; Keywords: convenience, tools, extensions ;; URL: https://github.com/waymondo/use-package-ensure-system-package ;; Version: 0.1 -;; Package-Requires: ((use-package "2.1") (system-packages "0.1")) +;; Package-Requires: ((use-package "2.1") (system-packages "1.0.4")) ;; Filename: use-package-ensure-system-package.el ;; License: GNU General Public License version 3, or (at your option) any later version ;; @@ -29,17 +29,7 @@ (defun use-package-ensure-system-package-install-command (pack) "Return the default install command for PACK." - (let ((command - (cdr (assoc 'install (cdr (assoc system-packages-package-manager - system-packages-supported-package-managers)))))) - (unless command - (error (format "%S not supported in %S" 'install system-packages-package-manager))) - (unless (listp command) - (setq command (list command))) - (when system-packages-use-sudo - (setq command (mapcar (lambda (part) (concat "sudo " part)) command))) - (setq command (mapconcat 'identity command " && ")) - (mapconcat 'identity (list command pack) " "))) + (system-packages-get-command 'install pack)) (defun use-package-ensure-system-package-consify (arg) "Turn `arg' into a cons of (`package-name' . `install-command')." From d2fec5e5e31c282f17ada3a7067df26f1f8662ed Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Mon, 30 Apr 2018 09:54:12 -0700 Subject: [PATCH 494/606] Document that remapping commands is supported with bind-key Copyright-paperwork-exempt: yes --- lisp/use-package/bind-key.el | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index e5cd73e9ea3..5b375a54597 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -38,6 +38,12 @@ ;; ;; (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: ;; From db3563945727a11bbd08a8f8a8de435c5a2b3618 Mon Sep 17 00:00:00 2001 From: Naoya Yamashita Date: Sat, 19 May 2018 14:21:26 +0900 Subject: [PATCH 495/606] fix gethash default value for use-package-statistics-time float-time expect list like (HIGH LOW USEC PSEC) > HIGH has the most significant bits of the seconds, while LOW has the > least significant 16 bits. USEC and PSEC are the microsecond and > picosecond counts. by `current-time` in editfns.c --- lisp/use-package/use-package-core.el | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index bd18c972303..a88efb91a21 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -989,10 +989,10 @@ The date is returned as a string." (defun use-package-statistics-time (package) "Return the time is took for PACKAGE to load." - (+ (float-time (gethash :config-secs package 0)) - (float-time (gethash :init-secs package 0)) - (float-time (gethash :preface-secs package 0)) - (float-time (gethash :use-package-secs package 0)))) + (+ (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. From f38a1009173c0b30c358041df52967ecbde03560 Mon Sep 17 00:00:00 2001 From: Artyom Khramov Date: Sun, 20 May 2018 00:44:43 +0600 Subject: [PATCH 496/606] Ensure system package cleanup The function introduced in https://github.com/jwiegley/use-package/issues/673 wasn't declared at compile time, and it made byte compiler unhappy. Moreover, it was forgotten to remove redundant compile time variables. Thanks @tarsius for pointing that out. This change * Removes redundant variable declarations * Adds `system-packages-get-command` function declaration. Copyright-paperwork-exempt: yes --- lisp/use-package/use-package-ensure-system-package.el | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lisp/use-package/use-package-ensure-system-package.el b/lisp/use-package/use-package-ensure-system-package.el index 9f2a59ae5e6..e4b3e32b547 100644 --- a/lisp/use-package/use-package-ensure-system-package.el +++ b/lisp/use-package/use-package-ensure-system-package.el @@ -23,9 +23,7 @@ (require 'system-packages nil t) (eval-when-compile - (defvar system-packages-package-manager) - (defvar system-packages-supported-package-managers) - (defvar system-packages-use-sudo)) + (declare-function system-packages-get-command "system-packages")) (defun use-package-ensure-system-package-install-command (pack) "Return the default install command for PACK." From c980371f6f1d96f5955cfbc4c355338b6d1bdb90 Mon Sep 17 00:00:00 2001 From: Justin Burkett Date: Sun, 3 Jun 2018 21:38:20 -0400 Subject: [PATCH 497/606] Correct prefix keys after use-package-autoload-keymap By adding events of the form (cons t event) to unread-command-events, Emacs correctly updates this-command-keys for the subsequent use of the prefix. Before this change, packages like my which-key were not getting the correct prefix after use-package-autoload-keymap loaded the relevant package. See https://github.com/justbur/emacs-which-key/issues/192 --- lisp/use-package/use-package-bind-key.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index d17ecb2cf75..8852f9188ba 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -61,7 +61,8 @@ deferred until the prefix key sequence is pressed." (bind-key* key keymap) (bind-key key keymap)) (setq unread-command-events - (listify-key-sequence kv))) + (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))))) From b84a77bcdcd648defa08ba7803e23c6b4f0e8389 Mon Sep 17 00:00:00 2001 From: Thomas Ingram Date: Wed, 13 Jun 2018 16:24:23 -0400 Subject: [PATCH 498/606] Added an Introduction taken from the README Copyright-paperwork-exempt: yes --- doc/misc/use-package.texi | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index 3af91dac9fd..baf60748596 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -129,7 +129,11 @@ FAQ - Issues and Errors @node Introduction @chapter Introduction -TODO +The @code{use-package} macro allows you to isolate package configuration +in your @file{.emacs} file in a way that is both performance-oriented and, +well, 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 around 2 seconds, with no loss of functionality! @node Installation @chapter Installation From b1d9ce08a6ee441f574c93cebfff4876ccf5cb1b Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 13 Jun 2018 13:49:00 -0700 Subject: [PATCH 499/606] Update use-package.texi --- doc/misc/use-package.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index baf60748596..dfd046f1b4b 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -131,7 +131,7 @@ FAQ - Issues and Errors The @code{use-package} macro allows you to isolate package configuration in your @file{.emacs} file in a way that is both performance-oriented and, -well, tidy. I created it because I have over 80 packages that I use in +well, tidy. I created it because I have over 400 packages that I use in Emacs, and things were getting difficult to manage. Yet with this utility my total load time is around 2 seconds, with no loss of functionality! From e2e6f9a44b580c6d30c9c168cbe48000c97c5fb6 Mon Sep 17 00:00:00 2001 From: Alex Branham Date: Tue, 20 Mar 2018 11:40:26 -0500 Subject: [PATCH 500/606] Enable lexical binding This supersedes https://github.com/jwiegley/use-package/issues/617 and closes https://github.com/jwiegley/use-package/issues/648 --- lisp/use-package/use-package-bind-key.el | 6 +- lisp/use-package/use-package-chords.el | 2 +- lisp/use-package/use-package-core.el | 82 +++++++++---------- lisp/use-package/use-package-delight.el | 6 +- lisp/use-package/use-package-diminish.el | 4 +- .../use-package-ensure-system-package.el | 8 +- lisp/use-package/use-package-ensure.el | 16 ++-- lisp/use-package/use-package-jump.el | 2 +- lisp/use-package/use-package-lint.el | 2 +- lisp/use-package/use-package.el | 2 +- test/lisp/use-package/use-package-tests.el | 2 +- 11 files changed, 66 insertions(+), 66 deletions(-) diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index d17ecb2cf75..10b5b483d05 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -1,4 +1,4 @@ -;;; use-package-bind-key.el --- Support for the :bind/:bind-keymap keywords +;;; use-package-bind-key.el --- Support for the :bind/:bind-keymap keywords -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley @@ -127,7 +127,7 @@ deferred until the prefix key sequence is pressed." ;;;###autoload (defun use-package-handler/:bind - (name keyword args rest state &optional bind-macro) + (name _keyword args rest state &optional bind-macro) (use-package-concat (use-package-process-keywords name rest state) `(,@(mapcar @@ -148,7 +148,7 @@ deferred until the prefix key sequence is pressed." ;;;###autoload (defun use-package-handler/:bind-keymap - (name keyword args rest state &optional override) + (name _keyword args rest state &optional override) (use-package-concat (use-package-process-keywords name rest state) (mapcar diff --git a/lisp/use-package/use-package-chords.el b/lisp/use-package/use-package-chords.el index 63a9737109f..936ff228999 100644 --- a/lisp/use-package/use-package-chords.el +++ b/lisp/use-package/use-package-chords.el @@ -1,4 +1,4 @@ -;;; use-package-chords.el --- key-chord keyword for use-package +;;; use-package-chords.el --- key-chord keyword for use-package -*- lexical-binding: t; -*- ;; Copyright (C) 2015-2017 Justin Talbott diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index bd18c972303..9f7828f43ef 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1,4 +1,4 @@ -;;; use-package-core.el --- A configuration macro for simplifying your .emacs +;;; use-package-core.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley @@ -47,10 +47,9 @@ (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)) - (require 'subr-x)) + (eval-when-compile (require 'subr-x))) (eval-when-compile - (require 'cl) (require 'regexp-opt)) (defgroup use-package nil @@ -300,7 +299,7 @@ include support for finding `use-package' and `require' forms. Must be set before loading use-package." :type 'boolean :set - #'(lambda (sym value) + #'(lambda (_sym value) (eval-after-load 'lisp-mode (if value `(add-to-list 'lisp-imenu-generic-expression @@ -546,7 +545,7 @@ extending any keys already present." name tail plist merge-function)) (use-package-error error-string)))))) -(defun use-package-unalias-keywords (name args) +(defun use-package-unalias-keywords (_name args) (setq args (cl-nsubstitute :if :when args)) (let (temp) (while (setq temp (plist-get args :unless)) @@ -779,7 +778,7 @@ no more than once." (setq ,loaded t ,result ,arg)))) ,@(funcall f `((funcall ,next)))))) -(defsubst use-package-normalize-value (label arg) +(defsubst use-package-normalize-value (_label arg) "Normalize the Lisp value given by ARG. The argument LABEL is ignored." (cond ((null arg) nil) @@ -801,7 +800,7 @@ The argument LABEL is ignored." (use-package-error (concat label " wants a symbol, or list of symbols"))))) -(defun use-package-normalize-symlist (name keyword args) +(defun use-package-normalize-symlist (_name keyword args) (use-package-as-one (symbol-name keyword) args #'use-package-normalize-symbols)) @@ -817,7 +816,7 @@ The argument LABEL is ignored." (use-package-error (concat label " wants a symbol, or nested list of symbols"))))) -(defun use-package-normalize-recursive-symlist (name keyword args) +(defun use-package-normalize-recursive-symlist (_name keyword args) (use-package-as-one (symbol-name keyword) args #'use-package-normalize-recursive-symbols)) @@ -839,7 +838,7 @@ The argument LABEL is ignored." (use-package-error (concat label " wants a directory path, or list of paths"))))) -(defun use-package-normalize-predicate (name keyword args) +(defun use-package-normalize-predicate (_name keyword args) (if (null args) t (use-package-only-one (symbol-name keyword) args @@ -857,7 +856,7 @@ The argument LABEL is ignored." (macroexpand form) form)) args)) -(defun use-package-normalize-forms (name keyword args) +(defun use-package-normalize-forms (_name keyword args) (use-package-normalize-form (symbol-name keyword) args)) (defun use-package-normalize-pairs @@ -942,7 +941,7 @@ If RECURSED is non-nil, recurse into sublists." #'use-package-recognize-function name))) -(defun use-package-autoloads-mode (name keyword args) +(defun use-package-autoloads-mode (_name _keyword args) (mapcar #'(lambda (x) (cons (cdr x) 'command)) (cl-remove-if-not #'(lambda (x) @@ -1055,20 +1054,21 @@ meaning: ;; Don't alias this to `ignore', as that will cause the resulting ;; function to be interactive. -(defun use-package-normalize/:disabled (name keyword arg)) +(defun use-package-normalize/:disabled (_name _keyword _arg) + "Do nothing, return nil.") -(defun use-package-handler/:disabled (name keyword arg rest state) +(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) +(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) +(defun use-package-handler/:if (name _keyword pred rest state) (let ((body (use-package-process-keywords name rest state))) `((when ,pred ,@body)))) @@ -1078,7 +1078,7 @@ meaning: (defalias 'use-package-normalize/:unless 'use-package-normalize-test) -(defun use-package-handler/:unless (name keyword pred rest state) +(defun use-package-handler/:unless (name _keyword pred rest state) (let ((body (use-package-process-keywords name rest state))) `((unless ,pred ,@body)))) @@ -1086,7 +1086,7 @@ meaning: (defalias 'use-package-normalize/:requires 'use-package-normalize-symlist) -(defun use-package-handler/:requires (name keyword requires rest state) +(defun use-package-handler/:requires (name _keyword requires rest state) (let ((body (use-package-process-keywords name rest state))) (if (null requires) body @@ -1097,11 +1097,11 @@ meaning: ;;;; :load-path -(defun use-package-normalize/:load-path (name keyword args) +(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) +(defun use-package-handler/:load-path (name _keyword arg rest state) (let ((body (use-package-process-keywords name rest state))) (use-package-concat (mapcar #'(lambda (path) @@ -1113,28 +1113,28 @@ meaning: (defalias 'use-package-normalize/:no-require 'use-package-normalize-predicate) -(defun use-package-handler/:no-require (name keyword arg rest state) +(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) +(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) +(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) +(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 @@ -1148,14 +1148,14 @@ meaning: ;;;; :catch (defvar use-package--form) -(defvar use-package--hush-function #'(lambda (keyword body) body)) +(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) +(defun use-package-normalize/:catch (_name keyword args) (if (null args) t (use-package-only-one (symbol-name keyword) args @@ -1199,7 +1199,7 @@ meaning: (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) +(defun use-package-handler/:interpreter (name _keyword arg rest state) (use-package-handle-mode name 'interpreter-mode-alist arg rest state)) ;;;; :mode @@ -1207,7 +1207,7 @@ meaning: (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) +(defun use-package-handler/:mode (name _keyword arg rest state) (use-package-handle-mode name 'auto-mode-alist arg rest state)) ;;;; :magic @@ -1215,7 +1215,7 @@ meaning: (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) +(defun use-package-handler/:magic (name _keyword arg rest state) (use-package-handle-mode name 'magic-mode-alist arg rest state)) ;;;; :magic-fallback @@ -1223,7 +1223,7 @@ meaning: (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) +(defun use-package-handler/:magic-fallback (name _keyword arg rest state) (use-package-handle-mode name 'magic-fallback-mode-alist arg rest state)) ;;;; :hook @@ -1250,7 +1250,7 @@ meaning: (defalias 'use-package-autoloads/:hook 'use-package-autoloads-mode) -(defun use-package-handler/:hook (name keyword args rest state) +(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) @@ -1273,7 +1273,7 @@ meaning: (defalias 'use-package-normalize/:commands 'use-package-normalize-symlist) -(defun use-package-handler/:commands (name keyword arg rest state) +(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. @@ -1295,7 +1295,7 @@ meaning: (defalias 'use-package-normalize/:defer 'use-package-normalize-predicate) -(defun use-package-handler/:defer (name keyword arg rest state) +(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 @@ -1351,7 +1351,7 @@ no keyword implies `:all'." ((listp features) (use-package-require-after-load (cons :all features) body)))) -(defun use-package-handler/:after (name keyword arg rest state) +(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)) @@ -1366,12 +1366,12 @@ no keyword implies `:all'." (defalias 'use-package-normalize/:demand 'use-package-normalize-predicate) -(defun use-package-handler/:demand (name keyword arg rest state) +(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) +(defun use-package-normalize/:custom (_name keyword args) "Normalize use-package custom keyword." (use-package-as-one (symbol-name keyword) args #'(lambda (label arg) @@ -1383,7 +1383,7 @@ no keyword implies `:all'." (list arg) arg)))) -(defun use-package-handler/:custom (name keyword args rest state) +(defun use-package-handler/:custom (name _keyword args rest state) "Generate use-package custom keyword code." (use-package-concat (mapcar @@ -1399,7 +1399,7 @@ no keyword implies `:all'." ;;;; :custom-face -(defun use-package-normalize/:custom-face (name-symbol keyword arg) +(defun use-package-normalize/:custom-face (name-symbol _keyword arg) "Normalize use-package custom-face keyword." (let ((error-msg (format "%s wants a ( ) or list of these" @@ -1416,7 +1416,7 @@ no keyword implies `:all'." (> (length def) 2)) (use-package-error error-msg)))))) -(defun use-package-handler/:custom-face (name keyword args rest state) +(defun use-package-handler/:custom-face (name _keyword args rest state) "Generate use-package custom-face keyword code." (use-package-concat (mapcar #'(lambda (def) `(custom-set-faces (quote ,def))) args) @@ -1426,7 +1426,7 @@ no keyword implies `:all'." (defalias 'use-package-normalize/:init 'use-package-normalize-forms) -(defun use-package-handler/:init (name keyword arg rest state) +(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))) @@ -1451,7 +1451,7 @@ no keyword implies `:all'." args (list args))) -(defun use-package-handler/:load (name keyword arg rest state) +(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))) @@ -1461,7 +1461,7 @@ no keyword implies `:all'." (defalias 'use-package-normalize/:config 'use-package-normalize-forms) -(defun use-package-handler/:config (name keyword arg rest state) +(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 diff --git a/lisp/use-package/use-package-delight.el b/lisp/use-package/use-package-delight.el index 9d4f6acf2de..85d5c7cb4d6 100644 --- a/lisp/use-package/use-package-delight.el +++ b/lisp/use-package/use-package-delight.el @@ -1,4 +1,4 @@ -;;; use-package-delight.el --- Support for the :delight keyword +;;; use-package-delight.el --- Support for the :delight keyword -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley @@ -52,7 +52,7 @@ ":delight expects `delight' arguments or a list of them")))) ;;;###autoload -(defun use-package-normalize/:delight (name keyword args) +(defun use-package-normalize/:delight (name _keyword args) "Normalize arguments to delight." (cond ((null args) `((,(use-package-as-mode name) nil ,name))) @@ -77,7 +77,7 @@ args))))) ;;;###autoload -(defun use-package-handler/:delight (name keyword args rest state) +(defun use-package-handler/:delight (name _keyword args rest state) (let ((body (use-package-process-keywords name rest state))) (use-package-concat body diff --git a/lisp/use-package/use-package-diminish.el b/lisp/use-package/use-package-diminish.el index c2da62257e6..1f3895f42cd 100644 --- a/lisp/use-package/use-package-diminish.el +++ b/lisp/use-package/use-package-diminish.el @@ -1,4 +1,4 @@ -;;; use-package-diminish.el --- Support for the :diminish keyword +;;; use-package-diminish.el --- Support for the :diminish keyword -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley @@ -62,7 +62,7 @@ (apply-partially #'use-package-normalize-diminish name) t)) ;;;###autoload -(defun use-package-handler/:diminish (name keyword arg rest state) +(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) diff --git a/lisp/use-package/use-package-ensure-system-package.el b/lisp/use-package/use-package-ensure-system-package.el index e4b3e32b547..476a4f2b930 100644 --- a/lisp/use-package/use-package-ensure-system-package.el +++ b/lisp/use-package/use-package-ensure-system-package.el @@ -1,4 +1,4 @@ -;;; use-package-ensure-system-package.el --- auto install system packages -*- lexical: t; -*- +;;; use-package-ensure-system-package.el --- auto install system packages -*- lexical-binding: t; -*- ;; Copyright (C) 2017 Justin Talbott @@ -43,10 +43,10 @@ (use-package-ensure-system-package-install-command (symbol-name (cdr arg)))))))) ;;;###autoload -(defun use-package-normalize/:ensure-system-package (name-symbol keyword args) +(defun use-package-normalize/:ensure-system-package (_name-symbol keyword args) "Turn `arg' into a list of cons-es of (`package-name' . `install-command')." (use-package-only-one (symbol-name keyword) args - (lambda (label arg) + (lambda (_label arg) (cond ((and (listp arg) (listp (cdr arg))) (mapcar #'use-package-ensure-system-package-consify arg)) @@ -54,7 +54,7 @@ (list (use-package-ensure-system-package-consify arg))))))) ;;;###autoload -(defun use-package-handler/:ensure-system-package (name keyword arg rest state) +(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 diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index 1a76b883e1c..50005a9e990 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -1,4 +1,4 @@ -;;; use-package-ensure.el --- Support for the :ensure and :pin keywords +;;; use-package-ensure.el --- Support for the :ensure and :pin keywords -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley @@ -76,9 +76,9 @@ The default value uses package.el to install the package." ;;;; :pin -(defun use-package-normalize/:pin (name keyword args) +(defun use-package-normalize/:pin (_name keyword args) (use-package-only-one (symbol-name keyword) args - #'(lambda (label arg) + #'(lambda (_label arg) (cond ((stringp arg) arg) ((use-package-non-nil-symbolp arg) (symbol-name arg)) @@ -116,7 +116,7 @@ manually updated package." (unless (bound-and-true-p package--initialized) (package-initialize t)))) -(defun use-package-handler/:pin (name keyword archive-name rest state) +(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) @@ -133,11 +133,11 @@ manually updated package." (defvar package-archive-contents) ;;;###autoload -(defun use-package-normalize/:ensure (name keyword args) +(defun use-package-normalize/:ensure (_name keyword args) (if (null args) (list t) (use-package-only-one (symbol-name keyword) args - #'(lambda (label arg) + #'(lambda (_label arg) (cond ((symbolp arg) (list arg)) @@ -152,7 +152,7 @@ manually updated package." (concat ":ensure wants an optional package name " "(an unquoted symbol name), or ( :pin )")))))))) -(defun use-package-ensure-elpa (name args state &optional no-refresh) +(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)) @@ -183,7 +183,7 @@ manually updated package." :error)))))))) ;;;###autoload -(defun use-package-handler/:ensure (name keyword ensure rest state) +(defun use-package-handler/:ensure (name _keyword ensure rest state) (let* ((body (use-package-process-keywords name rest state))) ;; We want to avoid installing packages when the `use-package' macro is ;; being macro-expanded by elisp completion (see `lisp--local-variables'), diff --git a/lisp/use-package/use-package-jump.el b/lisp/use-package/use-package-jump.el index 31d1b054060..4044ad16564 100644 --- a/lisp/use-package/use-package-jump.el +++ b/lisp/use-package/use-package-jump.el @@ -1,4 +1,4 @@ -;;; use-package-jump.el --- Attempt to jump to a use-package declaration +;;; use-package-jump.el --- Attempt to jump to a use-package declaration -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley diff --git a/lisp/use-package/use-package-lint.el b/lisp/use-package/use-package-lint.el index 53c682842f9..c6e7c3c0ce2 100644 --- a/lisp/use-package/use-package-lint.el +++ b/lisp/use-package/use-package-lint.el @@ -1,4 +1,4 @@ -;;; use-package-lint.el --- Attempt to find errors in use-package declarations +;;; use-package-lint.el --- Attempt to find errors in use-package declarations -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 5f98db1bed7..1a8fff895f6 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1,4 +1,4 @@ -;;; use-package.el --- A configuration macro for simplifying your .emacs +;;; use-package.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*- ;; Copyright (C) 2012-2017 John Wiegley diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index fc86fa63f81..55d9959fb10 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1,4 +1,4 @@ -;;; use-package-tests.el --- Tests for use-package.el +;;; use-package-tests.el --- Tests for use-package.el -*- lexical-binding: t; -*- ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as From 09b7e8e12985a059cccaf804e66cdc7f970778ab Mon Sep 17 00:00:00 2001 From: Alex Branham Date: Tue, 22 May 2018 11:41:21 -0500 Subject: [PATCH 501/606] Fix use-package-normalize-function tests --- test/lisp/use-package/use-package-tests.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 55d9959fb10..c4030b04608 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -132,9 +132,9 @@ (should (equal (use-package-normalize-function t) t)) (should (equal (use-package-normalize-function 'sym) 'sym)) (should (equal (use-package-normalize-function #'sym) 'sym)) - (should (equal (use-package-normalize-function (lambda () ...)) (lambda () ...))) - (should (equal (use-package-normalize-function '(lambda () ...)) (lambda () ...))) - (should (equal (use-package-normalize-function #'(lambda () ...)) (lambda () ...))) + (should (equal (use-package-normalize-function '(lambda () ...)) '(lambda () ...))) + (should (equal (use-package-normalize-function ''(lambda () ...)) '(lambda () ...))) + (should (equal (use-package-normalize-function '#'(lambda () ...)) '(lambda () ...))) (should (equal (use-package-normalize-function 1) 1)) (should (equal (use-package-normalize-function "Hello") "Hello")) From bdd7fd35653f12aa74fb883136bacb09b87efa39 Mon Sep 17 00:00:00 2001 From: Alex Branham Date: Tue, 22 May 2018 12:37:28 -0500 Subject: [PATCH 502/606] Fix use-package-normalize-function --- lisp/use-package/use-package-core.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 9f7828f43ef..525b478313b 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -920,7 +920,7 @@ If RECURSED is non-nil, recurse into sublists." (eq 'lambda (car v))) v) ((and (listp v) - (memq '(quote function) (car v)) + (memq (car v) '(quote function)) (eq 'lambda (car (cadr v)))) (cadr v)) (t v))) From 38dcba687213f65682cbe1afaa60f779c8f5a0c3 Mon Sep 17 00:00:00 2001 From: Russell Black Date: Thu, 28 Jun 2018 20:40:58 -0600 Subject: [PATCH 503/606] Place :chords at beginning of use-package-keywords When it is at the end, the keys don't get bound until after the package has been loaded, which is bad. Placing it at the beginning allows the key bindings to be mapped to auto-loaded functions before the package is loaded, so that a key chord press triggers the package load. --- lisp/use-package/use-package-chords.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-chords.el b/lisp/use-package/use-package-chords.el index 478759d10c3..909056fbebe 100644 --- a/lisp/use-package/use-package-chords.el +++ b/lisp/use-package/use-package-chords.el @@ -37,7 +37,7 @@ `(,(macroexpand `(bind-chords :package ,name ,@arg))))) -(add-to-list 'use-package-keywords :chords t) +(add-to-list 'use-package-keywords :chords) (provide 'use-package-chords) From 2a8c2ffea2073ac0b23d201b6a9c5cf074c86645 Mon Sep 17 00:00:00 2001 From: Justin Talbott Date: Mon, 9 Jul 2018 17:47:42 -0400 Subject: [PATCH 504/606] allow :ensure-system-package to check the presence of files at path closes https://github.com/jwiegley/use-package/issues/660 --- lisp/use-package/use-package-ensure-system-package.el | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-ensure-system-package.el b/lisp/use-package/use-package-ensure-system-package.el index 476a4f2b930..eaf6de79a12 100644 --- a/lisp/use-package/use-package-ensure-system-package.el +++ b/lisp/use-package/use-package-ensure-system-package.el @@ -53,13 +53,20 @@ (t (list (use-package-ensure-system-package-consify arg))))))) +(defun use-package-ensure-system-package-exists? (file-or-exe) + "If variable 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 (executable-find (symbol-name ',(car cons))) + `(unless (use-package-ensure-system-package-exists? ',(car cons)) (async-shell-command ,(cdr cons)))) arg) body))) From 607879e6478c74f0f0468d7346f13073afdb19fd Mon Sep 17 00:00:00 2001 From: Justin Talbott Date: Mon, 13 Aug 2018 15:15:42 -0400 Subject: [PATCH 505/606] prefix argument with _ to suppress Unused lexical argument warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit per @tarsius’s comment https://github.com/jwiegley/use-package/commit/5d9c854a6cf12fff2326ee5653e87e2d3d550a8d#commitcomment-29996666 --- lisp/use-package/use-package-chords.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-chords.el b/lisp/use-package/use-package-chords.el index 909056fbebe..547adc27427 100644 --- a/lisp/use-package/use-package-chords.el +++ b/lisp/use-package/use-package-chords.el @@ -30,7 +30,7 @@ (defalias 'use-package-normalize/:chords 'use-package-normalize-binder) ;;;###autoload -(defun use-package-handler/:chords (name keyword arg rest state) +(defun use-package-handler/:chords (name _keyword arg rest state) "Handler for `:chords' keyword in `use-package'." (use-package-concat (use-package-process-keywords name rest state) From ca39ed155f2ac4e127b0c5787cf0f1598ff93da7 Mon Sep 17 00:00:00 2001 From: Laurence Rochfort Date: Wed, 12 Sep 2018 17:53:26 +0100 Subject: [PATCH 506/606] [] Install system packages using system-packages-install :ensure-system-package was installing packages by running system-packages-get-command via async-shell-command. This meant that system-packages-use-sudo wasn't being honoured. This patch makes :ensure-system-package use system-packages-install for all cases, except where a custom install command is supplied, in which case async-shell-command is used. This issue was introduced in 9f034a0bcfdd8c4 [https://github.com/jwiegley/use-package/issues/673], as a fix for [https://github.com/jwiegley/use-package/issues/661]. Prior to that commit, system-packages-use-sudo was being honoured. This patch also fixes a bug where a cons containing a lone symbol in a list of conses causes nil to used as the package to install. GitHub-reference: fix https://github.com/jwiegley/use-package/issues/720 Copyright-paperwork-exempt: yes --- .../use-package-ensure-system-package.el | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/lisp/use-package/use-package-ensure-system-package.el b/lisp/use-package/use-package-ensure-system-package.el index eaf6de79a12..87abf407020 100644 --- a/lisp/use-package/use-package-ensure-system-package.el +++ b/lisp/use-package/use-package-ensure-system-package.el @@ -5,7 +5,7 @@ ;; Author: Justin Talbott ;; Keywords: convenience, tools, extensions ;; URL: https://github.com/waymondo/use-package-ensure-system-package -;; Version: 0.1 +;; Version: 0.2 ;; Package-Requires: ((use-package "2.1") (system-packages "1.0.4")) ;; Filename: use-package-ensure-system-package.el ;; License: GNU General Public License version 3, or (at your option) any later version @@ -25,22 +25,23 @@ (eval-when-compile (declare-function system-packages-get-command "system-packages")) -(defun use-package-ensure-system-package-install-command (pack) - "Return the default install command for PACK." - (system-packages-get-command 'install pack)) (defun use-package-ensure-system-package-consify (arg) "Turn `arg' into a cons of (`package-name' . `install-command')." (cond ((stringp arg) - (cons arg (use-package-ensure-system-package-install-command arg))) + (cons arg `(system-packages-install ,arg))) ((symbolp arg) - (cons arg (use-package-ensure-system-package-install-command (symbol-name arg)))) + (cons arg `(system-packages-install ,(symbol-name arg)))) ((consp arg) - (if (stringp (cdr arg)) - arg + (cond + ((not (cdr arg)) + (use-package-ensure-system-package-consify (car arg))) + ((stringp (cdr arg)) + (cons (car arg) `(async-shell-command ,(cdr arg)))) + (t (cons (car arg) - (use-package-ensure-system-package-install-command (symbol-name (cdr arg)))))))) + `(system-packages-install ,(symbol-name (cdr arg))))))))) ;;;###autoload (defun use-package-normalize/:ensure-system-package (_name-symbol keyword args) @@ -60,6 +61,7 @@ If it is a symbol, ensure the binary exist." (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'." @@ -67,7 +69,7 @@ If it is a symbol, ensure the binary exist." (use-package-concat (mapcar #'(lambda (cons) `(unless (use-package-ensure-system-package-exists? ',(car cons)) - (async-shell-command ,(cdr cons)))) arg) + ,(cdr cons))) arg) body))) (add-to-list 'use-package-keywords :ensure-system-package t) From fc6fef68692d1a9802a836e13168ebc72b30f36d Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Sat, 10 Nov 2018 18:52:37 +0100 Subject: [PATCH 507/606] Silence byte-compiler on Emacs 25 Emacs 25 defined a global variable `features', which triggers a warning "Lexical argument shadows the dynamic variable features". That's not `use-package's fault, but we should suppress the warning anyway, so that there is no additional noise that would cause us to potentially overlook warnings that absolutely have to be addressed. --- lisp/use-package/use-package-core.el | 46 ++++++++++++++-------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 525b478313b..51746b3fff6 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1315,41 +1315,41 @@ meaning: args (list args))) -(defun use-package-after-count-uses (features) +(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) + (cond ((use-package-non-nil-symbolp features*) 1) - ((and (consp features) - (memq (car features) '(:or :any))) + ((and (consp features*) + (memq (car features*) '(:or :any))) (let ((num 0)) - (cl-dolist (next (cdr features)) + (cl-dolist (next (cdr features*)) (setq num (+ num (use-package-after-count-uses next)))) num)) - ((and (consp features) - (memq (car features) '(:and :all))) + ((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))))) + (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 +(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))) + ((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)) + (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)))) + ((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)) From 95f24f962896eea34b5b8cb23a9ca7c9254dd5eb Mon Sep 17 00:00:00 2001 From: Andrew Stribblehill Date: Thu, 4 Apr 2019 11:19:52 +0200 Subject: [PATCH 508/606] Add a line of documentation for (use-pacakage ... :hook) Copyright-paperwork-exempt: yes --- lisp/use-package/use-package-core.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 7fc840f0a94..fec50fd4bb8 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1533,6 +1533,7 @@ this file. Usage: 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. +: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, @@ -1542,7 +1543,7 @@ this file. Usage: :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', + `: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. From 8fe0ac2983d7f608c554c46fd4231ddbbc8b5526 Mon Sep 17 00:00:00 2001 From: Naoya Yamashita Date: Sun, 14 Apr 2019 19:30:42 +0900 Subject: [PATCH 509/606] * use-package-core.el (use-package): fix declare style use-package specified lisp-indent-function to indent like defun. Currently, use-package main macro specify indent as (declare (indent 1)), then change indent mode like defun. (declare (indent defun)) is same effect. And it is useful when redefining use-package. --- lisp/use-package/use-package-core.el | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index fec50fd4bb8..99ddc56eb45 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1562,7 +1562,7 @@ this file. Usage: :custom-face Call `customize-set-faces' with each face definition. :ensure Loads the package using package.el if necessary. :pin Pin the package to an archive." - (declare (indent 1)) + (declare (indent defun)) (unless (memq :disabled args) (macroexp-progn (use-package-concat @@ -1581,8 +1581,6 @@ this file. Usage: (when use-package-compute-statistics `((use-package-statistics-gather :use-package ',name t))))))) -(put 'use-package 'lisp-indent-function 'defun) - (provide 'use-package-core) ;; Local Variables: From c297dfdd20be463106376ff3da8677138d099718 Mon Sep 17 00:00:00 2001 From: Vincent Zhang Date: Wed, 29 May 2019 16:04:35 +0800 Subject: [PATCH 510/606] Make custom-face evaluate elisp Fix https://github.com/jwiegley/use-package/issues/696. Copyright-paperwork-exempt: yes --- lisp/use-package/use-package-core.el | 2 +- test/lisp/use-package/use-package-tests.el | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index fec50fd4bb8..7b4d26ba2a3 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1419,7 +1419,7 @@ no keyword implies `:all'." (defun use-package-handler/:custom-face (name _keyword args rest state) "Generate use-package custom-face keyword code." (use-package-concat - (mapcar #'(lambda (def) `(custom-set-faces (quote ,def))) args) + (mapcar #'(lambda (def) `(custom-set-faces (backquote ,def))) args) (use-package-process-keywords name rest state))) ;;;; :init diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index c4030b04608..3e3e5a72a13 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1125,7 +1125,7 @@ (match-expansion (use-package foo :custom-face (foo ((t (:background "#e4edfc"))))) `(progn - (custom-set-faces '(foo ((t (:background "#e4edfc"))))) + (custom-set-faces (backquote (foo ((t (:background "#e4edfc")))))) (require 'foo nil nil)))) (ert-deftest use-package-test/:init-1 () From 4149ec6cfa11cf094f914539ac6915e0d874559f Mon Sep 17 00:00:00 2001 From: Justin Talbott Date: Sat, 9 Feb 2019 20:52:50 -0500 Subject: [PATCH 511/606] use `use-package-as-one` for normalizing `:ensure-system-package` This makes the preferred syntax consistent with other `use-package` keywords. All of these are now valid: ``` (use-package format-all :ensure-system-package (prettier . "npm i -g prettier") (rufo . "gem install rufo")) (use-package format-all :ensure-system-package ((prettier . "npm i -g prettier") (rufo . "gem install rufo"))) (use-package format-all :ensure-system-package (prettier . "npm i -g prettier")) ``` --- lisp/use-package/use-package-ensure-system-package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-ensure-system-package.el b/lisp/use-package/use-package-ensure-system-package.el index 87abf407020..948d69df4ba 100644 --- a/lisp/use-package/use-package-ensure-system-package.el +++ b/lisp/use-package/use-package-ensure-system-package.el @@ -46,7 +46,7 @@ ;;;###autoload (defun use-package-normalize/:ensure-system-package (_name-symbol keyword args) "Turn `arg' into a list of cons-es of (`package-name' . `install-command')." - (use-package-only-one (symbol-name keyword) args + (use-package-as-one (symbol-name keyword) args (lambda (_label arg) (cond ((and (listp arg) (listp (cdr arg))) From 8ec41be4180ffba60d59bfe181e65df78d9e81f8 Mon Sep 17 00:00:00 2001 From: Justin Talbott Date: Fri, 14 Jun 2019 19:48:25 -0400 Subject: [PATCH 512/606] extract use-package-hook-handler-flatten-mode-symbols function --- lisp/use-package/use-package-core.el | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 7b4d26ba2a3..543cb80d186 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1266,9 +1266,13 @@ meaning: (concat (symbol-name sym) use-package-hook-name-suffix))) (function ,fun))) - (if (use-package-non-nil-symbolp syms) (list syms) syms))))) + (use-package-hook-handler-flatten-mode-symbols syms))))) (use-package-normalize-commands args)))) +(defun use-package-hook-handler-flatten-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) From 8f1a345b5bfd6bcf057ff558b2cffa3b047ad0fd Mon Sep 17 00:00:00 2001 From: Justin Talbott Date: Fri, 14 Jun 2019 20:00:16 -0400 Subject: [PATCH 513/606] rename function --- lisp/use-package/use-package-core.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 543cb80d186..4729e230165 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1266,10 +1266,10 @@ meaning: (concat (symbol-name sym) use-package-hook-name-suffix))) (function ,fun))) - (use-package-hook-handler-flatten-mode-symbols syms))))) + (use-package-hook-handler-normalize-mode-symbols syms))))) (use-package-normalize-commands args)))) -(defun use-package-hook-handler-flatten-mode-symbols (syms) +(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)) From 0d720a0f618fe2edfd7e7c547f422ae1d8b831c7 Mon Sep 17 00:00:00 2001 From: Justin Talbott Date: Thu, 20 Jun 2019 11:27:46 -0400 Subject: [PATCH 514/606] update bind-chords to use of eval-after-load when maps declared also improve :chord keyword syntax processing to more closely mimic bind-keys since the same binding normalizer is used. also add tests for use-package-chords to cover these test cases --- lisp/use-package/bind-chord.el | 81 ++++++--- lisp/use-package/use-package-chords.el | 6 +- .../use-package/use-package-chords-tests.el | 161 ++++++++++++++++++ 3 files changed, 225 insertions(+), 23 deletions(-) create mode 100644 test/lisp/use-package/use-package-chords-tests.el diff --git a/lisp/use-package/bind-chord.el b/lisp/use-package/bind-chord.el index e5184bff60e..f009b2b8b29 100644 --- a/lisp/use-package/bind-chord.el +++ b/lisp/use-package/bind-chord.el @@ -1,11 +1,11 @@ ;;; bind-chord.el --- key-chord binding helper for use-package-chords -;; Copyright (C) 2015-2017 Justin Talbott +;; Copyright (C) 2015-2019 Justin Talbott ;; Author: Justin Talbott ;; Keywords: convenience, tools, extensions -;; URL: https://github.com/waymondo/use-package-chords -;; Version: 0.2 +;; 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 @@ -30,6 +30,63 @@ (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. @@ -39,23 +96,7 @@ Accepts keyword argument: The rest of the arguments are conses of keybinding string and a function symbol (unquoted)." - (let* ((map (plist-get args :map)) - (maps (if (listp map) map (list map))) - (key-bindings (progn - (while (keywordp (car args)) - (pop args) - (pop args)) - args))) - (macroexp-progn - (apply - #'nconc - (mapcar (lambda (form) - (if maps - (mapcar - #'(lambda (m) - `(bind-chord ,(car form) ',(cdr form) ,m)) maps) - `((bind-chord ,(car form) ',(cdr form))))) - key-bindings))))) + (macroexp-progn (bind-chords-form args nil))) (provide 'bind-chord) diff --git a/lisp/use-package/use-package-chords.el b/lisp/use-package/use-package-chords.el index 547adc27427..cf390dbe593 100644 --- a/lisp/use-package/use-package-chords.el +++ b/lisp/use-package/use-package-chords.el @@ -1,11 +1,11 @@ ;;; use-package-chords.el --- key-chord keyword for use-package -*- lexical-binding: t; -*- -;; Copyright (C) 2015-2017 Justin Talbott +;; Copyright (C) 2015-2019 Justin Talbott ;; Author: Justin Talbott ;; Keywords: convenience, tools, extensions -;; URL: https://github.com/waymondo/use-package-chords -;; Version: 0.2 +;; URL: https://github.com/jwiegley/use-package +;; Version: 0.2.1 ;; Package-Requires: ((use-package "2.1") (bind-key "1.0") (bind-chord "0.2") (key-chord "0.6")) ;; Filename: use-package-chords.el ;; License: GNU General Public License version 3, or (at your option) any later version diff --git a/test/lisp/use-package/use-package-chords-tests.el b/test/lisp/use-package/use-package-chords-tests.el new file mode 100644 index 00000000000..3c3dc4b4fe0 --- /dev/null +++ b/test/lisp/use-package/use-package-chords-tests.el @@ -0,0 +1,161 @@ +;;; use-package-chords-tests.el --- Tests for use-package-chords.el -*- lexical-binding: t; -*- + +;; 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: + +;; + + +;;; Code: + +(require 'use-package) +(require 'use-package-tests) +(require 'use-package-chords) + +(defmacro match-expansion (form &rest value) + `(should (pcase (expand-minimally ,form) + ,@(mapcar #'(lambda (x) (list x t)) value)))) + +(defun use-package-test-normalize-chord (&rest args) + (apply #'use-package-normalize-binder 'foo :chords args)) + +(ert-deftest use-package-test-normalize/:chords-1 () + (should (equal (use-package-test-normalize-chord + '(("C-a" . alpha))) + '(("C-a" . alpha))))) + +(ert-deftest use-package-test-normalize/:chords-2 () + (should (equal (use-package-test-normalize-chord + '(("C-a" . alpha) + :map foo-map + ("C-b" . beta))) + '(("C-a" . alpha) + :map foo-map + ("C-b" . beta))))) + +(ert-deftest use-package-test-normalize/:chords-3 () + (should (equal (use-package-test-normalize-chord + '(:map foo-map + ("C-a" . alpha) + ("C-b" . beta))) + '(:map foo-map + ("C-a" . alpha) + ("C-b" . beta))))) + +(ert-deftest use-package-test/:chords-1 () + (match-expansion + (use-package foo :chords ("C-k" . key1) ("C-u" . key2)) + `(progn + (unless + (fboundp 'key1) + (autoload #'key1 "foo" nil t)) + (unless + (fboundp 'key2) + (autoload #'key2 "foo" nil t)) + (bind-chord "C-k" #'key1 nil) + (bind-chord "C-u" #'key2 nil)))) + +(ert-deftest use-package-test/:chords-2 () + (match-expansion + (use-package foo :chords (("C-k" . key1) ("C-u" . key2))) + `(progn + (unless (fboundp 'key1) + (autoload #'key1 "foo" nil t)) + (unless (fboundp 'key2) + (autoload #'key2 "foo" nil t)) + (bind-chord "C-k" #'key1 nil) + (bind-chord "C-u" #'key2 nil)))) + +(ert-deftest use-package-test/:chords-3 () + (match-expansion + (use-package foo :chords (:map my-map ("C-k" . key1) ("C-u" . key2))) + `(progn + (unless + (fboundp 'key1) + (autoload #'key1 "foo" nil t)) + (unless + (fboundp 'key2) + (autoload #'key2 "foo" nil t)) + (if + (boundp 'my-map) + (progn + (bind-chord "C-k" #'key1 my-map) + (bind-chord "C-u" #'key2 my-map)) + (eval-after-load 'foo + '(progn + (bind-chord "C-k" #'key1 my-map) + (bind-chord "C-u" #'key2 my-map))))))) + +(ert-deftest use-package-test/:chords-4 () + (should-error + (match-expansion + (use-package foo :chords :map my-map ("C-k" . key1) ("C-u" . key2)) + `(bind-chords :package foo)))) + +(ert-deftest use-package-test/:chords-5 () + (match-expansion + (use-package foo :chords ("C-k" . key1) (:map my-map ("C-u" . key2))) + `(progn + (unless (fboundp 'key1) + (autoload #'key1 "foo" nil t)) + (unless (fboundp 'key2) + (autoload #'key2 "foo" nil t)) + (progn + (bind-chord "C-k" #'key1 nil) + (if + (boundp 'my-map) + (bind-chord "C-u" #'key2 my-map) + (eval-after-load 'foo + '(bind-chord "C-u" #'key2 my-map))))))) + +(ert-deftest use-package-test/:chords-6 () + (match-expansion + (use-package foo + :chords + ("C-k" . key1) + (:map my-map ("C-u" . key2)) + (:map my-map2 ("C-u" . key3))) + `(progn + (unless + (fboundp 'key1) + (autoload #'key1 "foo" nil t)) + (unless + (fboundp 'key2) + (autoload #'key2 "foo" nil t)) + (unless + (fboundp 'key3) + (autoload #'key3 "foo" nil t)) + (progn + (bind-chord "C-k" #'key1 nil) + (if + (boundp 'my-map) + (bind-chord "C-u" #'key2 my-map) + (eval-after-load 'foo + '(bind-chord "C-u" #'key2 my-map))) + (if + (boundp 'my-map2) + (bind-chord "C-u" #'key3 my-map2) + (eval-after-load 'foo + '(bind-chord "C-u" #'key3 my-map2))))))) + +;; Local Variables: +;; indent-tabs-mode: nil +;; no-byte-compile: t +;; no-update-autoloads: t +;; End: + +;;; use-package-tests.el ends here From 27fd32c47bf23a996c4542aa9e7b14f451b94f17 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 12 Jul 2019 08:25:21 -0700 Subject: [PATCH 515/606] Use `require', not `load', when byte-compiling --- lisp/use-package/use-package-core.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 7b4d26ba2a3..b80da77fd81 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -651,7 +651,7 @@ extending any keys already present." ,(when (eq use-package-verbose 'debug) `(message ,(format "Compiling package %s" name-string))) ,(unless (plist-get args :no-require) - `(load ,name-string nil t))))))))) + `(require ',name-symbol))))))))) ;; Certain keywords imply :defer, if :demand was not specified. (when (and (not (plist-member args :demand)) From 4c8d5f0b21dbbf888aac988c2370c4626458f713 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 15 Jul 2019 22:11:13 -0700 Subject: [PATCH 516/606] Switch from `require' to `load' + `featurep' --- lisp/use-package/use-package-core.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index b80da77fd81..db5e20f7ddf 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -651,7 +651,8 @@ extending any keys already present." ,(when (eq use-package-verbose 'debug) `(message ,(format "Compiling package %s" name-string))) ,(unless (plist-get args :no-require) - `(require ',name-symbol))))))))) + `(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)) From 20415fb9be8c7f0940c78aa163450109836344ec Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Mon, 15 Jul 2019 22:20:18 -0700 Subject: [PATCH 517/606] Update tests --- test/lisp/use-package/use-package-tests.el | 66 ++++++++++++++-------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 3e3e5a72a13..04a653e30e8 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -162,7 +162,8 @@ (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t))) + (unless (featurep 'foo) + (load "foo" nil t)))) (t)) (require 'foo nil nil))))) @@ -182,7 +183,8 @@ (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t))) + (unless (featurep 'foo) + (load "foo" nil t)))) (preface)) (init) (require 'foo nil nil) @@ -206,7 +208,8 @@ (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t))) + (unless (featurep 'foo) + (load "foo" nil t)))) (preface)) (init) (eval-after-load 'foo @@ -453,7 +456,8 @@ (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))) + (unless (featurep 'foo) + (load "foo" nil t))))) (require 'foo nil nil))))) (ert-deftest use-package-test/:requires-3 () @@ -470,7 +474,8 @@ (eval-and-compile (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))) + (unless (featurep 'foo) + (load "foo" nil t))))) (require 'foo nil nil))))) (ert-deftest use-package-test/:load-path-1 () @@ -499,7 +504,8 @@ (eval-and-compile (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))) + (unless (featurep 'foo) + (load "foo" nil t))))) (require 'foo nil nil))))) (ert-deftest use-package-test/:load-path-3 () @@ -816,7 +822,8 @@ (eval-and-compile (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))) + (unless (featurep 'foo) + (load "foo" nil t))))) (unless (fboundp 'bar) (autoload #'bar "foo" nil t)) (eval-when-compile @@ -871,7 +878,8 @@ (eval-and-compile (eval-when-compile (with-demoted-errors "Cannot load gnus-harvest: %S" nil - (load "gnus-harvest" nil t)))) + (unless (featurep 'gnus-harvest) + (load "gnus-harvest" nil t))))) (eval-when-compile (declare-function gnus-harvest-install "gnus-harvest")) (require 'gnus-harvest nil nil) @@ -896,7 +904,8 @@ (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))) + (unless (featurep 'foo) + (load "foo" nil t))))) (require 'foo nil nil))))) (ert-deftest use-package-test/:functions-1 () @@ -914,7 +923,8 @@ (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))) + (unless (featurep 'foo) + (load "foo" nil t))))) (require 'foo nil nil))))) (ert-deftest use-package-test/:functions-3 () @@ -930,7 +940,8 @@ (declare-function bar "foo") (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t))))))) + (unless (featurep 'foo) + (load "foo" nil t)))))))) (ert-deftest use-package-test/:functions-5 () (let ((byte-compile-current-file t)) @@ -942,7 +953,8 @@ (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))) + (unless (featurep 'foo) + (load "foo" nil t))))) (eval-after-load 'foo '(progn (config) @@ -961,7 +973,8 @@ (eval-and-compile (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))) + (unless (featurep 'foo) + (load "foo" nil t))))) (require 'foo nil nil))))) (ert-deftest use-package-test/:defer-3 () @@ -976,7 +989,8 @@ `(eval-and-compile (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t))))))) + (unless (featurep 'foo) + (load "foo" nil t)))))))) (ert-deftest use-package-test-normalize/:hook () (flet ((norm (&rest args) @@ -1009,7 +1023,8 @@ (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))) + (unless (featurep 'foo) + (load "foo" nil t))))) (unless (fboundp 'key) (autoload #'key "foo" nil t)) @@ -1143,7 +1158,8 @@ (eval-and-compile (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))) + (unless (featurep 'foo) + (load "foo" nil t))))) (init) (require 'foo nil nil))))) @@ -1190,7 +1206,8 @@ (eval-and-compile (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))) + (unless (featurep 'foo) + (load "foo" nil t))))) (eval-after-load 'bar '(require 'foo nil nil)))))) @@ -1333,7 +1350,8 @@ (eval-and-compile (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))) + (unless (featurep 'foo) + (load "foo" nil t))))) (require 'foo nil nil))))) (ert-deftest use-package-test/:demand-3 () @@ -1352,7 +1370,8 @@ (eval-and-compile (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))) + (unless (featurep 'foo) + (load "foo" nil t))))) (require 'foo nil nil) (config) t)))) @@ -1372,7 +1391,8 @@ (eval-and-compile (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))) + (unless (featurep 'foo) + (load "foo" nil t))))) (eval-after-load 'bar '(require 'foo nil nil)))))) @@ -1425,7 +1445,8 @@ (eval-and-compile (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))) + (unless (featurep 'foo) + (load "foo" nil t))))) (require 'foo nil nil) (config) t)))) @@ -1446,7 +1467,8 @@ (eval-and-compile (eval-when-compile (with-demoted-errors "Cannot load foo: %S" nil - (load "foo" nil t)))) + (unless (featurep 'foo) + (load "foo" nil t))))) (eval-after-load 'foo '(progn (config) From 8c7fa11a3f60325d04db1856687ac7903aa77df5 Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Wed, 6 Nov 2019 13:49:46 +0100 Subject: [PATCH 518/606] Fix typos --- etc/USE-PACKAGE-NEWS | 2 +- lisp/use-package/bind-key.el | 2 +- lisp/use-package/use-package-core.el | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index 59366b9604c..3b39c01ceea 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -176,7 +176,7 @@ - For extension authors, there is a new customization variable `use-package-merge-key-alist` that specifies how values passed to multiple - occurences of the same key should be merged into a single value, during + occurrences of the same key should be merged into a single value, during normalization of the `use-package` declaration into a proper plist. The default behavior is to simply append the values together (since they are always normalized to lists). diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 5b375a54597..01e1d4d73d9 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -94,7 +94,7 @@ ;; ;; M-x describe-personal-keybindings ;; -;; This display will tell you if you've overriden a default keybinding, and +;; 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. diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index db5e20f7ddf..83b9b291345 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1029,7 +1029,7 @@ meaning: "use-package statistics" "Show current statistics gathered about use-package declarations." (setq tabulated-list-format - ;; The sum of column width is 80 caracters: + ;; The sum of column width is 80 characters: #[("Package" 25 t) ("Status" 13 t) ("Last Event" 23 t) From 3a58f53b14798c4ffa8a6863cf2ac44eaa347e83 Mon Sep 17 00:00:00 2001 From: Damien Cassou Date: Tue, 26 Nov 2019 21:28:51 +0100 Subject: [PATCH 519/606] Fix typos Typos found with codespell. --- doc/misc/use-package.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index dfd046f1b4b..63ed2954e58 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -919,7 +919,7 @@ While the @code{:after} keyword delays loading until the dependencies are loaded the somewhat simpler @code{:requires} keyword simply never loads the package if the dependencies are not available at the time the @code{use-package} declaration is encountered. By "available" in this context it means that @code{foo} is available -of @code{(featurep 'foo)} evaulates to a non-nil value. For example: +of @code{(featurep 'foo)} evaluates to a non-nil value. For example: @lisp (use-package abbrev From 8b8522650e8ebf54b13be6dad37320e166e4e75f Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 4 Mar 2020 16:29:16 -0800 Subject: [PATCH 520/606] Clarify the documentation for :after --- lisp/use-package/use-package-core.el | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 83b9b291345..c18877d5e66 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1548,9 +1548,11 @@ this file. Usage: `: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. -:after Defer loading of a package until after any of the named - features are loaded. -:demand Prevent deferred loading in all cases. +:after Delay the use-package declaration until after the named modules + have loaded. Once load, it will be as though the use-package + declaration (without `:after') had been seen at that moment. +:demand Prevent the automatic deferred loading introduced by constructs + such as `:bind' (see `:defer' for the complete list). :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. From f30d5761af12836844b2e3e8da11f649a31d8abf Mon Sep 17 00:00:00 2001 From: John Lee Date: Sat, 9 May 2020 19:01:01 +0100 Subject: [PATCH 521/606] Even when there's no :config, run any pre/post config hooks i.e., following the existing docs for use-package-inject-hooks, these hooks are run: use-package--foo--pre-config-hook use-package--foo--post-config-hook This should make config customisations more predictable (for example, spacemacs uses these hooks extensively to allow 'layers' to be customised). I got rid of the "special" default value for :config, because it doesn't seem to be treated any differently than nil. Fixes https://github.com/jwiegley/use-package/issues/785 Copyright-paperwork-exempt: yes --- lisp/use-package/use-package-core.el | 5 ++-- test/lisp/use-package/use-package-tests.el | 30 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index c18877d5e66..f547fcfa5ae 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -156,8 +156,7 @@ See also `use-package-defaults', which uses this value." :group 'use-package) (defcustom use-package-defaults - '(;; this '(t) has special meaning; see `use-package-handler/:config' - (:config '(t) t) + '((:config nil t) (:init nil t) (:catch t (lambda (name args) (not use-package-expand-minimally))) @@ -1468,7 +1467,7 @@ no keyword implies `:all'." (use-package-concat (when use-package-compute-statistics `((use-package-statistics-gather :config ',name nil))) - (if (or (null arg) (equal arg '(t))) + (if (and (null arg) (not use-package-inject-hooks)) body (use-package-with-elapsed-timer (format "Configuring package %s" name-symbol) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 04a653e30e8..d92a818cdbe 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1474,6 +1474,36 @@ (config) t)))))) +(ert-deftest use-package-test/pre-post-hooks-with-:config () + (let ((use-package-inject-hooks t)) + (match-expansion + (use-package foo :config (config)) + `(progn + (when + (run-hook-with-args-until-failure 'use-package--foo--pre-init-hook) + (run-hooks 'use-package--foo--post-init-hook)) + (require 'foo nil nil) + (when + (run-hook-with-args-until-failure 'use-package--foo--pre-config-hook) + (config) + (run-hooks 'use-package--foo--post-config-hook)) + t)))) + +(ert-deftest use-package-test/pre-post-hooks-without-:config () + ;; https://github.com/jwiegley/use-package/issues/785 + (let ((use-package-inject-hooks t)) + (match-expansion + (use-package foo) + `(progn + (when + (run-hook-with-args-until-failure 'use-package--foo--pre-init-hook) + (run-hooks 'use-package--foo--post-init-hook)) + (require 'foo nil nil) + (when + (run-hook-with-args-until-failure 'use-package--foo--pre-config-hook) + (run-hooks 'use-package--foo--post-config-hook)) + t)))) + (ert-deftest use-package-test-normalize/:diminish () (should (equal (use-package-normalize-diminish 'foopkg :diminish nil) '(foopkg-mode))) From 0ec4660f74e6a182ce8be207f0e9a4cc1a59b9a2 Mon Sep 17 00:00:00 2001 From: John Lee Date: Sat, 9 May 2020 23:35:15 +0100 Subject: [PATCH 522/606] Add special value back again, in case needed for backwards compat I don't know why this special value exists, but perhaps old client code uses it. The additional `t' in the macro expansion is accidental but not harmful I guess. Copyright-paperwork-exempt: yes --- lisp/use-package/use-package-core.el | 5 +++-- test/lisp/use-package/use-package-tests.el | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index f547fcfa5ae..220927b082b 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -156,7 +156,8 @@ See also `use-package-defaults', which uses this value." :group 'use-package) (defcustom use-package-defaults - '((:config nil t) + '(;; 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))) @@ -1467,7 +1468,7 @@ no keyword implies `:all'." (use-package-concat (when use-package-compute-statistics `((use-package-statistics-gather :config ',name nil))) - (if (and (null arg) (not use-package-inject-hooks)) + (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) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index d92a818cdbe..61438185373 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1501,6 +1501,7 @@ (require 'foo nil nil) (when (run-hook-with-args-until-failure 'use-package--foo--pre-config-hook) + t (run-hooks 'use-package--foo--post-config-hook)) t)))) From 44c837879e542e5200359d63b3cf647166f3862c Mon Sep 17 00:00:00 2001 From: Nahuel Greco Date: Wed, 20 May 2020 13:44:47 -0300 Subject: [PATCH 523/606] typo, should be a vector, not a bytecode object Solves https://github.com/jwiegley/use-package/issues/842 --- lisp/use-package/use-package-core.el | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index c18877d5e66..1d637dbf3d0 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1030,10 +1030,10 @@ meaning: "Show current statistics gathered about use-package declarations." (setq tabulated-list-format ;; The sum of column width is 80 characters: - #[("Package" 25 t) - ("Status" 13 t) - ("Last Event" 23 t) - ("Time" 10 t)]) + [("Package" 25 t) + ("Status" 13 t) + ("Last Event" 23 t) + ("Time" 10 t)]) (tabulated-list-init-header)) (defun use-package-statistics-gather (keyword name after) From 8c31c57106e2938d627bf4107627c003620d2dd5 Mon Sep 17 00:00:00 2001 From: Ted Zlatanov Date: Mon, 22 Jun 2020 14:17:21 -0400 Subject: [PATCH 524/606] use-package-core.el: use the Emacs set-default function to avoid saving :custom vars twice --- lisp/use-package/use-package-core.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index e81e229a2f0..169dbc455bc 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1394,7 +1394,9 @@ no keyword implies `:all'." (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))) + `(funcall (or (get (quote ,variable) 'custom-set) #'set-default) + (quote ,variable) + ,value))) args) (use-package-process-keywords name rest state))) From 950068809b81a911b121d41e8df0e561fb0675ac Mon Sep 17 00:00:00 2001 From: Jimmy Yuen Ho Wong Date: Tue, 9 Jun 2020 05:26:09 +0100 Subject: [PATCH 525/606] Support keymap symbol in bind-key GitHub-reference: fix https://github.com/jwiegley/use-package/issues/845 --- lisp/use-package/bind-key.el | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 01e1d4d73d9..fef23740c67 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -154,11 +154,13 @@ spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of COMMAND must be an interactive function or lambda form. -KEYMAP, if present, should be a keymap and not a quoted symbol. +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 @@ -171,10 +173,11 @@ can safely be called at any time." `(let* ((,namevar ,key-name) (,keyvar (if (vectorp ,namevar) ,namevar (read-kbd-macro ,namevar))) + (kmap (if (and ,keymap (symbolp ,keymap)) (symbol-value ,keymap) ,keymap)) (,kdescvar (cons (if (stringp ,namevar) ,namevar (key-description ,namevar)) - (quote ,keymap))) - (,bindingvar (lookup-key (or ,keymap global-map) ,keyvar))) + (if (symbolp ,keymap) ,keymap (quote ,keymap)))) + (,bindingvar (lookup-key (or kmap global-map) ,keyvar))) (let ((entry (assoc ,kdescvar personal-keybindings)) (details (list ,command (unless (numberp ,bindingvar) @@ -183,11 +186,11 @@ can safely be called at any time." (setcdr entry details) (add-to-list 'personal-keybindings (cons ,kdescvar details)))) ,(if predicate - `(define-key (or ,keymap global-map) ,keyvar + `(define-key (or kmap global-map) ,keyvar '(menu-item "" nil :filter (lambda (&optional _) (when ,predicate ,command)))) - `(define-key (or ,keymap global-map) ,keyvar ,command))))) + `(define-key (or kmap global-map) ,keyvar ,command))))) ;;;###autoload (defmacro unbind-key (key-name &optional keymap) From de49954965ae4ab61b440d63eb4c0bf302a09b7d Mon Sep 17 00:00:00 2001 From: Jimmy Yuen Ho Wong Date: Fri, 26 Jun 2020 02:22:46 +0100 Subject: [PATCH 526/606] add test for GitHub-reference: https://github.com/jwiegley/use-package/issues/845 --- test/lisp/use-package/use-package-tests.el | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 61438185373..5d346d94df3 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1936,6 +1936,12 @@ (define-prefix-command 'my/map) (bind-key "" 'my/map nil nil)))) +(defvar test-map (make-keymap)) + +(ert-deftest bind-key/845 () + (bind-key "C-c f" 'ignore 'test-map) + (describe-personal-keybindings)) + ;; Local Variables: ;; indent-tabs-mode: nil ;; no-byte-compile: t From 2ca2212f7312061c5462c8826774857e2455c1a8 Mon Sep 17 00:00:00 2001 From: Jimmy Yuen Ho Wong Date: Tue, 7 Jul 2020 14:17:00 +0100 Subject: [PATCH 527/606] better tests --- test/lisp/use-package/use-package-tests.el | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 5d346d94df3..f0784315f75 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1936,11 +1936,17 @@ (define-prefix-command 'my/map) (bind-key "" 'my/map nil nil)))) -(defvar test-map (make-keymap)) (ert-deftest bind-key/845 () - (bind-key "C-c f" 'ignore 'test-map) - (describe-personal-keybindings)) + (defvar test-map (make-keymap)) + (bind-key "" 'ignore 'test-map) + (should (eq (lookup-key test-map (kbd "")) 'ignore)) + (let ((binding (cl-find "" personal-keybindings :test 'string= :key 'caar))) + (message "test-map %s" test-map) + (message "binding %s" binding) + (should (eq (cdar binding) 'test-map)) + (should (eq (nth 1 binding) 'ignore)) + (should (eq (nth 2 binding) nil)))) ;; Local Variables: ;; indent-tabs-mode: nil From d3f847eaee1da6a87482b016bb916e0781082fd6 Mon Sep 17 00:00:00 2001 From: Jimmy Yuen Ho Wong Date: Wed, 8 Jul 2020 04:57:39 +0100 Subject: [PATCH 528/606] Fix broken test due to GitHub-reference: https://github.com/jwiegley/use-package/issues/850 --- lisp/use-package/use-package-core.el | 2 +- test/lisp/use-package/use-package-tests.el | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 169dbc455bc..94b8e451903 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1563,7 +1563,7 @@ this file. Usage: :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 `customize-set-variable' with each variable definition. +:custom Call `custom-set' or `set-default' with each variable definition. :custom-face Call `customize-set-faces' with each face definition. :ensure Loads the package using package.el if necessary. :pin Pin the package to an archive." diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 61438185373..1e89a5679ff 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1133,7 +1133,11 @@ (match-expansion (use-package foo :custom (foo bar)) `(progn - (customize-set-variable 'foo bar "Customized with use-package foo") + (funcall + (or + (get 'foo 'custom-set) + (function set-default)) + 'foo bar) (require 'foo nil nil)))) (ert-deftest use-package-test/:custom-face-1 () From 13b1e202bf48893116aa359e4681682d59e55a9e Mon Sep 17 00:00:00 2001 From: Ted Zlatanov Date: Sun, 12 Jul 2020 16:09:10 -0400 Subject: [PATCH 529/606] Update the documentation for :custom as per GitHub-reference: https://github.com/jwiegley/use-package/issues/850 --- lisp/use-package/use-package-core.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 94b8e451903..a36f73f0267 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1563,7 +1563,9 @@ this file. Usage: :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. +: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 `customize-set-faces' with each face definition. :ensure Loads the package using package.el if necessary. :pin Pin the package to an archive." From 5bd7e0ca7da922b4d518b25c86dd12ad1af5455a Mon Sep 17 00:00:00 2001 From: Philipp Stephani Date: Sun, 21 Jun 2020 19:46:12 +0200 Subject: [PATCH 530/606] Migrate remaining files to lexical binding --- lisp/use-package/bind-chord.el | 2 +- lisp/use-package/bind-key.el | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/bind-chord.el b/lisp/use-package/bind-chord.el index e5184bff60e..0cb6b01857c 100644 --- a/lisp/use-package/bind-chord.el +++ b/lisp/use-package/bind-chord.el @@ -1,4 +1,4 @@ -;;; bind-chord.el --- key-chord binding helper for use-package-chords +;;; bind-chord.el --- key-chord binding helper for use-package-chords -*- lexical-binding: t; -*- ;; Copyright (C) 2015-2017 Justin Talbott diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 01e1d4d73d9..bf5a379b0be 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -1,4 +1,4 @@ -;;; bind-key.el --- A simple way to manage personal keybindings +;;; bind-key.el --- A simple way to manage personal keybindings -*- lexical-binding: t; -*- ;; Copyright (c) 2012-2017 John Wiegley From 4938167bfffcf08279445827d2eaae78c9557675 Mon Sep 17 00:00:00 2001 From: Kaleb Elwert Date: Tue, 11 Aug 2020 01:44:31 -0700 Subject: [PATCH 531/606] Remove use-package-font-lock-keywords Copyright-paperwork-exempt: yes --- lisp/use-package/use-package-core.el | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index a36f73f0267..b5671ee249f 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -309,13 +309,6 @@ Must be set before loading use-package." lisp-imenu-generic-expression))))) :group 'use-package) -(defconst use-package-font-lock-keywords - '(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" - (1 font-lock-keyword-face) - (2 font-lock-constant-face nil t)))) - -(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords) - (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 From 215dd35e499f564f53a0baca9c2868d960fbacd4 Mon Sep 17 00:00:00 2001 From: Naoya Yamashita Date: Fri, 21 Aug 2020 15:15:34 +0900 Subject: [PATCH 532/606] add multiple and eval :custom-face usage This commit follows suggestion at https://github.com/jwiegley/use-package/issues/696, https://github.com/jwiegley/use-package/issues/821 --- test/lisp/use-package/use-package-tests.el | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 42bf07453b4..b3080b5dd3d 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1147,6 +1147,19 @@ (custom-set-faces (backquote (foo ((t (:background "#e4edfc")))))) (require 'foo nil nil)))) +(ert-deftest use-package-test/:custom-face-2 () + (match-expansion + (use-package example + :custom-face + (example-1-face ((t (:foreground "LightPink")))) + (example-2-face ((t (:foreground "LightGreen"))))) + `(progn + (custom-set-faces + (backquote (example-1-face ((t (:foreground "LightPink")))))) + (custom-set-faces + (backquote (example-2-face ((t (:foreground "LightGreen")))))) + (require 'example nil nil)))) + (ert-deftest use-package-test/:init-1 () (match-expansion (use-package foo :init (init)) From 99643f8873e4181df7c1f61fa2bfb7d3b432b9db Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 10 Nov 2020 13:33:45 -0800 Subject: [PATCH 533/606] Update version to 2.4.1 --- doc/misc/use-package.texi | 4 +- etc/USE-PACKAGE-NEWS | 83 ++++++++++++++++++++++++++++ lisp/use-package/use-package-core.el | 4 +- lisp/use-package/use-package.el | 2 +- 4 files changed, 88 insertions(+), 5 deletions(-) diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index 63ed2954e58..cad42bdfa28 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -30,7 +30,7 @@ General Public License for more details. @finalout @titlepage @title use-package User Manual -@subtitle for version 2.4 +@subtitle for version 2.4.1 @author John Wiegley @page @vskip 0pt plus 1filll @@ -262,7 +262,7 @@ C-h v use-package-version RET should display something like @example -use-package-version’s value is "2.4" +use-package-version’s value is "2.4.1" @end example If you are completely new to use-package then see @ref{Getting Started}. diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index 3b39c01ceea..1f516966980 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -1,5 +1,88 @@ # Changes +## 2.4.1 + +This is mostly a bug-fix release: + +- Update the documentation for :custom as per #850 + +- Fix broken test due to #850 + +- better tests + +- add test for #845 + +- Support keymap symbol in bind-key. Fix #845 + +- use-package-core.el: use the Emacs set-default function to avoid saving :custom vars twice + +- Fix Travis + +- typo, should be a vector, not a bytecode object + + Solves https://github.com/jwiegley/use-package/issues/842 + +- Add special value back again, in case needed for backwards compat + + I don't know why this special value exists, but perhaps old client code uses it. + + The additional `t' in the macro expansion is accidental but not harmful I guess. + +- Even when there's no :config, run any pre/post config hooks + + i.e., following the existing docs for use-package-inject-hooks, these hooks are + run: + + use-package--foo--pre-config-hook + use-package--foo--post-config-hook + + This should make config customisations more predictable (for example, spacemacs + uses these hooks extensively to allow 'layers' to be customised). + + I got rid of the "special" default value for :config, because it doesn't seem to + be treated any differently than nil. + + Fixes #785 + +- Clarify the documentation for :after + +- add table of contents to README + +- Fix typos + + Typos found with codespell. + +- Fix typos + +- Attempt to explain omit "-hook" better + +- Update tests + +- Switch from `require' to `load' + `featurep' + +- Use `require', not `load', when byte-compiling + +- Make custom-face evaluate elisp. + + Fix #696. + +- Add a line of documentation for (use-pacakage ... :hook). + +- Fix typo in README + +- Fix documentation for defer + +- Add no-query option for pdf-tools-install + +- Fix typo in README + +- Fix all notes in README + +- Mention use-package-ensure in README + + Without requiring `use-package-ensure`, setting `use-package-always-ensure` + did not actually work for me. + ## 2.4 ### Breaking changes diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index a36f73f0267..cd5b907a0b0 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -6,7 +6,7 @@ ;; Maintainer: John Wiegley ;; Created: 17 Jun 2012 ;; Modified: 29 Nov 2017 -;; Version: 2.4 +;; Version: 2.4.1 ;; Package-Requires: ((emacs "24.3")) ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package @@ -56,7 +56,7 @@ "A use-package declaration for simplifying your `.emacs'." :group 'startup) -(defconst use-package-version "2.4" +(defconst use-package-version "2.4.1" "This version of use-package.") (defcustom use-package-keywords diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 1a8fff895f6..0e194d5f182 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -6,7 +6,7 @@ ;; Maintainer: John Wiegley ;; Created: 17 Jun 2012 ;; Modified: 29 Nov 2017 -;; Version: 2.4 +;; Version: 2.4.1 ;; Package-Requires: ((emacs "24.3") (bind-key "2.4")) ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package From 8ef7978028c3edaf47fb40a84fee576c4355753f Mon Sep 17 00:00:00 2001 From: Ted Zlatanov Date: Sat, 22 Aug 2020 18:42:36 -0400 Subject: [PATCH 534/606] set saved-variable-comment from :custom GitHub-reference: https://github.com/jwiegley/use-package/issues/861 --- lisp/use-package/use-package-core.el | 3 ++- test/lisp/use-package/use-package-tests.el | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index cd5b907a0b0..540c7349db0 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1396,7 +1396,8 @@ no keyword implies `:all'." (setq comment (format "Customized with use-package %s" name))) `(funcall (or (get (quote ,variable) 'custom-set) #'set-default) (quote ,variable) - ,value))) + ,value) + `(put (quote ,variable) 'saved-variable-comment ,comment))) args) (use-package-process-keywords name rest state))) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 42bf07453b4..38c2025cac6 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1138,6 +1138,19 @@ (get 'foo 'custom-set) (function set-default)) 'foo bar) + (set 'foo 'saved-variable-comment "Customized with use-package foo") + (require 'foo nil nil)))) + +(ert-deftest use-package-test/:custom-with-comment1 () + (match-expansion + (use-package foo :custom (foo bar "commented")) + `(progn + (funcall + (or + (get 'foo 'custom-set) + (function set-default)) + 'foo bar) + (set 'foo 'saved-variable-comment "commented") (require 'foo nil nil)))) (ert-deftest use-package-test/:custom-face-1 () From 3e24a7363b2966776c8e5145acf3d918ae1f5c6e Mon Sep 17 00:00:00 2001 From: Ted Zlatanov Date: Sun, 8 Nov 2020 14:58:08 +0000 Subject: [PATCH 535/606] Revert "use-package-core.el: use the Emacs set-default function to avoid saving :custom vars twice" This reverts commit 8c31c57106e2938d627bf4107627c003620d2dd5. --- lisp/use-package/use-package-core.el | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 540c7349db0..be43c65cd4f 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1394,10 +1394,7 @@ no keyword implies `:all'." (comment (nth 2 def))) (unless (and comment (stringp comment)) (setq comment (format "Customized with use-package %s" name))) - `(funcall (or (get (quote ,variable) 'custom-set) #'set-default) - (quote ,variable) - ,value) - `(put (quote ,variable) 'saved-variable-comment ,comment))) + `(customize-set-variable (quote ,variable) ,value ,comment))) args) (use-package-process-keywords name rest state))) From 5ceb51ae198cca77cdf911feee81924d800bdd75 Mon Sep 17 00:00:00 2001 From: Ted Zlatanov Date: Sun, 8 Nov 2020 14:59:58 +0000 Subject: [PATCH 536/606] set property theme-value to avoid saving variable --- lisp/use-package/use-package-core.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index be43c65cd4f..933e94aa2bd 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1394,7 +1394,8 @@ no keyword implies `:all'." (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))) + `(customize-set-variable (quote ,variable) ,value ,comment) + `(put ',variable 'theme-value '((use-package-synthetic-theme ignore-just-for-saving))))) args) (use-package-process-keywords name rest state))) From a3c310c11a9ec311a4028d7ce8da4c2fd204a46b Mon Sep 17 00:00:00 2001 From: Ted Zlatanov Date: Sun, 29 Nov 2020 12:23:02 +0000 Subject: [PATCH 537/606] Create new "use-package" themse and use it for :custom with custom-theme-set-variables --- lisp/use-package/use-package-core.el | 10 ++++++++-- test/lisp/use-package/use-package-tests.el | 21 +++++++++------------ 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 933e94aa2bd..c44c36f77fd 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -43,6 +43,11 @@ (require 'cl-lib) (require 'tabulated-list) +;; 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) + (if (and (eq emacs-major-version 24) (eq emacs-minor-version 3)) (defsubst hash-table-keys (hash-table) "Return a list of keys in HASH-TABLE." @@ -1394,8 +1399,9 @@ no keyword implies `:all'." (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) - `(put ',variable 'theme-value '((use-package-synthetic-theme ignore-just-for-saving))))) + `(let ((custom--inhibit-theme-enable nil)) + (custom-theme-set-variables 'use-package + '(,variable ,value nil () ,comment))))) args) (use-package-process-keywords name rest state))) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 38c2025cac6..a68491cfb7b 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1129,28 +1129,25 @@ ;; '((foo bar baz)))) )) + (ert-deftest use-package-test/:custom-1 () (match-expansion (use-package foo :custom (foo bar)) `(progn - (funcall - (or - (get 'foo 'custom-set) - (function set-default)) - 'foo bar) - (set 'foo 'saved-variable-comment "Customized with use-package foo") + (let + ((custom--inhibit-theme-enable nil)) + (custom-theme-set-variables 'use-package + '(foo bar nil nil "Customized with use-package foo"))) (require 'foo nil nil)))) (ert-deftest use-package-test/:custom-with-comment1 () (match-expansion (use-package foo :custom (foo bar "commented")) `(progn - (funcall - (or - (get 'foo 'custom-set) - (function set-default)) - 'foo bar) - (set 'foo 'saved-variable-comment "commented") + (let + ((custom--inhibit-theme-enable nil)) + (custom-theme-set-variables 'use-package + '(foo bar nil nil "commented"))) (require 'foo nil nil)))) (ert-deftest use-package-test/:custom-face-1 () From 6b7ab46e57127fdb7dc848d29199e6fc45a2f74b Mon Sep 17 00:00:00 2001 From: Ted Zlatanov Date: Sat, 9 Jan 2021 13:57:40 +0000 Subject: [PATCH 538/606] Remove use-package theme from global list of custom-enabled-themes * eval-when-compile for cases where use-package is only required at compile time * remove the 'use-package theme from custom-enabled-themes so e.g. (mapc #'disable-theme custom-enabled-themes) won't kill user settings. --- lisp/use-package/use-package-core.el | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index c44c36f77fd..9edcff0ea15 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -43,10 +43,15 @@ (require 'cl-lib) (require 'tabulated-list) -;; Declare a synthetic theme for :custom variables. -;; Necessary in order to avoid having those variables saved by custom.el. -(deftheme use-package) +(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)) (if (and (eq emacs-major-version 24) (eq emacs-minor-version 3)) (defsubst hash-table-keys (hash-table) From e3938e7b267a645891eb4c95860b1a24d30edb0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johann=20Kl=C3=A4hn?= Date: Wed, 3 Feb 2021 22:55:17 +0100 Subject: [PATCH 539/606] Use a single let binding when expanding consecutive :custom forms Copyright-paperwork-exempt: yes --- lisp/use-package/use-package-core.el | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 9edcff0ea15..72e080001b2 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1397,17 +1397,18 @@ no keyword implies `:all'." (defun use-package-handler/:custom (name _keyword args rest state) "Generate use-package custom keyword code." (use-package-concat - (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))) - `(let ((custom--inhibit-theme-enable nil)) - (custom-theme-set-variables 'use-package - '(,variable ,value nil () ,comment))))) - args) + `((let ((custom--inhibit-theme-enable nil)) + (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)))) (use-package-process-keywords name rest state))) ;;;; :custom-face From 2b9536f242ab2c408b9e87a04c1e6aad3596a073 Mon Sep 17 00:00:00 2001 From: Ted Zlatanov Date: Sat, 6 Feb 2021 10:16:10 +0000 Subject: [PATCH 540/606] Add use-package-use-theme and avoid missing theme errors --- lisp/use-package/use-package-core.el | 47 ++++++++++++++++------ test/lisp/use-package/use-package-tests.el | 8 ++++ 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 72e080001b2..28bc5a50ed0 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -135,6 +135,13 @@ 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' @@ -1397,18 +1404,34 @@ no keyword implies `:all'." (defun use-package-handler/:custom (name _keyword args rest state) "Generate use-package custom keyword code." (use-package-concat - `((let ((custom--inhibit-theme-enable nil)) - (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)))) + (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 diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index a68491cfb7b..3825aa36487 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1136,6 +1136,10 @@ `(progn (let ((custom--inhibit-theme-enable nil)) + (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 '(foo bar nil nil "Customized with use-package foo"))) (require 'foo nil nil)))) @@ -1146,6 +1150,10 @@ `(progn (let ((custom--inhibit-theme-enable nil)) + (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 '(foo bar nil nil "commented"))) (require 'foo nil nil)))) From ec750952f4cde13023554da3a94964f024ee4f71 Mon Sep 17 00:00:00 2001 From: Daniel Mendler Date: Wed, 10 Feb 2021 14:01:59 +0100 Subject: [PATCH 541/606] bind-key: Use new symbols for kmapvar --- lisp/use-package/bind-key.el | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index fef23740c67..13fd02ab89b 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -168,16 +168,19 @@ 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 (vectorp ,namevar) ,namevar (read-kbd-macro ,namevar))) - (kmap (if (and ,keymap (symbolp ,keymap)) (symbol-value ,keymap) ,keymap)) + (,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 (or kmap global-map) ,keyvar))) + (,bindingvar (lookup-key ,kmapvar ,keyvar))) (let ((entry (assoc ,kdescvar personal-keybindings)) (details (list ,command (unless (numberp ,bindingvar) @@ -186,11 +189,11 @@ can safely be called at any time." (setcdr entry details) (add-to-list 'personal-keybindings (cons ,kdescvar details)))) ,(if predicate - `(define-key (or kmap global-map) ,keyvar + `(define-key ,kmapvar ,keyvar '(menu-item "" nil :filter (lambda (&optional _) (when ,predicate ,command)))) - `(define-key (or kmap global-map) ,keyvar ,command))))) + `(define-key ,kmapvar ,keyvar ,command))))) ;;;###autoload (defmacro unbind-key (key-name &optional keymap) From 5ca7bc321d1684cf718c59088b785a5fc00fc276 Mon Sep 17 00:00:00 2001 From: Daniel Mendler Date: Wed, 10 Feb 2021 14:13:36 +0100 Subject: [PATCH 542/606] unbind-key: Ensure that keys are removed from the keymap * The removal from the keymap is performed by bind-key--remove * Use the same argument normalization as bind-key --- lisp/use-package/bind-key.el | 52 ++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 13fd02ab89b..1d611c2933c 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -199,17 +199,47 @@ can safely be called at any time." (defmacro unbind-key (key-name &optional keymap) "Unbind the given KEY-NAME, within the KEYMAP (if specified). See `bind-key' for more details." - `(progn - (bind-key ,key-name nil ,keymap) - (setq personal-keybindings - (cl-delete-if #'(lambda (k) - ,(if keymap - `(and (consp (car k)) - (string= (caar k) ,key-name) - (eq (cdar k) ',keymap)) - `(and (stringp (car k)) - (string= (car k) ,key-name)))) - personal-keybindings)))) + (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) From 40d25413319c893ba2519379cae072cef69236c2 Mon Sep 17 00:00:00 2001 From: Yurii Kholodkov Date: Tue, 16 Feb 2021 16:37:58 +0300 Subject: [PATCH 543/606] fix docstring. was: invalid function name Copyright-paperwork-exempt: yes --- lisp/use-package/use-package-core.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 28bc5a50ed0..962d950d458 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1597,7 +1597,7 @@ this file. Usage: :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 +: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 `customize-set-faces' with each face definition. From dbfb3484cddcb81400265e5885ac5c5b1c51bc87 Mon Sep 17 00:00:00 2001 From: Naoya Yamashita Date: Tue, 23 Feb 2021 02:49:18 +0900 Subject: [PATCH 544/606] add autoload keyword :autoload is similar to :command but this generate autoload statement as *no-interactive* function. --- lisp/use-package/use-package-core.el | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 28bc5a50ed0..e153b535156 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -94,6 +94,7 @@ ;; Any other keyword that also declares commands to be autoloaded (such as ;; :bind) must appear before this keyword. :commands + :autoload :init :defer :demand @@ -118,7 +119,8 @@ declaration is incorrect." (defcustom use-package-deferring-keywords '(:bind-keymap :bind-keymap* - :commands) + :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 @@ -1309,6 +1311,28 @@ meaning: (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) @@ -1570,6 +1594,7 @@ this file. Usage: 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. From a35b924054b553546f331513d2fcb0a29825affb Mon Sep 17 00:00:00 2001 From: Naoya Yamashita Date: Tue, 23 Feb 2021 03:10:45 +0900 Subject: [PATCH 545/606] add testcase --- test/lisp/use-package/use-package-tests.el | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 3825aa36487..28d4620ac1a 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -889,6 +889,12 @@ (gnus-harvest-install)) t)))) +(ert-deftest use-package-test/:autoload-1 () + (match-expansion + (use-package foo :autoload bar) + `(unless (fboundp 'bar) + (autoload #'bar "foo")))) + (ert-deftest use-package-test/:defines-1 () (match-expansion (use-package foo :defines bar) From 11b2184c8d2a2b31af2eeab888d2fbd7044275fb Mon Sep 17 00:00:00 2001 From: Philipp Stephani Date: Sun, 21 Jun 2020 19:48:03 +0200 Subject: [PATCH 546/606] =?UTF-8?q?Remove=20uses=20of=20deprecated=20?= =?UTF-8?q?=E2=80=98flet=E2=80=99=20macro?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead, use the non-deprecated ‘cl-flet’ and ‘cl-letf’ macros from the ‘cl-lib’ package. This also allows us to remove the ‘plist-delete’ helper function, which was only used to effectively un-deprecate ‘flet’. --- test/lisp/use-package/use-package-tests.el | 55 +++++++++------------- 1 file changed, 21 insertions(+), 34 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 3825aa36487..0bb86513c44 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -22,7 +22,7 @@ ;;; Code: -(require 'cl) +(require 'cl-lib) (require 'ert) (require 'use-package) @@ -99,20 +99,6 @@ (bind-key "C-c C-u" #'fix-expansion emacs-lisp-mode-map) -(eval-when-compile - (defun plist-delete (plist property) - "Delete PROPERTY from PLIST" - (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)) - - ;; `cl-flet' does not work for some of the mocking we do below, while `flet' - ;; always does. - (setplist 'flet (plist-delete (symbol-plist 'flet) 'byte-obsolete-info))) - (ert-deftest use-package-test-recognize-function () (should (use-package-recognize-function nil t)) (should-not (use-package-recognize-function nil)) @@ -232,9 +218,9 @@ (require 'foo nil nil)))) (ert-deftest use-package-test-normalize/:ensure () - (flet ((norm (&rest args) - (apply #'use-package-normalize/:ensure - 'foopkg :ensure args))) + (cl-flet ((norm (&rest args) + (apply #'use-package-normalize/:ensure + 'foopkg :ensure args))) (should (equal (norm '(t)) '(t))) (should (equal (norm '(nil)) '(nil))) (should (equal (norm '(sym)) '(sym))) @@ -333,11 +319,11 @@ (ert-deftest use-package-test/:ensure-11 () (let (tried-to-install) - (flet ((use-package-ensure-elpa - (name ensure state &optional no-refresh) - (when ensure - (setq tried-to-install name))) - (require (&rest ignore))) + (cl-letf (((symbol-function #'use-package-ensure-elpa) + (lambda (name ensure state &optional no-refresh) + (when ensure + (setq tried-to-install name)))) + ((symbol-function #'require) #'ignore)) (use-package foo :ensure t) (should (eq tried-to-install 'foo))))) @@ -737,9 +723,9 @@ (add-to-list 'interpreter-mode-alist '("interp" . fun))))) (ert-deftest use-package-test-normalize/:mode () - (flet ((norm (&rest args) - (apply #'use-package-normalize/:mode - 'foopkg :mode args))) + (cl-flet ((norm (&rest args) + (apply #'use-package-normalize/:mode + 'foopkg :mode args))) (should (equal (norm '(".foo")) '((".foo" . foopkg)))) (should (equal (norm '(".foo" ".bar")) @@ -993,9 +979,9 @@ (load "foo" nil t)))))))) (ert-deftest use-package-test-normalize/:hook () - (flet ((norm (&rest args) - (apply #'use-package-normalize/:hook - 'foopkg :hook args))) + (cl-flet ((norm (&rest args) + (apply #'use-package-normalize/:hook + 'foopkg :hook args))) (should-error (norm nil)) (should (equal (norm '(bar)) '((bar . foopkg)))) @@ -1117,9 +1103,9 @@ (add-hook 'emacs-lisp-mode-hook #'(lambda nil (function)))))))) (ert-deftest use-package-test-normalize/:custom () - (flet ((norm (&rest args) - (apply #'use-package-normalize/:custom - 'foopkg :custom args))) + (cl-flet ((norm (&rest args) + (apply #'use-package-normalize/:custom + 'foopkg :custom args))) (should-error (norm nil)) (should-error (norm '(bar))) ;; (should-error (norm '((foo bar baz quux)))) @@ -1818,7 +1804,7 @@ `(bind-key "C-c C-r" #'org-ref-helm-insert-cite-link override-global-map nil))) (ert-deftest use-package-test/560 () - (flet ((executable-find (name))) + (cl-letf (((symbol-function #'executable-find) #'ignore)) (let (notmuch-command) (match-expansion (use-package notmuch @@ -1929,7 +1915,8 @@ (use-package-expand-minimally t) debug-on-error warnings) - (flet ((display-warning (_ msg _) (push msg warnings))) + (cl-letf (((symbol-function #'display-warning) + (lambda (_ msg _) (push msg warnings)))) (progn (macroexpand-1 '(use-package ediff :defer t (setq my-var t))) From c09cb1301b8d2fe552d4806c9af5344309bc0c78 Mon Sep 17 00:00:00 2001 From: Jimmy Yuen Ho Wong Date: Sun, 7 Mar 2021 23:29:19 +0000 Subject: [PATCH 547/606] Fix void-variable use-package-enable-imenu-support --- lisp/use-package/use-package-core.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 28bc5a50ed0..7cde382e3bb 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -316,14 +316,15 @@ include support for finding `use-package' and `require' forms. Must be set before loading use-package." :type 'boolean :set - #'(lambda (_sym value) + #'(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))))) + lisp-imenu-generic-expression)))) + (set-default sym value)) :group 'use-package) (defconst use-package-font-lock-keywords From f3ff593a849c6f9663bcba864d7de8ea587901aa Mon Sep 17 00:00:00 2001 From: Jimmy Yuen Ho Wong Date: Sat, 13 Mar 2021 16:29:27 +0000 Subject: [PATCH 548/606] Properly sort use-package-statistics-report --- lisp/use-package/use-package-core.el | 47 ++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 28bc5a50ed0..879e61edc4a 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -998,11 +998,10 @@ If RECURSED is non-nil, recurse into sublists." (defun use-package-statistics-last-event (package) "Return the date when PACKAGE's status last changed. The date is returned as a string." - (format-time-string "%Y-%m-%d %a %H:%M" - (or (gethash :config package) - (gethash :init package) - (gethash :preface package) - (gethash :use-package package)))) + (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." @@ -1022,7 +1021,9 @@ The information is formatted in a way suitable for (vector (symbol-name package) (use-package-statistics-status statistics) - (use-package-statistics-last-event 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 () @@ -1042,15 +1043,43 @@ meaning: (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." (setq tabulated-list-format ;; The sum of column width is 80 characters: [("Package" 25 t) - ("Status" 13 t) - ("Last Event" 23 t) - ("Time" 10 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) From 1343783532e7e9f242818b5b8851069a7ca3faf9 Mon Sep 17 00:00:00 2001 From: Daniel Perez Alvarez Date: Sat, 17 Apr 2021 17:08:35 -0400 Subject: [PATCH 549/606] feat: add update custom packages command Copyright-paperwork-exempt: yes --- lisp/use-package/use-package-ensure-system-package.el | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-ensure-system-package.el b/lisp/use-package/use-package-ensure-system-package.el index 87abf407020..9899968877b 100644 --- a/lisp/use-package/use-package-ensure-system-package.el +++ b/lisp/use-package/use-package-ensure-system-package.el @@ -25,6 +25,8 @@ (eval-when-compile (declare-function system-packages-get-command "system-packages")) +(defvar use-package-ensure-system-package--custom-packages '() + "List of custom packages installed.") (defun use-package-ensure-system-package-consify (arg) "Turn `arg' into a cons of (`package-name' . `install-command')." @@ -38,11 +40,18 @@ ((not (cdr arg)) (use-package-ensure-system-package-consify (car arg))) ((stringp (cdr arg)) - (cons (car arg) `(async-shell-command ,(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 () + (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 `arg' into a list of cons-es of (`package-name' . `install-command')." From 24c50da3b272f571c320ef800a80c0bc0ce38e28 Mon Sep 17 00:00:00 2001 From: Troy Hinckley Date: Tue, 16 Jul 2019 08:29:09 -0700 Subject: [PATCH 550/606] Auto detect mode suffix in hook keyword --- lisp/use-package/use-package-core.el | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 28bc5a50ed0..a82e7b145c7 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1264,7 +1264,10 @@ meaning: (setq every nil))) every)))) #'use-package-recognize-function - name label arg)))) + (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) From ee292b80bebc2e7a4f3b32bd51363adbb28878d2 Mon Sep 17 00:00:00 2001 From: Troy Hinckley Date: Mon, 17 May 2021 18:33:28 -0600 Subject: [PATCH 551/606] Fix tests and documentation for hook --- test/lisp/use-package/use-package-tests.el | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 3825aa36487..b8063a046f5 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -998,15 +998,17 @@ 'foopkg :hook args))) (should-error (norm nil)) (should (equal (norm '(bar)) + '((bar . foopkg-mode)))) + (should (equal (norm '((bar . foopkg))) '((bar . foopkg)))) (should (equal (norm '((bar . baz))) '((bar . baz)))) (should (equal (norm '(((bar baz) . quux))) '(((bar baz) . quux)))) (should (equal (norm '(bar baz)) - '(((bar baz) . foopkg)))) + '(((bar baz) . foopkg-mode)))) (should (equal (norm '((bar baz) (quux bow))) - '(((bar baz) . foopkg) ((quux bow) . foopkg)))) + '(((bar baz) . foopkg-mode) ((quux bow) . foopkg-mode)))) (should (equal (norm '((bar . baz) (quux . bow))) '((bar . baz) (quux . bow)))) (should (equal (norm '(((bar1 bar2) . baz) ((quux1 quux2) . bow))) @@ -1945,9 +1947,9 @@ (use-package nonexistent :hook lisp-mode) `(when (locate-library nonexistent) - (unless (fboundp 'nonexistent) - (autoload #'nonexistent "nonexistent" nil t)) - (add-hook 'lisp-mode-hook #'nonexistent))))) + (unless (fboundp 'nonexistent-mode) + (autoload #'nonexistent-mode "nonexistent" nil t)) + (add-hook 'lisp-mode-hook #'nonexistent-mode))))) (ert-deftest bind-key/:prefix-map () (match-expansion From 2203246454fddd41e0a62e78b17befce561998b9 Mon Sep 17 00:00:00 2001 From: Hugo Heagren Date: Sun, 16 Jan 2022 00:21:36 +0000 Subject: [PATCH 552/606] bind-keys-form: new keyword :repeat-map, for defining repeat maps use-package-normalize/:bind: allow keyword :repeat-map. bind-keys-form: Add keyword :repeat-map. Specifying a symbol as the repeat-map defines a keymap with that name (and with the docstring `repeat-doc', if specified). Symbols for functions bound to keys under the scope of :repeat-map have their 'repeat-map property set to this map. Update docstring (and that of `bind-keys') to reflect changes. Rename `doc' to `prefix-doc' for clarity and consistency with 'repeat-doc'. --- lisp/use-package/bind-key.el | 36 +++++++++++++++++++++--- lisp/use-package/use-package-bind-key.el | 4 +++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 1d611c2933c..bb09a6935a8 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -257,14 +257,22 @@ Accepts keyword arguments: 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. :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 - doc + prefix-doc prefix-map prefix + repeat-map + repeat-doc filter menu-name pkg) @@ -276,11 +284,18 @@ function symbol (unquoted)." (not prefix-map)) (setq map (cadr args))) ((eq :prefix-docstring (car args)) - (setq doc (cadr 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 :prefix (car args)) (setq prefix (cadr args))) ((eq :filter (car args)) @@ -327,13 +342,16 @@ function symbol (unquoted)." (append (when prefix-map `((defvar ,prefix-map) - ,@(when doc `((put ',prefix-map 'variable-documentation ,doc))) + ,@(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) @@ -341,7 +359,11 @@ function symbol (unquoted)." (if prefix-map `((bind-key ,(car form) ,fun ,prefix-map ,filter)) (if (and map (not (eq map 'global-map))) - `((bind-key ,(car form) ,fun ,map ,filter)) + ;; Only needed in this branch, since when + ;; repeat-map is non-nil, map is always + ;; non-nil + `(,@(when repeat-map `((put ,fun 'repeat-map ',repeat-map))) + (bind-key ,(car form) ,fun ,map ,filter)) `((bind-key ,(car form) ,fun nil ,filter)))))) first)) (when next @@ -361,6 +383,12 @@ Accepts keyword arguments: 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. :filter FORM - optional form to determine when bindings apply The rest of the arguments are conses of keybinding string and a diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index e476b060ad6..d056d4266cc 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -86,6 +86,8 @@ deferred until the prefix key sequence is pressed." ;; :prefix-docstring STRING ;; :prefix-map SYMBOL ;; :prefix STRING + ;; :repeat-docstring STRING + ;; :repeat-map SYMBOL ;; :filter SEXP ;; :menu-name STRING ;; :package SYMBOL @@ -93,6 +95,8 @@ deferred until the prefix key sequence is pressed." (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))) + (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)))) From 5ef327ce9fc1397cdbbde8936eca37ae6383d787 Mon Sep 17 00:00:00 2001 From: Hugo Heagren Date: Mon, 17 Jan 2022 15:41:35 +0000 Subject: [PATCH 553/606] bind-key-form: allow :exit keyword inside repeat map Keys bound inside the scope of :exit are bound inside the repeat map, but do not have their repeat-map property set (so they run a function, but 'exit' the map). --- lisp/use-package/bind-key.el | 18 +++++++++++++++--- lisp/use-package/use-package-bind-key.el | 2 ++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index bb09a6935a8..a899aca0ffc 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -263,6 +263,9 @@ Accepts keyword arguments: '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. :filter FORM - optional form to determine when bindings apply The rest of the arguments are conses of keybinding string and a @@ -273,12 +276,14 @@ function symbol (unquoted)." prefix repeat-map repeat-doc + repeat-type ;; Only used internally filter menu-name pkg) ;; Process any initial keyword arguments - (let ((cont t)) + (let ((cont t) + (arg-change-func 'cddr)) (while (and cont args) (if (cond ((and (eq :map (car args)) (not prefix-map)) @@ -296,6 +301,9 @@ function symbol (unquoted)." override-global-map)))) (setq repeat-map (cadr args)) (setq map repeat-map)) + ((eq :exit (car args)) + (setq repeat-type :exit + arg-change-func 'cdr)) ((eq :prefix (car args)) (setq prefix (cadr args))) ((eq :filter (car args)) @@ -304,7 +312,7 @@ function symbol (unquoted)." (setq menu-name (cadr args))) ((eq :package (car args)) (setq pkg (cadr args)))) - (setq args (cddr args)) + (setq args (funcall arg-change-func args)) (setq cont nil)))) (when (or (and prefix-map (not prefix)) @@ -362,7 +370,8 @@ function symbol (unquoted)." ;; Only needed in this branch, since when ;; repeat-map is non-nil, map is always ;; non-nil - `(,@(when repeat-map `((put ,fun 'repeat-map ',repeat-map))) + `(,@(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)) @@ -389,6 +398,9 @@ Accepts keyword arguments: '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. :filter FORM - optional form to determine when bindings apply The rest of the arguments are conses of keybinding string and a diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index d056d4266cc..73ea8ca83e0 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -91,11 +91,13 @@ deferred until the prefix key sequence is pressed." ;; :filter SEXP ;; :menu-name STRING ;; :package SYMBOL + ;; :exit 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 :exit) (and (eq x :repeat-docstring) (stringp (cadr arg))) (eq x :filter) (and (eq x :menu-name) (stringp (cadr arg))) From c4bd2aa3b8094135c34c86893790f051cb5e1457 Mon Sep 17 00:00:00 2001 From: Hugo Heagren Date: Thu, 20 Jan 2022 10:59:37 +0000 Subject: [PATCH 554/606] bind-key-form: allow :continue keyword inside repeat map Purely syntactic sugar, using :continue is the same as not using any keyword inside :repeat-map at all. Amend end of function to pass repeat-map value onto next invocation in recursive uses. This allows for the same repeat map to be used for :exit and :continue. --- lisp/use-package/bind-key.el | 18 +++++++++++++++--- lisp/use-package/use-package-bind-key.el | 3 ++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index a899aca0ffc..87a33e3d6ca 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -266,6 +266,10 @@ Accepts keyword arguments: :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 @@ -301,6 +305,9 @@ function symbol (unquoted)." 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)) @@ -376,9 +383,10 @@ function symbol (unquoted)." `((bind-key ,(car form) ,fun nil ,filter)))))) first)) (when next - (bind-keys-form (if pkg - (cons :package (cons pkg next)) - next) map))))))) + (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) @@ -401,6 +409,10 @@ Accepts keyword arguments: :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 diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index 73ea8ca83e0..9642f311750 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -91,12 +91,13 @@ deferred until the prefix key sequence is pressed." ;; :filter SEXP ;; :menu-name STRING ;; :package SYMBOL - ;; :exit used within :repeat-map + ;; :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) From 1143f14d650c7201d7ddbcb7012dc2c9bf3b1824 Mon Sep 17 00:00:00 2001 From: Hugo Heagren Date: Fri, 28 Jan 2022 22:26:41 +0000 Subject: [PATCH 555/606] bind-keys-form: error for repeat sub-keywords without :repeat-map Error descriptively if :continue or :exit is specified without :repeat-map. --- lisp/use-package/bind-key.el | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 87a33e3d6ca..643094daa7f 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -326,6 +326,10 @@ function symbol (unquoted)." (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")) From 9be2580f5f26cc572d68a465c2fbe1159cc89a8d Mon Sep 17 00:00:00 2001 From: Wang Chunye Date: Fri, 20 Mar 2020 06:25:35 -0700 Subject: [PATCH 556/606] optimization: constand folding for read-kbd-macro to boost startup performance, it is better to avoid invoking `read-kbd-macro` at run time which requires 'cl-lib. it takes ~20ms to load cl-lib Copyright-paperwork-exempt: yes --- lisp/use-package/bind-key.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 1d611c2933c..919a1772131 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -172,8 +172,9 @@ can safely be called at any time." (kdescvar (make-symbol "kdesc")) (bindingvar (make-symbol "binding"))) `(let* ((,namevar ,key-name) - (,keyvar (if (vectorp ,namevar) ,namevar - (read-kbd-macro ,namevar))) + (,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)) From 30b35d6d62302133c8d9cab2fb26852a9010675f Mon Sep 17 00:00:00 2001 From: Damien Cassou Date: Mon, 4 Apr 2022 21:10:44 +0200 Subject: [PATCH 557/606] Update use-package.texi --- doc/misc/use-package.texi | 219 ++++++++++++++++++++++++-------------- 1 file changed, 137 insertions(+), 82 deletions(-) diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index cad42bdfa28..880af1203b6 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -17,8 +17,9 @@ later version. This document 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 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE@. See the GNU General Public License for more details. + @end quotation @end copying @@ -54,7 +55,8 @@ version 3 of the License, or (at your option) any later version. This document 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. +FOR A PARTICULAR PURPOSE@. See the GNU General Public License for more details. + @end quotation @end ifnottex @@ -62,6 +64,8 @@ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. * Introduction:: * Installation:: * Getting Started:: +* Basic Concepts:: +* Issues/Requests:: * Keywords:: * FAQ:: * Debugging Tools:: @@ -72,44 +76,39 @@ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @detailmenu --- The Detailed Node Listing --- - Installation * Installing from an Elpa Archive:: * Installing from the Git Repository:: * Post-Installation Tasks:: - - - Keywords -* @code{:after}: @code{after}. -* @code{:bind-keymap}, @code{:bind-keymap*}: @code{bind-keymap} @code{bind-keymap*}. -* @code{:bind}, @code{:bind*}: @code{bind} @code{bind*}. -* @code{:commands}: @code{commands}. -* @code{:preface}, @code{:init}, @code{:config}: @code{preface} @code{init} @code{config}. -* @code{:custom}: @code{custom}. -* @code{:custom-face}: @code{custom-face}. -* @code{:defer}, @code{:demand}: @code{defer} @code{demand}. -* @code{:defines}, @code{:functions}: @code{defines} @code{functions}. -* @code{:diminish}, @code{:delight}: @code{diminish} @code{delight}. -* @code{:disabled}: @code{disabled}. -* @code{:ensure}, @code{:pin}: @code{ensure} @code{pin}. -* @code{:hook}: @code{hook}. -* @code{:if}, @code{:when}, @code{:unless}: @code{if} @code{when} @code{unless}. -* @code{:load-path}: @code{load-path}. -* @code{:mode}, @code{:interpreter}: @code{mode} @code{interpreter}. -* @code{:magic}, @code{:magic-fallback}: @code{magic} @code{magic-fallback}. -* @code{:no-require}: @code{no-require}. -* @code{:requires}: @code{requires}. - - +* @code{after}:: +* @code{bind-keymap}, @code{bind-keymap*}: @code{bind-keymap} @code{bind-keymap*}. +* @code{bind}, @code{bind*}: @code{bind} @code{bind*}. +* @code{commands}:: +* @code{preface}, @code{init}, @code{config}: @code{preface} @code{init} @code{config}. +* @code{custom}:: +* @code{custom-face}:: +* @code{defer}, @code{demand}: @code{defer} @code{demand}. +* @code{defines}, @code{functions}: @code{defines} @code{functions}. +* @code{diminish}, @code{delight}: @code{diminish} @code{delight}. +* @code{disabled}:: +* @code{ensure}, @code{pin}: @code{ensure} @code{pin}. +* @code{hook}:: +* @code{if}, @code{when}, @code{unless}: @code{if} @code{when} @code{unless}. +* @code{load-path}:: +* @code{mode}, @code{interpreter}: @code{mode} @code{interpreter}. +* @code{magic}, @code{magic-fallback}: @code{magic} @code{magic-fallback}. +* @code{no-require}:: +* @code{requires}:: @code{:bind}, @code{:bind*} * Binding to local keymaps:: + FAQ * FAQ - How to @dots{}?:: @@ -123,21 +122,31 @@ FAQ - How to @dots{}? FAQ - Issues and Errors * This is an issues:: + + @end detailmenu @end menu @node Introduction @chapter Introduction -The @code{use-package} macro allows you to isolate package configuration -in your @file{.emacs} file in a way that is both performance-oriented and, -well, tidy. I created it because I have over 400 packages that I use in -Emacs, and things were getting difficult to manage. Yet with this utility -my total load time is around 2 seconds, with no loss of functionality! +The @code{use-package} macro allows you to isolate package configuration in your +@code{.emacs} file in a way that is both performance-oriented and, well, 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 +around 2 seconds, with no loss of functionality! + +More text to come@dots{} @node Installation @chapter Installation +@menu +* Installing from an Elpa Archive:: +* Installing from the Git Repository:: +* Post-Installation Tasks:: +@end menu + use-package can be installed using Emacs' package manager or manually from its development repository. @@ -163,7 +172,7 @@ To use Melpa: @lisp (require 'package) (add-to-list 'package-archives - '("melpa" . "https://melpa.org/packages/") t) + '("melpa" . "https://melpa.org/packages/") t) @end lisp @itemize @@ -174,7 +183,7 @@ To use Melpa-Stable: @lisp (require 'package) (add-to-list 'package-archives - '("melpa-stable" . "https://stable.melpa.org/packages/") t) + '("melpa-stable" . "https://stable.melpa.org/packages/") t) @end lisp Once you have added your preferred archive, you need to update the @@ -225,7 +234,7 @@ Finally add this to your init file: (with-eval-after-load 'info (info-initialize) (add-to-list 'Info-directory-list - "~/.emacs.d/site-lisp/use-package/")) + "~/.emacs.d/site-lisp/use-package/")) @end lisp Note that elements of @code{load-path} should not end with a slash, while those of @@ -267,37 +276,75 @@ use-package-version’s value is "2.4.1" If you are completely new to use-package then see @ref{Getting Started}. -If you run into problems, then please see the @ref{FAQ}. Also see the -@ref{Debugging Tools}. +If you run into problems, then please see the +@ref{FAQ}. Also see the @ref{Debugging Tools}. @node Getting Started @chapter Getting Started -TODO. For now, see @code{README.md}. +TODO@. For now, see @code{README.md}. + +@node Basic Concepts +@chapter Basic Concepts + +@code{use-package} was created for few basic reasons, each of which drove the +design in various ways. Understanding these reasons may help make some of +those decisions clearer: + +@itemize +@item +To gather all configuration details of a package into one place, making +it easier to copy, disable, or move it elsewhere in the init file. + + +@item +To reduce duplication and boilerplate, capturing several common practices +as mere keywords both easy and intuitive to use. + + +@item +To make startup time of Emacs as quick as possible, without sacrificing +the quantity of add-on packages used. + + +@item +To make it so errors encountered during startup disable only the package +raising the error, and as little else as possible, leaving a close to a +functional Emacs as possible. + + +@item +To allow byte-compilation of one's init file so that any warnings or +errors seen are meaningful. In this way, even if byte-compilation is not +used for speed (reason 3), it can still be used as a sanity check. +@end itemize + +@node Issues/Requests +@chapter Issues/Requests @node Keywords @chapter Keywords @menu -* @code{:after}: @code{after}. -* @code{:bind-keymap}, @code{:bind-keymap*}: @code{bind-keymap} @code{bind-keymap*}. -* @code{:bind}, @code{:bind*}: @code{bind} @code{bind*}. -* @code{:commands}: @code{commands}. -* @code{:preface}, @code{:init}, @code{:config}: @code{preface} @code{init} @code{config}. -* @code{:custom}: @code{custom}. -* @code{:custom-face}: @code{custom-face}. -* @code{:defer}, @code{:demand}: @code{defer} @code{demand}. -* @code{:defines}, @code{:functions}: @code{defines} @code{functions}. -* @code{:diminish}, @code{:delight}: @code{diminish} @code{delight}. -* @code{:disabled}: @code{disabled}. -* @code{:ensure}, @code{:pin}: @code{ensure} @code{pin}. -* @code{:hook}: @code{hook}. -* @code{:if}, @code{:when}, @code{:unless}: @code{if} @code{when} @code{unless}. -* @code{:load-path}: @code{load-path}. -* @code{:mode}, @code{:interpreter}: @code{mode} @code{interpreter}. -* @code{:magic}, @code{:magic-fallback}: @code{magic} @code{magic-fallback}. -* @code{:no-require}: @code{no-require}. -* @code{:requires}: @code{requires}. +* @code{after}:: +* @code{bind-keymap}, @code{bind-keymap*}: @code{bind-keymap} @code{bind-keymap*}. +* @code{bind}, @code{bind*}: @code{bind} @code{bind*}. +* @code{commands}:: +* @code{preface}, @code{init}, @code{config}: @code{preface} @code{init} @code{config}. +* @code{custom}:: +* @code{custom-face}:: +* @code{defer}, @code{demand}: @code{defer} @code{demand}. +* @code{defines}, @code{functions}: @code{defines} @code{functions}. +* @code{diminish}, @code{delight}: @code{diminish} @code{delight}. +* @code{disabled}:: +* @code{ensure}, @code{pin}: @code{ensure} @code{pin}. +* @code{hook}:: +* @code{if}, @code{when}, @code{unless}: @code{if} @code{when} @code{unless}. +* @code{load-path}:: +* @code{mode}, @code{interpreter}: @code{mode} @code{interpreter}. +* @code{magic}, @code{magic-fallback}: @code{magic} @code{magic-fallback}. +* @code{no-require}:: +* @code{requires}:: @end menu @node @code{after} @@ -341,6 +388,13 @@ When you nest selectors, such as @code{(:any (:all foo bar) (:all baz quux))}, i means that the package will be loaded when either both @code{foo} and @code{bar} have been loaded, or both @code{baz} and @code{quux} have been loaded. +@strong{NOTE}: Pay attention if you set @code{use-package-always-defer} to t, and also use +the @code{:after} keyword, as you will need to specify how the declared package is +to be loaded: e.g., by some @code{:bind}. If you're not using one of the mechanisms +that registers autoloads, such as @code{:bind} or @code{:hook}, and your package manager +does not provide autoloads, it's possible that without adding @code{:demand t} to +those declarations, your package will never be loaded. + @node @code{bind-keymap} @code{bind-keymap*} @section @code{:bind-keymap}, @code{:bind-keymap*} @@ -400,8 +454,8 @@ The @code{:bind} keyword takes either a cons or a list of conses: @lisp (use-package hi-lock :bind (("M-o l" . highlight-lines-matching-regexp) - ("M-o r" . highlight-regexp) - ("M-o w" . highlight-phrase))) + ("M-o r" . highlight-regexp) + ("M-o w" . highlight-phrase))) @end lisp The @code{:commands} keyword likewise takes either a symbol or a list of symbols. @@ -415,9 +469,9 @@ Examples: @lisp (use-package helm :bind (("M-x" . helm-M-x) - ("M-" . helm-find-files) - ([f10] . helm-buffers-list) - ([S-f10] . helm-recentf))) + ("M-" . helm-find-files) + ([f10] . helm-buffers-list) + ([S-f10] . helm-recentf))) @end lisp @menu @@ -434,7 +488,7 @@ supports this with a @code{:map} modifier, taking the local keymap to bind to: @lisp (use-package helm :bind (:map helm-command-map - ("C-c h" . helm-execute-persistent-action))) + ("C-c h" . helm-execute-persistent-action))) @end lisp The effect of this statement is to wait until @code{helm} has loaded, and then to @@ -447,13 +501,13 @@ first use of @code{:map} are applied to the global keymap: @lisp (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))) + :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 lisp @node @code{commands} @@ -506,9 +560,9 @@ As you might expect, you can use @code{:init} and @code{:config} together: (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)) + :map isearch-mode-map + ("M-o" . isearch-moccur) + ("M-O" . isearch-moccur-all)) :init (setq isearch-lazy-highlight t) :config @@ -761,7 +815,7 @@ equivalent: (use-package ace-jump-mode :hook ((prog-mode . ace-jump-mode) - (text-mode . ace-jump-mode))) + (text-mode . ace-jump-mode))) (use-package ace-jump-mode :commands ace-jump-mode @@ -878,22 +932,22 @@ This does exactly the same thing as the following: @node @code{magic} @code{magic-fallback} @section @code{:magic}, @code{:magic-fallback} -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 +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. The difference between the two is -that `:magic-fallback` has a lower priority than `:mode`. For example: +that @code{:magic-fallback} has a lower priority than @code{:mode}. For example: -``` elisp +@lisp (use-package pdf-tools :load-path "site-lisp/pdf-tools/lisp" :magic ("%PDF" . pdf-view-mode) :config (pdf-tools-install)) -``` +@end lisp -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"`. +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 @code{no-require} @section @code{:no-require} @@ -1001,4 +1055,5 @@ Please also see the @ref{FAQ}. @printindex vr +Emacs 28.0.92 (Org mode 9.5.2) @bye From cb85f9c274b21db2be81193776c8b48c0abd443d Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Sun, 26 Jun 2022 16:14:14 +0200 Subject: [PATCH 558/606] Fix typo in use-package docstring --- lisp/use-package/use-package-core.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 28bc5a50ed0..a32371a6eaa 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1600,7 +1600,7 @@ this file. Usage: :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 `customize-set-faces' with each face definition. +: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." (declare (indent 1)) From 4004dde6ea92d9139b67e59c072a9ce52f4ed15c Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Tue, 18 May 2021 15:44:34 +0200 Subject: [PATCH 559/606] Avoid positional arguments to define-minor-mode Back in Emacs-21.1, `define-minor-mode' grew keyword arguments to replace its old positional arguments. Starting with Emacs-28.1 a warning will be omitted if positional arguments are still used. --- lisp/use-package/bind-key.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 1d611c2933c..9a2ddcd8437 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -131,7 +131,8 @@ (define-minor-mode override-global-mode "A minor mode so that keymap settings override other modes." - t "") + :global t + :lighter "") ;; the keymaps in `emulation-mode-map-alists' take precedence over ;; `minor-mode-map-alist' From 620fe443c2e7598191cb5d6c6a41064471edb57c Mon Sep 17 00:00:00 2001 From: Matthias Schmitt Date: Sat, 14 Sep 2019 23:25:21 +0200 Subject: [PATCH 560/606] Add: 'local' keyword --- lisp/use-package/use-package-core.el | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 28bc5a50ed0..5530b6c4f89 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -100,7 +100,8 @@ :load ;; This must occur almost last; the only forms which should appear after ;; are those that must happen directly after the config forms. - :config) + :config + :local) "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 @@ -1517,6 +1518,31 @@ no keyword implies `:all'." (when use-package-compute-statistics `((use-package-statistics-gather :config ',name t)))))) +;;;; :local + +(defun use-package-normalize/:local (name keyword args) + (let ((first-arg-name (symbol-name (caar args)))) + (if (not (string-suffix-p "-hook" first-arg-name)) + (let* ((sym-name (symbol-name name)) + (addition (if (string-suffix-p "-mode" sym-name) + "-hook" + "-mode-hook")) + (hook (intern (concat sym-name addition)))) + `((,hook . ,(use-package-normalize-forms name keyword args)))) + (cl-loop for (hook . code) in args + collect `(,hook . ,(use-package-normalize-forms name keyword code)))))) + +(defun use-package-handler/:local (name _keyword arg rest state) + (let* ((body (use-package-process-keywords name rest state))) + (use-package-concat + body + (cl-loop for (hook . code) in arg + for func-name = (intern (concat "use-package-func/" (symbol-name hook))) + collect (progn + (push 'progn code) + `(defun ,func-name () ,code)) + collect `(add-hook ',hook ',func-name))))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; The main macro From 835fdb16be2fa95508549173b1d935d3f754c6e8 Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Mon, 8 Aug 2022 13:26:10 +0200 Subject: [PATCH 561/606] manual: Regenerate texi file --- doc/misc/use-package.texi | 128 ++++++-------------------------------- 1 file changed, 19 insertions(+), 109 deletions(-) diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index 880af1203b6..2b868564372 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -8,7 +8,7 @@ @copying @quotation -Copyright (C) 2012-2017 John Wiegley +Copyright (C) 2012-2022 John Wiegley You can redistribute this document and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -31,7 +31,7 @@ General Public License for more details. @finalout @titlepage @title use-package User Manual -@subtitle for version 2.4.1 +@subtitle for version 2.4.1-81-gb185c6b+1 @author John Wiegley @page @vskip 0pt plus 1filll @@ -44,20 +44,13 @@ General Public License for more details. @node Top @top use-package User Manual -use-package is@dots{} +The @code{use-package} macro allows you to isolate package configuration in your +@code{.emacs} file in a way that is both performance-oriented and, well, 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 +around 2 seconds, with no loss of functionality! -@quotation -Copyright (C) 2012-2017 John Wiegley - -You can redistribute this document 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. - -This document 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. - -@end quotation +@insertcopying @end ifnottex @menu @@ -67,11 +60,7 @@ FOR A PARTICULAR PURPOSE@. See the GNU General Public License for more details. * Basic Concepts:: * Issues/Requests:: * Keywords:: -* FAQ:: * Debugging Tools:: -* Command Index:: -* Function Index:: -* Variable Index:: @detailmenu --- The Detailed Node Listing --- @@ -109,21 +98,6 @@ Keywords * Binding to local keymaps:: -FAQ - -* FAQ - How to @dots{}?:: -* FAQ - Issues and Errors:: - -FAQ - How to @dots{}? - -* This is a question:: - - -FAQ - Issues and Errors - -* This is an issues:: - - @end detailmenu @end menu @@ -141,12 +115,6 @@ More text to come@dots{} @node Installation @chapter Installation -@menu -* Installing from an Elpa Archive:: -* Installing from the Git Repository:: -* Post-Installation Tasks:: -@end menu - use-package can be installed using Emacs' package manager or manually from its development repository. @@ -276,8 +244,7 @@ use-package-version’s value is "2.4.1" If you are completely new to use-package then see @ref{Getting Started}. -If you run into problems, then please see the -@ref{FAQ}. Also see the @ref{Debugging Tools}. +If you run into problems, then please see the @ref{Debugging Tools}. @node Getting Started @chapter Getting Started @@ -293,25 +260,22 @@ those decisions clearer: @itemize @item -To gather all configuration details of a package into one place, making -it easier to copy, disable, or move it elsewhere in the init file. - +To gather all configuration details of a package into one place, +making it easier to copy, disable, or move it elsewhere in the init +file. @item -To reduce duplication and boilerplate, capturing several common practices -as mere keywords both easy and intuitive to use. - +To reduce duplication and boilerplate, capturing several common +practices as mere keywords both easy and intuitive to use. @item -To make startup time of Emacs as quick as possible, without sacrificing -the quantity of add-on packages used. - +To make startup time of Emacs as quick as possible, without +sacrificing the quantity of add-on packages used. @item -To make it so errors encountered during startup disable only the package -raising the error, and as little else as possible, leaving a close to a -functional Emacs as possible. - +To make it so errors encountered during startup disable only the +package raising the error, and as little else as possible, leaving a +close to a functional Emacs as possible. @item To allow byte-compilation of one's init file so that any warnings or @@ -997,63 +961,9 @@ As a convenience, a list of such packages may be specified: For more complex logic, such as that supported by @code{:after}, simply use @code{:if} and the appropriate Lisp expression. -@node FAQ -@appendix FAQ - -The next two nodes lists frequently asked questions. - -Please also use the @ref{Debugging Tools}. - -@menu -* FAQ - How to @dots{}?:: -* FAQ - Issues and Errors:: -@end menu - -@node FAQ - How to @dots{}? -@appendixsec FAQ - How to @dots{}? - -@menu -* This is a question:: -@end menu - -@node This is a question -@appendixsubsec This is a question - -This is an answer. - -@node FAQ - Issues and Errors -@appendixsec FAQ - Issues and Errors - -@menu -* This is an issues:: -@end menu - -@node This is an issues -@appendixsubsec This is an issues - -This is a description. - @node Debugging Tools @chapter Debugging Tools TODO -Please also see the @ref{FAQ}. - -@node Command Index -@appendix Command Index - -@printindex cp - -@node Function Index -@appendix Function Index - -@printindex fn - -@node Variable Index -@appendix Variable Index - -@printindex vr - -Emacs 28.0.92 (Org mode 9.5.2) @bye From 53c1889342af1e087208bb7ef4f5c7d0acb61d45 Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Mon, 8 Aug 2022 13:33:17 +0200 Subject: [PATCH 562/606] Quote single quotes in docstrings or use different quoting The byte-compiler started pointing this out: Warning: docstring has wrong usage of unescaped single quotes (use \= or different quoting) --- lisp/use-package/bind-key.el | 26 +++++++++++++------------- lisp/use-package/use-package-core.el | 4 ++-- lisp/use-package/use-package-ensure.el | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index df76c39ceed..bf5785ff5b4 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -160,7 +160,7 @@ For example: (bind-key \"M-h\" #'some-interactive-function my-mode-map) - (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. @@ -262,16 +262,16 @@ Accepts keyword arguments: :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) + `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 +: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 + `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) + 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 @@ -409,16 +409,16 @@ Accepts keyword arguments: :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) + `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 +: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 + `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) + 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 diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 2859e3382ca..ab35131e4f4 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -908,12 +908,12 @@ If RECURSED is non-nil, recurse into sublists." "A predicate that recognizes functional constructions: nil sym - 'sym + \\='sym (quote sym) #'sym (function sym) (lambda () ...) - '(lambda () ...) + \\='(lambda () ...) (quote (lambda () ...)) #'(lambda () ...) (function (lambda () ...))" diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index 50005a9e990..cb31b4b7dd4 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -93,7 +93,7 @@ The default value uses package.el to install the package." (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 +ARCHIVE can be a string or a symbol or `manual' to indicate a manually updated package." (if (member archive '(manual "manual")) 't From 85c1287c260bcf18b54c388a64da20188ab13eec Mon Sep 17 00:00:00 2001 From: Koen van Greevenbroek Date: Wed, 10 Aug 2022 10:59:44 +0200 Subject: [PATCH 563/606] Make sure that bind-key's `override-global-mode` is initially on In 4004dde the arguments to `define-minor-mode` were changed erroneously. Whereas the `override-global-mode` was initially defined as `(define-minor-mode override-global-mode "..." t "")`, the two latter arguments where changed to `:global t :lighter ""`. However, the two original arguments corresponded to the keywords `:init-value` and `:lighter`, respectively. With `:init-value t` now missing, the minor mode isn't enabled by default, and `bind-key*` appears not to work. Copyright-paperwork-exempt: yes --- lisp/use-package/bind-key.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index bf5785ff5b4..14784b09a15 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -131,6 +131,7 @@ (define-minor-mode override-global-mode "A minor mode so that keymap settings override other modes." + :init-value t :global t :lighter "") From a05b9e28edfa443480a42998b95b9ff30fb1b14b Mon Sep 17 00:00:00 2001 From: realcomplex Date: Thu, 11 Aug 2022 09:08:25 +0200 Subject: [PATCH 564/606] Go back to making `override-global-mode` non-global Copyright-paperwork-exempt: yes --- lisp/use-package/bind-key.el | 1 - 1 file changed, 1 deletion(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 14784b09a15..1f775711ef3 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -132,7 +132,6 @@ (define-minor-mode override-global-mode "A minor mode so that keymap settings override other modes." :init-value t - :global t :lighter "") ;; the keymaps in `emulation-mode-map-alists' take precedence over From 6c2fdaffd98609fb33b5434cd563d07483bd4ef8 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 18 Aug 2022 22:53:04 -0700 Subject: [PATCH 565/606] Revert "Remove use-package-font-lock-keywords" This reverts commit 4938167bfffcf08279445827d2eaae78c9557675. --- lisp/use-package/use-package-core.el | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 0734dcf1c80..ab35131e4f4 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -328,6 +328,13 @@ Must be set before loading use-package." (set-default sym value)) :group 'use-package) +(defconst use-package-font-lock-keywords + '(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" + (1 font-lock-keyword-face) + (2 font-lock-constant-face nil t)))) + +(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords) + (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 From 3feedce08d426e6f6855398f4acc675aa71d2cea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Codru=C8=9B=20Constantin=20Gu=C8=99oi?= Date: Fri, 9 Sep 2022 08:03:18 +0100 Subject: [PATCH 566/606] Fix emacs native compilation warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``` ■ Warning (comp): use-package-core.el:907:2: Warning: docstring has wrong usage of unescaped single quotes (use \= or different quoting) ■ Warning (comp): use-package-core.el:930:2: Warning: docstring has wrong usage of unescaped single quotes (use \= or different quoting) ``` To reproduce, have emacs build with native compilation and notice the compilation logs. You can then open this file and run `M-x emacs-lisp-native-compile-and-load` before and after the changes to see the warning is removed. --- lisp/use-package/use-package-core.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index ab35131e4f4..946c029ff4a 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -910,12 +910,12 @@ If RECURSED is non-nil, recurse into sublists." sym \\='sym (quote sym) - #'sym + #\\='sym (function sym) (lambda () ...) \\='(lambda () ...) (quote (lambda () ...)) - #'(lambda () ...) + #\\='(lambda () ...) (function (lambda () ...))" (or (if binding (symbolp v) @@ -930,7 +930,7 @@ If RECURSED is non-nil, recurse into sublists." (defun use-package-normalize-function (v) "Reduce functional constructions to one of two normal forms: sym - #'(lambda () ...)" + #\\='(lambda () ...)" (cond ((symbolp v) v) ((and (listp v) (memq (car v) '(quote function)) From 1494f65f61f16451576bb4d933f976b61e28e9d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Codru=C8=9B=20Constantin=20Gu=C8=99oi?= Date: Sat, 10 Sep 2022 17:16:18 +0100 Subject: [PATCH 567/606] Fix emacs native compilation warning for bind-key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To reproduce, have emacs built with native compilation and notice the compilation logs. You can then open the offending file and run `M-x emacs-lisp-native-compile-and-load` before and after the changes to see the warning is removed. ``` ■ Warning (comp): bind-key.el:150:2: Warning: docstring has wrong usage of unescaped single quotes (use \= or different quoting) ``` --- lisp/use-package/bind-key.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 1f775711ef3..17e161cd72e 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -158,9 +158,9 @@ 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) - (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. From daa124e1cc5ea0154f47f7ee271b8922a51c1be8 Mon Sep 17 00:00:00 2001 From: Jacob First Date: Thu, 29 Sep 2022 02:36:32 -0400 Subject: [PATCH 568/606] Fix bind-chords docs: :map argument may be a list of keymaps --- lisp/use-package/bind-chord.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/bind-chord.el b/lisp/use-package/bind-chord.el index ff19c81fc78..d69a724df66 100644 --- a/lisp/use-package/bind-chord.el +++ b/lisp/use-package/bind-chord.el @@ -92,7 +92,8 @@ function symbol (unquoted)." "Bind multiple chords at once. Accepts keyword argument: -:map - a keymap into which the keybindings should be added +:map - a keymap or list of keymaps into which the keybindings should be + added The rest of the arguments are conses of keybinding string and a function symbol (unquoted)." From ec96b4766418fdfce2d7827fa6ddeb7257ad6cf7 Mon Sep 17 00:00:00 2001 From: Jacob First Date: Thu, 29 Sep 2022 02:36:43 -0400 Subject: [PATCH 569/606] bind-keys supports passing a list of keymaps as :map argument --- lisp/use-package/bind-key.el | 109 ++++++++++++--------- lisp/use-package/use-package-bind-key.el | 13 +-- test/lisp/use-package/use-package-tests.el | 83 +++++++++++++++- 3 files changed, 149 insertions(+), 56 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 17e161cd72e..5060e16ddf9 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -248,12 +248,12 @@ In contrast to `define-key', this function removes the binding from the keymap." "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) +(defun bind-keys-form (args &rest keymaps) "Bind multiple keys at once. Accepts keyword arguments: :map MAP - a keymap into which the keybindings should be - added + added, or a list of such keymaps :prefix KEY - prefix key for these bindings :prefix-map MAP - name of the prefix map that should be created for these bindings @@ -276,7 +276,7 @@ Accepts keyword arguments: The rest of the arguments are conses of keybinding string and a function symbol (unquoted)." - (let (map + (let (maps prefix-doc prefix-map prefix @@ -293,20 +293,17 @@ function symbol (unquoted)." (while (and cont args) (if (cond ((and (eq :map (car args)) (not prefix-map)) - (setq map (cadr args))) + (let ((arg (cadr args))) + (setq maps (if (listp arg) arg (list arg))))) ((eq :prefix-docstring (car args)) (setq prefix-doc (cadr args))) - ((and (eq :prefix-map (car args)) - (not (memq map '(global-map - override-global-map)))) + ((eq :prefix-map (car args)) (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)))) + ((eq :repeat-map (car args)) (setq repeat-map (cadr args)) - (setq map repeat-map)) + (setq maps (list repeat-map))) ((eq :continue (car args)) (setq repeat-type :continue arg-change-func 'cdr)) @@ -335,7 +332,8 @@ function symbol (unquoted)." (when (and menu-name (not prefix)) (error "If :menu-name is supplied, :prefix must be too")) - (unless map (setq map keymap)) + (unless maps (setq maps keymaps)) + (unless maps (setq maps (list nil))) ;; Process key binding arguments (let (first next) @@ -349,50 +347,67 @@ function symbol (unquoted)." (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) + (cl-labels + ((wrap (maps bindings) + (if (and pkg + (cl-every + (lambda (map) + (and map + (not (memq map '(global-map + override-global-map))))) + maps)) + `((if (mapcan 'boundp ',maps) ,(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)) + (if 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))) + ,@(cl-mapcan + (lambda (map) + (wrap (list map) + `((bind-key ,prefix ',prefix-map ,map ,filter)))) + maps) + ,@(wrap maps + (cl-mapcan + (lambda (form) + (let ((fun + (and (cdr form) (list 'function (cdr form))))) + `((bind-key ,(car form) ,fun ,prefix-map ,filter)))) + first))) + (cl-mapcan + (lambda (map) + (wrap (list map) + (cl-mapcan + (lambda (form) + (let ((fun (and (cdr form) (list 'function (cdr form))))) + (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))) + maps)) (when next - (bind-keys-form `(,@(when repeat-map `(:repeat-map ,repeat-map)) - ,@(if pkg - (cons :package (cons pkg next)) - next)) map))))))) + (apply 'bind-keys-form + `(,@(when repeat-map `(:repeat-map ,repeat-map)) + ,@(if pkg + (cons :package (cons pkg next)) + next)) + maps))))))) ;;;###autoload (defmacro bind-keys (&rest args) @@ -400,7 +415,7 @@ function symbol (unquoted)." Accepts keyword arguments: :map MAP - a keymap into which the keybindings should be - added + added, or a list of such keymaps :prefix KEY - prefix key for these bindings :prefix-map MAP - name of the prefix map that should be created for these bindings diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index 9642f311750..7c79f450831 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -86,19 +86,20 @@ deferred until the prefix key sequence is pressed." ;; :prefix-docstring STRING ;; :prefix-map SYMBOL ;; :prefix STRING - ;; :repeat-docstring 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))) + ;; :continue and :exit are used within :repeat-map + ((or (and (eq x :map) (or (symbolp (cadr arg)) + (listp (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-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))) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 9510fffb01c..007d2b07ac8 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1951,15 +1951,92 @@ (autoload #'nonexistent-mode "nonexistent" nil t)) (add-hook 'lisp-mode-hook #'nonexistent-mode))))) +(ert-deftest bind-key/:map () + (match-expansion + (bind-keys + ("C-1" . command-1) + ("C-2" . command-2) + :map keymap-1 + ("C-3" . command-3) + ("C-4" . command-4) + :map (keymap-2 keymap-3) + ("C-5" . command-5) + ("C-6" . command-6)) + `(progn (bind-key "C-1" #'command-1 nil nil) + (bind-key "C-2" #'command-2 nil nil) + (bind-key "C-3" #'command-3 keymap-1 nil) + (bind-key "C-4" #'command-4 keymap-1 nil) + (bind-key "C-5" #'command-5 keymap-2 nil) + (bind-key "C-6" #'command-6 keymap-2 nil) + (bind-key "C-5" #'command-5 keymap-3 nil) + (bind-key "C-6" #'command-6 keymap-3 nil)))) + (ert-deftest bind-key/:prefix-map () (match-expansion - (bind-keys :prefix "" - :prefix-map my/map) + (bind-keys ("C-1" . command-1) + :prefix "" + :prefix-map my/map + ("C-2" . command-2) + ("C-3" . command-3)) `(progn + (bind-key "C-1" #'command-1 nil nil) (defvar my/map) (define-prefix-command 'my/map) - (bind-key "" 'my/map nil nil)))) + (bind-key "" 'my/map nil nil) + (bind-key "C-2" #'command-2 my/map nil) + (bind-key "C-3" #'command-3 my/map nil)))) +(ert-deftest bind-key/:repeat-map-1 () + ;; NOTE: This test is pulled from the discussion in issue #964, + ;; adjusting for the final syntax that was implemented. + (match-expansion + (bind-keys + ("C-c n" . git-gutter+-next-hunk) + ("C-c p" . git-gutter+-previous-hunk) + ("C-c s" . git-gutter+-stage-hunks) + ("C-c r" . git-gutter+-revert-hunk) + :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) + :repeat-docstring + "Keymap to repeat git-gutter+-* commands.") + `(progn + (bind-key "C-c n" #'git-gutter+-next-hunk nil nil) + (bind-key "C-c p" #'git-gutter+-previous-hunk nil nil) + (bind-key "C-c s" #'git-gutter+-stage-hunks nil nil) + (bind-key "C-c r" #'git-gutter+-revert-hunk nil nil) + (defvar my/git-gutter+-repeat-map (make-sparse-keymap)) + (put #'git-gutter+-next-hunk 'repeat-map 'my/git-gutter+-repeat-map) + (bind-key "n" #'git-gutter+-next-hunk my/git-gutter+-repeat-map nil) + (put #'git-gutter+-previous-hunk 'repeat-map 'my/git-gutter+-repeat-map) + (bind-key "p" #'git-gutter+-previous-hunk my/git-gutter+-repeat-map nil) + (put #'git-gutter+-stage-hunks 'repeat-map 'my/git-gutter+-repeat-map) + (bind-key "s" #'git-gutter+-stage-hunks my/git-gutter+-repeat-map nil) + (put #'git-gutter+-revert-hunk 'repeat-map 'my/git-gutter+-repeat-map) + (bind-key "r" #'git-gutter+-revert-hunk my/git-gutter+-repeat-map nil) + (defvar my/git-gutter+-repeat-map (make-sparse-keymap) "Keymap to repeat git-gutter+-* commands.")))) + +(ert-deftest bind-key/:repeat-map-2 () + (match-expansion + (bind-keys :map m ("x" . cmd1) :repeat-map rm ("y" . cmd2)) + `(progn + (bind-key "x" #'cmd1 m nil) + (defvar rm (make-sparse-keymap)) + (put #'cmd2 'repeat-map 'rm) + (bind-key "y" #'cmd2 rm nil)))) + +(ert-deftest bind-key/:repeat-map-3 () + (match-expansion + (bind-keys :repeat-map rm ("y" . cmd2) :map m ("x" . cmd1)) + `(progn + (defvar rm (make-sparse-keymap)) + (put #'cmd2 'repeat-map 'rm) + (bind-key "y" #'cmd2 rm nil) + (defvar rm (make-sparse-keymap)) + (put #'cmd1 'repeat-map 'rm) + (bind-key "x" #'cmd1 m nil)))) (ert-deftest bind-key/845 () (defvar test-map (make-keymap)) From 6b344a919754d53070280e691924011ad9086c76 Mon Sep 17 00:00:00 2001 From: Andrey Listopadov Date: Sat, 15 Oct 2022 19:03:03 +0300 Subject: [PATCH 570/606] Use face-spec-set instead of custom-set-faces GitHub-reference: https://github.com/jwiegley/use-package/issues/934 Copyright-paperwork-exempt: yes --- lisp/use-package/use-package-core.el | 2 +- test/lisp/use-package/use-package-tests.el | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 31b80486432..21b1a7ab40e 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1518,7 +1518,7 @@ no keyword implies `:all'." (defun use-package-handler/:custom-face (name _keyword args rest state) "Generate use-package custom-face keyword code." (use-package-concat - (mapcar #'(lambda (def) `(custom-set-faces (backquote ,def))) args) + (mapcar #'(lambda (def) `(apply #'face-spec-set (backquote ,def))) args) (use-package-process-keywords name rest state))) ;;;; :init diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 1ccd3ad0786..7d98ca99e4a 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1156,7 +1156,7 @@ (match-expansion (use-package foo :custom-face (foo ((t (:background "#e4edfc"))))) `(progn - (custom-set-faces (backquote (foo ((t (:background "#e4edfc")))))) + (apply #'face-spec-set (backquote (foo ((t (:background "#e4edfc")))))) (require 'foo nil nil)))) (ert-deftest use-package-test/:custom-face-2 () @@ -1166,11 +1166,11 @@ (example-1-face ((t (:foreground "LightPink")))) (example-2-face ((t (:foreground "LightGreen"))))) `(progn - (custom-set-faces - (backquote (example-1-face ((t (:foreground "LightPink")))))) - (custom-set-faces - (backquote (example-2-face ((t (:foreground "LightGreen")))))) - (require 'example nil nil)))) + (apply #'face-spec-set + (backquote (example-1-face ((t (:foreground "LightPink")))))) + (apply #'face-spec-set + (backquote (example-2-face ((t (:foreground "LightGreen")))))) + (require 'example nil nil)))) (ert-deftest use-package-test/:init-1 () (match-expansion From 0fafd98513fd582f50aa114a4db0c59f0de12bcd Mon Sep 17 00:00:00 2001 From: Payas Relekar Date: Tue, 25 Oct 2022 20:02:35 +0530 Subject: [PATCH 571/606] Update copyright for submission to ELPA - Update year to 2022 - Set copyright to Free Software Foundation, Inc. --- lisp/use-package/bind-chord.el | 2 +- lisp/use-package/bind-key.el | 2 +- lisp/use-package/use-package-bind-key.el | 2 +- lisp/use-package/use-package-chords.el | 2 +- lisp/use-package/use-package-core.el | 2 +- lisp/use-package/use-package-delight.el | 2 +- lisp/use-package/use-package-diminish.el | 2 +- lisp/use-package/use-package-ensure-system-package.el | 2 +- lisp/use-package/use-package-ensure.el | 2 +- lisp/use-package/use-package-jump.el | 2 +- lisp/use-package/use-package-lint.el | 2 +- lisp/use-package/use-package.el | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lisp/use-package/bind-chord.el b/lisp/use-package/bind-chord.el index ff19c81fc78..bf0f5866ac4 100644 --- a/lisp/use-package/bind-chord.el +++ b/lisp/use-package/bind-chord.el @@ -1,6 +1,6 @@ ;;; bind-chord.el --- key-chord binding helper for use-package-chords -*- lexical-binding: t; -*- -;; Copyright (C) 2015-2019 Justin Talbott +;; Copyright (C) 2015-2022 Free Software Foundation, Inc. ;; Author: Justin Talbott ;; Keywords: convenience, tools, extensions diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 17e161cd72e..817ca5efb2d 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -1,6 +1,6 @@ ;;; bind-key.el --- A simple way to manage personal keybindings -*- lexical-binding: t; -*- -;; Copyright (c) 2012-2017 John Wiegley +;; Copyright (c) 2012-2022 Free Software Foundation, Inc. ;; Author: John Wiegley ;; Maintainer: John Wiegley diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index 9642f311750..5ca2d016478 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -1,6 +1,6 @@ ;;; use-package-bind-key.el --- Support for the :bind/:bind-keymap keywords -*- lexical-binding: t; -*- -;; Copyright (C) 2012-2017 John Wiegley +;; Copyright (C) 2012-2022 Free Software Foundation, Inc. ;; Author: John Wiegley ;; Maintainer: John Wiegley diff --git a/lisp/use-package/use-package-chords.el b/lisp/use-package/use-package-chords.el index cf390dbe593..4a4d9e7fea7 100644 --- a/lisp/use-package/use-package-chords.el +++ b/lisp/use-package/use-package-chords.el @@ -1,6 +1,6 @@ ;;; use-package-chords.el --- key-chord keyword for use-package -*- lexical-binding: t; -*- -;; Copyright (C) 2015-2019 Justin Talbott +;; Copyright (C) 2015-2022 Free Software Foundation, Inc. ;; Author: Justin Talbott ;; Keywords: convenience, tools, extensions diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 31b80486432..76c6a97e062 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1,6 +1,6 @@ ;;; use-package-core.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*- -;; Copyright (C) 2012-2017 John Wiegley +;; Copyright (C) 2012-2022 Free Software Foundation, Inc. ;; Author: John Wiegley ;; Maintainer: John Wiegley diff --git a/lisp/use-package/use-package-delight.el b/lisp/use-package/use-package-delight.el index 85d5c7cb4d6..558be5e4706 100644 --- a/lisp/use-package/use-package-delight.el +++ b/lisp/use-package/use-package-delight.el @@ -1,6 +1,6 @@ ;;; use-package-delight.el --- Support for the :delight keyword -*- lexical-binding: t; -*- -;; Copyright (C) 2012-2017 John Wiegley +;; Copyright (C) 2012-2022 Free Software Foundation, Inc. ;; Author: John Wiegley ;; Maintainer: John Wiegley diff --git a/lisp/use-package/use-package-diminish.el b/lisp/use-package/use-package-diminish.el index 1f3895f42cd..5b20830ee6a 100644 --- a/lisp/use-package/use-package-diminish.el +++ b/lisp/use-package/use-package-diminish.el @@ -1,6 +1,6 @@ ;;; use-package-diminish.el --- Support for the :diminish keyword -*- lexical-binding: t; -*- -;; Copyright (C) 2012-2017 John Wiegley +;; Copyright (C) 2012-2022 Free Software Foundation, Inc. ;; Author: John Wiegley ;; Maintainer: John Wiegley diff --git a/lisp/use-package/use-package-ensure-system-package.el b/lisp/use-package/use-package-ensure-system-package.el index 7c591af7d9b..8f1affadae0 100644 --- a/lisp/use-package/use-package-ensure-system-package.el +++ b/lisp/use-package/use-package-ensure-system-package.el @@ -1,6 +1,6 @@ ;;; use-package-ensure-system-package.el --- auto install system packages -*- lexical-binding: t; -*- -;; Copyright (C) 2017 Justin Talbott +;; Copyright (C) 2022 Free Software Foundation, Inc. ;; Author: Justin Talbott ;; Keywords: convenience, tools, extensions diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index cb31b4b7dd4..78a7e8be1e2 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -1,6 +1,6 @@ ;;; use-package-ensure.el --- Support for the :ensure and :pin keywords -*- lexical-binding: t; -*- -;; Copyright (C) 2012-2017 John Wiegley +;; Copyright (C) 2012-2022 Free Software Foundation, Inc. ;; Author: John Wiegley ;; Maintainer: John Wiegley diff --git a/lisp/use-package/use-package-jump.el b/lisp/use-package/use-package-jump.el index 4044ad16564..224d2e06b6e 100644 --- a/lisp/use-package/use-package-jump.el +++ b/lisp/use-package/use-package-jump.el @@ -1,6 +1,6 @@ ;;; use-package-jump.el --- Attempt to jump to a use-package declaration -*- lexical-binding: t; -*- -;; Copyright (C) 2012-2017 John Wiegley +;; Copyright (C) 2012-2022 Free Software Foundation, Inc. ;; Author: John Wiegley ;; Maintainer: John Wiegley diff --git a/lisp/use-package/use-package-lint.el b/lisp/use-package/use-package-lint.el index c6e7c3c0ce2..49a47a9d32b 100644 --- a/lisp/use-package/use-package-lint.el +++ b/lisp/use-package/use-package-lint.el @@ -1,6 +1,6 @@ ;;; use-package-lint.el --- Attempt to find errors in use-package declarations -*- lexical-binding: t; -*- -;; Copyright (C) 2012-2017 John Wiegley +;; Copyright (C) 2012-2022 Free Software Foundation, Inc. ;; Author: John Wiegley ;; Maintainer: John Wiegley diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 0e194d5f182..62bb2407a51 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -1,6 +1,6 @@ ;;; use-package.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*- -;; Copyright (C) 2012-2017 John Wiegley +;; Copyright (C) 2012-2022 Free Software Foundation, Inc. ;; Author: John Wiegley ;; Maintainer: John Wiegley From abd655c99ef457962d8b424fd70b94f90595ed6b Mon Sep 17 00:00:00 2001 From: Payas Relekar Date: Thu, 27 Oct 2022 08:50:53 +0530 Subject: [PATCH 572/606] Update version to 2.4.2 In preparation for inclusion to GNU ELPA. --- etc/USE-PACKAGE-NEWS | 4 ++++ lisp/use-package/use-package-core.el | 4 ++-- lisp/use-package/use-package.el | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index 1f516966980..6e8530ef377 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -1,5 +1,9 @@ # Changes +## 2.4.2 + +This release prepares for inclusion to GNU ELPA and includes no other changes + ## 2.4.1 This is mostly a bug-fix release: diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 76c6a97e062..6832c447c7d 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -6,7 +6,7 @@ ;; Maintainer: John Wiegley ;; Created: 17 Jun 2012 ;; Modified: 29 Nov 2017 -;; Version: 2.4.1 +;; Version: 2.4.2 ;; Package-Requires: ((emacs "24.3")) ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package @@ -66,7 +66,7 @@ "A use-package declaration for simplifying your `.emacs'." :group 'startup) -(defconst use-package-version "2.4.1" +(defconst use-package-version "2.4.2" "This version of use-package.") (defcustom use-package-keywords diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 62bb2407a51..574431d80b5 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -6,7 +6,7 @@ ;; Maintainer: John Wiegley ;; Created: 17 Jun 2012 ;; Modified: 29 Nov 2017 -;; Version: 2.4.1 +;; Version: 2.4.2 ;; Package-Requires: ((emacs "24.3") (bind-key "2.4")) ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package From 2ee9b31ca4bde97999eedd444430afdb5dbf1cad Mon Sep 17 00:00:00 2001 From: Payas Relekar Date: Fri, 28 Oct 2022 10:37:18 +0530 Subject: [PATCH 573/606] bind-key.el: Bump version for ELPA --- lisp/use-package/bind-key.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 817ca5efb2d..cca5ad86187 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -6,7 +6,7 @@ ;; Maintainer: John Wiegley ;; Created: 16 Jun 2012 ;; Modified: 29 Nov 2017 -;; Version: 2.4 +;; Version: 2.4.1 ;; Keywords: keys keybinding config dotemacs ;; URL: https://github.com/jwiegley/use-package From 370890e518ebf2f2f6c5e2a0a27576e111de22d6 Mon Sep 17 00:00:00 2001 From: Payas Relekar Date: Fri, 28 Oct 2022 17:39:16 +0530 Subject: [PATCH 574/606] Bump version to 2.4.3 --- etc/USE-PACKAGE-NEWS | 2 +- lisp/use-package/use-package-core.el | 4 ++-- lisp/use-package/use-package.el | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index 6e8530ef377..38f5dc70a16 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -1,6 +1,6 @@ # Changes -## 2.4.2 +## 2.4.3 This release prepares for inclusion to GNU ELPA and includes no other changes diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index f27d158fc05..52d7abd4cbb 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -6,7 +6,7 @@ ;; Maintainer: John Wiegley ;; Created: 17 Jun 2012 ;; Modified: 29 Nov 2017 -;; Version: 2.4.2 +;; Version: 2.4.3 ;; Package-Requires: ((emacs "24.3")) ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package @@ -66,7 +66,7 @@ "A use-package declaration for simplifying your `.emacs'." :group 'startup) -(defconst use-package-version "2.4.2" +(defconst use-package-version "2.4.3" "This version of use-package.") (defcustom use-package-keywords diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 574431d80b5..240693c1189 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -6,7 +6,7 @@ ;; Maintainer: John Wiegley ;; Created: 17 Jun 2012 ;; Modified: 29 Nov 2017 -;; Version: 2.4.2 +;; Version: 2.4.3 ;; Package-Requires: ((emacs "24.3") (bind-key "2.4")) ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package From 76a5ce5d8693cf7e8a70209b4275e0c21708e4a9 Mon Sep 17 00:00:00 2001 From: Andrey Listopadov Date: Sat, 29 Oct 2022 13:24:13 +0300 Subject: [PATCH 575/606] Allow passing the SPEC-TYPE argument via :custom-face GitHub-reference: https://github.com/jwiegley/use-package/issues/1008 Copyright-paperwork-exempt: yes --- lisp/use-package/use-package-core.el | 4 ++-- lisp/use-package/use-package.el | 2 +- test/lisp/use-package/use-package-tests.el | 7 +++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index f27d158fc05..135b1ca96b0 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1501,7 +1501,7 @@ no keyword implies `:all'." (defun use-package-normalize/:custom-face (name-symbol _keyword arg) "Normalize use-package custom-face keyword." (let ((error-msg - (format "%s wants a ( ) or list of these" + (format "%s wants a ( [spec-type]) or list of these" name-symbol))) (unless (listp arg) (use-package-error error-msg)) @@ -1512,7 +1512,7 @@ no keyword implies `:all'." (spec (nth 1 def))) (when (or (not face) (not spec) - (> (length def) 2)) + (> (length def) 3)) (use-package-error error-msg)))))) (defun use-package-handler/:custom-face (name _keyword args rest state) diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 574431d80b5..240693c1189 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -6,7 +6,7 @@ ;; Maintainer: John Wiegley ;; Created: 17 Jun 2012 ;; Modified: 29 Nov 2017 -;; Version: 2.4.2 +;; Version: 2.4.3 ;; Package-Requires: ((emacs "24.3") (bind-key "2.4")) ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 7d98ca99e4a..185f7691ba9 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1172,6 +1172,13 @@ (backquote (example-2-face ((t (:foreground "LightGreen")))))) (require 'example nil nil)))) +(ert-deftest use-package-test/:custom-face-3 () + (match-expansion + (use-package foo :custom-face (foo ((t (:background "#e4edfc"))) face-defspec-spec)) + `(progn + (apply #'face-spec-set (backquote (foo ((t (:background "#e4edfc"))) face-defspec-spec))) + (require 'foo nil nil)))) + (ert-deftest use-package-test/:init-1 () (match-expansion (use-package foo :init (init)) From 7122ac5397c1fbb4e76c123d490106a99bcb611d Mon Sep 17 00:00:00 2001 From: Payas Relekar Date: Sat, 5 Nov 2022 13:28:24 +0530 Subject: [PATCH 576/606] Bump version to 2.4.4 --- etc/USE-PACKAGE-NEWS | 2 +- lisp/use-package/use-package-core.el | 4 ++-- lisp/use-package/use-package.el | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS index 38f5dc70a16..c499820755f 100644 --- a/etc/USE-PACKAGE-NEWS +++ b/etc/USE-PACKAGE-NEWS @@ -1,6 +1,6 @@ # Changes -## 2.4.3 +## 2.4.4 This release prepares for inclusion to GNU ELPA and includes no other changes diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 53bc3ed2a42..7d7217d094b 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -6,7 +6,7 @@ ;; Maintainer: John Wiegley ;; Created: 17 Jun 2012 ;; Modified: 29 Nov 2017 -;; Version: 2.4.3 +;; Version: 2.4.4 ;; Package-Requires: ((emacs "24.3")) ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package @@ -66,7 +66,7 @@ "A use-package declaration for simplifying your `.emacs'." :group 'startup) -(defconst use-package-version "2.4.3" +(defconst use-package-version "2.4.4" "This version of use-package.") (defcustom use-package-keywords diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 240693c1189..9d046e0b149 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -6,7 +6,7 @@ ;; Maintainer: John Wiegley ;; Created: 17 Jun 2012 ;; Modified: 29 Nov 2017 -;; Version: 2.4.3 +;; Version: 2.4.4 ;; Package-Requires: ((emacs "24.3") (bind-key "2.4")) ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package From 45e6ee1371bdfec607aaf0b5be2b340460f704db Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Sun, 13 Nov 2022 23:16:05 +0100 Subject: [PATCH 577/606] Fix tests on Emacs 26 or older MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes the following error in Emacs 25.3: In toplevel form: bind-key.el:549:1:Error: the function ‘mapcan’ is not known to be defined. --- lisp/use-package/bind-key.el | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index cca5ad86187..567ef9e4e85 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -223,11 +223,11 @@ See `bind-key' for more details." 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)) + (setq key (cl-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) @@ -241,7 +241,7 @@ In contrast to `define-key', this function removes the binding from the keymap." (delete (last key) submap) ;; Delete submap if it is empty (when (= 1 (length submap)) - (bind-key--remove prefix keymap))))) + (bind-key--remove prefix keymap))))) ;;;###autoload (defmacro bind-key* (key-name command &optional predicate) From 43254ae62f1a775edab9a3c74d0411ba0577de0e Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Sun, 13 Nov 2022 23:20:40 +0100 Subject: [PATCH 578/606] Fix building on Emacs 24.3 This fixes the following error: use-package-core.el:60:32:Error: Cannot open load file: subr-x --- lisp/use-package/use-package-core.el | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 53bc3ed2a42..9e7b3b56e12 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -53,11 +53,18 @@ ;; iterating over them to "disable all themes" won't disable it. (setq custom-enabled-themes (remq 'use-package custom-enabled-themes)) -(if (and (eq emacs-major-version 24) (eq emacs-minor-version 3)) - (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)) - (eval-when-compile (require 'subr-x))) +(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)) From ff30d22909194f818e5262537bcd045c4bf86e90 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Mon, 14 Nov 2022 02:15:19 +0100 Subject: [PATCH 579/606] Various checkdoc fixes --- lisp/use-package/bind-key.el | 8 +-- lisp/use-package/use-package-bind-key.el | 2 +- lisp/use-package/use-package-core.el | 56 ++++++++++--------- .../use-package-ensure-system-package.el | 4 +- lisp/use-package/use-package-ensure.el | 6 +- lisp/use-package/use-package-jump.el | 13 ++--- lisp/use-package/use-package-lint.el | 2 +- .../use-package/use-package-chords-tests.el | 2 +- 8 files changed, 47 insertions(+), 46 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index cca5ad86187..1a84d6a9066 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -29,7 +29,7 @@ ;; If you have lots of keybindings set in your .emacs file, it can be hard to ;; know which ones you haven't set yet, and which may now be overriding some -;; new default in a new emacs version. This module aims to solve that +;; new default in a new Emacs version. This module aims to solve that ;; problem. ;; ;; Bind keys as follows in your .emacs: @@ -104,7 +104,7 @@ (require 'easy-mmode) (defgroup bind-key nil - "A simple way to manage personal keybindings" + "A simple way to manage personal keybindings." :group 'emacs) (defcustom bind-key-column-widths '(18 . 40) @@ -127,7 +127,7 @@ ;; Create override-global-mode to force key remappings (defvar override-global-map (make-keymap) - "override-global-mode keymap") + "Keymap for `override-global-mode'.") (define-minor-mode override-global-mode "A minor mode so that keymap settings override other modes." @@ -150,7 +150,7 @@ Elements have the form ((KEY . [MAP]) CMD ORIGINAL-CMD)") 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 +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. diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index 5ca2d016478..5e6a10925ca 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -29,7 +29,7 @@ ;;; Commentary: ;; Provides support for the :bind, :bind*, :bind-keymap and :bind-keymap* -;; keywords. Note that these are currently still baked into +;; 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. diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 7d7217d094b..5b001e496dd 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -63,11 +63,11 @@ (require 'regexp-opt)) (defgroup use-package nil - "A use-package declaration for simplifying your `.emacs'." + "A `use-package' declaration for simplifying your `.emacs'." :group 'startup) (defconst use-package-version "2.4.4" - "This version of use-package.") + "This version of `use-package'.") (defcustom use-package-keywords '(:disabled @@ -106,13 +106,13 @@ "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 +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 +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 +nothing at all to happen, even if the rest of the `use-package' declaration is incorrect." :type '(repeat symbol) :group 'use-package) @@ -132,9 +132,9 @@ otherwise requested." :group 'use-package) (defcustom use-package-ignore-unknown-keywords nil - "If non-nil, issue warning instead of error when unknown -keyword is encountered. The unknown keyword and its associated -arguments will be ignored in the `use-package' expansion." + "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) @@ -149,7 +149,7 @@ call)." "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, +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) @@ -196,9 +196,9 @@ 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 +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). @@ -206,9 +206,9 @@ 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 +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 +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 @@ -293,7 +293,7 @@ This disables: 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 +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) @@ -305,7 +305,7 @@ definitions, to understand the main intent of what's happening." "\\s-+\\(")) (or (bound-and-true-p lisp-mode-symbol-regexp) "\\(?:\\sw\\|\\s_\\|\\\\.\\)+") "\\)") - "Sexp providing regexp for finding use-package forms in user files. + "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 @@ -316,7 +316,7 @@ This is used by `use-package-jump-to-package-form' and 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." +Must be set before loading `use-package'." :type 'boolean :set #'(lambda (sym value) @@ -338,8 +338,8 @@ Must be set before loading use-package." (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 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." @@ -365,14 +365,14 @@ undefined variables." (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 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 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))) @@ -738,8 +738,8 @@ 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." +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) @@ -989,6 +989,8 @@ If RECURSED is non-nil, recurse into sublists." ;; (defun use-package-reset-statistics () + "Reset statistics for `use-package'. +See also `use-package-statistics'." (interactive) (setq use-package-statistics (make-hash-table))) @@ -1031,7 +1033,7 @@ The information is formatted in a way suitable for (format "%.2f" (use-package-statistics-time statistics)))))) (defun use-package-report () - "Show current statistics gathered about use-package declarations. + "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!) @@ -1055,7 +1057,7 @@ meaning: (define-derived-mode use-package-statistics-mode tabulated-list-mode "use-package statistics" - "Show current statistics gathered about use-package declarations." + "Show current statistics gathered about `use-package' declarations." (setq tabulated-list-format ;; The sum of column width is 80 characters: [("Package" 25 t) diff --git a/lisp/use-package/use-package-ensure-system-package.el b/lisp/use-package/use-package-ensure-system-package.el index 8f1affadae0..c42996f9d2a 100644 --- a/lisp/use-package/use-package-ensure-system-package.el +++ b/lisp/use-package/use-package-ensure-system-package.el @@ -29,7 +29,7 @@ "List of custom packages installed.") (defun use-package-ensure-system-package-consify (arg) - "Turn `arg' into a cons of (`package-name' . `install-command')." + "Turn ARG into a cons of (`package-name' . `install-command')." (cond ((stringp arg) (cons arg `(system-packages-install ,arg))) @@ -54,7 +54,7 @@ ;;;###autoload (defun use-package-normalize/:ensure-system-package (_name-symbol keyword args) - "Turn `arg' into a list of cons-es of (`package-name' . `install-command')." + "Turn ARGS into a list of conses of (`package-name' . `install-command')." (use-package-as-one (symbol-name keyword) args (lambda (_label arg) (cond diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index 78a7e8be1e2..a879c294dc3 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -37,7 +37,7 @@ (require 'use-package-core) (defgroup use-package-ensure nil - "Support for :ensure and :pin keywords in use-package declarations." + "Support for :ensure and :pin keywords in `use-package' declarations." :group 'use-package) (eval-when-compile @@ -64,7 +64,7 @@ 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 +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. @@ -111,7 +111,7 @@ manually updated package." (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." + (error "Archive '%s' requested for package '%s' is not available" archive-name package)) (unless (bound-and-true-p package--initialized) (package-initialize t)))) diff --git a/lisp/use-package/use-package-jump.el b/lisp/use-package/use-package-jump.el index 224d2e06b6e..6b9c02808e1 100644 --- a/lisp/use-package/use-package-jump.el +++ b/lisp/use-package/use-package-jump.el @@ -30,8 +30,8 @@ ;; 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 delay-loaded, it will not work. Improvements are -;; needed. +;; initialization. If it was delay-loaded, it will not work. +;; Improvements are needed. ;;; Code: @@ -48,11 +48,10 @@ Returns an absolute file path or nil if none is found." ;;;###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." + "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)) diff --git a/lisp/use-package/use-package-lint.el b/lisp/use-package/use-package-lint.el index 49a47a9d32b..12974ab15e4 100644 --- a/lisp/use-package/use-package-lint.el +++ b/lisp/use-package/use-package-lint.el @@ -63,7 +63,7 @@ ;;;###autoload (defun use-package-lint () - "Check for errors in use-package declarations. + "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) diff --git a/test/lisp/use-package/use-package-chords-tests.el b/test/lisp/use-package/use-package-chords-tests.el index 3c3dc4b4fe0..2b7588dd807 100644 --- a/test/lisp/use-package/use-package-chords-tests.el +++ b/test/lisp/use-package/use-package-chords-tests.el @@ -158,4 +158,4 @@ ;; no-update-autoloads: t ;; End: -;;; use-package-tests.el ends here +;;; use-package-chords-tests.el ends here From 4e8b72efc836f8e7941345b6d5fdc168f470e056 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Sun, 13 Nov 2022 23:49:47 +0100 Subject: [PATCH 580/606] manual: Regenerate texi file --- doc/misc/use-package.texi | 82 +++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index 2b868564372..a5f850c8753 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -8,7 +8,7 @@ @copying @quotation -Copyright (C) 2012-2022 John Wiegley +Copyright (C) 2012-2022 Free Software Foundation, Inc. You can redistribute this document and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -31,7 +31,7 @@ General Public License for more details. @finalout @titlepage @title use-package User Manual -@subtitle for version 2.4.1-81-gb185c6b+1 +@subtitle for version 2.4.1-119-g0be480e+1 @author John Wiegley @page @vskip 0pt plus 1filll @@ -73,25 +73,25 @@ Installation Keywords -* @code{after}:: -* @code{bind-keymap}, @code{bind-keymap*}: @code{bind-keymap} @code{bind-keymap*}. -* @code{bind}, @code{bind*}: @code{bind} @code{bind*}. -* @code{commands}:: -* @code{preface}, @code{init}, @code{config}: @code{preface} @code{init} @code{config}. -* @code{custom}:: -* @code{custom-face}:: -* @code{defer}, @code{demand}: @code{defer} @code{demand}. -* @code{defines}, @code{functions}: @code{defines} @code{functions}. -* @code{diminish}, @code{delight}: @code{diminish} @code{delight}. -* @code{disabled}:: -* @code{ensure}, @code{pin}: @code{ensure} @code{pin}. -* @code{hook}:: -* @code{if}, @code{when}, @code{unless}: @code{if} @code{when} @code{unless}. -* @code{load-path}:: -* @code{mode}, @code{interpreter}: @code{mode} @code{interpreter}. -* @code{magic}, @code{magic-fallback}: @code{magic} @code{magic-fallback}. -* @code{no-require}:: -* @code{requires}:: +* @code{:after}: @code{after}. +* @code{:bind-keymap}, @code{:bind-keymap*}: @code{bind-keymap} @code{bind-keymap*}. +* @code{:bind}, @code{:bind*}: @code{bind} @code{bind*}. +* @code{:commands}: @code{commands}. +* @code{:preface}, @code{:init}, @code{:config}: @code{preface} @code{init} @code{config}. +* @code{:custom}: @code{custom}. +* @code{:custom-face}: @code{custom-face}. +* @code{:defer}, @code{:demand}: @code{defer} @code{demand}. +* @code{:defines}, @code{:functions}: @code{defines} @code{functions}. +* @code{:diminish}, @code{:delight}: @code{diminish} @code{delight}. +* @code{:disabled}: @code{disabled}. +* @code{:ensure}, @code{:pin}: @code{ensure} @code{pin}. +* @code{:hook}: @code{hook}. +* @code{:if}, @code{:when}, @code{:unless}: @code{if} @code{when} @code{unless}. +* @code{:load-path}: @code{load-path}. +* @code{:mode}, @code{:interpreter}: @code{mode} @code{interpreter}. +* @code{:magic}, @code{:magic-fallback}: @code{magic} @code{magic-fallback}. +* @code{:no-require}: @code{no-require}. +* @code{:requires}: @code{requires}. @code{:bind}, @code{:bind*} @@ -239,7 +239,7 @@ C-h v use-package-version RET should display something like @example -use-package-version’s value is "2.4.1" +use-package-version’s value is "2.4.3" @end example If you are completely new to use-package then see @ref{Getting Started}. @@ -290,25 +290,25 @@ used for speed (reason 3), it can still be used as a sanity check. @chapter Keywords @menu -* @code{after}:: -* @code{bind-keymap}, @code{bind-keymap*}: @code{bind-keymap} @code{bind-keymap*}. -* @code{bind}, @code{bind*}: @code{bind} @code{bind*}. -* @code{commands}:: -* @code{preface}, @code{init}, @code{config}: @code{preface} @code{init} @code{config}. -* @code{custom}:: -* @code{custom-face}:: -* @code{defer}, @code{demand}: @code{defer} @code{demand}. -* @code{defines}, @code{functions}: @code{defines} @code{functions}. -* @code{diminish}, @code{delight}: @code{diminish} @code{delight}. -* @code{disabled}:: -* @code{ensure}, @code{pin}: @code{ensure} @code{pin}. -* @code{hook}:: -* @code{if}, @code{when}, @code{unless}: @code{if} @code{when} @code{unless}. -* @code{load-path}:: -* @code{mode}, @code{interpreter}: @code{mode} @code{interpreter}. -* @code{magic}, @code{magic-fallback}: @code{magic} @code{magic-fallback}. -* @code{no-require}:: -* @code{requires}:: +* @code{:after}: @code{after}. +* @code{:bind-keymap}, @code{:bind-keymap*}: @code{bind-keymap} @code{bind-keymap*}. +* @code{:bind}, @code{:bind*}: @code{bind} @code{bind*}. +* @code{:commands}: @code{commands}. +* @code{:preface}, @code{:init}, @code{:config}: @code{preface} @code{init} @code{config}. +* @code{:custom}: @code{custom}. +* @code{:custom-face}: @code{custom-face}. +* @code{:defer}, @code{:demand}: @code{defer} @code{demand}. +* @code{:defines}, @code{:functions}: @code{defines} @code{functions}. +* @code{:diminish}, @code{:delight}: @code{diminish} @code{delight}. +* @code{:disabled}: @code{disabled}. +* @code{:ensure}, @code{:pin}: @code{ensure} @code{pin}. +* @code{:hook}: @code{hook}. +* @code{:if}, @code{:when}, @code{:unless}: @code{if} @code{when} @code{unless}. +* @code{:load-path}: @code{load-path}. +* @code{:mode}, @code{:interpreter}: @code{mode} @code{interpreter}. +* @code{:magic}, @code{:magic-fallback}: @code{magic} @code{magic-fallback}. +* @code{:no-require}: @code{no-require}. +* @code{:requires}: @code{requires}. @end menu @node @code{after} From 6a26c55d70a653af8606166d2b24b2c1516647dc Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Sat, 12 Nov 2022 10:15:40 +0100 Subject: [PATCH 581/606] Recommend GNU ELPA over MELPA --- doc/misc/use-package.texi | 43 +++++++++------------------------------ 1 file changed, 10 insertions(+), 33 deletions(-) diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index 2b868564372..de6351c592f 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -67,7 +67,7 @@ around 2 seconds, with no loss of functionality! Installation -* Installing from an Elpa Archive:: +* Installing from GNU ELPA:: * Installing from the Git Repository:: * Post-Installation Tasks:: @@ -119,50 +119,27 @@ use-package can be installed using Emacs' package manager or manually from its development repository. @menu -* Installing from an Elpa Archive:: +* Installing from GNU ELPA:: * Installing from the Git Repository:: * Post-Installation Tasks:: @end menu -@node Installing from an Elpa Archive -@section Installing from an Elpa Archive +@node Installing from GNU ELPA +@section Installing from GNU ELPA -use-package is available from Melpa and Melpa-Stable. If you haven't used -Emacs' package manager before, then it is high time you familiarize yourself +use-package is available from GNU ELPA. If you haven't used Emacs' +package manager before, then it is high time you familiarize yourself with it by reading the documentation in the Emacs manual, see -@ref{Packages,,,emacs,}. Then add one of the archives to @code{package-archives}: +@ref{Packages,,,emacs,}. -@itemize -@item -To use Melpa: -@end itemize - -@lisp -(require 'package) -(add-to-list 'package-archives - '("melpa" . "https://melpa.org/packages/") t) -@end lisp - -@itemize -@item -To use Melpa-Stable: -@end itemize - -@lisp -(require 'package) -(add-to-list 'package-archives - '("melpa-stable" . "https://stable.melpa.org/packages/") t) -@end lisp - -Once you have added your preferred archive, you need to update the -local package list using: +First, you need to update the local package list using: @example M-x package-refresh-contents RET @end example -Once you have done that, you can install use-package and its dependencies -using: +Once you have done that, you can install use-package and its +dependencies using: @example M-x package-install RET use-package RET From a6b1b6276370eff2ad89f33115518cb4c297eb23 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Tue, 15 Nov 2022 08:51:39 +0100 Subject: [PATCH 582/606] Use two spaces to end sentences --- doc/misc/use-package.texi | 82 +++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index a5f850c8753..fc504305b48 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -45,9 +45,9 @@ General Public License for more details. @top use-package User Manual The @code{use-package} macro allows you to isolate package configuration in your -@code{.emacs} file in a way that is both performance-oriented and, well, tidy. I +@code{.emacs} file in a way that is both performance-oriented and, well, 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 +were getting difficult to manage. Yet with this utility my total load time is around 2 seconds, with no loss of functionality! @insertcopying @@ -105,9 +105,9 @@ Keywords @chapter Introduction The @code{use-package} macro allows you to isolate package configuration in your -@code{.emacs} file in a way that is both performance-oriented and, well, tidy. I +@code{.emacs} file in a way that is both performance-oriented and, well, 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 +were getting difficult to manage. Yet with this utility my total load time is around 2 seconds, with no loss of functionality! More text to come@dots{} @@ -127,10 +127,10 @@ its development repository. @node Installing from an Elpa Archive @section Installing from an Elpa Archive -use-package is available from Melpa and Melpa-Stable. If you haven't used +use-package is available from Melpa and Melpa-Stable. If you haven't used Emacs' package manager before, then it is high time you familiarize yourself with it by reading the documentation in the Emacs manual, see -@ref{Packages,,,emacs,}. Then add one of the archives to @code{package-archives}: +@ref{Packages,,,emacs,}. Then add one of the archives to @code{package-archives}: @itemize @item @@ -229,7 +229,7 @@ Now see @ref{Post-Installation Tasks}. @section Post-Installation Tasks After installing use-package you should verify that you are indeed using the -use-package release you think you are using. It's best to restart Emacs before +use-package release you think you are using. It's best to restart Emacs before doing so, to make sure you are not using an outdated value for @code{load-path}. @example @@ -249,13 +249,13 @@ If you run into problems, then please see the @ref{Debugging Tools}. @node Getting Started @chapter Getting Started -TODO@. For now, see @code{README.md}. +TODO@. For now, see @code{README.md}. @node Basic Concepts @chapter Basic Concepts @code{use-package} was created for few basic reasons, each of which drove the -design in various ways. Understanding these reasons may help make some of +design in various ways. Understanding these reasons may help make some of those decisions clearer: @itemize @@ -279,7 +279,7 @@ close to a functional Emacs as possible. @item To allow byte-compilation of one's init file so that any warnings or -errors seen are meaningful. In this way, even if byte-compilation is not +errors seen are meaningful. In this way, even if byte-compilation is not used for speed (reason 3), it can still be used as a sanity check. @end itemize @@ -316,8 +316,8 @@ used for speed (reason 3), it can still be used as a sanity check. Sometimes it only makes sense to configure a package after another has been loaded, because certain variables or functions are not in scope until that -time. This can achieved using an @code{:after} keyword that allows a fairly rich -description of the exact conditions when loading should occur. Here is an +time. This can achieved using an @code{:after} keyword that allows a fairly rich +description of the exact conditions when loading should occur. Here is an example: @lisp @@ -332,13 +332,13 @@ example: @end lisp In this case, because all of these packages are demand-loaded in the order -they occur, the use of @code{:after} is not strictly necessary. By using it, +they occur, the use of @code{:after} is not strictly necessary. By using it, however, the above code becomes order-independent, without an implicit depedence on the nature of your init file. By default, @code{:after (foo bar)} is the same as @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: +have been loaded. Here are some of the other possibilities: @lisp :after (foo bar) @@ -354,7 +354,7 @@ been loaded, or both @code{baz} and @code{quux} have been loaded. @strong{NOTE}: Pay attention if you set @code{use-package-always-defer} to t, and also use the @code{:after} keyword, as you will need to specify how the declared package is -to be loaded: e.g., by some @code{:bind}. If you're not using one of the mechanisms +to be loaded: e.g., by some @code{:bind}. If you're not using one of the mechanisms that registers autoloads, such as @code{:bind} or @code{:hook}, and your package manager does not provide autoloads, it's possible that without adding @code{:demand t} to those declarations, your package will never be loaded. @@ -363,14 +363,14 @@ those declarations, your package will never be loaded. @section @code{:bind-keymap}, @code{: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 +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 Emacs' @code{autoload} mechanism. 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" +@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 -command functions. This is handled behind the scenes by generating custom code +command 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. @@ -409,7 +409,7 @@ A more literal way to do the exact same thing is: @end lisp When you use the @code{:commands} keyword, it creates autoloads for those commands -and defers loading of the module until they are used. Since the @code{:init} form +and defers loading of the module until they are used. Since the @code{:init} form is always run---even if @code{ace-jump-mode} might not be on your system---remember to restrict @code{:init} code to only what would succeed either way. @@ -425,7 +425,7 @@ The @code{:bind} keyword takes either a cons or a list of conses: The @code{:commands} keyword likewise takes either a symbol or a list of symbols. NOTE: Special keys like @code{tab} or @code{F1}-@code{Fn} can be written in square brackets, -i.e. @code{[tab]} instead of @code{"tab"}. The syntax for the keybindings is similar to +i.e. @code{[tab]} instead of @code{"tab"}. The syntax for the keybindings is similar to the "kbd" syntax: see @uref{https://www.gnu.org/software/emacs/manual/html_node/emacs/Init-Rebinding.html, the Emacs Manual} for more information. Examples: @@ -459,7 +459,7 @@ The effect of this statement is to wait until @code{helm} has loaded, and then t bind the key @code{C-c h} to @code{helm-execute-persistent-action} within Helm's local keymap, @code{helm-mode-map}. -Multiple uses of @code{:map} may be specified. Any binding occurring before the +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 @@ -493,7 +493,7 @@ Here is the simplest @code{use-package} declaration: @end lisp This loads in the package @code{foo}, but only if @code{foo} is available on your -system. If not, a warning is logged to the @code{*Messages*} buffer. If it +system. If not, a warning is logged to the @code{*Messages*} buffer. If it succeeds, a message about @code{"Loading foo"} is logged, along with the time it took to load, if it took over 0.1 seconds. @@ -567,14 +567,14 @@ The @code{:custom-face} keyword allows customization of package custom faces. @node @code{defer} @code{demand} @section @code{:defer}, @code{:demand} -In almost all cases you don't need to manually specify @code{:defer t}. This is -implied whenever @code{:bind} or @code{:mode} or @code{:interpreter} is used. Typically, you +In almost all cases you don't need to manually specify @code{:defer t}. This is +implied whenever @code{:bind} or @code{:mode} or @code{:interpreter} is used. Typically, you only need to specify @code{:defer} if you know for a fact that some other package will do something to cause your package to load at the appropriate time, and thus you would like to defer loading even though use-package isn't creating any autoloads for you. -You can override package deferral with the @code{:demand} keyword. Thus, even if +You can override package deferral with the @code{:demand} keyword. Thus, even if you use @code{:bind}, using @code{:demand} will force loading to occur immediately and not establish an autoload for the bound key. @@ -616,7 +616,7 @@ If you need to silence a missing function warning, you can use @code{:functions} @section @code{:diminish}, @code{:delight} @code{use-package} also provides built-in support for the diminish and delight -utilities---if you have them installed. Their purpose is to remove or change +utilities---if you have them installed. Their purpose is to remove or change minor mode strings in your mode-line. @uref{https://github.com/myrjola/diminish.el, diminish} is invoked with the @code{:diminish} keyword, which is passed either a @@ -635,7 +635,7 @@ package name with "-mode" appended at the end: @uref{https://elpa.gnu.org/packages/delight.html, delight} is invoked with the @code{:delight} keyword, which is passed a minor mode symbol, a replacement string or quoted @uref{https://www.gnu.org/software/emacs/manual/html_node/elisp/Mode-Line-Data.html, mode-line data} (in which case the minor mode symbol is guessed to be the package name with "-mode" appended at the -end), both of these, or several lists of both. If no arguments are provided, +end), both of these, or several lists of both. If no arguments are provided, the default mode name is hidden completely. @lisp @@ -677,7 +677,7 @@ from the output entirely, to accelerate startup times. @node @code{ensure} @code{pin} @section @code{:ensure}, @code{:pin} -You can use @code{use-package} to load packages from ELPA with @code{package.el}. This +You can use @code{use-package} to load packages from ELPA with @code{package.el}. This is particularly useful if you share your @code{.emacs} among several machines; the relevant packages are downloaded automatically once declared in your @code{.emacs}. The @code{:ensure} keyword causes the package(s) to be installed automatically if @@ -707,7 +707,7 @@ archives is also a valid use-case. By default @code{package.el} prefers @code{melpa} over @code{melpa-stable} due to the versioning @code{(> evil-20141208.623 evil-1.0.9)}, so even if you are tracking only a single package from @code{melpa}, you will need to tag all the non-@code{melpa} -packages with the appropriate archive. If this really annoys you, then you can +packages with the appropriate archive. If this really annoys you, then you can set @code{use-package-always-pin} to set a default. If you want to manually keep a package updated and ignore upstream updates, @@ -752,7 +752,7 @@ Example: @section @code{:hook} The @code{:hook} keyword allows adding functions onto hooks, here only the basename -of the hook is required. Thus, all of the following are equivalent: +of the hook is required. Thus, all of the following are equivalent: @lisp (use-package ace-jump-mode @@ -827,8 +827,8 @@ the same thing as @code{:if (not foo)}. @section @code{:load-path} If your package needs a directory added to the @code{load-path} in order to load, -use @code{:load-path}. This takes a symbol, a function, a string or a list of -strings. If the path is relative, it is expanded within +use @code{:load-path}. This takes a symbol, a function, a string or a list of +strings. If the path is relative, it is expanded within @code{user-emacs-directory}: @lisp @@ -839,8 +839,8 @@ strings. If the path is relative, it is expanded within Note that when using a symbol or a function to provide a dynamically generated list of paths, you must inform the byte-compiler of this definition so 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}). Further, this +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}). Further, this value is fixed at whatever was determined during compilation, to avoid looking up the same information again on each startup: @@ -859,7 +859,7 @@ up the same information again on each startup: 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. The specifier to either keyword can be a cons cell, a list of cons +variables. The specifier to either keyword can be a cons cell, a list of cons cells, or a string or regexp: @lisp @@ -898,8 +898,8 @@ This does exactly the same thing as the following: 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. The difference between the two is -that @code{:magic-fallback} has a lower priority than @code{:mode}. For example: +file matches a given regular expression. The difference between the two is +that @code{:magic-fallback} has a lower priority than @code{:mode}. For example: @lisp (use-package pdf-tools @@ -918,9 +918,9 @@ string @code{"%PDF"}. 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 +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 +@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 @@ -936,8 +936,8 @@ such cases, use the @code{:no-require} keyword: While the @code{:after} keyword delays loading until the dependencies are loaded, the somewhat simpler @code{:requires} keyword simply never loads the package if the dependencies are not available at the time the @code{use-package} declaration is -encountered. By "available" in this context it means that @code{foo} is available -of @code{(featurep 'foo)} evaluates to a non-nil value. For example: +encountered. By "available" in this context it means that @code{foo} is available +of @code{(featurep 'foo)} evaluates to a non-nil value. For example: @lisp (use-package abbrev From 8cf8631c695fa4ee40a6cc2942a44288e05386f3 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Tue, 15 Nov 2022 09:41:47 +0100 Subject: [PATCH 583/606] Fix makeinfo warnings Resolves https://github.com/jwiegley/use-package/issues/962 --- doc/misc/use-package.texi | 78 +++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index fc504305b48..9f5b57fcbaf 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -73,27 +73,27 @@ Installation Keywords -* @code{:after}: @code{after}. -* @code{:bind-keymap}, @code{:bind-keymap*}: @code{bind-keymap} @code{bind-keymap*}. -* @code{:bind}, @code{:bind*}: @code{bind} @code{bind*}. -* @code{:commands}: @code{commands}. -* @code{:preface}, @code{:init}, @code{:config}: @code{preface} @code{init} @code{config}. -* @code{:custom}: @code{custom}. -* @code{:custom-face}: @code{custom-face}. -* @code{:defer}, @code{:demand}: @code{defer} @code{demand}. -* @code{:defines}, @code{:functions}: @code{defines} @code{functions}. -* @code{:diminish}, @code{:delight}: @code{diminish} @code{delight}. -* @code{:disabled}: @code{disabled}. -* @code{:ensure}, @code{:pin}: @code{ensure} @code{pin}. -* @code{:hook}: @code{hook}. -* @code{:if}, @code{:when}, @code{:unless}: @code{if} @code{when} @code{unless}. -* @code{:load-path}: @code{load-path}. -* @code{:mode}, @code{:interpreter}: @code{mode} @code{interpreter}. -* @code{:magic}, @code{:magic-fallback}: @code{magic} @code{magic-fallback}. -* @code{:no-require}: @code{no-require}. -* @code{:requires}: @code{requires}. +* @code{after}:: @code{:after}. +* @code{bind-keymap} @code{bind-keymap*}:: @code{:bind-keymap}, @code{:bind-keymap*}. +* @code{bind} @code{bind*}:: @code{:bind}, @code{:bind*}. +* @code{commands}:: @code{:commands}. +* @code{preface} @code{init} @code{config}:: @code{:preface}, @code{:init}, @code{:config}. +* @code{custom}:: @code{:custom}. +* @code{custom-face}:: @code{:custom-face}. +* @code{defer} @code{demand}:: @code{:defer}, @code{:demand}. +* @code{defines} @code{functions}:: @code{:defines}, @code{:functions}. +* @code{diminish} @code{delight}:: @code{:diminish}, @code{:delight}. +* @code{disabled}:: @code{:disabled}. +* @code{ensure} @code{pin}:: @code{:ensure}, @code{:pin}. +* @code{hook}:: @code{:hook}. +* @code{if} @code{when} @code{unless}:: @code{:if}, @code{:when}, @code{:unless}. +* @code{load-path}:: @code{:load-path}. +* @code{mode} @code{interpreter}:: @code{:mode}, @code{:interpreter}. +* @code{magic} @code{magic-fallback}:: @code{:magic}, @code{:magic-fallback}. +* @code{no-require}:: @code{:no-require}. +* @code{requires}:: @code{:requires}. -@code{:bind}, @code{:bind*} +@code{bind}, @code{bind*} * Binding to local keymaps:: @@ -290,25 +290,25 @@ used for speed (reason 3), it can still be used as a sanity check. @chapter Keywords @menu -* @code{:after}: @code{after}. -* @code{:bind-keymap}, @code{:bind-keymap*}: @code{bind-keymap} @code{bind-keymap*}. -* @code{:bind}, @code{:bind*}: @code{bind} @code{bind*}. -* @code{:commands}: @code{commands}. -* @code{:preface}, @code{:init}, @code{:config}: @code{preface} @code{init} @code{config}. -* @code{:custom}: @code{custom}. -* @code{:custom-face}: @code{custom-face}. -* @code{:defer}, @code{:demand}: @code{defer} @code{demand}. -* @code{:defines}, @code{:functions}: @code{defines} @code{functions}. -* @code{:diminish}, @code{:delight}: @code{diminish} @code{delight}. -* @code{:disabled}: @code{disabled}. -* @code{:ensure}, @code{:pin}: @code{ensure} @code{pin}. -* @code{:hook}: @code{hook}. -* @code{:if}, @code{:when}, @code{:unless}: @code{if} @code{when} @code{unless}. -* @code{:load-path}: @code{load-path}. -* @code{:mode}, @code{:interpreter}: @code{mode} @code{interpreter}. -* @code{:magic}, @code{:magic-fallback}: @code{magic} @code{magic-fallback}. -* @code{:no-require}: @code{no-require}. -* @code{:requires}: @code{requires}. +* @code{after}:: @code{after}. +* @code{bind-keymap} @code{bind-keymap*}:: @code{:bind-keymap}, @code{:bind-keymap*}. +* @code{bind} @code{bind*}:: @code{bind} @code{:bind*}. +* @code{commands}:: @code{:commands}. +* @code{preface} @code{init} @code{config}:: @code{:preface}, @code{:init}, @code{:config}. +* @code{custom}:: @code{:custom}. +* @code{custom-face}:: @code{:custom-face}. +* @code{defer} @code{demand}:: @code{:defer}, @code{:demand}. +* @code{defines} @code{functions}:: @code{:defines}, @code{:functions}. +* @code{diminish} @code{delight}:: @code{:diminish}, @code{:delight}. +* @code{disabled}:: @code{:disabled}. +* @code{ensure} @code{pin}:: @code{:ensure}, @code{:pin}. +* @code{hook}:: @code{:hook}. +* @code{if} @code{when} @code{unless}:: @code{:if}, @code{:when}, @code{:unless}. +* @code{load-path}:: @code{:load-path}. +* @code{mode} @code{interpreter}:: @code{:mode}, @code{:interpreter}. +* @code{magic} @code{magic-fallback}:: @code{:magic}, @code{:magic-fallback}. +* @code{no-require}:: @code{:no-require}. +* @code{requires}:: @code{:requires}. @end menu @node @code{after} From 3e81af80a2fdf200395aea6bdf15dd897303956f Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 15 Nov 2022 15:24:12 -0800 Subject: [PATCH 584/606] Revert "Allow multiple keymaps in :map argument" --- doc/misc/use-package.texi | 70 ++++++------- lisp/use-package/bind-chord.el | 3 +- lisp/use-package/bind-key.el | 109 +++++++++------------ lisp/use-package/use-package-bind-key.el | 13 ++- test/lisp/use-package/use-package-tests.el | 83 +--------------- 5 files changed, 92 insertions(+), 186 deletions(-) diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index a11416a470c..573baac89aa 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -73,25 +73,25 @@ Installation Keywords -* @code{after}:: @code{:after}. -* @code{bind-keymap} @code{bind-keymap*}:: @code{:bind-keymap}, @code{:bind-keymap*}. -* @code{bind} @code{bind*}:: @code{:bind}, @code{:bind*}. -* @code{commands}:: @code{:commands}. -* @code{preface} @code{init} @code{config}:: @code{:preface}, @code{:init}, @code{:config}. -* @code{custom}:: @code{:custom}. -* @code{custom-face}:: @code{:custom-face}. -* @code{defer} @code{demand}:: @code{:defer}, @code{:demand}. -* @code{defines} @code{functions}:: @code{:defines}, @code{:functions}. -* @code{diminish} @code{delight}:: @code{:diminish}, @code{:delight}. -* @code{disabled}:: @code{:disabled}. -* @code{ensure} @code{pin}:: @code{:ensure}, @code{:pin}. -* @code{hook}:: @code{:hook}. -* @code{if} @code{when} @code{unless}:: @code{:if}, @code{:when}, @code{:unless}. +* @code{after}:: @code{:after}. +* @code{bind-keymap} @code{bind-keymap*}:: @code{:bind-keymap}, @code{:bind-keymap*}. +* @code{bind} @code{bind*}:: @code{:bind}, @code{:bind*}. +* @code{commands}:: @code{:commands}. +* @code{preface} @code{init} @code{config}:: @code{:preface}, @code{:init}, @code{:config}. +* @code{custom}:: @code{:custom}. +* @code{custom-face}:: @code{:custom-face}. +* @code{defer} @code{demand}:: @code{:defer}, @code{:demand}. +* @code{defines} @code{functions}:: @code{:defines}, @code{:functions}. +* @code{diminish} @code{delight}:: @code{:diminish}, @code{:delight}. +* @code{disabled}:: @code{:disabled}. +* @code{ensure} @code{pin}:: @code{:ensure}, @code{:pin}. +* @code{hook}:: @code{:hook}. +* @code{if} @code{when} @code{unless}:: @code{:if}, @code{:when}, @code{:unless}. * @code{load-path}:: @code{:load-path}. -* @code{mode} @code{interpreter}:: @code{:mode}, @code{:interpreter}. -* @code{magic} @code{magic-fallback}:: @code{:magic}, @code{:magic-fallback}. +* @code{mode} @code{interpreter}:: @code{:mode}, @code{:interpreter}. +* @code{magic} @code{magic-fallback}:: @code{:magic}, @code{:magic-fallback}. * @code{no-require}:: @code{:no-require}. -* @code{requires}:: @code{:requires}. +* @code{requires}:: @code{:requires}. @code{bind}, @code{bind*} @@ -267,25 +267,25 @@ used for speed (reason 3), it can still be used as a sanity check. @chapter Keywords @menu -* @code{after}:: @code{after}. -* @code{bind-keymap} @code{bind-keymap*}:: @code{:bind-keymap}, @code{:bind-keymap*}. +* @code{after}:: @code{after}. +* @code{bind-keymap} @code{bind-keymap*}:: @code{:bind-keymap}, @code{:bind-keymap*}. * @code{bind} @code{bind*}:: @code{bind} @code{:bind*}. -* @code{commands}:: @code{:commands}. -* @code{preface} @code{init} @code{config}:: @code{:preface}, @code{:init}, @code{:config}. -* @code{custom}:: @code{:custom}. -* @code{custom-face}:: @code{:custom-face}. -* @code{defer} @code{demand}:: @code{:defer}, @code{:demand}. -* @code{defines} @code{functions}:: @code{:defines}, @code{:functions}. -* @code{diminish} @code{delight}:: @code{:diminish}, @code{:delight}. -* @code{disabled}:: @code{:disabled}. -* @code{ensure} @code{pin}:: @code{:ensure}, @code{:pin}. -* @code{hook}:: @code{:hook}. -* @code{if} @code{when} @code{unless}:: @code{:if}, @code{:when}, @code{:unless}. -* @code{load-path}:: @code{:load-path}. -* @code{mode} @code{interpreter}:: @code{:mode}, @code{:interpreter}. -* @code{magic} @code{magic-fallback}:: @code{:magic}, @code{:magic-fallback}. -* @code{no-require}:: @code{:no-require}. -* @code{requires}:: @code{:requires}. +* @code{commands}:: @code{:commands}. +* @code{preface} @code{init} @code{config}:: @code{:preface}, @code{:init}, @code{:config}. +* @code{custom}:: @code{:custom}. +* @code{custom-face}:: @code{:custom-face}. +* @code{defer} @code{demand}:: @code{:defer}, @code{:demand}. +* @code{defines} @code{functions}:: @code{:defines}, @code{:functions}. +* @code{diminish} @code{delight}:: @code{:diminish}, @code{:delight}. +* @code{disabled}:: @code{:disabled}. +* @code{ensure} @code{pin}:: @code{:ensure}, @code{:pin}. +* @code{hook}:: @code{:hook}. +* @code{if} @code{when} @code{unless}:: @code{:if}, @code{:when}, @code{:unless}. +* @code{load-path}:: @code{:load-path}. +* @code{mode} @code{interpreter}:: @code{:mode}, @code{:interpreter}. +* @code{magic} @code{magic-fallback}:: @code{:magic}, @code{:magic-fallback}. +* @code{no-require}:: @code{:no-require}. +* @code{requires}:: @code{:requires}. @end menu @node @code{after} diff --git a/lisp/use-package/bind-chord.el b/lisp/use-package/bind-chord.el index d592736e227..bf0f5866ac4 100644 --- a/lisp/use-package/bind-chord.el +++ b/lisp/use-package/bind-chord.el @@ -92,8 +92,7 @@ function symbol (unquoted)." "Bind multiple chords at once. Accepts keyword argument: -:map - a keymap or list of keymaps into which the keybindings should be - added +: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)." diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index b02b7a4ad9f..f0b9cdb588d 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -248,12 +248,12 @@ In contrast to `define-key', this function removes the binding from the keymap." "Similar to `bind-key', but overrides any mode-specific bindings." `(bind-key ,key-name ,command override-global-map ,predicate)) -(defun bind-keys-form (args &rest keymaps) +(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, or a list of such keymaps + added :prefix KEY - prefix key for these bindings :prefix-map MAP - name of the prefix map that should be created for these bindings @@ -276,7 +276,7 @@ Accepts keyword arguments: The rest of the arguments are conses of keybinding string and a function symbol (unquoted)." - (let (maps + (let (map prefix-doc prefix-map prefix @@ -293,17 +293,20 @@ function symbol (unquoted)." (while (and cont args) (if (cond ((and (eq :map (car args)) (not prefix-map)) - (let ((arg (cadr args))) - (setq maps (if (listp arg) arg (list arg))))) + (setq map (cadr args))) ((eq :prefix-docstring (car args)) (setq prefix-doc (cadr args))) - ((eq :prefix-map (car 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))) - ((eq :repeat-map (car args)) + ((and (eq :repeat-map (car args)) + (not (memq map '(global-map + override-global-map)))) (setq repeat-map (cadr args)) - (setq maps (list repeat-map))) + (setq map repeat-map)) ((eq :continue (car args)) (setq repeat-type :continue arg-change-func 'cdr)) @@ -332,8 +335,7 @@ function symbol (unquoted)." (when (and menu-name (not prefix)) (error "If :menu-name is supplied, :prefix must be too")) - (unless maps (setq maps keymaps)) - (unless maps (setq maps (list nil))) + (unless map (setq map keymap)) ;; Process key binding arguments (let (first next) @@ -347,67 +349,50 @@ function symbol (unquoted)." (setq first (list (car args)))) (setq args (cdr args)))) - (cl-labels - ((wrap (maps bindings) - (if (and pkg - (cl-every - (lambda (map) - (and map - (not (memq map '(global-map - override-global-map))))) - maps)) - `((if (mapcan 'boundp ',maps) + (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))))) - (if 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))) - ,@(cl-mapcan - (lambda (map) - (wrap (list map) - `((bind-key ,prefix ',prefix-map ,map ,filter)))) - maps) - ,@(wrap maps - (cl-mapcan - (lambda (form) - (let ((fun - (and (cdr form) (list 'function (cdr form))))) - `((bind-key ,(car form) ,fun ,prefix-map ,filter)))) - first))) - (cl-mapcan - (lambda (map) - (wrap (list map) - (cl-mapcan - (lambda (form) - (let ((fun (and (cdr form) (list 'function (cdr form))))) - (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))) - maps)) + (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 - (apply 'bind-keys-form - `(,@(when repeat-map `(:repeat-map ,repeat-map)) - ,@(if pkg - (cons :package (cons pkg next)) - next)) - maps))))))) + (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) @@ -415,7 +400,7 @@ function symbol (unquoted)." Accepts keyword arguments: :map MAP - a keymap into which the keybindings should be - added, or a list of such keymaps + added :prefix KEY - prefix key for these bindings :prefix-map MAP - name of the prefix map that should be created for these bindings diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index 460d6255e93..5e6a10925ca 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -86,20 +86,19 @@ deferred until the prefix key sequence is pressed." ;; :prefix-docstring STRING ;; :prefix-map SYMBOL ;; :prefix STRING - ;; :repeat-docstring 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) (or (symbolp (cadr arg)) - (listp (cadr arg)))) + ;; :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-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))) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 709c1988ffb..185f7691ba9 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1964,92 +1964,15 @@ (autoload #'nonexistent-mode "nonexistent" nil t)) (add-hook 'lisp-mode-hook #'nonexistent-mode))))) -(ert-deftest bind-key/:map () - (match-expansion - (bind-keys - ("C-1" . command-1) - ("C-2" . command-2) - :map keymap-1 - ("C-3" . command-3) - ("C-4" . command-4) - :map (keymap-2 keymap-3) - ("C-5" . command-5) - ("C-6" . command-6)) - `(progn (bind-key "C-1" #'command-1 nil nil) - (bind-key "C-2" #'command-2 nil nil) - (bind-key "C-3" #'command-3 keymap-1 nil) - (bind-key "C-4" #'command-4 keymap-1 nil) - (bind-key "C-5" #'command-5 keymap-2 nil) - (bind-key "C-6" #'command-6 keymap-2 nil) - (bind-key "C-5" #'command-5 keymap-3 nil) - (bind-key "C-6" #'command-6 keymap-3 nil)))) - (ert-deftest bind-key/:prefix-map () (match-expansion - (bind-keys ("C-1" . command-1) - :prefix "" - :prefix-map my/map - ("C-2" . command-2) - ("C-3" . command-3)) + (bind-keys :prefix "" + :prefix-map my/map) `(progn - (bind-key "C-1" #'command-1 nil nil) (defvar my/map) (define-prefix-command 'my/map) - (bind-key "" 'my/map nil nil) - (bind-key "C-2" #'command-2 my/map nil) - (bind-key "C-3" #'command-3 my/map nil)))) + (bind-key "" 'my/map nil nil)))) -(ert-deftest bind-key/:repeat-map-1 () - ;; NOTE: This test is pulled from the discussion in issue #964, - ;; adjusting for the final syntax that was implemented. - (match-expansion - (bind-keys - ("C-c n" . git-gutter+-next-hunk) - ("C-c p" . git-gutter+-previous-hunk) - ("C-c s" . git-gutter+-stage-hunks) - ("C-c r" . git-gutter+-revert-hunk) - :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) - :repeat-docstring - "Keymap to repeat git-gutter+-* commands.") - `(progn - (bind-key "C-c n" #'git-gutter+-next-hunk nil nil) - (bind-key "C-c p" #'git-gutter+-previous-hunk nil nil) - (bind-key "C-c s" #'git-gutter+-stage-hunks nil nil) - (bind-key "C-c r" #'git-gutter+-revert-hunk nil nil) - (defvar my/git-gutter+-repeat-map (make-sparse-keymap)) - (put #'git-gutter+-next-hunk 'repeat-map 'my/git-gutter+-repeat-map) - (bind-key "n" #'git-gutter+-next-hunk my/git-gutter+-repeat-map nil) - (put #'git-gutter+-previous-hunk 'repeat-map 'my/git-gutter+-repeat-map) - (bind-key "p" #'git-gutter+-previous-hunk my/git-gutter+-repeat-map nil) - (put #'git-gutter+-stage-hunks 'repeat-map 'my/git-gutter+-repeat-map) - (bind-key "s" #'git-gutter+-stage-hunks my/git-gutter+-repeat-map nil) - (put #'git-gutter+-revert-hunk 'repeat-map 'my/git-gutter+-repeat-map) - (bind-key "r" #'git-gutter+-revert-hunk my/git-gutter+-repeat-map nil) - (defvar my/git-gutter+-repeat-map (make-sparse-keymap) "Keymap to repeat git-gutter+-* commands.")))) - -(ert-deftest bind-key/:repeat-map-2 () - (match-expansion - (bind-keys :map m ("x" . cmd1) :repeat-map rm ("y" . cmd2)) - `(progn - (bind-key "x" #'cmd1 m nil) - (defvar rm (make-sparse-keymap)) - (put #'cmd2 'repeat-map 'rm) - (bind-key "y" #'cmd2 rm nil)))) - -(ert-deftest bind-key/:repeat-map-3 () - (match-expansion - (bind-keys :repeat-map rm ("y" . cmd2) :map m ("x" . cmd1)) - `(progn - (defvar rm (make-sparse-keymap)) - (put #'cmd2 'repeat-map 'rm) - (bind-key "y" #'cmd2 rm nil) - (defvar rm (make-sparse-keymap)) - (put #'cmd1 'repeat-map 'rm) - (bind-key "x" #'cmd1 m nil)))) (ert-deftest bind-key/845 () (defvar test-map (make-keymap)) From 2399d0d5cef59b3be70cb544dcb20387b55a98c9 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Wed, 16 Nov 2022 08:37:27 +0100 Subject: [PATCH 585/606] Normalize GPLv3 license statements --- lisp/use-package/bind-chord.el | 16 +++++++++--- lisp/use-package/bind-key.el | 24 ++++++++---------- lisp/use-package/use-package-bind-key.el | 20 +++++++-------- lisp/use-package/use-package-chords.el | 18 ++++++++++--- lisp/use-package/use-package-core.el | 20 +++++++-------- lisp/use-package/use-package-delight.el | 20 +++++++-------- lisp/use-package/use-package-diminish.el | 20 +++++++-------- .../use-package-ensure-system-package.el | 15 +++++++++-- lisp/use-package/use-package-ensure.el | 20 +++++++-------- lisp/use-package/use-package-jump.el | 20 +++++++-------- lisp/use-package/use-package-lint.el | 20 +++++++-------- lisp/use-package/use-package.el | 20 +++++++-------- .../use-package/use-package-chords-tests.el | 25 +++++++------------ test/lisp/use-package/use-package-tests.el | 25 ++++++++----------- 14 files changed, 142 insertions(+), 141 deletions(-) diff --git a/lisp/use-package/bind-chord.el b/lisp/use-package/bind-chord.el index bf0f5866ac4..ada84ae6d1a 100644 --- a/lisp/use-package/bind-chord.el +++ b/lisp/use-package/bind-chord.el @@ -8,11 +8,21 @@ ;; 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 -;; + +;; 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 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . ;;; Commentary: -;; ;;; Code: diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index f0b9cdb588d..6eda2758390 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -10,21 +10,19 @@ ;; 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 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. -;; 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. +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . -;; 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 diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index 5e6a10925ca..a4f0664dccd 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -11,20 +11,18 @@ ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package -;; This program is free software; you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 3, or (at -;; your option) any later version. +;; 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 of the License, or +;; (at your option) any later version. -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. +;; 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. +;; along with this program. If not, see . ;;; Commentary: diff --git a/lisp/use-package/use-package-chords.el b/lisp/use-package/use-package-chords.el index 4a4d9e7fea7..479083b9296 100644 --- a/lisp/use-package/use-package-chords.el +++ b/lisp/use-package/use-package-chords.el @@ -8,15 +8,25 @@ ;; Version: 0.2.1 ;; Package-Requires: ((use-package "2.1") (bind-key "1.0") (bind-chord "0.2") (key-chord "0.6")) ;; Filename: use-package-chords.el -;; License: GNU General Public License version 3, or (at your option) any later version -;; + +;; 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 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . ;;; Commentary: -;; + ;; The `:chords' keyword allows you to define `key-chord' bindings for ;; `use-package' declarations in the same manner as the `:bind' ;; keyword. -;; ;;; Code: diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 429b108ac71..b5a6d27a22d 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -11,20 +11,18 @@ ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package -;; This program is free software; you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 3, or (at -;; your option) any later version. +;; 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 of the License, or +;; (at your option) any later version. -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. +;; 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. +;; along with this program. If not, see . ;;; Commentary: diff --git a/lisp/use-package/use-package-delight.el b/lisp/use-package/use-package-delight.el index 558be5e4706..4343978be5b 100644 --- a/lisp/use-package/use-package-delight.el +++ b/lisp/use-package/use-package-delight.el @@ -11,20 +11,18 @@ ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package -;; This program is free software; you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 3, or (at -;; your option) any later version. +;; 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 of the License, or +;; (at your option) any later version. -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. +;; 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. +;; along with this program. If not, see . ;;; Commentary: diff --git a/lisp/use-package/use-package-diminish.el b/lisp/use-package/use-package-diminish.el index 5b20830ee6a..9e15e27525a 100644 --- a/lisp/use-package/use-package-diminish.el +++ b/lisp/use-package/use-package-diminish.el @@ -11,20 +11,18 @@ ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package -;; This program is free software; you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 3, or (at -;; your option) any later version. +;; 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 of the License, or +;; (at your option) any later version. -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. +;; 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. +;; along with this program. If not, see . ;;; Commentary: diff --git a/lisp/use-package/use-package-ensure-system-package.el b/lisp/use-package/use-package-ensure-system-package.el index c42996f9d2a..9c9f0797a05 100644 --- a/lisp/use-package/use-package-ensure-system-package.el +++ b/lisp/use-package/use-package-ensure-system-package.el @@ -8,8 +8,19 @@ ;; Version: 0.2 ;; Package-Requires: ((use-package "2.1") (system-packages "1.0.4")) ;; Filename: use-package-ensure-system-package.el -;; License: GNU General Public License version 3, or (at your option) any later version -;; + +;; 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 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . ;;; Commentary: ;; diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index a879c294dc3..90b0b9aa5d5 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -11,20 +11,18 @@ ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package -;; This program is free software; you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 3, or (at -;; your option) any later version. +;; 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 of the License, or +;; (at your option) any later version. -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. +;; 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. +;; along with this program. If not, see . ;;; Commentary: diff --git a/lisp/use-package/use-package-jump.el b/lisp/use-package/use-package-jump.el index 6b9c02808e1..03d1af83b72 100644 --- a/lisp/use-package/use-package-jump.el +++ b/lisp/use-package/use-package-jump.el @@ -11,20 +11,18 @@ ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package -;; This program is free software; you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 3, or (at -;; your option) any later version. +;; 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 of the License, or +;; (at your option) any later version. -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. +;; 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. +;; along with this program. If not, see . ;;; Commentary: diff --git a/lisp/use-package/use-package-lint.el b/lisp/use-package/use-package-lint.el index 12974ab15e4..e0066b59485 100644 --- a/lisp/use-package/use-package-lint.el +++ b/lisp/use-package/use-package-lint.el @@ -11,20 +11,18 @@ ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package -;; This program is free software; you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 3, or (at -;; your option) any later version. +;; 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 of the License, or +;; (at your option) any later version. -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. +;; 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. +;; along with this program. If not, see . ;;; Commentary: diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 9d046e0b149..d74c632e011 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -11,20 +11,18 @@ ;; Keywords: dotemacs startup speed config package ;; URL: https://github.com/jwiegley/use-package -;; This program is free software; you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 3, or (at -;; your option) any later version. +;; 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 of the License, or +;; (at your option) any later version. -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. +;; 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. +;; along with this program. If not, see . ;;; Commentary: diff --git a/test/lisp/use-package/use-package-chords-tests.el b/test/lisp/use-package/use-package-chords-tests.el index 2b7588dd807..6fc09087b99 100644 --- a/test/lisp/use-package/use-package-chords-tests.el +++ b/test/lisp/use-package/use-package-chords-tests.el @@ -1,25 +1,18 @@ ;;; use-package-chords-tests.el --- Tests for use-package-chords.el -*- lexical-binding: t; -*- -;; 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 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. -;; 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. +;; 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: +;; along with this program. If not, see . -;; - - ;;; Code: (require 'use-package) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 185f7691ba9..bd79cfb7c65 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1,25 +1,20 @@ ;;; use-package-tests.el --- Tests for use-package.el -*- lexical-binding: t; -*- -;; 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 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. -;; 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. +;; 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. - +;; along with this program. If not, see . + ;;; Commentary: -;; - - ;;; Code: (require 'cl-lib) From 79c2c3a3ada6e5f4b80778604a2b48f380504bb1 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Wed, 16 Nov 2022 08:43:10 +0100 Subject: [PATCH 586/606] Delete redundant headers --- lisp/use-package/bind-key.el | 1 - lisp/use-package/use-package-bind-key.el | 6 ------ lisp/use-package/use-package-core.el | 6 ------ lisp/use-package/use-package-delight.el | 6 ------ lisp/use-package/use-package-diminish.el | 6 ------ lisp/use-package/use-package-ensure.el | 6 ------ lisp/use-package/use-package-jump.el | 6 ------ lisp/use-package/use-package-lint.el | 6 ------ lisp/use-package/use-package.el | 1 - 9 files changed, 44 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 6eda2758390..b6c401f5522 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -5,7 +5,6 @@ ;; Author: John Wiegley ;; Maintainer: John Wiegley ;; Created: 16 Jun 2012 -;; Modified: 29 Nov 2017 ;; Version: 2.4.1 ;; Keywords: keys keybinding config dotemacs ;; URL: https://github.com/jwiegley/use-package diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index a4f0664dccd..75def7febdf 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -4,12 +4,6 @@ ;; Author: John Wiegley ;; Maintainer: John Wiegley -;; Created: 17 Jun 2012 -;; Modified: 4 Dec 2017 -;; Version: 1.0 -;; Package-Requires: ((emacs "24.3") (use-package "2.4") (bind-key "2.4")) -;; Keywords: dotemacs startup speed config package -;; URL: https://github.com/jwiegley/use-package ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index b5a6d27a22d..99a613e2489 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -4,12 +4,6 @@ ;; Author: John Wiegley ;; Maintainer: John Wiegley -;; Created: 17 Jun 2012 -;; Modified: 29 Nov 2017 -;; Version: 2.4.4 -;; Package-Requires: ((emacs "24.3")) -;; Keywords: dotemacs startup speed config package -;; URL: https://github.com/jwiegley/use-package ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by diff --git a/lisp/use-package/use-package-delight.el b/lisp/use-package/use-package-delight.el index 4343978be5b..c6abac9a643 100644 --- a/lisp/use-package/use-package-delight.el +++ b/lisp/use-package/use-package-delight.el @@ -4,12 +4,6 @@ ;; Author: John Wiegley ;; Maintainer: John Wiegley -;; Created: 17 Jun 2012 -;; Modified: 3 Dec 2017 -;; Version: 1.0 -;; Package-Requires: ((emacs "24.3") (use-package "2.4")) -;; Keywords: dotemacs startup speed config package -;; URL: https://github.com/jwiegley/use-package ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by diff --git a/lisp/use-package/use-package-diminish.el b/lisp/use-package/use-package-diminish.el index 9e15e27525a..9b8a09a2973 100644 --- a/lisp/use-package/use-package-diminish.el +++ b/lisp/use-package/use-package-diminish.el @@ -4,12 +4,6 @@ ;; Author: John Wiegley ;; Maintainer: John Wiegley -;; Created: 17 Jun 2012 -;; Modified: 3 Dec 2017 -;; Version: 1.0 -;; Package-Requires: ((emacs "24.3") (use-package "2.4")) -;; Keywords: dotemacs startup speed config package -;; URL: https://github.com/jwiegley/use-package ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index 90b0b9aa5d5..c9cc6e70c51 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -4,12 +4,6 @@ ;; Author: John Wiegley ;; Maintainer: John Wiegley -;; Created: 17 Jun 2012 -;; Modified: 3 Dec 2017 -;; Version: 1.0 -;; Package-Requires: ((emacs "24.3") (use-package "2.4")) -;; Keywords: dotemacs startup speed config package -;; URL: https://github.com/jwiegley/use-package ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by diff --git a/lisp/use-package/use-package-jump.el b/lisp/use-package/use-package-jump.el index 03d1af83b72..0c4cd20d052 100644 --- a/lisp/use-package/use-package-jump.el +++ b/lisp/use-package/use-package-jump.el @@ -4,12 +4,6 @@ ;; Author: John Wiegley ;; Maintainer: John Wiegley -;; Created: 17 Jun 2012 -;; Modified: 3 Dec 2017 -;; Version: 1.0 -;; Package-Requires: ((emacs "24.3") (use-package "2.4")) -;; Keywords: dotemacs startup speed config package -;; URL: https://github.com/jwiegley/use-package ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by diff --git a/lisp/use-package/use-package-lint.el b/lisp/use-package/use-package-lint.el index e0066b59485..2092c0d269c 100644 --- a/lisp/use-package/use-package-lint.el +++ b/lisp/use-package/use-package-lint.el @@ -4,12 +4,6 @@ ;; Author: John Wiegley ;; Maintainer: John Wiegley -;; Created: 17 Jun 2012 -;; Modified: 3 Dec 2017 -;; Version: 1.0 -;; Package-Requires: ((emacs "24.3") (use-package "2.4")) -;; Keywords: dotemacs startup speed config package -;; URL: https://github.com/jwiegley/use-package ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index d74c632e011..04befb7e464 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -5,7 +5,6 @@ ;; Author: John Wiegley ;; Maintainer: John Wiegley ;; Created: 17 Jun 2012 -;; Modified: 29 Nov 2017 ;; Version: 2.4.4 ;; Package-Requires: ((emacs "24.3") (bind-key "2.4")) ;; Keywords: dotemacs startup speed config package From 30fa36673748fc155606d5e01b5980c6d6c27afa Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Wed, 16 Nov 2022 09:33:40 +0100 Subject: [PATCH 587/606] Add .dir-locals.el --- lisp/use-package/bind-key.el | 1 - lisp/use-package/use-package-core.el | 4 ---- test/lisp/use-package/use-package-chords-tests.el | 1 - test/lisp/use-package/use-package-tests.el | 1 - 4 files changed, 7 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index f0b9cdb588d..48197642dc7 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -542,7 +542,6 @@ function symbol (unquoted)." ;; Local Variables: ;; outline-regexp: ";;;\\(;* [^\s\t\n]\\|###autoload\\)\\|(" -;; indent-tabs-mode: nil ;; End: ;;; bind-key.el ends here diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 429b108ac71..099e2e7aea6 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1721,8 +1721,4 @@ this file. Usage: (provide 'use-package-core) -;; Local Variables: -;; indent-tabs-mode: nil -;; End: - ;;; use-package-core.el ends here diff --git a/test/lisp/use-package/use-package-chords-tests.el b/test/lisp/use-package/use-package-chords-tests.el index 2b7588dd807..5fd3d117c57 100644 --- a/test/lisp/use-package/use-package-chords-tests.el +++ b/test/lisp/use-package/use-package-chords-tests.el @@ -153,7 +153,6 @@ '(bind-chord "C-u" #'key3 my-map2))))))) ;; Local Variables: -;; indent-tabs-mode: nil ;; no-byte-compile: t ;; no-update-autoloads: t ;; End: diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 185f7691ba9..71ebf6ca5f8 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1986,7 +1986,6 @@ (should (eq (nth 2 binding) nil)))) ;; Local Variables: -;; indent-tabs-mode: nil ;; no-byte-compile: t ;; no-update-autoloads: t ;; End: From 06f92d1cc0763d2a825cb063c4f45499156506ef Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Thu, 17 Nov 2022 12:05:58 +0100 Subject: [PATCH 588/606] Fix Package-Requires for bind-{chord,key}.el --- lisp/use-package/bind-chord.el | 2 +- lisp/use-package/bind-key.el | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/bind-chord.el b/lisp/use-package/bind-chord.el index ada84ae6d1a..ed736a4b966 100644 --- a/lisp/use-package/bind-chord.el +++ b/lisp/use-package/bind-chord.el @@ -6,7 +6,7 @@ ;; 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")) +;; Package-Requires: ((emacs "24.3") (bind-key "1.0") (key-chord "0.6")) ;; Filename: bind-chord.el ;; This program is free software; you can redistribute it and/or modify diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 7e4c28770bb..5baf94b2b13 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -6,6 +6,7 @@ ;; Maintainer: John Wiegley ;; Created: 16 Jun 2012 ;; Version: 2.4.1 +;; Package-Requires: ((emacs "24.3")) ;; Keywords: keys keybinding config dotemacs ;; URL: https://github.com/jwiegley/use-package @@ -516,8 +517,7 @@ function symbol (unquoted)." (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)) - ) + (at-present-desc (get-binding-description at-present))) (let ((line (format (format "%%-%ds%%-%ds%%s\n" (car bind-key-column-widths) From efae6048dd2b534669f931d3992ddba52c31122b Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Thu, 17 Nov 2022 12:06:22 +0100 Subject: [PATCH 589/606] Add package keyword from finder-known-keywords --- lisp/use-package/bind-key.el | 2 +- lisp/use-package/use-package.el | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 5baf94b2b13..3168f686a09 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -7,7 +7,7 @@ ;; Created: 16 Jun 2012 ;; Version: 2.4.1 ;; Package-Requires: ((emacs "24.3")) -;; Keywords: keys keybinding config dotemacs +;; Keywords: keys keybinding config dotemacs extensions ;; URL: https://github.com/jwiegley/use-package ;; This program is free software; you can redistribute it and/or modify diff --git a/lisp/use-package/use-package.el b/lisp/use-package/use-package.el index 04befb7e464..bafa0934a6d 100644 --- a/lisp/use-package/use-package.el +++ b/lisp/use-package/use-package.el @@ -7,7 +7,7 @@ ;; Created: 17 Jun 2012 ;; Version: 2.4.4 ;; Package-Requires: ((emacs "24.3") (bind-key "2.4")) -;; Keywords: dotemacs startup speed config package +;; Keywords: dotemacs startup speed config package extensions ;; URL: https://github.com/jwiegley/use-package ;; This program is free software; you can redistribute it and/or modify From 8296164eab91fcb1ff0eb75390691665735419d2 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Sun, 27 Nov 2022 10:02:04 +0100 Subject: [PATCH 590/606] Remove tests lacking a copyright assignment for now * use-package-tests.el (use-package-test/pre-post-hooks-with-:config) (use-package-test/pre-post-hooks-without-:config): Remove tests. --- test/lisp/use-package/use-package-tests.el | 31 ---------------------- 1 file changed, 31 deletions(-) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index ac3dce2c021..b66b08ec117 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1505,37 +1505,6 @@ (config) t)))))) -(ert-deftest use-package-test/pre-post-hooks-with-:config () - (let ((use-package-inject-hooks t)) - (match-expansion - (use-package foo :config (config)) - `(progn - (when - (run-hook-with-args-until-failure 'use-package--foo--pre-init-hook) - (run-hooks 'use-package--foo--post-init-hook)) - (require 'foo nil nil) - (when - (run-hook-with-args-until-failure 'use-package--foo--pre-config-hook) - (config) - (run-hooks 'use-package--foo--post-config-hook)) - t)))) - -(ert-deftest use-package-test/pre-post-hooks-without-:config () - ;; https://github.com/jwiegley/use-package/issues/785 - (let ((use-package-inject-hooks t)) - (match-expansion - (use-package foo) - `(progn - (when - (run-hook-with-args-until-failure 'use-package--foo--pre-init-hook) - (run-hooks 'use-package--foo--post-init-hook)) - (require 'foo nil nil) - (when - (run-hook-with-args-until-failure 'use-package--foo--pre-config-hook) - t - (run-hooks 'use-package--foo--post-config-hook)) - t)))) - (ert-deftest use-package-test-normalize/:diminish () (should (equal (use-package-normalize-diminish 'foopkg :diminish nil) '(foopkg-mode))) From ebbd98edb3f2b38da4d55a62a09704f8d1a12c5a Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Sun, 27 Nov 2022 10:14:35 +0100 Subject: [PATCH 591/606] Revert "Add: 'local' keyword" This reverts commit 620fe443c2e7598191cb5d6c6a41064471edb57c. --- lisp/use-package/use-package-core.el | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 1190f144893..6606681f2ea 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -100,8 +100,7 @@ :load ;; This must occur almost last; the only forms which should appear after ;; are those that must happen directly after the config forms. - :config - :local) + :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 @@ -1580,31 +1579,6 @@ no keyword implies `:all'." (when use-package-compute-statistics `((use-package-statistics-gather :config ',name t)))))) -;;;; :local - -(defun use-package-normalize/:local (name keyword args) - (let ((first-arg-name (symbol-name (caar args)))) - (if (not (string-suffix-p "-hook" first-arg-name)) - (let* ((sym-name (symbol-name name)) - (addition (if (string-suffix-p "-mode" sym-name) - "-hook" - "-mode-hook")) - (hook (intern (concat sym-name addition)))) - `((,hook . ,(use-package-normalize-forms name keyword args)))) - (cl-loop for (hook . code) in args - collect `(,hook . ,(use-package-normalize-forms name keyword code)))))) - -(defun use-package-handler/:local (name _keyword arg rest state) - (let* ((body (use-package-process-keywords name rest state))) - (use-package-concat - body - (cl-loop for (hook . code) in arg - for func-name = (intern (concat "use-package-func/" (symbol-name hook))) - collect (progn - (push 'progn code) - `(defun ,func-name () ,code)) - collect `(add-hook ',hook ',func-name))))) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; The main macro From 500c459effbe34821ad615fbb7de1a13bf4676c6 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Wed, 30 Nov 2022 16:15:15 +0100 Subject: [PATCH 592/606] ; * etc/NEWS: Mention use-package. --- etc/NEWS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/etc/NEWS b/etc/NEWS index a2087757898..f1f2cf6c4cf 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2925,6 +2925,13 @@ features, such as completion, documentation, error detection, etc., based on data provided by language servers using the Language Server Protocol (LSP). ++++ +*** use-package: Declarative package configuration. +use-package is shipped with Emacs. It provides the 'use-package' +macro, which allows you to isolate package configuration in your init +file in a way that is declarative, tidy, and performance-oriented. +See the new Info manual 'use-package' for more. + +++ ** New commands 'image-crop' and 'image-cut'. These commands allow interactively cropping/cutting the image at From 97c8a5878769d63d8d1593585d71da3c597be108 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Wed, 30 Nov 2022 16:17:38 +0100 Subject: [PATCH 593/606] * doc/misc/Makefile.in (INFO_COMMON): Add use-package. --- doc/misc/Makefile.in | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/misc/Makefile.in b/doc/misc/Makefile.in index a7dbbbb48fe..49cd8e13b03 100644 --- a/doc/misc/Makefile.in +++ b/doc/misc/Makefile.in @@ -67,14 +67,14 @@ MAKEINFO_OPTS = --force -I$(emacsdir) DOCMISC_W32 = @DOCMISC_W32@ ## Info files to build and install on all platforms. -INFO_COMMON = auth autotype bovine calc ccmode cl \ - dbus dired-x ebrowse ede ediff edt efaq eglot eieio \ - emacs-gnutls emacs-mime epa erc ert eshell eudc eww \ - flymake forms gnus htmlfontify idlwave ido info.info \ - mairix-el message mh-e modus-themes newsticker nxml-mode \ - octave-mode org pcl-cvs pgg rcirc reftex remember sasl \ - sc semantic ses sieve smtpmail speedbar srecode todo-mode \ - tramp transient url vhdl-mode vip viper vtable widget wisent woman +INFO_COMMON = auth autotype bovine calc ccmode cl dbus dired-x \ + ebrowse ede ediff edt efaq eglot eieio emacs-gnutls \ + emacs-mime epa erc ert eshell eudc eww flymake forms gnus \ + htmlfontify idlwave ido info.info mairix-el message mh-e \ + modus-themes newsticker nxml-mode octave-mode org pcl-cvs pgg \ + rcirc reftex remember sasl sc semantic ses sieve smtpmail \ + speedbar srecode todo-mode tramp transient url use-package \ + vhdl-mode vip viper vtable widget wisent woman ## Info files to install on current platform. INFO_INSTALL = $(INFO_COMMON) $(DOCMISC_W32) From 01bfbd186adfaff3d2b5c7b2d04d1ae19fa1f40d Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Sat, 3 Dec 2022 00:55:56 +0100 Subject: [PATCH 594/606] Fix use-package tests * test/lisp/use-package/use-package-chords-tests.el: * test/lisp/use-package/use-package-tests.el: Remove local variables section. Require 'ert' and fix copyright header. --- .../use-package/use-package-chords-tests.el | 18 +++++++++++++++++- test/lisp/use-package/use-package-tests.el | 4 ++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/test/lisp/use-package/use-package-chords-tests.el b/test/lisp/use-package/use-package-chords-tests.el index d78f6883c7d..665784eaf46 100644 --- a/test/lisp/use-package/use-package-chords-tests.el +++ b/test/lisp/use-package/use-package-chords-tests.el @@ -1,5 +1,7 @@ ;;; use-package-chords-tests.el --- Tests for use-package-chords.el -*- lexical-binding: t; -*- +;; Copyright (C) 2019-2022 Free Software Foundation, Inc. + ;; 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 of the License, or @@ -15,14 +17,24 @@ ;;; Code: +(require 'ert) (require 'use-package) -(require 'use-package-tests) (require 'use-package-chords) +(setq use-package-always-ensure nil + use-package-verbose 'errors + use-package-expand-minimally t) + (defmacro match-expansion (form &rest value) `(should (pcase (expand-minimally ,form) ,@(mapcar #'(lambda (x) (list x t)) value)))) +;; Copied from use-package-tests.el. +(defmacro expand-minimally (form) + `(let ((use-package-verbose 'errors) + (use-package-expand-minimally t)) + (macroexpand-1 ',form))) + (defun use-package-test-normalize-chord (&rest args) (apply #'use-package-normalize-binder 'foo :chords args)) @@ -50,6 +62,8 @@ ("C-b" . beta))))) (ert-deftest use-package-test/:chords-1 () + ;; FIXME: + :tags '(:unstable) (match-expansion (use-package foo :chords ("C-k" . key1) ("C-u" . key2)) `(progn @@ -63,6 +77,8 @@ (bind-chord "C-u" #'key2 nil)))) (ert-deftest use-package-test/:chords-2 () + ;; FIXME: + :tags '(:unstable) (match-expansion (use-package foo :chords (("C-k" . key1) ("C-u" . key2))) `(progn diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index b66b08ec117..05969f5a95f 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -1,5 +1,7 @@ ;;; use-package-tests.el --- Tests for use-package.el -*- lexical-binding: t; -*- +;; Copyright (C) 2014-2022 Free Software Foundation, Inc. + ;; 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 of the License, or @@ -13,8 +15,6 @@ ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . -;;; Commentary: - ;;; Code: (require 'cl-lib) From 98e54f597e11fa760553bf7b12d8ebb388b5a488 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Thu, 8 Dec 2022 00:47:04 +0100 Subject: [PATCH 595/606] Add new use-package manual * doc/misc/use-package.texi: Rewrite manual. --- doc/misc/use-package.texi | 2301 +++++++++++++++++++++++++------------ 1 file changed, 1584 insertions(+), 717 deletions(-) diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index 573baac89aa..d39125c4555 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -1,29 +1,32 @@ \input texinfo @c -*- texinfo -*- @c %**start of header -@setfilename use-package.info +@setfilename ../../use-package.info @settitle use-package User Manual -@documentencoding UTF-8 -@documentlanguage en +@include docstyle.texi +@syncodeindex vr cp +@syncodeindex fn cp @c %**end of header @copying +This manual is for use-package, a configuration macro for simplifying +your init file. + +Copyright @copyright{} 2022 Free Software Foundation, Inc. + @quotation -Copyright (C) 2012-2022 Free Software Foundation, Inc. - -You can redistribute this document 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. - -This document 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. +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 +@dircategory Emacs misc features @direntry * use-package: (use-package). Declarative package configuration for Emacs. @end direntry @@ -31,8 +34,8 @@ General Public License for more details. @finalout @titlepage @title use-package User Manual -@subtitle for version 2.4.1-119-g0be480e+1 -@author John Wiegley +@subtitle for version 2.4.5 +@author John Wiegley & Stefan Kangas @page @vskip 0pt plus 1filll @insertcopying @@ -44,198 +47,48 @@ General Public License for more details. @node Top @top use-package User Manual -The @code{use-package} macro allows you to isolate package configuration in your -@code{.emacs} file in a way that is both performance-oriented and, well, 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 -around 2 seconds, with no loss of functionality! +The @code{use-package} macro allows you to isolate package +customization in your init file in a declarative way. It takes care +of a lot of 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 for the configuration and loading of +packages. @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:: +@end menu @end ifnottex -@menu -* Introduction:: -* Installation:: -* Getting Started:: -* Basic Concepts:: -* Issues/Requests:: -* Keywords:: -* Debugging Tools:: - -@detailmenu ---- The Detailed Node Listing --- - -Installation - -* Installing from GNU ELPA:: -* Installing from the Git Repository:: -* Post-Installation Tasks:: - -Keywords - -* @code{after}:: @code{:after}. -* @code{bind-keymap} @code{bind-keymap*}:: @code{:bind-keymap}, @code{:bind-keymap*}. -* @code{bind} @code{bind*}:: @code{:bind}, @code{:bind*}. -* @code{commands}:: @code{:commands}. -* @code{preface} @code{init} @code{config}:: @code{:preface}, @code{:init}, @code{:config}. -* @code{custom}:: @code{:custom}. -* @code{custom-face}:: @code{:custom-face}. -* @code{defer} @code{demand}:: @code{:defer}, @code{:demand}. -* @code{defines} @code{functions}:: @code{:defines}, @code{:functions}. -* @code{diminish} @code{delight}:: @code{:diminish}, @code{:delight}. -* @code{disabled}:: @code{:disabled}. -* @code{ensure} @code{pin}:: @code{:ensure}, @code{:pin}. -* @code{hook}:: @code{:hook}. -* @code{if} @code{when} @code{unless}:: @code{:if}, @code{:when}, @code{:unless}. -* @code{load-path}:: @code{:load-path}. -* @code{mode} @code{interpreter}:: @code{:mode}, @code{:interpreter}. -* @code{magic} @code{magic-fallback}:: @code{:magic}, @code{:magic-fallback}. -* @code{no-require}:: @code{:no-require}. -* @code{requires}:: @code{:requires}. - -@code{bind}, @code{bind*} - -* Binding to local keymaps:: - - -@end detailmenu -@end menu - -@node Introduction -@chapter Introduction - -The @code{use-package} macro allows you to isolate package configuration in your -@code{.emacs} file in a way that is both performance-oriented and, well, 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 -around 2 seconds, with no loss of functionality! - -More text to come@dots{} - -@node Installation -@chapter Installation - -use-package can be installed using Emacs' package manager or manually from -its development repository. - -@menu -* Installing from GNU ELPA:: -* Installing from the Git Repository:: -* Post-Installation Tasks:: -@end menu - -@node Installing from GNU ELPA -@section Installing from GNU ELPA - -use-package is available from GNU ELPA. If you haven't used -Emacs' package manager before, then it is high time you familiarize yourself -with it by reading the documentation in the Emacs manual, see -@ref{Packages,,,emacs,}. Then add one of the archives to @code{package-archives}: - -First, you need to update the local package list using: - -@example -M-x package-refresh-contents RET -@end example - -Once you have done that, you can install use-package and its -dependencies using: - -@example -M-x package-install RET use-package RET -@end example - -Now see @ref{Post-Installation Tasks}. - -@node Installing from the Git Repository -@section Installing from the Git Repository - -First, use Git to clone the use-package repository: - -@example -$ git clone https://github.com/jwiegley/use-package.git ~/.emacs.d/site-lisp/use-package -$ cd ~/.emacs.d/site-lisp/use-package -@end example - -Then compile the libraries and generate the info manuals: - -@example -$ make -@end example - -You may need to create @code{/path/to/use-package/config.mk} with the following -content before running @code{make}: - -@example -LOAD_PATH = -L /path/to/use-package -@end example - -Finally add this to your init file: - -@lisp -(add-to-list 'load-path "~/.emacs.d/site-lisp/use-package") -(require 'use-package) - -(with-eval-after-load 'info - (info-initialize) - (add-to-list 'Info-directory-list - "~/.emacs.d/site-lisp/use-package/")) -@end lisp - -Note that elements of @code{load-path} should not end with a slash, while those of -@code{Info-directory-list} should. - -Instead of running use-package directly from the repository by adding it to -the @code{load-path}, you might want to instead install it in some other directory -using @code{sudo make install} and setting @code{load-path} accordingly. - -To update use-package use: - -@example -$ git pull -$ make -@end example - -At times it might be necessary to run @code{make clean all} instead. - -To view all available targets use @code{make help}. - -Now see @ref{Post-Installation Tasks}. - -@node Post-Installation Tasks -@section Post-Installation Tasks - -After installing use-package you should verify that you are indeed using the -use-package release you think you are using. It's best to restart Emacs before -doing so, to make sure you are not using an outdated value for @code{load-path}. - -@example -C-h v use-package-version RET -@end example - -should display something like - -@example -use-package-version’s value is "2.4.3" -@end example - -If you are completely new to use-package then see @ref{Getting Started}. - -If you run into problems, then please see the @ref{Debugging Tools}. - -@node Getting Started -@chapter Getting Started - -TODO@. For now, see @code{README.md}. - +@c ---------------------------------------------------------------------------- @node Basic Concepts @chapter Basic Concepts -@code{use-package} was created for few basic reasons, each of which drove the -design in various ways. Understanding these reasons may help make some of -those decisions clearer: +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: -@itemize +@enumerate @item To gather all configuration details of a package into one place, making it easier to copy, disable, or move it elsewhere in the init @@ -251,231 +104,53 @@ sacrificing the quantity of add-on packages used. @item To make it so errors encountered during startup disable only the -package raising the error, and as little else as possible, leaving a +package raising the error, and as little else as possible, leaving as close to a functional Emacs as possible. @item To allow byte-compilation of one's init file so that any warnings or -errors seen are meaningful. In this way, even if byte-compilation is not -used for speed (reason 3), it can still be used as a sanity check. -@end itemize +errors seen are meaningful. In this way, even if byte-compilation is +not used for speed (reason 3), it can still be used as a sanity check. +@end enumerate -@node Issues/Requests -@chapter Issues/Requests +It is worth noting that use-package is not intended to replace the +standard @w{@code{M-x customize}}. On the contrary, it is designed to +work together with it, for things that customize cannot do. -@node Keywords -@chapter Keywords +@c ---------------------------------------------------------------------------- +@node Getting Started +@chapter Getting Started -@menu -* @code{after}:: @code{after}. -* @code{bind-keymap} @code{bind-keymap*}:: @code{:bind-keymap}, @code{:bind-keymap*}. -* @code{bind} @code{bind*}:: @code{bind} @code{:bind*}. -* @code{commands}:: @code{:commands}. -* @code{preface} @code{init} @code{config}:: @code{:preface}, @code{:init}, @code{:config}. -* @code{custom}:: @code{:custom}. -* @code{custom-face}:: @code{:custom-face}. -* @code{defer} @code{demand}:: @code{:defer}, @code{:demand}. -* @code{defines} @code{functions}:: @code{:defines}, @code{:functions}. -* @code{diminish} @code{delight}:: @code{:diminish}, @code{:delight}. -* @code{disabled}:: @code{:disabled}. -* @code{ensure} @code{pin}:: @code{:ensure}, @code{:pin}. -* @code{hook}:: @code{:hook}. -* @code{if} @code{when} @code{unless}:: @code{:if}, @code{:when}, @code{:unless}. -* @code{load-path}:: @code{:load-path}. -* @code{mode} @code{interpreter}:: @code{:mode}, @code{:interpreter}. -* @code{magic} @code{magic-fallback}:: @code{:magic}, @code{:magic-fallback}. -* @code{no-require}:: @code{:no-require}. -* @code{requires}:: @code{:requires}. -@end menu - -@node @code{after} -@section @code{:after} - -Sometimes it only makes sense to configure a package after another has been -loaded, because certain variables or functions are not in scope until that -time. This can achieved using an @code{:after} keyword that allows a fairly rich -description of the exact conditions when loading should occur. Here is an -example: +This chapter provides instructions and examples for quickly getting +started with use-package. The first thing you need to do is make sure +that @samp{use-package} itself is loaded. To do that, put this at the +top of your init file: @lisp -(use-package hydra - :load-path "site-lisp/hydra") - -(use-package ivy - :load-path "site-lisp/swiper") - -(use-package ivy-hydra - :after (ivy hydra)) +(require 'use-package) +(require 'bind-key) ; if you use any :bind variant @end lisp -In this case, because all of these packages are demand-loaded in the order -they occur, the use of @code{:after} is not strictly necessary. By using it, -however, the above code becomes order-independent, without an implicit -depedence on the nature of your init file. +The above makes the @code{use-macro} for in the rest of your init +file. In this manual, we call each call to @code{use-macro} a +@dfn{declaration}, to highlight the declarative nature of its +semantic. -By default, @code{:after (foo bar)} is the same as @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: +To unconditionally load a package named @samp{foo}, add the following +declaration to your init file: @lisp -: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 lisp - -When you nest selectors, such as @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 both @code{baz} and @code{quux} have been loaded. - -@strong{NOTE}: Pay attention if you set @code{use-package-always-defer} to t, and also use -the @code{:after} keyword, as you will need to specify how the declared package is -to be loaded: e.g., by some @code{:bind}. If you're not using one of the mechanisms -that registers autoloads, such as @code{:bind} or @code{:hook}, and your package manager -does not provide autoloads, it's possible that without adding @code{:demand t} to -those declarations, your package will never be loaded. - -@node @code{bind-keymap} @code{bind-keymap*} -@section @code{:bind-keymap}, @code{: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 Emacs' @code{autoload} mechanism. - -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 -command 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 -(use-package projectile - :bind-keymap - ("C-c p" . projectile-command-map) -@end lisp - -@node @code{bind} @code{bind*} -@section @code{:bind}, @code{:bind*} - -Another common thing to do when loading a module is to bind a key to primary -commands within that module: - -@lisp -(use-package ace-jump-mode - :bind ("C-." . ace-jump-mode)) -@end lisp - -This does two things: first, it creates an autoload for the @code{ace-jump-mode} -command and defers loading of @code{ace-jump-mode} until you actually use it. -Second, it binds the key @code{C-.} to that command. After loading, you can use -@code{M-x describe-personal-keybindings} to see all such keybindings you've set -throughout your @code{.emacs} file. - -A more literal way to do the exact same thing is: - -@lisp -(use-package ace-jump-mode - :commands ace-jump-mode - :init - (bind-key "C-." 'ace-jump-mode)) -@end lisp - -When you use the @code{:commands} keyword, it creates autoloads for those commands -and defers loading of the module until they are used. Since the @code{:init} form -is always run---even if @code{ace-jump-mode} might not be on your system---remember -to restrict @code{:init} code to only what would succeed either way. - -The @code{:bind} keyword takes either a cons or a list of conses: - -@lisp -(use-package hi-lock - :bind (("M-o l" . highlight-lines-matching-regexp) - ("M-o r" . highlight-regexp) - ("M-o w" . highlight-phrase))) -@end lisp - -The @code{:commands} keyword likewise takes either a symbol or a list of symbols. - -NOTE: Special keys like @code{tab} or @code{F1}-@code{Fn} can be written in square brackets, -i.e. @code{[tab]} instead of @code{"tab"}. The syntax for the keybindings is similar to -the "kbd" syntax: see @uref{https://www.gnu.org/software/emacs/manual/html_node/emacs/Init-Rebinding.html, the Emacs Manual} for more information. - -Examples: - -@lisp -(use-package helm - :bind (("M-x" . helm-M-x) - ("M-" . helm-find-files) - ([f10] . helm-buffers-list) - ([S-f10] . helm-recentf))) -@end lisp - -@menu -* Binding to local keymaps:: -@end menu - -@node Binding to local keymaps -@subsection Binding to local keymaps - -Slightly different from binding a key to a keymap, is binding a key @strong{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 -(use-package helm - :bind (:map helm-command-map - ("C-c h" . helm-execute-persistent-action))) -@end lisp - -The effect of this statement is to wait until @code{helm} has loaded, and then to -bind the key @code{C-c h} to @code{helm-execute-persistent-action} within Helm's local -keymap, @code{helm-mode-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 -(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 lisp - -@node @code{commands} -@section @code{:commands} - -@node @code{preface} @code{init} @code{config} -@section @code{:preface}, @code{:init}, @code{:config} - -Here is the simplest @code{use-package} declaration: - -@lisp -;; This is only needed once, near the top of the file -(eval-when-compile - ;; Following line is not needed if use-package.el is in ~/.emacs.d - (add-to-list 'load-path "") - (require 'use-package)) - (use-package foo) @end lisp -This loads in the package @code{foo}, but only if @code{foo} is available on your -system. If not, a warning is logged to the @code{*Messages*} buffer. If it -succeeds, a message about @code{"Loading foo"} is logged, along with the time it -took to load, if it took over 0.1 seconds. +@noindent +This declaration is equivalent to using @code{require}, with some +use-package specific error handling added in. Just like require, it +needs the package @samp{foo} to be installed and available in your +@code{load-path} (@pxref{Installing packages}). -Use the @code{:init} keyword to execute code before a package is loaded. It -accepts one or more forms, up until the next keyword: +To evaluate Lisp code @emph{before} the @samp{foo} package is loaded, +use the @code{:init} keyword: @lisp (use-package foo @@ -483,9 +158,11 @@ accepts one or more forms, up until the next keyword: (setq foo-variable t)) @end lisp -Similarly, @code{:config} can be used to execute code after a package is loaded. -In cases where loading is done lazily (see more about autoloading below), this -execution is deferred until after the autoload occurs: +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 +autoload occurs. As you might expect, you can use @code{:init} and +@code{:config} together: @lisp (use-package foo @@ -495,7 +172,32 @@ execution is deferred until after the autoload occurs: (foo-mode 1)) @end lisp -As you might expect, you can use @code{:init} and @code{:config} together: +The above declarations will all 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 (autoloading). If you have installed a package from +@acronym{GNU ELPA} that provides it's own autoloads, it is often +enough to say: + +@lisp +(use-package foo + :defer t) +@end lisp + +@noindent +This will avoid loading the package. Now, when you run any autoloaded +command, the package @samp{foo} is loaded automatically. Package +authors will make their own decisions about which commands are marked +to autoload by default. + +In some cases, you might need or want to provide your own autoloads. +The below more complex example autoloads the commands +@code{isearch-moccur} and @code{isearch-all} from +@file{color-moccur.el}, and binds keys both globally and in +@code{isearch-mode-map}. When one of these commands are used, the +package is loaded. At that point, @code{moccur-edit} is also loaded, +to allow editing of the @code{moccur} buffer. @lisp (use-package color-moccur @@ -510,96 +212,982 @@ As you might expect, you can use @code{:init} and @code{:config} together: (use-package moccur-edit)) @end lisp -In this case, I want to autoload the commands @code{isearch-moccur} and -@code{isearch-all} from @code{color-moccur.el}, and bind keys both at the global level -and within the @code{isearch-mode-map} (see next section). When the package is -actually loaded (by using one of these commands), @code{moccur-edit} is also -loaded, to allow editing of the @code{moccur} buffer. +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. -@node @code{custom} -@section @code{:custom} +That should be enough to get you started! -The @code{:custom} keyword allows customization of package custom variables. +@c ---------------------------------------------------------------------------- +@node Loading Packages +@chapter Loading Packages + +@cindex loading packages +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. + +If you install packages manually, you must make sure they are +available on your @code{load-path}. @xref{Lisp Libraries,,, emacs, +GNU Emacs Manual} for details. + +Some packages have more than one library. In those cases, you might +need more than one @code{use-package} declaration to make sure it 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. +* Load dependencies:: Don't load without dependencies. +* Load path:: Using a custom @code{load-path}. +* Manual autoloads:: Setting up autoloads manually. +@end menu + +@node Loading basics +@section How and when use-package loads packages + +The @code{use-package} macro either will either load a package +immediately, or when they are first used (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 below declaration immediately loads the library +@code{foo}, just like @code{require} would. If the library @samp{foo} +is not available in your @code{load-path}, it logs a warning to the +@samp{*Messages*} buffer: + +@lisp +(use-package foo) +@end lisp + +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 the overwhelming majority of cases also resides +in a @emph{package} named @code{foo}. But the @code{foo} package +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. This manual +will often use these terms 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 autoloading packages +@cindex loading lazily +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 tries to set things +up in such a way that it only loads packages when a command is first +used (either with @kbd{M-x} or 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 +(use-package foo + :defer t) +@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 + +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 this to +make use-package load @samp{foo} after 30 seconds of idle time: + +@lisp +(use-package foo + :defer 30) +@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 anything 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 + +@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 + +@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 + +@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 @samp{foo} in graphical Emacs sessions, +you could use the following: + +@lisp +(use-package foo + :if (display-graphic-p)) +@end lisp + +Another common use case is to make it conditional on the operating +system: + +@lisp +(use-package foo + :if (memq window-system '(mac ns))) +@end lisp + +@cindex conditional loading before @code{:preface} or @code{:ensure} +If you need to conditionalize a use-package form so that the condition +occurs before even @code{:ensure} or @code{:preface}, use @code{when} +around the use-package form itself. For example: + +@lisp +(when (memq window-system '(mac ns)) + (use-package foo + :ensure t)) +@end lisp + +@node Loading sequentially +@section Loading packages in sequence + +@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 achieved with the @code{:after} +keyword, which allows a fairly rich description of the exact +conditions when loading should occur. It takes 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 ELPA} packages hydra, +ivy, and ivy-hydra. Note that ivy-hydra will always be loaded last: + +@lisp +(use-package hydra) + +(use-package ivy) + +(use-package ivy-hydra + :after (ivy hydra)) +@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 (with :after) +@findex :any (with :after) +The @code{:after} keyword also accepts a list of selectors. By +default, @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 @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. + +Pay attention when setting @code{use-package-always-defer} to a +non-@code{nil} value, and also using the @code{:after} keyword. In +this case, you will need to specify how the declared package is to be +loaded: for example, by some @code{:bind}. If you are not using one +of the keywords that registers autoloads, such as @code{:bind} or +@code{:hook}, 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 Load dependencies +@section Prevent loading 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 +(use-package abbrev + :requires foo) +@end lisp + +This is the same as: + +@lisp +(use-package abbrev + :if (featurep 'foo)) +@end lisp + +As a convenience, a list of such packages may be specified: + +@lisp +(use-package abbrev + :requires (foo bar baz)) +@end lisp + +For more complex logic, such as that supported by @code{:after}, +simply use @code{:if} and the appropriate Lisp expression. + +@node Load path +@section Setting a custom @code{load-path} + +If a package resides in some directory that is not in your +@code{load-path}, use the @code{:load-path} keyword to add it. It +takes a symbol, a function, a string or a list of strings. If the +path is relative, it is expanded within @code{user-emacs-directory}. + +For example: + +@lisp +(use-package ess-site + :load-path "site-lisp/ess/lisp/" + :commands R) +@end lisp + +Note that when using a symbol or a function to provide a dynamically +generated list of paths, 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}). Further, this value is fixed at +whatever was determined during compilation, to avoid looking up the +same information again on each startup. For example: + +@lisp +(eval-and-compile + (defun ess-site-load-path () + (shell-command "find ~ -path ess/lisp"))) + +(use-package ess-site + :load-path (lambda () (list (ess-site-load-path))) + :commands R) +@end lisp + +@node Manual autoloads +@section Setting up autoloads manually + +@findex :commands +@findex :autoload +To autoload an interactive command, use the @code{:commands} keyword. +When you use the @code{:commands} keyword, it creates autoloads for +those commands (which defers loading of the module until they are +used). The @code{:commands} keyword takes either a symbol or a list +of symbols. + +The @code{:autoload} keyword works like @code{:commands}, but is used +to autoload non-interactive functions. Here is an example: + +@lisp +(use-package org-crypt + :autoload org-crypt-use-before-save-magic) +@end lisp + +@c ---------------------------------------------------------------------------- +@node Configuring Packages +@chapter Configuring Packages + +This chapter describes the various keywords provided by +@code{use-package} that helps 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 + +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 because you have them within a guard +block. + +@item +Define code that can 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 preface, and restrict it 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 @code{foo} package happens to not exist on your system. +You must therefore remember to restrict @code{:init} code to only what +would succeed either way. @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 +@subheading When to use @code{:preface}, @code{:config} and @code{:init}? + +Where possible, it is better to avoid @code{:preface}, @code{:config} +and @code{:init}. Instead, prefer autoloading keywords such as +@code{:bind}, @code{:hook}, and @code{:mode}, as they will take care +of setting up autoloads for you without any need for boilerplate code. +For example, consider the following declaration: + +@lisp +(use-package foo + :init + (add-hook 'some-hook 'foo-mode)) +@end lisp + +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 @code{:defer t}: + +@lisp +(use-package foo + :defer t + :init + (add-hook 'some-hook 'foo-mode)) +@end lisp + +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 avoid. The better option in this case is +therefore to use @code{:hook} (@xref{Hooks}), which also implies +@w{@code{:defer t}}. The above is thereby reduced down to: + +@lisp +(use-package foo + :hook some-hook) +@end lisp + +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 :bind +@cindex binding keys +@cindex key bindings +One common thing to do when loading a package is to bind a key 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. + +@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 + +To bind keys globally, the @code{:bind} keyword takes either a single +cons or a list of conses. Every cons has the form @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 (@pxref{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 +(use-package ace-jump-mode + :bind ("C-." . ace-jump-mode)) +@end lisp + +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 +(use-package hi-lock + :bind (("M-o l" . highlight-lines-matching-regexp) + ("M-o r" . highlight-regexp) + ("M-o w" . highlight-phrase))) +@end lisp + +@subheading Using special keys + +Inside key strings, special keys like @kbd{TAB} or @kbd{F1}--@kbd{F12} +have to be written inside angle brackets, e.g. @code{"C-"}. +Standalone special keys (and some combinations) can be written in +square brackets, e.g.@ @code{[tab]} instead of @code{""}. + +Examples: + +@lisp +(use-package helm + :bind (("M-x" . helm-M-x) + ("M-" . helm-find-files) + ([f10] . helm-buffers-list) + ([S-f10] . helm-recentf))) +@end lisp + +@subheading Remapping commands + +Remapping 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 +(use-package unfill + :bind ([remap fill-paragraph] . unfill-toggle)) +@end lisp + +@subheading What @code{:bind} does behind the scenes + +To understand what @code{:bind} does behind the scenes, it might be +useful to consider an example: + +@lisp +(use-package ace-jump-mode + :bind ("C-." . ace-jump-mode)) +@end lisp + +This could be expressed in a much more verbose way with the +@code{:commands} and @code{:init} keywords. + +@lisp +(use-package ace-jump-mode + :commands ace-jump-mode + :init + (bind-key "C-." 'ace-jump-mode)) +@end lisp + +Without using even the @code{:commands} keyword, we could also write +the above like so: + +@lisp +(use-package ace-jump-mode + :defer t + :init + (autoload 'ace-jump-mode "ace-jump-mode" nil t) + (bind-key "C-." 'ace-jump-mode)) +@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 + +@findex :map, 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 +(use-package helm + :bind (:map helm-command-map + ("C-c h" . helm-execute-persistent-action))) +@end lisp + +The effect of this statement is to wait until @code{helm} has loaded, +and then to bind the key @code{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 +(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 lisp + +@node Binding to a keymap +@subsection Binding to keymaps + +@findex :bind-keymap, inside :bind +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 command 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 +(use-package foo + :bind-keymap ("C-c p" . foo-command-map)) +@end lisp + +@node Binding to repeat-maps +@subsection Binding to repeat-maps + +@findex :repeat-map, inside :bind +@cindex 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 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 as above, +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 +(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 lisp + +@findex :exit, inside :repeat-map and :bind +Specifying @code{:exit} inside the scope of @code{:repeat-map} will +prevent the @code{repeat-map} property being set, so that the command +can be used from within the repeat map, but after it 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: + +@lisp +(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 lisp + +@findex :continue, inside :repeat-map 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 +(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 lisp + +@node Displaying keybindings +@subsection Displaying personal keybinding + +@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{@code{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 +The @code{:hook} keyword allows adding functions onto hooks. It takes +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 +(use-package company + :commands company-mode + :init + (add-hook 'prog-mode-hook #'company-mode)) +@end lisp + +Using @code{:hook}, this can be simplified to: + +@lisp +(use-package company + :hook (prog-mode . company-mode)) +@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 +(use-package company + :hook prog-mode) +@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 +(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)) +@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 +;; DOES NOT WORK +(use-package ace-jump-mode + :hook (prog-mode-hook . ace-jump-mode)) +@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 + +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. +The specifier to either keyword can be a cons cell, a list of cons +cells, or a string or regexp: + +@lisp +(use-package ruby-mode + :mode "\\.rb\\'" + :interpreter "ruby") + +;; The package is "python" but the mode is "python-mode": +(use-package python + :mode ("\\.py\\'" . python-mode) + :interpreter ("python" . python-mode)) +@end lisp + +@node Magic handlers +@section Magic handlers + +@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. +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 +(use-package pdf-tools + :magic ("%PDF" . pdf-view-mode) + :config + (pdf-tools-install :no-query)) +@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 + +@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 recommended 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 (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 lisp -The documentation string is not mandatory. +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, there +is also the new @code{setopt} macro that does this for you. -@node @code{custom-face} -@section @code{:custom-face} +Note that the values customized using this keyword are @emph{not} +saved in the standard Emacs @code{custom-file}. You should therefore +set each user option using either the @code{:custom} keyword @emph{or} +@w{@code{M-x customize-option}}, which will save customized values in +the Emacs @code{custom-file}. Do not use both for the same variable, +as this risk having conflicting values in your use-package declaration +and your @code{custom-file}. This can lead to problems that are both +tricky and tedious to debug. -The @code{:custom-face} keyword allows customization of package custom faces. +@node Faces +@section Faces + +The @code{:custom-face} keyword allows customization of package custom +faces. @lisp (use-package eruby-mode :custom-face (eruby-standard-face ((t (:slant italic))))) -@end lisp -@node @code{defer} @code{demand} -@section @code{:defer}, @code{:demand} +(use-package example + :custom-face + (example-1-face ((t (:foreground "LightPink")))) + (example-2-face ((t (:foreground "LightGreen"))) face-defspec-spec)) -In almost all cases you don't need to manually specify @code{:defer t}. This is -implied whenever @code{:bind} or @code{:mode} or @code{:interpreter} is used. Typically, you -only need to specify @code{:defer} if you know for a fact that some other package -will do something to cause your package to load at the appropriate time, and -thus you would like to defer loading even though use-package isn't creating -any autoloads for you. - -You can override package deferral with the @code{:demand} keyword. Thus, even if -you use @code{:bind}, using @code{:demand} will force loading to occur immediately and -not establish an autoload for the bound key. - -@node @code{defines} @code{functions} -@section @code{:defines}, @code{:functions} - -Another feature of @code{use-package} is that it always loads every file that it -can when @code{.emacs} is being byte-compiled. This helps to silence spurious -warnings about unknown variables and functions. - -However, there are times when this is just not enough. For those times, use -the @code{:defines} and @code{:functions} keywords to introduce dummy variable and -function declarations solely for the sake of the byte-compiler: - -@lisp -(use-package texinfo - :defines texinfo-section-list - :commands texinfo-mode - :init - (add-to-list 'auto-mode-alist '("\\.texi$" . texinfo-mode))) -@end lisp - -If you need to silence a missing function warning, you can use @code{:functions}: - -@lisp -(use-package ruby-mode - :mode "\\.rb\\'" - :interpreter "ruby" - :functions inf-ruby-keys +(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 - (defun my-ruby-mode-hook () - (require 'inf-ruby) - (inf-ruby-keys)) - - (add-hook 'ruby-mode-hook 'my-ruby-mode-hook)) + (load-theme 'zenburn t)) @end lisp -@node @code{diminish} @code{delight} -@section @code{:diminish}, @code{:delight} +@node Hiding minor modes +@section Hiding minor modes with diminish and delight -@code{use-package} also provides built-in support for the diminish and delight -utilities---if you have them installed. Their purpose is to remove or change -minor mode strings in your mode-line. +@code{use-package} supports the diminish and delight packages, both of +which make it possible 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 diminish.} To use either of them, you must first +install the corresponding package from @acronym{GNU ELPA}. -@uref{https://github.com/myrjola/diminish.el, diminish} is invoked with the @code{:diminish} keyword, which is passed 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: +@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 diminish package is installable from +@acronym{GNU ELPA}.} is installed, you can use the @code{:diminish} +keyword. First, add the following declaration to the beginning of +your init file. The optional @w{@code{:ensure t}} makes sure the +package is installed if it isn't already (@pxref{Installing +packages}). + +@lisp +(use-package diminish :ensure t) +@end lisp + +The @code{:diminish} keyword takes 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 (use-package abbrev @@ -609,11 +1197,26 @@ package name with "-mode" appended at the end: (quietly-read-abbrev-file))) @end lisp -@uref{https://elpa.gnu.org/packages/delight.html, delight} is invoked with the @code{:delight} keyword, which is passed a minor mode -symbol, a replacement string or quoted @uref{https://www.gnu.org/software/emacs/manual/html_node/elisp/Mode-Line-Data.html, mode-line data} (in which case the minor -mode symbol is guessed to be the package name with "-mode" appended at the -end), both of these, or several lists of both. If no arguments are provided, -the default mode name is hidden completely. +@node Delight +@subsection Delight + +@findex :delight +When delight@footnote{The @samp{delight} package is installable from +GNU ELPA.} is installed, you can use the @code{:delight} keyword. +First, add the following declaration to the beginning of your init +file. The optional @w{@code{:ensure t}} makes sure the package is +installed if it isn't already (@pxref{Installing packages}). + +@lisp +(use-package delight :ensure t) +@end lisp + +The @code{:delight} keyword takes a minor mode symbol, a replacement +string, or quoted mode line data (in which case the minor mode symbol +is guessed 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. @lisp ;; Don't show anything for rainbow-mode. @@ -636,30 +1239,31 @@ the default mode name is hidden completely. (visual-line-mode)) @end lisp -@node @code{disabled} -@section @code{:disabled} +@c ---------------------------------------------------------------------------- +@node Installing packages +@chapter Installing packages automatically -The @code{:disabled} keyword can turn off a module you're having difficulties with, -or stop loading something you're not using at the present time: +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. This is particularly useful if you use your init +file on more than one system. -@lisp -(use-package ess-site - :disabled - :commands R) -@end lisp +@menu +* Install package:: +* Pinning packages:: +* Other package managers:: +@end menu -When byte-compiling your @code{.emacs} file, disabled declarations are omitted -from the output entirely, to accelerate startup times. +@node Install package +@section Installing package -@node @code{ensure} @code{pin} -@section @code{:ensure}, @code{:pin} +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. -You can use @code{use-package} to load packages from ELPA with @code{package.el}. This -is particularly useful if you share your @code{.emacs} among several machines; the -relevant packages are downloaded automatically once declared in your @code{.emacs}. -The @code{:ensure} keyword causes the package(s) to be installed automatically if -not already present on your system (set @code{(setq use-package-always-ensure t)} -if you wish this behavior to be global for all packages): +For example: @lisp (use-package magit @@ -667,280 +1271,543 @@ if you wish this behavior to be global for all packages): @end lisp If you need to install a different package from the one named by -@code{use-package}, you can specify it like this: +@code{use-package}, you can use a symbol: @lisp (use-package tex :ensure auctex) @end lisp -Lastly, when running on Emacs 24.4 or later, use-package can pin a package to -a specific archive, allowing you to mix and match packages from different -archives. The primary use-case for this is preferring packages from the -@code{melpa-stable} and @code{gnu} archives, but using specific packages from @code{melpa} -when you need to track newer versions than what is available in the @code{stable} -archives is also a valid use-case. +You can customize the user option @code{use-package-always-ensure} to +non-@code{nil} if you want this behavior to be global for all +packages. -By default @code{package.el} prefers @code{melpa} over @code{melpa-stable} due to the -versioning @code{(> evil-20141208.623 evil-1.0.9)}, so even if you are tracking -only a single package from @code{melpa}, you will need to tag all the non-@code{melpa} -packages with the appropriate archive. If this really annoys you, then you can -set @code{use-package-always-pin} to set a default. +@lisp +(require 'use-package-ensure) +(setq use-package-always-ensure t) +@end lisp -If you want to manually keep a package updated and ignore upstream updates, -you can pin it to @code{manual}, which as long as there is no repository by that -name, will Just Work(tm). +@noindent +You can override the above setting for a single package by adding +@w{@code{:ensure nil}} to its declaration. -@code{use-package} throws an error if you try to pin a package to an archive that -has not been configured using @code{package-archives} (apart from the magic -@code{manual} archive mentioned above): +@node Pinning packages +@section Pinning packages using @code{:pin} -@example -Archive 'foo' requested for package 'bar' is not available. -@end example +@findex :pin +use-package can 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 ELPA} or +@acronym{NonGNU ELPA} (indicated by @code{gnu} and @code{nongnu}, +respectively), while installing specific packages from third-party +archives. -Example: +For example: @lisp (use-package company :ensure t - :pin melpa-stable) + :pin gnu) ; GNU ELPA +@end lisp -(use-package evil - :ensure t) - ;; no :pin needed, as package.el will choose the version in melpa +@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. -(use-package adaptive-wrap - :ensure t - ;; as this package is available only in the gnu archive, this is - ;; technically not needed, but it helps to highlight where it - ;; comes from - :pin gnu) +@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 (use-package org :ensure t ;; ignore org-mode from upstream and use a manually installed version :pin manual) @end lisp -@strong{NOTE}: the @code{:pin} argument has no effect on emacs versions < 24.4. +@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 @code{hook} -@section @code{:hook} +@node Other package managers +@section Non-standard package managers -The @code{:hook} keyword allows adding functions onto hooks, here only the basename -of the hook is required. Thus, all of the following are equivalent: +By default, use-package assumes that you are using the built-in +@code{package.el} package manager. We expect that most users will +find that it is more than 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 + +Some users might want to byte-compile their init file to make Emacs +startup even faster. This is not recommended in most cases, as the +speed-up is often too small to be worth it, and can lead to confusion +if the byte-compiled files are out-of-date. If you still want to do +it, read on. + +@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 +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 -(use-package ace-jump-mode - :hook prog-mode) - -(use-package ace-jump-mode - :hook (prog-mode . ace-jump-mode)) - -(use-package ace-jump-mode - :commands ace-jump-mode +(use-package texinfo + :defines texinfo-section-list + :commands texinfo-mode :init - (add-hook 'prog-mode-hook #'ace-jump-mode)) + (add-to-list 'auto-mode-alist '("\\.texi$" . texinfo-mode))) @end lisp -And likewise, when multiple hooks should be applied, the following are also -equivalent: - -@lisp -(use-package ace-jump-mode - :hook (prog-mode text-mode)) - -(use-package ace-jump-mode - :hook ((prog-mode text-mode) . ace-jump-mode)) - -(use-package ace-jump-mode - :hook ((prog-mode . ace-jump-mode) - (text-mode . ace-jump-mode))) - -(use-package ace-jump-mode - :commands ace-jump-mode - :init - (add-hook 'prog-mode-hook #'ace-jump-mode) - (add-hook 'text-mode-hook #'ace-jump-mode)) -@end lisp - -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} (meaning 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 @code{if} @code{when} @code{unless} -@section @code{:if}, @code{:when}, @code{:unless} - -You can use the @code{:if} keyword to predicate the loading and initialization of -modules. - -For example, I only want @code{edit-server} running for my main, graphical Emacs, -not for other Emacsen I may start at the command line: - -@lisp -(use-package edit-server - :if window-system - :init - (add-hook 'after-init-hook 'server-start t) - (add-hook 'after-init-hook 'edit-server-start t)) -@end lisp - -In another example, we can load things conditional on the operating system: - -@lisp -(use-package exec-path-from-shell - :if (memq window-system '(mac ns)) - :ensure t - :config - (exec-path-from-shell-initialize)) -@end lisp - -Note that @code{:when} is provided as an alias for @code{:if}, and @code{:unless foo} means -the same thing as @code{:if (not foo)}. - -@node @code{load-path} -@section @code{:load-path} - -If your package needs a directory added to the @code{load-path} in order to load, -use @code{:load-path}. This takes a symbol, a function, a string or a list of -strings. If the path is relative, it is expanded within -@code{user-emacs-directory}: - -@lisp -(use-package ess-site - :load-path "site-lisp/ess/lisp/" - :commands R) -@end lisp - -Note that when using a symbol or a function to provide a dynamically generated -list of paths, you must inform the byte-compiler of this definition so 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}). Further, this -value is fixed at whatever was determined during compilation, to avoid looking -up the same information again on each startup: - -@lisp -(eval-and-compile - (defun ess-site-load-path () - (shell-command "find ~ -path ess/lisp"))) - -(use-package ess-site - :load-path (lambda () (list (ess-site-load-path))) - :commands R) -@end lisp - -@node @code{mode} @code{interpreter} -@section @code{:mode}, @code{: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. The specifier to either keyword can be a cons cell, a list of cons -cells, or a string or regexp: +If you need to silence a missing function warning, you can use +@code{:functions}: @lisp (use-package ruby-mode :mode "\\.rb\\'" - :interpreter "ruby") - -;; The package is "python" but the mode is "python-mode": -(use-package python - :mode ("\\.py\\'" . python-mode) - :interpreter ("python" . python-mode)) -@end lisp - -If you aren't using @code{:commands}, @code{:bind}, @code{:bind*}, @code{:bind-keymap}, -@code{:bind-keymap*}, @code{:mode}, or @code{:interpreter} (all of which imply @code{:defer}; see -the docstring for @code{use-package} for a brief description of each), you can -still defer loading with the @code{:defer} keyword: - -@lisp -(use-package ace-jump-mode - :defer t - :init - (autoload 'ace-jump-mode "ace-jump-mode" nil t) - (bind-key "C-." 'ace-jump-mode)) -@end lisp - -This does exactly the same thing as the following: - -@lisp -(use-package ace-jump-mode - :bind ("C-." . ace-jump-mode)) -@end lisp - -@node @code{magic} @code{magic-fallback} -@section @code{:magic}, @code{: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. The difference between the two is -that @code{:magic-fallback} has a lower priority than @code{:mode}. For example: - -@lisp -(use-package pdf-tools - :load-path "site-lisp/pdf-tools/lisp" - :magic ("%PDF" . pdf-view-mode) + :interpreter "ruby" + :functions inf-ruby-keys :config - (pdf-tools-install)) + (defun my-ruby-mode-hook () + (require 'inf-ruby) + (inf-ruby-keys)) + + (add-hook 'ruby-mode-hook 'my-ruby-mode-hook)) @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 @code{no-require} -@section @code{:no-require} - -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: +@findex :no-require +@cindex prevent a package from loading at compile-time +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 (use-package foo :no-require t :config - (message "This is evaluated when `foo' is loaded")) + (message "Evaluate this immediately after loading `foo'")) @end lisp -@node @code{requires} -@section @code{:requires} +@c ---------------------------------------------------------------------------- +@node Troubleshooting +@chapter Troubleshooting -While the @code{:after} keyword delays loading until the dependencies are loaded, -the somewhat simpler @code{:requires} keyword simply never loads the package if the -dependencies are not available at the time the @code{use-package} declaration is -encountered. By "available" in this context it means that @code{foo} is available -of @code{(featurep 'foo)} evaluates to a non-nil value. For example: +@cindex troubleshooting +@cindex debugging +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 @code{*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 -(use-package abbrev - :requires foo) +(when init-file-debug + (setq use-package-verbose t + use-package-expand-minimally nil + use-package-compute-statistics t + debug-on-error t)) @end lisp -This is the same as: +@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 + +@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 -(use-package abbrev - :if (featurep 'foo)) +(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 lisp -As a convenience, a list of such packages may be specified: +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 + +@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 @code{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. + +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 it's +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 -(use-package abbrev - :requires (foo bar baz)) +(use-package foo + :disabled) @end lisp -For more complex logic, such as that supported by @code{:after}, simply use @code{:if} -and the appropriate Lisp expression. +When byte-compiling your init file, use-package omits disabled +declarations from the output entirely, in order to make Emacs startup +faster. -@node Debugging Tools -@chapter Debugging Tools +@c ---------------------------------------------------------------------------- +@node Keyword extensions +@appendix Keyword extensions -TODO +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:: +* use-package-chords:: +* Creating an extension:: +@end menu + +@node use-package-ensure-system-package +@section :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, you will want to make sure +@code{exec-path} is cognisant of all binary package names that you +would like to ensure are installed. The +@uref{https://github.com/purcell/exec-path-from-shell,@samp{exec-path-from-shell}} +package is often a good way to do this.} + +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 +(use-package foo + :ensure-system-package foo) +@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 GNU 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 +(use-package system-packages + :ensure t) +@end lisp + +For example, on a @code{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 +(use-package foo + :ensure-system-package + (foocmd . foo)) +@end lisp + +On a @code{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 its +@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 upon any external package. + +@lisp +(use-package tern + :ensure-system-package (tern . "npm i -g tern")) +@end lisp + +To install several packages, you can pass in a list of conses: + +@lisp +(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 lisp + +Finally, in case the package dependency does not provide a global +executable, you can ensure packages exist by checking the presence of a +file path by providing a string like so: + +@lisp +(use-package dash-at-point + :if (eq system-type 'darwin) + :ensure-system-package + ("/Applications/Dash.app" . "brew cask install dash")) +@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 use-package-chords +@section @code{(use-package-chords)} + +The @code{:chords} keyword allows you to define +@uref{https://www.emacswiki.org/emacs/key-chord.el,@code{key-chord}} +bindings for @code{use-package} declarations in the same manner as the +@code{:bind} keyword. + +To enable the extension: + +@lisp +(use-package use-package-chords + :ensure t + :config (key-chord-mode 1)) +@end lisp + +Then you can define your chord bindings in the same manner as +@code{:bind} using a cons or a list of conses: + +@lisp +(use-package ace-jump-mode + :chords (("jj" . ace-jump-char-mode) + ("jk" . ace-jump-word-mode) + ("jl" . ace-jump-line-mode))) +@end lisp + +@node Creating an extension +@section How to create an extension keyword + +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 +(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 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, it +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 handler 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 +(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 lisp + +@item +Test it. + +After the keyword has been inserted into @code{use-package-keywords}, +and a normalizer and a handler defined, you can now test it by seeing +how usages of the keyword will expand. For this, use @code{M-x +pp-macroexpand-last-sexp} with the cursor set immediately after the +@code{(use-package ...)} 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 From 537f11f8cd188dda6524dd7e2148d318537d4690 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Thu, 8 Dec 2022 01:49:04 +0100 Subject: [PATCH 596/606] ; * doc/misc/use-package.texi: Improve indexing. --- doc/misc/use-package.texi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index d39125c4555..7819cb250d0 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -522,6 +522,7 @@ simply use @code{:if} and the appropriate Lisp expression. @node Load path @section Setting a custom @code{load-path} +@findex :load-path If a package resides in some directory that is not in your @code{load-path}, use the @code{:load-path} keyword to add it. It takes a symbol, a function, a string or a list of strings. If the @@ -723,6 +724,7 @@ can simplify this using the @code{:bind} keyword. @node Global keybindings @subsection Global keybindings +@findex :bind To bind keys globally, the @code{:bind} keyword takes either a single cons or a list of conses. Every cons has the form @code{(@var{key} . @var{command}}, where @var{key} is a string indicating the key to @@ -969,6 +971,7 @@ keybindings you've set using either the @code{:bind} keyword or the @section Hooks @cindex hooks +@findex :hook The @code{:hook} keyword allows adding functions onto hooks. It takes 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 @@ -1055,6 +1058,8 @@ implied by @code{:hook}. @node Modes and interpreters @section Modes and interpreters +@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. @@ -1131,6 +1136,7 @@ tricky and tedious to debug. @node Faces @section Faces +@findex :custom-face The @code{:custom-face} keyword allows customization of package custom faces. @@ -1259,6 +1265,7 @@ file on more than one system. @node Install package @section Installing package +@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. From 888558ec425031e878c4243b205bd281134c10b2 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Thu, 8 Dec 2022 02:00:13 +0100 Subject: [PATCH 597/606] Improve bind-keys* and override-global-mode docstrings * lisp/use-package/bind-key.el (bind-keys*): Add docstring. (override-global-mode) Improve docstring. --- lisp/use-package/bind-key.el | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 3168f686a09..9ebb859a359 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -128,7 +128,18 @@ "Keymap for `override-global-mode'.") (define-minor-mode override-global-mode - "A minor mode so that keymap settings override other modes." + "A minor mode for allowing keybindings to override other modes. +The main purpose of this mode is to simplify bindings keys in +such a way that they take precedence over other modes. + +To achieve this, the keymap `override-global-map' is added to +`emulation-mode-map-alists', which makes it take precedence over +keymaps in `minor-mode-map-alist'. Thereby, key bindings get an +even higher precedence than global key bindings defined with +`keymap-global-set' (or, in Emacs 28 or older, `global-set-key'). + +The macro `bind-key*' (which see) provides a convenient way to +add keys to that keymap." :init-value t :lighter "") @@ -425,6 +436,11 @@ function symbol (unquoted)." ;;;###autoload (defmacro bind-keys* (&rest args) + "Bind multiple keys at once, in `override-global-map'. +Accepts the same keyword arguments as `bind-keys' (which see). + +This binds keys in such a way that bindings are not overridden by +other modes. See `override-global-mode'." (macroexp-progn (bind-keys-form args 'override-global-map))) (defun get-binding-description (elem) From 141fe8b827399057e2f854cd5e6b0c148c5fe12b Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Thu, 8 Dec 2022 02:25:53 +0100 Subject: [PATCH 598/606] use-package: Improve :mode keyword documentation * doc/misc/use-package.texi (Modes and interpreters): Improve section and document the use of a list of regexps. Resolves https://github.com/jwiegley/use-package/issues/996 --- doc/misc/use-package.texi | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index 7819cb250d0..c1cc22808e6 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -1064,19 +1064,43 @@ 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. The specifier to either keyword can be a cons cell, a list of cons -cells, or a string or regexp: +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 @samp{.rb} extension), or when the +first line of the file (known as the ``shebang'') matches the string +@code{"ruby"}: @lisp (use-package ruby-mode :mode "\\.rb\\'" :interpreter "ruby") +@end lisp +The default @code{python-mode} configuration can be reproduced using +the below declaration. Note that the package that should be loaded +differs from the mode name in this case, so we must use a cons: + +@lisp ;; The package is "python" but the mode is "python-mode": (use-package python :mode ("\\.py\\'" . python-mode) :interpreter ("python" . python-mode)) @end lisp +Both the @code{:mode} and @code{:interpreter} keywords also accept a +list of regexps: + +@lisp +(use-package foo + ;; Equivalent to "\\(ba[rz]\\)\\'": + :mode ("\\.bar\\'" "\\.baz\\'") + ;; Equivalent to "\\(foo[ab]\\)": + :interpreter ("fooa" "foob")) +@end lisp + @node Magic handlers @section Magic handlers From c65e08706812553b4f8dc55e8d2df2cde0d26b39 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Thu, 8 Dec 2022 06:27:22 +0100 Subject: [PATCH 599/606] ; use-package: Improve :ensure-system-package docstrings * lisp/use-package/use-package-ensure-system-package.el (use-package-ensure-system-package--custom-packages) (use-package-ensure-system-package-consify) (use-package-ensure-system-package-update-custom-packages) (use-package-normalize/:ensure-system-package) (use-package-ensure-system-package-exists?): Improve docstrings. --- lisp/use-package/use-package-ensure-system-package.el | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lisp/use-package/use-package-ensure-system-package.el b/lisp/use-package/use-package-ensure-system-package.el index 9c9f0797a05..c55bacaf817 100644 --- a/lisp/use-package/use-package-ensure-system-package.el +++ b/lisp/use-package/use-package-ensure-system-package.el @@ -37,10 +37,10 @@ (declare-function system-packages-get-command "system-packages")) (defvar use-package-ensure-system-package--custom-packages '() - "List of custom packages installed.") + "List of commands used to install custom packages.") (defun use-package-ensure-system-package-consify (arg) - "Turn ARG into a cons of (`package-name' . `install-command')." + "Turn ARG into a cons of the form (PACKAGE-NAME . INSTALL-COMMAND')." (cond ((stringp arg) (cons arg `(system-packages-install ,arg))) @@ -59,13 +59,15 @@ `(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 (`package-name' . `install-command')." + "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 @@ -75,7 +77,7 @@ (list (use-package-ensure-system-package-consify arg))))))) (defun use-package-ensure-system-package-exists? (file-or-exe) - "If variable is a string, ensure the file path exists. + "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) From d3e9bd3b57ddd4b42c611a4141d0188d17c52f05 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Thu, 8 Dec 2022 06:36:44 +0100 Subject: [PATCH 600/606] ; Document use-package-reset-statistics * doc/misc/use-package.texi (Gathering Statistics): Document use-package-reset-statistics. --- doc/misc/use-package.texi | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index c1cc22808e6..f69b3123f30 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -1553,14 +1553,18 @@ 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 @code{M-x use-package-report} to see the results. The +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. +@cindex 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 +this after loading @code{use-package}, but before any @code{use-package} forms. @node Disabling a package From 5899cac11167deca044dc80bfd85bb88fbb44500 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Thu, 8 Dec 2022 08:48:24 +0100 Subject: [PATCH 601/606] Change use-package custom :group to `initialization` * lisp/use-package/use-package-core.el (use-package): Move defgroup to custom :group 'initialization'. --- lisp/use-package/use-package-core.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 6606681f2ea..ff4e03c8627 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -63,7 +63,7 @@ (defgroup use-package nil "A `use-package' declaration for simplifying your `.emacs'." - :group 'startup) + :group 'initialization) (defconst use-package-version "2.4.4" "This version of `use-package'.") From 4be96c9dcbe8405df5b29507388481c15884da1f Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Thu, 8 Dec 2022 01:12:02 +0100 Subject: [PATCH 602/606] Drop key-chord.el support from use-package * lisp/use-package/bind-chord.el: * lisp/use-package/use-package-chords.el: * test/lisp/use-package/use-package-chords-tests.el: Delete files. * doc/misc/use-package.texi (use-package-chords): Delete section. Ref: https://lists.gnu.org/r/emacs-devel/2022-12/msg00052.html --- doc/misc/use-package.texi | 27 --- lisp/use-package/bind-chord.el | 113 ------------ lisp/use-package/use-package-chords.el | 54 ------ .../use-package/use-package-chords-tests.el | 169 ------------------ 4 files changed, 363 deletions(-) delete mode 100644 lisp/use-package/bind-chord.el delete mode 100644 lisp/use-package/use-package-chords.el delete mode 100644 test/lisp/use-package/use-package-chords-tests.el diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index f69b3123f30..e7bddd628c9 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -1604,7 +1604,6 @@ be optionally enabled. @menu * use-package-ensure-system-package:: -* use-package-chords:: * Creating an extension:: @end menu @@ -1710,32 +1709,6 @@ The user options @code{system-packages-package-manager} and commands. Custom commands should include the call to sudo in the command if needed. -@node use-package-chords -@section @code{(use-package-chords)} - -The @code{:chords} keyword allows you to define -@uref{https://www.emacswiki.org/emacs/key-chord.el,@code{key-chord}} -bindings for @code{use-package} declarations in the same manner as the -@code{:bind} keyword. - -To enable the extension: - -@lisp -(use-package use-package-chords - :ensure t - :config (key-chord-mode 1)) -@end lisp - -Then you can define your chord bindings in the same manner as -@code{:bind} using a cons or a list of conses: - -@lisp -(use-package ace-jump-mode - :chords (("jj" . ace-jump-char-mode) - ("jk" . ace-jump-word-mode) - ("jl" . ace-jump-line-mode))) -@end lisp - @node Creating an extension @section How to create an extension keyword diff --git a/lisp/use-package/bind-chord.el b/lisp/use-package/bind-chord.el deleted file mode 100644 index ed736a4b966..00000000000 --- a/lisp/use-package/bind-chord.el +++ /dev/null @@ -1,113 +0,0 @@ -;;; 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 -;; Keywords: convenience, tools, extensions -;; URL: https://github.com/jwiegley/use-package -;; Version: 0.2.1 -;; Package-Requires: ((emacs "24.3") (bind-key "1.0") (key-chord "0.6")) -;; Filename: bind-chord.el - -;; 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 of the License, or -;; (at your option) any later version. - -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see . - -;;; 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/lisp/use-package/use-package-chords.el b/lisp/use-package/use-package-chords.el deleted file mode 100644 index 479083b9296..00000000000 --- a/lisp/use-package/use-package-chords.el +++ /dev/null @@ -1,54 +0,0 @@ -;;; use-package-chords.el --- key-chord keyword for use-package -*- lexical-binding: t; -*- - -;; Copyright (C) 2015-2022 Free Software Foundation, Inc. - -;; Author: Justin Talbott -;; Keywords: convenience, tools, extensions -;; URL: https://github.com/jwiegley/use-package -;; Version: 0.2.1 -;; Package-Requires: ((use-package "2.1") (bind-key "1.0") (bind-chord "0.2") (key-chord "0.6")) -;; Filename: use-package-chords.el - -;; 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 of the License, or -;; (at your option) any later version. - -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see . - -;;; Commentary: - -;; The `:chords' keyword allows you to define `key-chord' bindings for -;; `use-package' declarations in the same manner as the `:bind' -;; keyword. - -;;; Code: - -(require 'use-package) -(require 'bind-chord) - -;;;###autoload -(defalias 'use-package-autoloads/:chords 'use-package-autoloads-mode) - -;;;###autoload -(defalias 'use-package-normalize/:chords 'use-package-normalize-binder) - -;;;###autoload -(defun use-package-handler/:chords (name _keyword arg rest state) - "Handler for `:chords' keyword in `use-package'." - (use-package-concat - (use-package-process-keywords name rest state) - `(,(macroexpand - `(bind-chords :package ,name ,@arg))))) - -(add-to-list 'use-package-keywords :chords) - -(provide 'use-package-chords) - -;;; use-package-chords.el ends here diff --git a/test/lisp/use-package/use-package-chords-tests.el b/test/lisp/use-package/use-package-chords-tests.el deleted file mode 100644 index 665784eaf46..00000000000 --- a/test/lisp/use-package/use-package-chords-tests.el +++ /dev/null @@ -1,169 +0,0 @@ -;;; use-package-chords-tests.el --- Tests for use-package-chords.el -*- lexical-binding: t; -*- - -;; Copyright (C) 2019-2022 Free Software Foundation, Inc. - -;; 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 of the License, or -;; (at your option) any later version. - -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see . - -;;; Code: - -(require 'ert) -(require 'use-package) -(require 'use-package-chords) - -(setq use-package-always-ensure nil - use-package-verbose 'errors - use-package-expand-minimally t) - -(defmacro match-expansion (form &rest value) - `(should (pcase (expand-minimally ,form) - ,@(mapcar #'(lambda (x) (list x t)) value)))) - -;; Copied from use-package-tests.el. -(defmacro expand-minimally (form) - `(let ((use-package-verbose 'errors) - (use-package-expand-minimally t)) - (macroexpand-1 ',form))) - -(defun use-package-test-normalize-chord (&rest args) - (apply #'use-package-normalize-binder 'foo :chords args)) - -(ert-deftest use-package-test-normalize/:chords-1 () - (should (equal (use-package-test-normalize-chord - '(("C-a" . alpha))) - '(("C-a" . alpha))))) - -(ert-deftest use-package-test-normalize/:chords-2 () - (should (equal (use-package-test-normalize-chord - '(("C-a" . alpha) - :map foo-map - ("C-b" . beta))) - '(("C-a" . alpha) - :map foo-map - ("C-b" . beta))))) - -(ert-deftest use-package-test-normalize/:chords-3 () - (should (equal (use-package-test-normalize-chord - '(:map foo-map - ("C-a" . alpha) - ("C-b" . beta))) - '(:map foo-map - ("C-a" . alpha) - ("C-b" . beta))))) - -(ert-deftest use-package-test/:chords-1 () - ;; FIXME: - :tags '(:unstable) - (match-expansion - (use-package foo :chords ("C-k" . key1) ("C-u" . key2)) - `(progn - (unless - (fboundp 'key1) - (autoload #'key1 "foo" nil t)) - (unless - (fboundp 'key2) - (autoload #'key2 "foo" nil t)) - (bind-chord "C-k" #'key1 nil) - (bind-chord "C-u" #'key2 nil)))) - -(ert-deftest use-package-test/:chords-2 () - ;; FIXME: - :tags '(:unstable) - (match-expansion - (use-package foo :chords (("C-k" . key1) ("C-u" . key2))) - `(progn - (unless (fboundp 'key1) - (autoload #'key1 "foo" nil t)) - (unless (fboundp 'key2) - (autoload #'key2 "foo" nil t)) - (bind-chord "C-k" #'key1 nil) - (bind-chord "C-u" #'key2 nil)))) - -(ert-deftest use-package-test/:chords-3 () - (match-expansion - (use-package foo :chords (:map my-map ("C-k" . key1) ("C-u" . key2))) - `(progn - (unless - (fboundp 'key1) - (autoload #'key1 "foo" nil t)) - (unless - (fboundp 'key2) - (autoload #'key2 "foo" nil t)) - (if - (boundp 'my-map) - (progn - (bind-chord "C-k" #'key1 my-map) - (bind-chord "C-u" #'key2 my-map)) - (eval-after-load 'foo - '(progn - (bind-chord "C-k" #'key1 my-map) - (bind-chord "C-u" #'key2 my-map))))))) - -(ert-deftest use-package-test/:chords-4 () - (should-error - (match-expansion - (use-package foo :chords :map my-map ("C-k" . key1) ("C-u" . key2)) - `(bind-chords :package foo)))) - -(ert-deftest use-package-test/:chords-5 () - (match-expansion - (use-package foo :chords ("C-k" . key1) (:map my-map ("C-u" . key2))) - `(progn - (unless (fboundp 'key1) - (autoload #'key1 "foo" nil t)) - (unless (fboundp 'key2) - (autoload #'key2 "foo" nil t)) - (progn - (bind-chord "C-k" #'key1 nil) - (if - (boundp 'my-map) - (bind-chord "C-u" #'key2 my-map) - (eval-after-load 'foo - '(bind-chord "C-u" #'key2 my-map))))))) - -(ert-deftest use-package-test/:chords-6 () - (match-expansion - (use-package foo - :chords - ("C-k" . key1) - (:map my-map ("C-u" . key2)) - (:map my-map2 ("C-u" . key3))) - `(progn - (unless - (fboundp 'key1) - (autoload #'key1 "foo" nil t)) - (unless - (fboundp 'key2) - (autoload #'key2 "foo" nil t)) - (unless - (fboundp 'key3) - (autoload #'key3 "foo" nil t)) - (progn - (bind-chord "C-k" #'key1 nil) - (if - (boundp 'my-map) - (bind-chord "C-u" #'key2 my-map) - (eval-after-load 'foo - '(bind-chord "C-u" #'key2 my-map))) - (if - (boundp 'my-map2) - (bind-chord "C-u" #'key3 my-map2) - (eval-after-load 'foo - '(bind-chord "C-u" #'key3 my-map2))))))) - -;; Local Variables: -;; no-byte-compile: t -;; no-update-autoloads: t -;; End: - -;;; use-package-chords-tests.el ends here From 15fb115551e8bd308555f5365994e6764cb9e80a Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Thu, 8 Dec 2022 17:10:47 +0100 Subject: [PATCH 603/606] Update use-package defgroups * lisp/use-package/bind-key.el (bind-key): * lisp/use-package/use-package-core.el (use-package): * lisp/use-package/use-package-ensure.el (use-package-ensure): Add :link, :version and :group to defgroups. --- lisp/use-package/bind-key.el | 5 ++++- lisp/use-package/use-package-core.el | 4 +++- lisp/use-package/use-package-ensure.el | 4 +++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 9ebb859a359..9b9fc3531c4 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -103,7 +103,10 @@ (defgroup bind-key nil "A simple way to manage personal keybindings." - :group 'emacs) + :group 'keyboard + :group 'convenience + :link '(emacs-commentary-link :tag "Commentary" "bind-key.el") + :version "29.1") (defcustom bind-key-column-widths '(18 . 40) "Width of columns in `describe-personal-keybindings'." diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index ff4e03c8627..5ebe6576190 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -63,7 +63,9 @@ (defgroup use-package nil "A `use-package' declaration for simplifying your `.emacs'." - :group 'initialization) + :group 'initialization + :link '(custom-manual "(use-package) Top") + :version "29.1") (defconst use-package-version "2.4.4" "This version of `use-package'.") diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el index c9cc6e70c51..bbb8e4175b8 100644 --- a/lisp/use-package/use-package-ensure.el +++ b/lisp/use-package/use-package-ensure.el @@ -30,7 +30,9 @@ (defgroup use-package-ensure nil "Support for :ensure and :pin keywords in `use-package' declarations." - :group 'use-package) + :group 'use-package + :link '(custom-manual "(use-package) Installing packages") + :version "29.1") (eval-when-compile (declare-function package-installed-p "package") From b9fa81514f97c0b55119ef9941fd124a1c046119 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Thu, 8 Dec 2022 17:14:31 +0100 Subject: [PATCH 604/606] ; Minor doc fixes in bind-key.el * lisp/use-package/bind-key.el (bind-key-segregation-regexp) (bind-key): Minor doc fixes. --- lisp/use-package/bind-key.el | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 9b9fc3531c4..bbe3319d9bb 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -115,8 +115,7 @@ (defcustom bind-key-segregation-regexp "\\`\\(\\(C-[chx] \\|M-[gso] \\)\\([CM]-\\)?\\|.+-\\)" - "Regular expression used to divide key sets in the output from -\\[describe-personal-keybindings]." + "Regexp used by \\[describe-personal-keybindings] to divide key sets." :type 'regexp :group 'bind-key) @@ -161,9 +160,9 @@ Elements have the form ((KEY . [MAP]) CMD ORIGINAL-CMD)") "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. +`define-key'. Or it may be a string to be interpreted as +spelled-out keystrokes, e.g., \"C-c C-z\". See the documentation +of `edmacro-mode' for details. COMMAND must be an interactive function or lambda form. From 6bb4267a54e1b8e1c02f996a581faca1ed604aab Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Thu, 8 Dec 2022 17:49:30 +0100 Subject: [PATCH 605/606] * admin/git-bisect-start: Prune use-package merge commits. --- admin/git-bisect-start | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/admin/git-bisect-start b/admin/git-bisect-start index cf0c8cde410..7a715b4261d 100755 --- a/admin/git-bisect-start +++ b/admin/git-bisect-start @@ -35,6 +35,10 @@ git bisect start -# Prune commits 1e5b753bf4..806734c1b1 introduced by 0186faf2a1 (Eglot -# merge on Oct 20 2022) +# Prune commits 1e5b753bf4..806734c1b1 introduced by 0186faf2a1 +# (Eglot merge on Oct 20 2022) git bisect good 806734c1b1f433de43d59d9a5e3a1e89d64315f6 + +# Prune commits 31ea42e15e..a6cbfdd8f1 introduced by 4a1e9d61b5 +# (use-package merge on Nov 30 2022) +git bisect good 4a1e9d61b57c36255752437a2668e037e79fe870 From 5bcd0cee0fc5eba81d254cba91459ba340c71dd3 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Thu, 8 Dec 2022 18:00:19 +0100 Subject: [PATCH 606/606] * etc/USE-PACKAGE-NEWS: Delete file. Ref: https://lists.gnu.org/r/emacs-devel/2022-11/msg01535.html --- etc/USE-PACKAGE-NEWS | 277 ------------------------------------------- 1 file changed, 277 deletions(-) delete mode 100644 etc/USE-PACKAGE-NEWS diff --git a/etc/USE-PACKAGE-NEWS b/etc/USE-PACKAGE-NEWS deleted file mode 100644 index c499820755f..00000000000 --- a/etc/USE-PACKAGE-NEWS +++ /dev/null @@ -1,277 +0,0 @@ -# Changes - -## 2.4.4 - -This release prepares for inclusion to GNU ELPA and includes no other changes - -## 2.4.1 - -This is mostly a bug-fix release: - -- Update the documentation for :custom as per #850 - -- Fix broken test due to #850 - -- better tests - -- add test for #845 - -- Support keymap symbol in bind-key. Fix #845 - -- use-package-core.el: use the Emacs set-default function to avoid saving :custom vars twice - -- Fix Travis - -- typo, should be a vector, not a bytecode object - - Solves https://github.com/jwiegley/use-package/issues/842 - -- Add special value back again, in case needed for backwards compat - - I don't know why this special value exists, but perhaps old client code uses it. - - The additional `t' in the macro expansion is accidental but not harmful I guess. - -- Even when there's no :config, run any pre/post config hooks - - i.e., following the existing docs for use-package-inject-hooks, these hooks are - run: - - use-package--foo--pre-config-hook - use-package--foo--post-config-hook - - This should make config customisations more predictable (for example, spacemacs - uses these hooks extensively to allow 'layers' to be customised). - - I got rid of the "special" default value for :config, because it doesn't seem to - be treated any differently than nil. - - Fixes #785 - -- Clarify the documentation for :after - -- add table of contents to README - -- Fix typos - - Typos found with codespell. - -- Fix typos - -- Attempt to explain omit "-hook" better - -- Update tests - -- Switch from `require' to `load' + `featurep' - -- Use `require', not `load', when byte-compiling - -- Make custom-face evaluate elisp. - - Fix #696. - -- Add a line of documentation for (use-pacakage ... :hook). - -- Fix typo in README - -- Fix documentation for defer - -- Add no-query option for pdf-tools-install - -- Fix typo in README - -- Fix all notes in README - -- Mention use-package-ensure in README - - Without requiring `use-package-ensure`, setting `use-package-always-ensure` - did not actually work for me. - -## 2.4 - -### Breaking changes - -- `use-package` no longer requires `diminish` as a dependency, allowing people - to decide whether they want to use diminish or delight. This means that if - you do use diminish, you'll now need to pull it into your configuration - before any use of the `:diminish` kewyord. For example: - - ``` elisp - (use-package diminish :ensure t) - ``` - -- Emacs 24.3 or higher is now a requirement. - -- The `:defer-install` keyword has been removed. It may reappear as an add-on - module for use-package in a future release. See issue #442 for more details. - -- There is no longer a `use-package-debug` option, since `use-package-verbose` - already has the possible value of `debug`. - -- The ordering of several elements of `use-package-keywords` have changed; if - you had previously customized this (or were an extension author adding to - this list), you may need to rework your changes. - -- For extension authors, `:commands` should no longer be propagated down for - autoloading. See more below. - -### Other changes - -- Upgrade license to GPL 3. - -- If `use-package-verbose` is set to the symbol `debug`, any evaluation errors - during package configuration will cause a complete report to be written to a - `*use-package*` buffer, including: the text of the error, the `use-package` - declaration that caused the error, the post-normalized form of this - declaration, and the macro-expanded version (without verbosity-related - code). Note that this still does not help if there are parsing errors, which - cause Emacs to register a Lisp error at startup time. - -- New customization variable `use-package-deferring-keywords`, mainly intended - for use by extension packages, indicates keywords that, if used without - `:demand`, cause deferred loading (as if `:defer t` had been specified). - -- The `:ensure` keyword now accepts a specific pinning sub-keyword. For - example: - - ``` elisp - (use-package foo - :pin "elpa") - ``` - - This ensure the package `foo` is installed from `"elpa"`. - - ``` elisp - (use-package foo - :ensure bar - :ensure (quux :pin "melpa")) - ``` - - This says that `foo` ensures that `bar` is installed, as well as `quux` from - `"melpa"`. It does *not* ensure that `foo` is installed, because explicit - `:ensure` keywords were given. - -- New `:hook` keyword. - -- New `:catch` keyword. If `t` or `nil`, it enables (the default, see - `use-package-defaults`) or disables catching errors at load time in - use-package expansions. 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`). - -- New keywords `:custom (foo1 bar1) (foo2 bar2)` etc., and `:custom-face`. - - NOTE: These are only for people who wish to keep customizations with their - accompanying use-package declarations. Functionally, the only benefit over - using `setq` in a `:config` block is that customizations might execute code - when values are assigned. If you currently use `M-x customize-option` and - save to a settings file, you do not want to use this option. - -- New `:magic` and `:magic-fallback` keywords. - -- New `:defer-install` keyword. - -- New customization variable `use-package-enable-imenu-support`. - -- New customization variable `use-package-hook-name-suffix`. Any symbols named - in `:hook`, or in the CAR of cons cells passed to `:hook`, have this text - appended to them as a convenience. If you find yourself using this keyword - to add to hooks of different names, or just don't want such appending done, - you can change the text to an empty string. - -- New customization variable `use-package-compute-statistics`, and an - accompanying command `M-x use-package-report`. See the README for more - details. - -- Allow `:diminish` to take no arguments. - -- Support multiple symbols passed to `:after`, and a mini-DSL using `:all` and - `:any`. - -- `:mode` and `:interpreter` can now accept `(rx ...)` forms. - -- Using `:load-path` without also using `:ensure` now implies `:ensure nil`. - -- `:bind (:map foo-map ...)` now defers binding in the map until the package - has been loaded. - -- Print key bindings for keymaps in `describe-personal-keybindings`. - -- When `use-package-inject-hooks` is non-nil, always fire `:init` and - `:config` hooks. - -- Documentation added for the `:after`, `:defer-install`, `:delight`, - `:requires`, `:when` and `:unless` keywords. - -- `:requires SYM` is subtly different from `:if (featurep SYM)`, in that it - happens before the `:preface`. This means that using `:requires` will cause - definitions in the `:preface` to not be visible to the byte-compiler, - leading to possible warnings about unknown functions, or functions that may - not be available at run-time (which can generally be ignored, since - `:requires` is intended as a check for basic system functionality; `:after` - should be used to check for the presence of other modules). - -- New undocumented (and currently experimental) keyword `:load` may be used to - change the name of the actual package loaded, rather than the package name, - and may even add other names. For example: `(use-package auctex :load - tex-site)`. This keyword is used internally to generate the `require` for a - package, so that deferral is simply a matter of not generating this keyword. - -- The source code is now broken into several files, so that certain optional - features (diminish, delight, ensure) may be maintained separately from the - core functionality. - -- When using the `:after` keyword, now even autoloadeds keybinding are - deferred until after that other package has loaded, in order to allow - convenient `:bind` to maps only present in that other package. Consider the - following: - - ``` elisp - (use-package helm-descbinds - :load-path "site-lisp/helm-descbinds" - :after helm - :bind ("C-h b" . helm-descbinds) - :init - (fset 'describe-bindings 'helm-descbinds)) - ``` - - The binding of `C-h b` here will not occur until helm is loaded; and after - it is loaded, `helm-descbinds` itself is not loaded until the user presses - `C-h b`. - -- For extension authors, if you add a keyword to `use-package-keywords` whose - presence should indicate deferred loading, please also add it to - `use-package-deferring-keywords`. Note that this is a bit of a sledgehammer, - in that the mere presence of these keywords implies deferred loading. For a - more subtle approach, see the new `use-package-autoloads/` support - mentioned in the next bullet. - -- For extension authors, if you wish deferred loading to possibly occur, - create functions named `use-package-autoloads/` for each keyword - that you define, returning an alist of the form `(SYMBOL . TYPE)` of symbols - to be autoloaded. `SYMBOL` should be an interactive function, and `TYPE` the - smybol `command`, but this functionality may be extended in future. These - autoloads are established if deferred loading is to happen. - -- If you specify a lambda form rather than a function symbol in any of the - constructs that *might* introduce autoloads: `:bind`, `:bind*`, - `:interpreter`, `:mode`, `:magic`, `:magic-fallback`, and `:hook`: then - deferred loading will no longer be implied, since there's nothing to - associate an autoload with that could later load the module. In these cases, - it will be as if you'd specified `:demand t`, in order to ensure the lambda - form is able to execute in the context of the loaded package. - -- For extension authors, there is a new customization variable - `use-package-merge-key-alist` that specifies how values passed to multiple - occurrences of the same key should be merged into a single value, during - normalization of the `use-package` declaration into a proper plist. The - default behavior is to simply append the values together (since they are - always normalized to lists). - -### Bug fixes - -- Repeating a bind no longer causes duplicates in personal-keybindings. -- When byte-compiling, correctly output declare-function directives. -- Append to *use-package* when debugging, don't clear it. -- Don't allow :commands, :bind, etc., to be given an empty list. -- Explicit :defer t should override use-package-always-demand.