From fe71a7e7d63c1685d22b59e792c6b67cefebf2af Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Sun, 15 Dec 2024 15:04:13 +0100 Subject: [PATCH] Account for duplicated commands with different transient behavior Previously "b" could be used to invoke `transient-echo-arguments' in this example: (transient-define-prefix demo () [("a" transient-echo-arguments :inapt-if ignore) ("b" transient-echo-arguments :inapt-if always) ("c" transient-echo-arguments :inapt-if ignore)]) --- lisp/transient.el | 71 ++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/lisp/transient.el b/lisp/transient.el index 2269188..37b6ad7 100644 --- a/lisp/transient.el +++ b/lisp/transient.el @@ -2046,36 +2046,40 @@ of the corresponding object." (define-key map [handle-switch-frame] #'transient--do-suspend)) (dolist (obj transient--suffixes) (let* ((cmd (oref obj command)) + (id (vector cmd)) (kind (cond ((get cmd 'transient--prefix) 'prefix) ((cl-typep obj 'transient-infix) 'infix) - (t 'suffix)))) - (cond - ((oref obj inapt) - (define-key map (vector cmd) #'transient--do-warn-inapt)) - ((slot-boundp obj 'transient) - (define-key map (vector cmd) - (pcase (list kind - (transient--resolve-pre-command (oref obj transient)) - return) - (`(prefix t ,_) #'transient--do-recurse) - (`(prefix nil ,_) #'transient--do-stack) - (`(infix t ,_) #'transient--do-stay) - (`(suffix t ,_) #'transient--do-call) - ('(suffix nil t) #'transient--do-return) - (`(,_ nil ,_) #'transient--do-exit) - (`(,_ ,do ,_) do)))) - ((not (lookup-key transient-predicate-map (vector cmd))) - (define-key map (vector cmd) - (pcase (list kind default return) - (`(prefix ,(or 'transient--do-stay 'transient--do-call) ,_) - #'transient--do-recurse) - (`(prefix t ,_) #'transient--do-recurse) - (`(prefix ,_ ,_) #'transient--do-stack) - (`(infix ,_ ,_) #'transient--do-stay) - (`(suffix t ,_) #'transient--do-call) - ('(suffix nil t) #'transient--do-return) - (`(suffix nil ,_) #'transient--do-exit) - (`(suffix ,do ,_) do))))))) + (t 'suffix))) + (pre (cond + ((oref obj inapt) #'transient--do-warn-inapt) + ((slot-boundp obj 'transient) + (pcase (list kind + (transient--resolve-pre-command + (oref obj transient)) + return) + (`(prefix t ,_) #'transient--do-recurse) + (`(prefix nil ,_) #'transient--do-stack) + (`(infix t ,_) #'transient--do-stay) + (`(suffix t ,_) #'transient--do-call) + ('(suffix nil t) #'transient--do-return) + (`(,_ nil ,_) #'transient--do-exit) + (`(,_ ,do ,_) do))) + ((not (lookup-key transient-predicate-map id)) + (pcase (list kind default return) + (`(prefix ,(or 'transient--do-stay 'transient--do-call) ,_) + #'transient--do-recurse) + (`(prefix t ,_) #'transient--do-recurse) + (`(prefix ,_ ,_) #'transient--do-stack) + (`(infix ,_ ,_) #'transient--do-stay) + (`(suffix t ,_) #'transient--do-call) + ('(suffix nil t) #'transient--do-return) + (`(suffix nil ,_) #'transient--do-exit) + (`(suffix ,do ,_) do)))))) + (when pre + (if-let ((alt (lookup-key map id))) + (unless (eq alt pre) + (define-key map (vconcat (oref obj key) id) pre)) + (define-key map id pre))))) map)) (defun transient--make-redisplay-map () @@ -2812,7 +2816,8 @@ exit." ;;; Pre-Commands (defun transient--call-pre-command () - (if-let ((fn (transient--get-pre-command this-command))) + (if-let ((fn (transient--get-pre-command this-command nil + (this-command-keys-vector)))) (let ((action (funcall fn))) (when (eq action transient--exit) (setq transient--exitp (or transient--exitp t))) @@ -2824,10 +2829,14 @@ exit." (setq this-command 'transient-undefined))) transient--stay)) -(defun transient--get-pre-command (&optional cmd enforce-type) +(defun transient--get-pre-command (&optional cmd enforce-type keys) (or (and (not (eq enforce-type 'non-suffix)) (symbolp cmd) - (lookup-key transient--predicate-map (vector cmd))) + (or (and keys + (let ((def (lookup-key transient--predicate-map + (vconcat keys (list cmd))))) + (and (symbolp def) def))) + (lookup-key transient--predicate-map (vector cmd)))) (and (not (eq enforce-type 'suffix)) (transient--resolve-pre-command (oref transient--prefix transient-non-suffix)