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

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

[elpa] externals/transient 686b7ebc5f 5/6: Fix handling of sub-prefix co


From: Stefan Monnier
Subject: [elpa] externals/transient 686b7ebc5f 5/6: Fix handling of sub-prefix command that use the minibuffer
Date: Wed, 19 Jan 2022 18:53:38 -0500 (EST)

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

    Fix handling of sub-prefix command that use the minibuffer
    
    When a suffix command used the minibuffer, then we have to suspend the
    transient's hooks and keymaps while doing so and `post-command-hook'
    is called twice, once before entering the minibuffer and then again
    when the command is actually done.  On the first call we delay work
    until either the second call or until the minibuffer is exited
    abnormally.
    
    This also applies if the suffix command is itself a prefix command.
    
    A prefix command sets up the transient by calling `transient-setup' in
    its body.  If that command uses the minibuffer then it does so before
    calling `transient-setup'.
    
    If the minibuffer is aborted, then the transient state is cleaned up
    using a function that `transient--delay-post-command' added to
    `minibuffer-exit-hook'.  This case works reasonably but can be
    improved (see next commit).
    
    If the minibuffer is exited normally, then the transient state is
    adjusted by a function that `transient--delay-post-command' put on
    `transient--post-command-hook'.
    
    But before that happens `transient-setup' is called.  That puts the
    normal function on `post-command-hook'.  Then the sub-prefix command
    finishes and that hook function is called, which calls
    `transient--post-exit'.
    
    But then the hook function that was put on
    `transient--post-command-hook' is also called and it also calls
    `transient--post-exit'.  If that second call was a noop that wouldn't
    be a huge deal but it is not.  Now it calls `transient--stack-pop',
    causing a return to the outer prefix.
    
    Preventing that is easy.  On the pre-minibuffer call to
    `transient--post-command' we can detect that the suffix is a
    sub-prefix and in that case we only delay work until the minibuffer is
    aborted (if it is aborted) but not until the `post-command-hook' is
    called when the command is actually done.
    
    Closes #187.
---
 lisp/transient.el | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/lisp/transient.el b/lisp/transient.el
index 9b50ac86d0..6542ce44f6 100644
--- a/lisp/transient.el
+++ b/lisp/transient.el
@@ -2106,7 +2106,7 @@ value.  Otherwise return CHILDREN as is."
 
 (add-hook 'post-command-hook 'transient--post-command-hook)
 
-(defun transient--delay-post-command ()
+(defun transient--delay-post-command (&optional abort-only)
   (transient--debug 'delay-post-command)
   (let ((depth (minibuffer-depth))
         (command this-command)
@@ -2114,15 +2114,17 @@ value.  Otherwise return CHILDREN as is."
                      #'transient--post-exit
                    #'transient--resume-override))
         post-command abort-minibuffer)
-    (setq post-command
-          (lambda () "@transient--delay-post-command"
-            (let ((act (and (eq this-command command)
-                            (not (eq (this-command-keys-vector) [])))))
-              (transient--debug 'post-command-hook "act: %s" act)
-              (when act
-                (remove-hook 'transient--post-command-hook post-command)
-                (remove-hook 'minibuffer-exit-hook abort-minibuffer)
-                (funcall delayed)))))
+    (unless abort-only
+      (setq post-command
+            (lambda () "@transient--delay-post-command"
+              (let ((act (and (eq this-command command)
+                              (not (eq (this-command-keys-vector) [])))))
+                (transient--debug 'post-command-hook "act: %s" act)
+                (when act
+                  (remove-hook 'transient--post-command-hook post-command)
+                  (remove-hook 'minibuffer-exit-hook abort-minibuffer)
+                  (funcall delayed)))))
+      (add-hook 'transient--post-command-hook post-command))
     (setq abort-minibuffer
           (lambda () "@transient--delay-post-command"
             (let ((act (and (or (memq this-command transient--abort-commands)
@@ -2135,7 +2137,6 @@ value.  Otherwise return CHILDREN as is."
                 (remove-hook 'transient--post-command-hook post-command)
                 (remove-hook 'minibuffer-exit-hook abort-minibuffer)
                 (funcall delayed)))))
-    (add-hook 'transient--post-command-hook post-command)
     (add-hook 'minibuffer-exit-hook abort-minibuffer)))
 
 (defun transient--post-command ()
@@ -2146,7 +2147,7 @@ value.  Otherwise return CHILDREN as is."
            (= (minibuffer-depth)
               (1+ transient--minibuffer-depth)))
       (transient--suspend-override)
-      (transient--delay-post-command))
+      (transient--delay-post-command (eq transient--exitp 'replace)))
      (transient--exitp
       (transient--post-exit))
      ((eq this-command (oref transient--prefix command)))
@@ -2164,7 +2165,10 @@ value.  Otherwise return CHILDREN as is."
   (unless (and (eq transient--exitp 'replace)
                (or transient--prefix
                    ;; The current command could act as a prefix,
-                   ;; but decided not to call `transient-setup'.
+                   ;; but decided not to call `transient-setup',
+                   ;; or it is prevented from doing so because it
+                   ;; uses the minibuffer and the user aborted
+                   ;; that.
                    (prog1 nil (transient--stack-zap))))
     (remove-hook 'pre-command-hook  #'transient--pre-command)
     (remove-hook 'post-command-hook #'transient--post-command))



reply via email to

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