From 0517689cf3bb55b034788d6427220bd42f8ca4b1 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 16 Feb 2017 13:48:05 -0800 Subject: [PATCH] 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))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -- 2.39.2