branch: externals/transient
commit b4edb633488fc251df0883b69b1eb350cb2e94ec
Author: Jonas Bernoulli <jo...@bernoul.li>
Commit: Jonas Bernoulli <jo...@bernoul.li>

    transient-get-value: Replace with three functions
    
    `transient-get-value' was added in [1: d33fe5ab].  At this time it was
    only used by commands that save the value.  We didn't make a distinction
    between `transient--suffixes' and `transient-current-suffixes' at this
    time.
    
    In [2: 1b9929ec] the `unsavable' suffix slot was added and this function
    started to drop the values of unsavable suffixes.
    
    In [3: 8db5f0fd] we started to also use it to preserve the value across
    refreshes.  That made it necessary to use `transient--suffixes'.  It
    would have made sense to only use that variable.  Instead we started
    to use it, if non-nil, and fall back to `transient-current-suffixes'
    otherwise (which previously was used exclusively).
    
    Sometime along the way, package authors started to need the value of
    the prefix or of another suffix while setting up the menu and its
    suffixes.  `transient-args' is not intended for that purpose and I
    started to tell them to use `transient-get-value'.
    
    So now `transient-get-value' is being used for at least three distinct
    purposes.  They have in common that they deal with the value of the
    extant prefix (so `transient-args' is not appropriate); but they need
    different subsets of that value.
    
    We could deal with that by adding arguments to `transient-get-value'.
    Instead we use three different functions, and give them names that
    make these differences obvious.
    
    - New `transient--get-savable-value' obviously filters out the non-
      savable parts of the value and is obviously used when saving the
      value.
    
    - New `transient--get-extended-value' returns the full value.  This
      includes the parts that are currently inactive, but have to be
      preserved because they may become active again.  This is used to
      preserve the value across refreshes.  This also includes unsavable
      parts of the value, since we still want to use those parts.
    
    - `transient-get-value' now returns the "effective" value.  This
      includes the "unsavable" (but "intend for use") parts.  It does
      not include the "inactive" parts.  Keep the current name of this
      function because that is being used in third-party package.
    
      Note that while this now filters out the value of suffixes whose
      `inapt' slot is non-nil, that doesn't make a difference just yet.
      Such suffixes are not being added to `transient--suffixes' yet,
      but we will start doing that in a few commits.
    
      In other words, there effectively is no change in how this deals
      with inapt parts of the value.
    
      However, the behavior changes with regards to unsavable parts of
      the value.  Those are no longer dropped.  That is a bugfix.
    
    1: 2019-08-12 d33fe5abaf5d0de2a8e80e7e52555d725ebdc6e5
       Split new transient-get-value from transient-args
    
    2: 2020-10-20 1b9929eca9b1076fb04794b6736d42a1d394fadb
       Add new `unsavable' infix slot
    
    3: 2024-06-22 8db5f0fd4469f3b2af34e07a283372ca273fa685
       transient--refresh-transient: Preserve value
---
 docs/transient.org  | 23 ++++++++++++++++++-----
 docs/transient.texi | 25 +++++++++++++++++++------
 lisp/transient.el   | 51 +++++++++++++++++++++++++++++++++++++++------------
 3 files changed, 76 insertions(+), 23 deletions(-)

diff --git a/docs/transient.org b/docs/transient.org
index 0a29330f44..9d1d6834bb 100644
--- a/docs/transient.org
+++ b/docs/transient.org
@@ -1494,14 +1494,27 @@ function, which for infix arguments serves about the 
same purpose as
   command was not invoked from {{{var(PREFIX)}}}, then it returns the set, 
saved
   or default value for {{{var(PREFIX)}}}.
 
+  PREFIX may also be a list of prefixes.  If no prefix is active, the
+  fallback value of the first of these prefixes is used.
+
+  The generic function ~transient-prefix-value~ is used to determine the
+  returned value.
+
+  This function is intended to be used by suffix commands, whether they
+  are invoked from a menu or not.  It is not intended to be used when
+  setting up a menu and its suffixes, in which case ~transient-get-value~
+  should be used.
+
 - Function: transient-get-value ::
 
-  This function returns the value of the current prefix.
+  This function returns the value of the erant prefix.
 
-  This is mostly intended for internal use, but may also be of use
-  in ~transient-set-value~ and ~transient-save-value~ methods.  Unlike
-  ~transient-args~, this does not include the values of suffixes whose
-  ~unsavable~ slot is non-~nil~.
+  This function is intended to be used when setting up a menu and its
+  suffixes.  It is not intended to be used when a suffix command is
+  invoked, whether from a menu or not, in which case ~transient-args~
+  should be used.  In other words, use this, e.g., in a suffixes ~:if*~
+  or ~:inapt-if*~ predicate and ~:description~ function, but never in its
+  ~interactive~ form or function body.
 
 - Function: transient-arg-value arg args ::
 
diff --git a/docs/transient.texi b/docs/transient.texi
index bf8d5e84d5..280872fbb3 100644
--- a/docs/transient.texi
+++ b/docs/transient.texi
@@ -1685,15 +1685,28 @@ If the current command was invoked from the transient 
prefix command
 @var{PREFIX}, then it returns the active infix arguments.  If the current
 command was not invoked from @var{PREFIX}, then it returns the set, saved
 or default value for @var{PREFIX}.
+
+PREFIX may also be a list of prefixes.  If no prefix is active, the
+fallback value of the first of these prefixes is used.
+
+The generic function @code{transient-prefix-value} is used to determine the
+returned value.
+
+This function is intended to be used by suffix commands, whether they
+are invoked from a menu or not.  It is not intended to be used when
+setting up a menu and its suffixes, in which case @code{transient-get-value}
+should be used.
 @end defun
 
 @defun transient-get-value
-This function returns the value of the current prefix.
-
-This is mostly intended for internal use, but may also be of use
-in @code{transient-set-value} and @code{transient-save-value} methods.  Unlike
-@code{transient-args}, this does not include the values of suffixes whose
-@code{unsavable} slot is non-@code{nil}.
+This function returns the value of the erant prefix.
+
+This function is intended to be used when setting up a menu and its
+suffixes.  It is not intended to be used when a suffix command is
+invoked, whether from a menu or not, in which case @code{transient-args}
+should be used.  In other words, use this, e.g., in a suffixes @code{:if*}
+or @code{:inapt-if*} predicate and @code{:description} function, but never in 
its
+@code{interactive} form or function body.
 @end defun
 
 @defun transient-arg-value arg args
diff --git a/lisp/transient.el b/lisp/transient.el
index 4d60e3e2eb..51dd29f5b1 100644
--- a/lisp/transient.el
+++ b/lisp/transient.el
@@ -2442,7 +2442,7 @@ value.  Otherwise return CHILDREN as is.")
         ;; invoked suffix indicates that it has updated that.
         (setq transient--refreshp (oref transient--prefix refresh-suffixes))
       ;; Otherwise update the prefix value from suffix values.
-      (oset transient--prefix value (transient-get-value))))
+      (oset transient--prefix value (transient--get-extended-value))))
   (transient--init-objects name layout params)
   (transient--init-keymaps))
 
@@ -3016,7 +3016,7 @@ value.  Otherwise return CHILDREN as is.")
   (push (list (oref transient--prefix command)
               transient--layout
               transient--editp
-              :value  (transient-get-value)
+              :value  (transient--get-extended-value)
               :return (oref transient--prefix return)
               :scope  (oref transient--prefix scope))
         transient--stack))
@@ -3970,7 +3970,7 @@ Only intended for use by `transient-set'.
 See also `transient-prefix-set'.")
 
 (cl-defmethod transient-set-value ((obj transient-prefix))
-  (let ((value (transient-get-value)))
+  (let ((value (transient--get-savable-value)))
     (oset (oref obj prototype) value value)
     (transient--history-push obj value)))
 
@@ -3980,7 +3980,7 @@ See also `transient-prefix-set'.")
   "Save the value of the transient prefix OBJ.")
 
 (cl-defmethod transient-save-value ((obj transient-prefix))
-  (let ((value (transient-get-value)))
+  (let ((value (transient--get-savable-value)))
     (oset (oref obj prototype) value value)
     (setf (alist-get (oref obj command) transient-values) value)
     (transient-save-values)
@@ -4014,7 +4014,12 @@ PREFIX may also be a list of prefixes.  If no prefix is 
active, the
 fallback value of the first of these prefixes is used.
 
 The generic function `transient-prefix-value' is used to determine the
-returned value."
+returned value.
+
+This function is intended to be used by suffix commands, whether they
+are invoked from a menu or not.  It is not intended to be used when
+setting up a menu and its suffixes, in which case `transient-get-value'
+should be used."
   (when (listp prefix)
     (setq prefix (car (or (memq transient-current-command prefix) prefix))))
   (if-let ((obj (get prefix 'transient--prefix)))
@@ -4062,18 +4067,39 @@ they can be returned.  That does not cause the menu to 
be displayed."
        (transient--init-suffixes prefix)))))
 
 (defun transient-get-value ()
-  "Return the value of the current prefix.
+  "Return the value of the extant prefix.
+
+This function is intended to be used when setting up a menu and its
+suffixes.  It is not intended to be used when a suffix command is
+invoked, whether from a menu or not, in which case `transient-args'
+should be used."
+  (transient--with-emergency-exit :get-value
+    (mapcan (lambda (obj)
+              (and (not (oref obj inapt))
+                   (transient--get-wrapped-value obj)))
+            transient--suffixes)))
+
+(defun transient--get-extended-value ()
+  "Return the extended value of the extant prefix.
 
-This is mostly intended for internal use, but may also be of use
-in `transient-set-value' and `transient-save-value' methods.  Unlike
-`transient-args', this does not include the values of suffixes whose
-`unsavable' slot is non-nil."
+Unlike `transient-get-value' also include the values of
+inapt arguments.  This function is mainly intended for internal use.
+It is used to preserve the full value when a menu is being refreshed,
+including the presently ineffective parts."
   (transient--with-emergency-exit :get-value
+    (mapcan #'transient--get-wrapped-value transient--suffixes)))
+
+(defun transient--get-savable-value ()
+  "Return the value of the extant prefix, excluding unsavable parts.
+
+This function is only intended for internal use.  It is used to save
+the value."
+  (transient--with-emergency-exit :get-savable-value
     (mapcan (lambda (obj)
               (and (not (and (slot-exists-p obj 'unsavable)
                              (oref obj unsavable)))
                    (transient--get-wrapped-value obj)))
-            (or transient--suffixes transient-current-suffixes))))
+            transient--suffixes)))
 
 (defun transient--get-wrapped-value (obj)
   "Return a list of the value(s) of suffix object OBJ.
@@ -4257,7 +4283,8 @@ Otherwise return the value of the `command' slot."
   "Push VALUE to OBJ's entry in `transient-history'.")
 
 (cl-defmethod transient--history-push
-  ((obj transient-prefix) &optional (value (transient-get-value)))
+  ((obj transient-prefix)
+   &optional (value (transient--get-savable-value)))
   (let ((key (transient--history-key obj)))
     (setf (alist-get key transient-history)
           (cons value (delete value (alist-get key transient-history))))))

Reply via email to