]> git.eshelyaron.com Git - emacs.git/commitdiff
Support multiple symbols passed to :after
authorJohn Wiegley <johnw@newartisans.com>
Thu, 16 Feb 2017 21:48:05 +0000 (13:48 -0800)
committerJohn Wiegley <johnw@newartisans.com>
Thu, 16 Feb 2017 21:51:22 +0000 (13:51 -0800)
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

index c6387d7e1f1f75411e239861f3b0a1a4c57390dc..4b425242ed1210bf0d4647b56b954306049acef4 100644 (file)
@@ -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)))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;