branch: externals/transient
commit f6c249c7f68deec44ed63d18e35aa112b0b294be
Author: Jonas Bernoulli <[email protected]>
Commit: Jonas Bernoulli <[email protected]>
Allow setting a suffix's default level via its prototype
---
docs/transient.org | 42 ++++++++++++++++++++++++++++++++++++++++++
docs/transient.texi | 42 ++++++++++++++++++++++++++++++++++++++++++
lisp/transient.el | 31 +++++++++++++++++++++++++------
3 files changed, 109 insertions(+), 6 deletions(-)
diff --git a/docs/transient.org b/docs/transient.org
index 5c27813dea..6d9c33c786 100644
--- a/docs/transient.org
+++ b/docs/transient.org
@@ -408,6 +408,48 @@ available even if the user lowers the transient level.
the level specified by ~transient-default-level~ are temporarily
available anyway.
+- Function: transient-set-default-level suffix level ::
+
+ This function sets the default level of the suffix COMMAND to LEVEL.
+
+ If a suffix command appears in multiple menus, it may make sense to
+ consistently change its level in all those menus at once. For
+ example, the ~--gpg-sign~ argument (which is implemented using the
+ command ~magit:--gpg-sign~), is bound in all of Magit's menu which
+ create commits. Users who sometimes sign their commits would want
+ that argument to be available in all of these menus, while for users
+ who never sign it is just unnecessary noise in any menus.
+
+ To always make ~--gpg-sign~ available, use:
+
+ #+begin_src emacs-lisp
+ (transient-set-default-level 'magit:--gpg-sign 1)
+ #+end_src
+
+ To never make ~--gpg-sign~ available, use:
+
+ #+begin_src emacs-lisp
+ (transient-set-default-level 'magit:--gpg-sign 0)
+ #+end_src
+
+ This sets the level in the suffix prototype object for this command.
+ Commands only have a suffix prototype if they were defined using one
+ of ~transient-define-argument~, ~transient-define-infix~ and
+ ~transient-define-suffix~. For all other commands this would signal
+ an error. (This is one of the reasons why package authors should
+ use one of these functions to define shared suffix commands, and
+ especially shared arguments.)
+
+ If the user changes the level of a suffix in a particular menu,
+ using {{{kbd(C-x l)}}} as shown above, then that obviously shadows the
default.
+
+ It is also possible to set the level of a suffix binding in a
+ particular menu, either when defining the menu using
+ ~transient-define-prefix,~ or later using ~transient-insert-suffix~. If
+ such bindings specify a level, then that also overrides the default.
+ (Per-suffix default levels is a new feature, so you might encounter
+ this quite often.)
+
** Other Commands
When invoking a transient in a small frame, the transient window may
diff --git a/docs/transient.texi b/docs/transient.texi
index 70aa0200e2..5527e8bc2b 100644
--- a/docs/transient.texi
+++ b/docs/transient.texi
@@ -554,6 +554,48 @@ the level specified by @code{transient-default-level} are
temporarily
available anyway.
@end table
+@defun transient-set-default-level suffix level
+This function sets the default level of the suffix COMMAND to LEVEL@.
+
+If a suffix command appears in multiple menus, it may make sense to
+consistently change its level in all those menus at once. For
+example, the @code{--gpg-sign} argument (which is implemented using the
+command @code{magit:--gpg-sign}), is bound in all of Magit's menu which
+create commits. Users who sometimes sign their commits would want
+that argument to be available in all of these menus, while for users
+who never sign it is just unnecessary noise in any menus.
+
+To always make @code{--gpg-sign} available, use:
+
+@lisp
+(transient-set-default-level 'magit:--gpg-sign 1)
+@end lisp
+
+To never make @code{--gpg-sign} available, use:
+
+@lisp
+(transient-set-default-level 'magit:--gpg-sign 0)
+@end lisp
+
+This sets the level in the suffix prototype object for this command.
+Commands only have a suffix prototype if they were defined using one
+of @code{transient-define-argument}, @code{transient-define-infix} and
+@code{transient-define-suffix}. For all other commands this would signal
+an error. (This is one of the reasons why package authors should
+use one of these functions to define shared suffix commands, and
+especially shared arguments.)
+
+If the user changes the level of a suffix in a particular menu,
+using @kbd{C-x l} as shown above, then that obviously shadows the default.
+
+It is also possible to set the level of a suffix binding in a
+particular menu, either when defining the menu using
+@code{transient-define-prefix,} or later using @code{transient-insert-suffix}.
If
+such bindings specify a level, then that also overrides the default.
+(Per-suffix default levels is a new feature, so you might encounter
+this quite often.)
+@end defun
+
@node Other Commands
@section Other Commands
diff --git a/lisp/transient.el b/lisp/transient.el
index 3165d964aa..c2a25f167c 100644
--- a/lisp/transient.el
+++ b/lisp/transient.el
@@ -774,7 +774,7 @@ the prototype is stored in the clone's `prototype' slot.")
:documentation "The parent group object.")
(level
:initarg :level
- :initform (symbol-value 'transient--default-child-level)
+ :initform nil
:documentation "Enable if level of prefix is equal or greater.")
(if
:initarg :if
@@ -1269,7 +1269,7 @@ commands are aliases for."
(message "WARNING: %s: When %s is used, %s must also be specified"
'transient-define-prefix :setup-children :class))
(list 'vector
- (or level transient--default-child-level)
+ level
(list 'quote
(cond (class)
((cl-typep (car spec)
@@ -1370,7 +1370,7 @@ commands are aliases for."
(shortarg (plist-get args :shortarg)))
(use :key shortarg)))
(list 'list
- (or level transient--default-child-level)
+ level
(macroexp-quote (or class 'transient-suffix))
(cons 'list args))))
@@ -1605,6 +1605,21 @@ See info node `(transient)Modifying Existing
Transients'."
(defun transient--nthcdr (n list)
(nthcdr (if (< n 0) (- (length list) (abs n)) n) list))
+(defun transient-set-default-level (command level)
+ "Set the default level of suffix COMMAND to LEVEL.
+
+The default level is shadowed if the binding of the suffix in a
+prefix menu specifies a level, and also if the user changes the
+level of such a binding.
+
+The default level can only be set for commands that were defined
+using `transient-define-suffix', `transient-define-infix' or
+`transient-define-argument'."
+ (if-let ((proto (transient--suffix-prototype command)))
+ (oset proto level level)
+ (user-error "Cannot set level for `%s'; no prototype object exists"
+ command)))
+
;;; Variables
(defvar transient-current-prefix nil
@@ -2291,7 +2306,8 @@ value. Otherwise return CHILDREN as is.")
(string (list spec))))
(defun transient--init-group (levels spec parent)
- (pcase-let ((`(,level ,class ,args ,children) (append spec nil)))
+ (pcase-let* ((`(,level ,class ,args ,children) (append spec nil))
+ (level (or level transient--default-child-level)))
(and-let* (((transient--use-level-p level))
(obj (apply class :parent parent :level level args))
((transient--use-suffix-p obj))
@@ -2308,9 +2324,12 @@ value. Otherwise return CHILDREN as is.")
(pcase-let* ((`(,level ,class ,args) spec)
(cmd (plist-get args :command))
(key (transient--kbd (plist-get args :key)))
+ (proto (and cmd (transient--suffix-prototype cmd)))
(level (or (alist-get (cons cmd key) levels nil nil #'equal)
(alist-get cmd levels)
- level)))
+ level
+ (and proto (oref proto level))
+ transient--default-child-level)))
(let ((fn (and (symbolp cmd)
(symbol-function cmd))))
(when (autoloadp fn)
@@ -2321,7 +2340,7 @@ value. Otherwise return CHILDREN as is.")
(apply class :parent parent :level level args)
(unless (and cmd (symbolp cmd))
(error "BUG: Non-symbolic suffix command: %s" cmd))
- (if-let ((proto (and cmd (transient--suffix-prototype
cmd))))
+ (if proto
(apply #'clone proto :level level args)
(apply class :command cmd :parent parent :level level
args)))))