mirror of
https://github.com/masscollaborationlabs/emacs.git
synced 2025-07-05 11:49:37 +00:00
Changes to the way auto-deferral is indicated
This change adds a new extension hook `use-package-autoloads/<KEYWORD>` 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`.
This commit is contained in:
parent
80e8a599b4
commit
8fefa49d39
4 changed files with 181 additions and 109 deletions
|
@ -30,10 +30,6 @@
|
||||||
parameter, but are now done as an extension to `rest`. Please see
|
parameter, but are now done as an extension to `rest`. Please see
|
||||||
`use-package-handler/:bind` for a canonical example.
|
`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
|
### Other changes
|
||||||
|
|
||||||
- Upgrade license to GPL 3.
|
- Upgrade license to GPL 3.
|
||||||
|
@ -154,6 +150,28 @@
|
||||||
it is loaded, `helm-descbinds` itself is not loaded until the user presses
|
it is loaded, `helm-descbinds` itself is not loaded until the user presses
|
||||||
`C-h b`.
|
`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/<KEYWORD>` support
|
||||||
|
mentioned in the next bullet.
|
||||||
|
|
||||||
|
- For extension authors, if you wish deferred loading to possibly occur,
|
||||||
|
create functions named `use-package-autoloads/<KEYWORD>` 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
|
- For extension authors, there is a new customization variable
|
||||||
`use-package-merge-key-alist` that specifies how values passed to multiple
|
`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
|
occurences of the same key should be merged into a single value, during
|
||||||
|
|
|
@ -114,20 +114,23 @@ deferred until the prefix key sequence is pressed."
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defalias 'use-package-normalize/:bind* 'use-package-normalize-binder)
|
(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
|
;;;###autoload
|
||||||
(defun use-package-handler/:bind
|
(defun use-package-handler/:bind
|
||||||
(name keyword args rest state &optional bind-macro)
|
(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-concat
|
||||||
(use-package-process-keywords name
|
(use-package-process-keywords name rest state)
|
||||||
(use-package-sort-keywords
|
|
||||||
(use-package-plist-append rest :commands commands))
|
|
||||||
state)
|
|
||||||
`((ignore
|
`((ignore
|
||||||
(,(if bind-macro bind-macro 'bind-keys)
|
(,(if bind-macro bind-macro 'bind-keys)
|
||||||
:package ,name ,@nargs))))))
|
:package ,name ,@(use-package-normalize-commands args))))))
|
||||||
|
|
||||||
(defun use-package-handler/:bind* (name keyword arg rest state)
|
(defun use-package-handler/:bind* (name keyword arg rest state)
|
||||||
(use-package-handler/:bind name keyword arg rest state 'bind-keys*))
|
(use-package-handler/:bind name keyword arg rest state 'bind-keys*))
|
||||||
|
|
|
@ -100,17 +100,15 @@ declaration is incorrect."
|
||||||
:group 'use-package)
|
:group 'use-package)
|
||||||
|
|
||||||
(defcustom use-package-deferring-keywords
|
(defcustom use-package-deferring-keywords
|
||||||
'(:bind
|
'(:bind-keymap
|
||||||
:bind*
|
|
||||||
:bind-keymap
|
|
||||||
:bind-keymap*
|
:bind-keymap*
|
||||||
:interpreter
|
|
||||||
:mode
|
|
||||||
:magic
|
|
||||||
:magic-fallback
|
|
||||||
:hook
|
|
||||||
:commands)
|
: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)
|
:type '(repeat symbol)
|
||||||
:group 'use-package)
|
:group 'use-package)
|
||||||
|
|
||||||
|
@ -160,7 +158,7 @@ See also `use-package-defaults', which uses this value."
|
||||||
(and use-package-always-demand
|
(and use-package-always-demand
|
||||||
(not (plist-member args :defer))
|
(not (plist-member args :defer))
|
||||||
(not (plist-member args :demand))))))
|
(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
|
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
|
element is the `use-package' keyword and the second is a form
|
||||||
that can be evaluated to get the default value. The third element
|
that can be evaluated to get the default value. The third element
|
||||||
|
@ -497,7 +495,8 @@ extending any keys already present."
|
||||||
(xs (use-package-split-list #'keywordp (cdr input)))
|
(xs (use-package-split-list #'keywordp (cdr input)))
|
||||||
(args (car xs))
|
(args (car xs))
|
||||||
(tail (cdr xs))
|
(tail (cdr xs))
|
||||||
(normalizer (intern (concat "use-package-normalize/"
|
(normalizer
|
||||||
|
(intern-soft (concat "use-package-normalize/"
|
||||||
(symbol-name keyword))))
|
(symbol-name keyword))))
|
||||||
(arg (and (functionp normalizer)
|
(arg (and (functionp normalizer)
|
||||||
(funcall normalizer name keyword args))))
|
(funcall normalizer name keyword args))))
|
||||||
|
@ -562,6 +561,32 @@ extending any keys already present."
|
||||||
(setq args (use-package-plist-maybe-put
|
(setq args (use-package-plist-maybe-put
|
||||||
args (nth 0 spec) (eval (nth 1 spec))))))
|
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
|
;; If byte-compiling, pre-load the package so all its symbols are in
|
||||||
;; scope. This is done by prepending statements to the :preface.
|
;; scope. This is done by prepending statements to the :preface.
|
||||||
(when (bound-and-true-p byte-compile-current-file)
|
(when (bound-and-true-p byte-compile-current-file)
|
||||||
|
@ -593,10 +618,13 @@ extending any keys already present."
|
||||||
use-package-deferring-keywords)))
|
use-package-deferring-keywords)))
|
||||||
(setq args (append args '(:defer t))))
|
(setq args (append args '(:defer t))))
|
||||||
|
|
||||||
|
;; The :load keyword overrides :no-require
|
||||||
(when (and (plist-member args :load)
|
(when (and (plist-member args :load)
|
||||||
(plist-member args :no-require))
|
(plist-member args :no-require))
|
||||||
(setq args (use-package-plist-delete 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))
|
(when (and (not (plist-member args :load))
|
||||||
(not (plist-member args :defer))
|
(not (plist-member args :defer))
|
||||||
(not (plist-member args :no-require)))
|
(not (plist-member args :no-require)))
|
||||||
|
@ -851,22 +879,12 @@ If RECURSED is non-nil, recurse into sublists."
|
||||||
(t v)))
|
(t v)))
|
||||||
|
|
||||||
(defun use-package-normalize-commands (args)
|
(defun use-package-normalize-commands (args)
|
||||||
"Map over ARGS of the form ((_ . F) ...).
|
"Map over ARGS of the form ((_ . F) ...), normalizing functional F's."
|
||||||
Normalizing functional F's and returning a list of F's
|
(mapcar #'(lambda (x)
|
||||||
representing symbols (that may need to be autloaded)."
|
|
||||||
(let ((nargs (mapcar
|
|
||||||
#'(lambda (x)
|
|
||||||
(if (consp x)
|
(if (consp x)
|
||||||
(cons (car x)
|
(cons (car x) (use-package-normalize-function (cdr x)))
|
||||||
(use-package-normalize-function (cdr x)))
|
x))
|
||||||
x)) args)))
|
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-mode (name keyword args)
|
(defun use-package-normalize-mode (name keyword args)
|
||||||
"Normalize arguments for keywords which add regexp/mode pairs to an alist."
|
"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
|
#'use-package-recognize-function
|
||||||
name)))
|
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
|
;;; Statistics
|
||||||
|
@ -1078,26 +1117,8 @@ meaning:
|
||||||
|
|
||||||
;;;; :interpreter
|
;;;; :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-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))
|
(use-package-handle-mode name 'interpreter-mode-alist arg rest state))
|
||||||
|
@ -1105,6 +1126,7 @@ meaning:
|
||||||
;;;; :mode
|
;;;; :mode
|
||||||
|
|
||||||
(defalias 'use-package-normalize/:mode 'use-package-normalize-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)
|
(defun use-package-handler/:mode (name keyword arg rest state)
|
||||||
(use-package-handle-mode name 'auto-mode-alist arg rest state))
|
(use-package-handle-mode name 'auto-mode-alist arg rest state))
|
||||||
|
@ -1112,6 +1134,7 @@ meaning:
|
||||||
;;;; :magic
|
;;;; :magic
|
||||||
|
|
||||||
(defalias 'use-package-normalize/:magic 'use-package-normalize-mode)
|
(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))
|
(use-package-handle-mode name 'magic-mode-alist arg rest state))
|
||||||
|
@ -1119,6 +1142,7 @@ meaning:
|
||||||
;;;; :magic-fallback
|
;;;; :magic-fallback
|
||||||
|
|
||||||
(defalias 'use-package-normalize/:magic-fallback 'use-package-normalize-mode)
|
(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))
|
(use-package-handle-mode name 'magic-fallback-mode-alist arg rest state))
|
||||||
|
@ -1145,16 +1169,12 @@ meaning:
|
||||||
#'use-package-recognize-function
|
#'use-package-recognize-function
|
||||||
name label arg))))
|
name label arg))))
|
||||||
|
|
||||||
|
(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."
|
"Generate use-package custom keyword code."
|
||||||
(let* ((result (use-package-normalize-commands args))
|
|
||||||
(nargs (car result))
|
|
||||||
(commands (cdr result)))
|
|
||||||
(use-package-concat
|
(use-package-concat
|
||||||
(use-package-process-keywords name
|
(use-package-process-keywords name rest state)
|
||||||
(use-package-sort-keywords
|
|
||||||
(use-package-plist-append rest :commands commands))
|
|
||||||
state)
|
|
||||||
`((ignore
|
`((ignore
|
||||||
,@(cl-mapcan
|
,@(cl-mapcan
|
||||||
#'(lambda (def)
|
#'(lambda (def)
|
||||||
|
@ -1169,7 +1189,7 @@ meaning:
|
||||||
use-package-hook-name-suffix)))
|
use-package-hook-name-suffix)))
|
||||||
(function ,fun)))
|
(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-normalize-commands args))))))
|
||||||
|
|
||||||
;;;; :commands
|
;;;; :commands
|
||||||
|
|
||||||
|
|
|
@ -1001,30 +1001,30 @@
|
||||||
|
|
||||||
(ert-deftest use-package-test/:hook-1 ()
|
(ert-deftest use-package-test/:hook-1 ()
|
||||||
(let ((byte-compile-current-file t))
|
(let ((byte-compile-current-file t))
|
||||||
(should
|
(match-expansion
|
||||||
(equal
|
|
||||||
(expand-minimally
|
|
||||||
(use-package foo
|
(use-package foo
|
||||||
:bind (("C-a" . key))
|
:bind (("C-a" . key))
|
||||||
:hook (hook . fun)))
|
:hook (hook . fun))
|
||||||
'(progn
|
`(progn
|
||||||
(eval-and-compile
|
(eval-and-compile
|
||||||
(eval-when-compile
|
(eval-when-compile
|
||||||
(with-demoted-errors
|
(with-demoted-errors
|
||||||
"Cannot load foo: %S" nil
|
"Cannot load foo: %S" nil
|
||||||
(load "foo" nil t))))
|
(load "foo" nil t))))
|
||||||
(unless (fboundp 'fun)
|
(unless
|
||||||
(autoload #'fun "foo" nil t))
|
(fboundp 'key)
|
||||||
(eval-when-compile
|
|
||||||
(declare-function fun "foo"))
|
|
||||||
(unless (fboundp 'key)
|
|
||||||
(autoload #'key "foo" nil t))
|
(autoload #'key "foo" nil t))
|
||||||
(eval-when-compile
|
(eval-when-compile
|
||||||
(declare-function key "foo"))
|
(declare-function key "foo"))
|
||||||
|
(unless
|
||||||
|
(fboundp 'fun)
|
||||||
|
(autoload #'fun "foo" nil t))
|
||||||
|
(eval-when-compile
|
||||||
|
(declare-function fun "foo"))
|
||||||
(ignore
|
(ignore
|
||||||
(add-hook 'hook-hook #'fun))
|
(add-hook 'hook-hook #'fun))
|
||||||
(ignore
|
(ignore
|
||||||
(bind-keys :package foo ("C-a" . key))))))))
|
(bind-keys :package foo ("C-a" . key)))))))
|
||||||
|
|
||||||
(ert-deftest use-package-test/:hook-2 ()
|
(ert-deftest use-package-test/:hook-2 ()
|
||||||
(match-expansion
|
(match-expansion
|
||||||
|
@ -1079,6 +1079,37 @@
|
||||||
#'(lambda nil
|
#'(lambda nil
|
||||||
(bind-key "" erefactor-map emacs-lisp-mode-map)))))))))
|
(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 ()
|
(ert-deftest use-package-test-normalize/:custom ()
|
||||||
(flet ((norm (&rest args)
|
(flet ((norm (&rest args)
|
||||||
(apply #'use-package-normalize/:custom
|
(apply #'use-package-normalize/:custom
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue