From f086cb620b4c3cb99b5d1a885cf534718d0367d9 Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Sat, 2 Jan 2021 12:45:47 +0100 Subject: [PATCH] transient--insert-suffix: Allow same key with different predicates Previously it was not possible to add two bindings that use the same key but different predicates using `transient-insert-suffix'. Such only superficially conflicting bindings had to be added when the prefix was defined using `transient-define-prefix'. Now we use a heuristic to allow `transient-insert-suffix' to add such bindings as well. If both bindings define a predicate and these predicates are not equal, then the two bindings are assumed to be distinct. If on the other hand at least one of the bindings lacks a predicate or the predicates are equal, then the new binding is considered a replacement for the old binding, as before. Closes #106. --- lisp/transient.el | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/lisp/transient.el b/lisp/transient.el index 5f6b509d..cbd5ec4d 100644 --- a/lisp/transient.el +++ b/lisp/transient.el @@ -1065,7 +1065,15 @@ example, sets a variable use `transient-define-infix' instead. ;; We must keep `mem' until after we have inserted ;; behind it, which `transient-remove-suffix' does ;; not allow us to do. - (setq action 'replace) + (let ((spred (transient--suffix-predicate suf)) + (epred (transient--suffix-predicate elt))) + ;; If both suffixes have a predicate and they + ;; are not identical, then the probability is + ;; high that we want to keep both. + (when (or (not spred) + (not epred) + (equal spred epred)) + (setq action 'replace))) (transient-remove-suffix prefix key)))) (cl-ecase action (insert (setcdr mem (cons elt (cdr mem))) @@ -1801,6 +1809,20 @@ value. Otherwise return CHILDREN as is." (apply #'derived-mode-p if-not-derived)))) (t default))) +(defun transient--suffix-predicate (spec) + (let ((plist (nth 2 spec))) + (seq-some (lambda (prop) + (when-let ((pred (plist-get plist prop))) + (list prop pred))) + '( :if :if-not + :if-nil :if-non-nil + :if-mode :if-not-mode + :if-derived :if-not-derived + :inapt-if :inapt-if-not + :inapt-if-nil :inapt-if-non-nil + :inapt-if-mode :inapt-if-not-mode + :inapt-if-derived :inapt-if-not-derived)))) + ;;; Flow-Control (defun transient--init-transient ()