branch: externals/transient
commit bf92c1585326d4295a40367c93a7b7456113d7d7
Author: Jonas Bernoulli <[email protected]>
Commit: Jonas Bernoulli <[email protected]>

    Support returning to more menu elements
    
    Store the object itself in the `button-date' property for all classes;
    now also groups, the prefix and information elements.
    
    This makes it necessary to check the object type in more places.
    
    - In `transient--do-push-button' we have to explicitly do nothing on
      `transient-information' objects, a class, which at this time derives
      from `transient-suffix' (which probably should be changed).
    
    - We have to add no-op `transient-show-summary' implementations for all
      classes.  Adding these methods is a unfortunate consequence of this
      change but is a part of the motivation for this change; we just don't
      implement the behavior in this commit already, to reduce its scope.
    
    - For groups `transient--goto-button' no longer receives the description
      directly but has to recalculate it.
    
    `transient--heading-at-point' can be removed since returning to any
    element is now handled by `transient--goto-button', but that in turn
    needs a new helper function `transient--match-button' because supporting
    more classes complicates the matter.  This is a bit hacky and we should
    be able to refine or replace this later on.
    
    This also fixes some edge-cases.
    
    - Returning to the (optional) menu description is now done explicitly,
      instead of as a result of failing to locate it.
    
    - Returning to a group heading, which isn't in the first column, no
      longer fails.
    
    - Returning to information elements is now supported.
---
 lisp/transient.el | 53 ++++++++++++++++++++++++++++++++---------------------
 1 file changed, 32 insertions(+), 21 deletions(-)

diff --git a/lisp/transient.el b/lisp/transient.el
index 4414096268..5cbe8e063c 100644
--- a/lisp/transient.el
+++ b/lisp/transient.el
@@ -3295,6 +3295,7 @@ Use that command's pre-command to determine transient 
behavior."
                 (posn-point (event-start last-command-event))
               (point))]
        [obj (get-text-property pos 'button-data)]
+       [_(cl-typep obj '(and transient-suffix (not transient-information)))]
        (setq this-command (oref obj command))
        (setq transient--current-suffix obj)
        (transient--call-pre-command))
@@ -4429,8 +4430,7 @@ have a history of their own.")
       (when transient-enable-menu-navigation
         (setq focus (or (get-text-property (point) 'button-data)
                         (and (not (bobp))
-                             (get-text-property (1- (point)) 'button-data))
-                        (transient--heading-at-point))))
+                             (get-text-property (1- (point)) 'button-data)))))
       (erase-buffer)
       (transient--insert-menu setup))
     (unless (window-live-p transient--window)
@@ -4740,7 +4740,7 @@ as a button."
                                                 'transient-enabled-suffix
                                               'transient-disabled-suffix)))
                         str)))
-    (transient-buttonize str (and (slot-boundp obj 'command) obj))))
+    (transient-buttonize str obj)))
 
 (cl-defmethod transient-format ((obj transient-infix))
   "Return a string generated using OBJ's `format'.
@@ -5250,6 +5250,12 @@ of the documentation string, if any.
 If RETURN is non-nil, return the summary instead of showing it.
 This is used when a tooltip is needed.")
 
+(cl-defmethod transient-show-summary ((_obj transient-prefix) &optional 
_return))
+
+(cl-defmethod transient-show-summary ((_obj transient-group) &optional 
_return))
+
+(cl-defmethod transient-show-summary ((_obj transient-information) &optional 
_return))
+
 (cl-defmethod transient-show-summary ((obj transient-suffix) &optional return)
   (with-slots (command summary) obj
     (when-let*
@@ -5323,28 +5329,33 @@ See `forward-button' for information about N."
     string))
 
 (defun transient--goto-button (object)
-  (cond-let
-    ((stringp object)
-     (when (re-search-forward (concat "^" (regexp-quote object)) nil t)
-       (goto-char (match-beginning 0))))
-    ([command (oref object command)]
-     (cl-flet ((found ()
-                 (and$ (get-text-property (point) 'button-data)
-                       (eq (oref $ command) command))))
-       (while (and (ignore-errors (forward-button 1))
-                   (not (found))))
-       (unless (found)
+  (cl-etypecase object
+    (transient-prefix (goto-char (point-min)))
+    ((or transient-group transient-suffix)
+     (let ((found (transient--match-button object)))
+       (while (and (not (funcall found))
+                   (ignore-errors (forward-button 1))))
+       (unless (funcall found)
          (goto-char (point-min))
          (ignore-errors (forward-button 1))
-         (unless (found)
+         (unless (funcall found)
            (goto-char (point-min))))))))
 
-(defun transient--heading-at-point ()
-  (and (eq (get-text-property (point) 'face) 'transient-heading)
-       (let ((beg (line-beginning-position)))
-         (buffer-substring-no-properties
-          beg (next-single-property-change
-               beg 'face nil (line-end-position))))))
+(defun transient--match-button (object)
+  (cl-etypecase object
+    ((or transient-group transient-information)
+     (let ((description (transient-format-description object)))
+       (lambda ()
+         (let ((obj (get-text-property (point) 'button-data)))
+           (and (cl-typep obj '(or transient-group transient-information))
+                (equal (string-trim-left (button-label (button-at (point))))
+                       description))))))
+    (transient-suffix
+     (let ((command (oref object command)))
+       (lambda ()
+         (let ((obj (get-text-property (point) 'button-data)))
+           (and (cl-typep obj 'transient-suffix)
+                (eq (oref obj command) command))))))))
 
 ;;; Compatibility
 ;;;; Menu Isearch

Reply via email to