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

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

[elpa] externals/transient 667488ebff 305/366: Extend multi-value suppor


From: Jonas Bernoulli
Subject: [elpa] externals/transient 667488ebff 305/366: Extend multi-value support
Date: Tue, 25 Jan 2022 18:54:50 -0500 (EST)

branch: externals/transient
commit 667488ebffe015524e8bbd7eeced626ee52dd7bf
Author: Jonas Bernoulli <jonas@bernoul.li>
Commit: Jonas Bernoulli <jonas@bernoul.li>

    Extend multi-value support
    
    Extend `transient-option's methods to deal with it.  Deprecate the
    `transient-files' class whose methods previously responsible for that.
    Add a second type of multi-value options.  Previously only options
    that can take multiple values were supported, now options that can be
    repeated are supported as well.  Support default values.
    
    Closes #154.
---
 docs/transient.org  |  34 +++++++++++++---
 docs/transient.texi |  39 +++++++++++++++---
 lisp/transient.el   | 113 ++++++++++++++++++++++++----------------------------
 3 files changed, 116 insertions(+), 70 deletions(-)

diff --git a/docs/transient.org b/docs/transient.org
index 2211dd0b01..4941a8a434 100644
--- a/docs/transient.org
+++ b/docs/transient.org
@@ -8,7 +8,7 @@
 #+TEXINFO_DIR_CATEGORY: Emacs
 #+TEXINFO_DIR_TITLE: Transient: (transient).
 #+TEXINFO_DIR_DESC: Transient Commands
-#+SUBTITLE: for version 0.3.7
+#+SUBTITLE: for version 0.3.7 (v0.3.7-8-gc9ab648e+1)
 
 #+TEXINFO_DEFFN: t
 #+OPTIONS: H:4 num:4 toc:2
@@ -37,7 +37,7 @@ Calling a suffix command usually causes the transient to be 
exited
 but suffix commands can also be configured to not exit the transient.
 
 #+TEXINFO: @noindent
-This manual is for Transient version 0.3.7.
+This manual is for Transient version 0.3.7 (v0.3.7-8-gc9ab648e+1).
 
 #+BEGIN_QUOTE
 Copyright (C) 2018-2021 Jonas Bernoulli <jonas@bernoul.li>
@@ -1421,8 +1421,9 @@ object should not affect later invocations.
 - The ~transient-switches~ class can be used for a set of mutually
   exclusive command-line switches.
 
-- The ~transient-files~ class can be used for a "--" argument that
-  indicates that all remaining arguments are files.
+- The ~transient-files~ class is deprecated in favor of
+  ~transient-option'~, which learned all the tricks of this class.
+  Just switch the class and you are ready to go.
 
 - Classes used for infix commands that represent variables should
   derived from the abstract ~transient-variables~ class.
@@ -1651,7 +1652,30 @@ They are defined here anyway to allow sharing certain 
methods.
   the prefixes.
 
 - ~multi-value~ For options, whether the option can have multiple
-  values.  If non-nil, then default to use ~completing-read-multiple~.
+  values.  If this is non-nil, then the values are read using
+  ~completing-read-multiple~ by default and if you specify your own
+  reader, then it should read the values using that function or
+  similar.
+
+  Supported non-nil values are:
+
+  - Use ~rest~ for an option that can have multiple values.  This is
+    useful e.g. for an ~--~ argument that indicates that all remaining
+    arguments are files (such as ~git log -- file1 file2~).
+
+    In the list returned by ~transient-args~ such an option and its
+    values are represented by a single list of the form ~(ARGUMENT
+    . VALUES)~.
+
+  - Use ~repeat~ for an option that can be specified multiple times.
+
+    In the list returned by ~transient-args~ each instance of the option
+    and its value appears separately in the usual from, for example:
+    ~("--another-argument" "--option=first" "--option=second")~.
+
+  In both cases the option's values have to be specified in the
+  default value of a prefix using the same format as returned by
+  ~transient-args~, e.g.: ~("--other" "--o=1" "--o=2" ("--" "f1" "f2"))~.
 
 - ~always-read~ For options, whether to read a value on every invocation.
   If this is nil, then options that have a value are simply unset and
diff --git a/docs/transient.texi b/docs/transient.texi
index 232e762034..8c8ea9d166 100644
--- a/docs/transient.texi
+++ b/docs/transient.texi
@@ -31,7 +31,7 @@ General Public License for more details.
 @finalout
 @titlepage
 @title Transient User and Developer Manual
-@subtitle for version 0.3.7
+@subtitle for version 0.3.7 (v0.3.7-8-gc9ab648e+1)
 @author Jonas Bernoulli
 @page
 @vskip 0pt plus 1filll
@@ -65,7 +65,7 @@ Calling a suffix command usually causes the transient to be 
exited
 but suffix commands can also be configured to not exit the transient.
 
 @noindent
-This manual is for Transient version 0.3.7.
+This manual is for Transient version 0.3.7 (v0.3.7-8-gc9ab648e+1).
 
 @quotation
 Copyright (C) 2018-2021 Jonas Bernoulli <jonas@@bernoul.li>
@@ -1751,8 +1751,9 @@ exclusive command-line switches.
 
 
 @item
-The @code{transient-files} class can be used for a "--" argument that
-indicates that all remaining arguments are files.
+The @code{transient-files} class is deprecated in favor of
+@code{transient-option'}, which learned all the tricks of this class.
+Just switch the class and you are ready to go.
 
 
 @item
@@ -2049,7 +2050,35 @@ the prefixes.
 
 @item
 @code{multi-value} For options, whether the option can have multiple
-values.  If non-nil, then default to use @code{completing-read-multiple}.
+values.  If this is non-nil, then the values are read using
+@code{completing-read-multiple} by default and if you specify your own
+reader, then it should read the values using that function or
+similar.
+
+Supported non-nil values are:
+
+@itemize
+@item
+Use @code{rest} for an option that can have multiple values.  This is
+useful e.g. for an @code{--} argument that indicates that all remaining
+arguments are files (such as @code{git log -- file1 file2}).
+
+In the list returned by @code{transient-args} such an option and its
+values are represented by a single list of the form @code{(ARGUMENT
+    . VALUES)}.
+
+
+@item
+Use @code{repeat} for an option that can be specified multiple times.
+
+In the list returned by @code{transient-args} each instance of the option
+and its value appears separately in the usual from, for example:
+@code{("--another-argument" "--option=first" "--option=second")}.
+@end itemize
+
+In both cases the option's values have to be specified in the
+default value of a prefix using the same format as returned by
+@code{transient-args}, e.g.: @code{("--other" "--o=1" "--o=2" ("--" "f1" 
"f2"))}.
 
 
 @item
diff --git a/lisp/transient.el b/lisp/transient.el
index 39e5b862ce..afde84e3c2 100644
--- a/lisp/transient.el
+++ b/lisp/transient.el
@@ -742,9 +742,9 @@ slot is non-nil."
   "Class used for sets of mutually exclusive command-line switches.")
 
 (defclass transient-files (transient-infix) ()
-  "Class used for the \"--\" argument.
-All remaining arguments are treated as files.
-They become the value of this argument.")
+  "This class is deprecated in favor of `transient-option'.
+`transient-option' learned all the tricks of this class.
+Just switch the class and you are ready to go.")
 
 ;;;; Group
 
@@ -2462,30 +2462,30 @@ Otherwise call the primary method according to object's 
class."
                   default)
               nil)))))
 
+(cl-defmethod transient-init-value ((obj transient-argument))
+  (oset obj value
+        (let ((value (oref transient--prefix value))
+              (argument (and (slot-boundp obj 'argument)
+                             (oref obj argument)))
+              (multi-value (oref obj multi-value))
+              (regexp (if (slot-exists-p obj 'argument-regexp)
+                          (oref obj argument-regexp)
+                        (format "\\`%s\\(.*\\)" (oref obj argument)))))
+          (if (memq multi-value '(t rest))
+              (cdr (assoc argument value))
+            (let ((match (lambda (v)
+                           (and (stringp v)
+                                (string-match regexp v)
+                                (match-string 1 v)))))
+              (if multi-value
+                  (delq nil (mapcar match value))
+                (cl-some match value)))))))
+
 (cl-defmethod transient-init-value ((obj transient-switch))
   (oset obj value
         (car (member (oref obj argument)
                      (oref transient--prefix value)))))
 
-(cl-defmethod transient-init-value ((obj transient-option))
-  (oset obj value
-        (transient--value-match (format "\\`%s\\(.*\\)" (oref obj argument)))))
-
-(cl-defmethod transient-init-value ((obj transient-switches))
-  (oset obj value
-        (transient--value-match (oref obj argument-regexp))))
-
-(defun transient--value-match (re)
-  (when-let ((match (cl-find-if (lambda (v)
-                                  (and (stringp v)
-                                       (string-match re v)))
-                                (oref transient--prefix value))))
-    (match-string 1 match)))
-
-(cl-defmethod transient-init-value ((obj transient-files))
-  (oset obj value
-        (cdr (assoc "--" (oref transient--prefix value)))))
-
 ;;;; Read
 
 (cl-defgeneric transient-infix-read (obj)
@@ -2735,7 +2735,7 @@ If the current command was invoked from the transient 
prefix
 command PREFIX, then return the active infix arguments.  If
 the current command was not invoked from PREFIX, then return
 the set, saved or default value for PREFIX."
-  (delq nil (mapcar #'transient-infix-value (transient-suffixes prefix))))
+  (cl-mapcan #'transient--get-wrapped-value (transient-suffixes prefix)))
 
 (defun transient-suffixes (prefix)
   "Return the suffix objects of the transient prefix command PREFIX."
@@ -2747,11 +2747,19 @@ the set, saved or default value for PREFIX."
 
 (defun transient-get-value ()
   (transient--with-emergency-exit
-    (delq nil (mapcar (lambda (obj)
-                        (and (or (not (slot-exists-p obj 'unsavable))
-                                 (not (oref obj unsavable)))
-                             (transient-infix-value obj)))
-                      transient-current-suffixes))))
+    (cl-mapcan (lambda (obj)
+                 (and (or (not (slot-exists-p obj 'unsavable))
+                          (not (oref obj unsavable)))
+                      (transient--get-wrapped-value obj)))
+               transient-current-suffixes)))
+
+(defun transient--get-wrapped-value (obj)
+  (when-let ((value (transient-infix-value obj)))
+    (cl-ecase (and (slot-exists-p obj 'multi-value)
+                   (oref obj multi-value))
+      ((nil)    (list value))
+      ((t rest) (list value))
+      (repeat   value))))
 
 (cl-defgeneric transient-infix-value (obj)
   "Return the value of the suffix object OBJ.
@@ -2783,13 +2791,13 @@ does nothing." nil)
   (oref obj value))
 
 (cl-defmethod transient-infix-value ((obj transient-option))
-  "Return (concat ARGUMENT VALUE) or nil.
-
-ARGUMENT and VALUE are the values of the respective slots of OBJ.
-If VALUE is nil, then return nil.  VALUE may be the empty string,
-which is not the same as nil."
+  "Return ARGUMENT and VALUE as a unit or nil if the latter is nil."
   (when-let ((value (oref obj value)))
-    (concat (oref obj argument) value)))
+    (let ((arg (oref obj argument)))
+      (cl-ecase (oref obj multi-value)
+        ((nil)    (concat arg value))
+        ((t rest) (cons arg value))
+        (repeat   (mapcar (lambda (v) (concat arg v)) value))))))
 
 (cl-defmethod transient-infix-value ((_   transient-variable))
   "Return nil, which means \"no value\".
@@ -2799,15 +2807,6 @@ value of the variable.  I.e. this is a side-effect and 
does not
 contribute to the value of the transient."
   nil)
 
-(cl-defmethod transient-infix-value ((obj transient-files))
-  "Return (cons ARGUMENT VALUE) or nil.
-
-ARGUMENT and VALUE are the values of the respective slots of OBJ.
-If VALUE is nil, then return nil.  VALUE may be the empty string,
-which is not the same as nil."
-  (when-let ((value (oref obj value)))
-    (cons (oref obj argument) value)))
-
 ;;;; Utilities
 
 (defun transient-arg-value (arg args)
@@ -3197,14 +3196,17 @@ If the OBJ's `key' is currently unreachable, then apply 
the face
                       'transient-inactive-argument)))
 
 (cl-defmethod transient-format-value ((obj transient-option))
-  (let ((value (oref obj value)))
-    (propertize (concat (oref obj argument)
-                        (if (listp value)
-                            (mapconcat #'identity value ",")
-                          value))
-                'face (if value
-                          'transient-value
-                        'transient-inactive-value))))
+  (let ((argument (oref obj argument)))
+    (if-let ((value (oref obj value)))
+        (propertize
+         (cl-ecase (oref obj multi-value)
+           ((nil)    (concat argument value))
+           ((t rest) (concat argument
+                             (and (not (string-suffix-p " " argument)) " ")
+                             (mapconcat #'prin1-to-string value " ")))
+           (repeat   (mapconcat (lambda (v) (concat argument v)) value " ")))
+         'face 'transient-value)
+      (propertize argument 'face 'transient-inactive-value))))
 
 (cl-defmethod transient-format-value ((obj transient-switches))
   (with-slots (value argument-format choices) obj
@@ -3224,15 +3226,6 @@ If the OBJ's `key' is currently unreachable, then apply 
the face
               (propertize "|" 'face 'transient-inactive-value))
              (propertize "]" 'face 'transient-inactive-value)))))
 
-(cl-defmethod transient-format-value ((obj transient-files))
-  (let ((argument (oref obj argument)))
-    (if-let ((value (oref obj value)))
-        (propertize (concat argument " "
-                            (mapconcat (lambda (f) (format "%S" f))
-                                       (oref obj value) " "))
-                    'face 'transient-argument)
-      (propertize argument 'face 'transient-inactive-argument))))
-
 (defun transient--key-unreachable-p (obj)
   (and transient--redisplay-key
        (let ((key (oref obj key)))



reply via email to

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