emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/setup 4d3a967bbb 3/5: Add way to repeat the first N arg


From: ELPA Syncer
Subject: [elpa] externals/setup 4d3a967bbb 3/5: Add way to repeat the first N arguments.
Date: Thu, 2 Mar 2023 07:58:39 -0500 (EST)

branch: externals/setup
commit 4d3a967bbb5c8388bcaea3b170adb11613bbea5d
Author: Earl Hyatt <okamsn@protonmail.com>
Commit: Philip Kaludercic <philipk@posteo.net>

    Add way to repeat the first N arguments.
    
    Instead of just numbers or `t` for `:repeatable`, one can also use
    a dotted pair of numbers or of a number and `t`.
    
    This allows the first arguments to be repeated in the body,
    if we only want repeat a few arguments while using the
    `:ensure` keyword.
    
    For example,
    
        (setup-define :example-local-hook
          (lambda (hook function)
            `(add-hook ',(setup-get 'hook)
                       (lambda ()
                         (add-hook ',hook ,function nil t))))
          :documentation "Add FUNCTION to HOOK only in buffers of the current 
mode."
          :debug '(symbolp sexp)
          :ensure '(nil func)
          :repeatable '(1 . 1))
    
    lets us write it as `(:example-local-hook hook f1 f2 f3 f4 ...)`
    without needing to repeat `hook` in the local macro.
---
 setup.el | 51 ++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 40 insertions(+), 11 deletions(-)

diff --git a/setup.el b/setup.el
index 9872d4e0f1..51da9890da 100644
--- a/setup.el
+++ b/setup.el
@@ -218,6 +218,10 @@ Wrap the macro in a `with-eval-after-load' body.
   :repeatable ARITY
 Allow macro to be automatically repeated.  If ARITY is t, use
 `func-arity' to determine the minimal number of arguments.
+If ARITY is a dotted pair, then the car of ARITY is the number
+of shared arguments in the repeated function calls and the
+cdr is the number of arguments that make of the remainder
+of the function call.  The cdr may also be t, as above.
 
   :signature SIG
 Give an advertised calling convention.
@@ -263,21 +267,46 @@ invalid."
   (put name 'lisp-indent-function (plist-get opts :indent))
   ;; define macro for `macroexpand-all'
   (setf (alist-get name setup-macros)   ;New in Emacs-25.
-        (let* ((arity (if (eq (plist-get opts :repeatable) t)
-                          (car (func-arity fn))
-                        (plist-get opts :repeatable)))
-               (fn (if (null arity)
+        (let* ((possible-num-repeated (if (eq (plist-get opts :repeatable) t)
+                                          (car (func-arity fn))
+                                        (plist-get opts :repeatable)))
+               (fn (if (null possible-num-repeated)
                        fn
                      (lambda (&rest args)
-                       (unless (zerop (mod (length args) arity))
-                         (error "Illegal arguments"))
-                       (let (aggr)
+                       (let ((aggr)
+                             (using-shared-args (consp possible-num-repeated))
+                             (num-shared)
+                             (shared-args)
+                             (num-repeated))
+
+                         (if using-shared-args
+                             (progn
+                               (setq num-shared (car possible-num-repeated)
+                                     num-repeated (if (eq (cdr 
possible-num-repeated) t)
+                                                      (- (car (func-arity fn))
+                                                         num-shared)
+                                                    (cdr 
possible-num-repeated))
+                                     shared-args args
+                                     args (nthcdr num-shared args))
+                               (setf (nthcdr num-shared shared-args) nil))
+                           (setq num-repeated possible-num-repeated))
+
+                         (unless (zerop (mod (length args) num-repeated))
+                           (error "Illegal arguments"))
+
                          (while args
-                           (let ((rest (nthcdr arity args)))
-                             (setf (nthcdr arity args) nil)
+                           (let ((rest (nthcdr num-repeated args)))
+                             (setf (nthcdr num-repeated args) nil)
                              (let ((ensure-spec (plist-get opts :ensure)))
-                               (when ensure-spec
-                                 (setq args (setup--ensure ensure-spec args 
t))))
+                               (cond
+                                ((and using-shared-args ensure-spec)
+                                 (setq args (setup--ensure
+                                             ensure-spec
+                                             (append shared-args args) t)))
+                                (using-shared-args
+                                 (setq args (append shared-args args)))
+                                (ensure-spec
+                                 (setq args (setup--ensure ensure-spec args 
t)))))
                              (push (apply fn args) aggr)
                              (setq args rest)))
                          (macroexp-progn (nreverse aggr)))))))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]