Skip to content

Commit

Permalink
Support display-only information in place of a suffix
Browse files Browse the repository at this point in the history
Group headings are also display-only information, but this commit
enables displaying such information anywhere in the layout where a
suffix can appear.

By inheriting from `transient-suffix' (instead of `transient-child')
we avoid having to implement many new methods and/or adding special-
cases to existing methods, but semantically this is questionable.

Setting the `command' slot to nil, instead of leaving it unbound also
avoids lots of special-cases.  As does setting `key' to " ", which
does not conflict with any real suffix binding for "SPC", because
display-only children are only used in the layout; they are filtered
out by `transient--flatten-suffixes' before any keymaps are populated.

Still, using the name `key' is a misnomer in this case.  It also means
that a few functions that perform additional work based on the used
key, need to ignore these fake keys, namely `transient--init-suffix'
and `transient-format-description'.

Additionally `transient--init-suffix' is taught that display-only
children don't have an associated command.

`transient--parse-suffix' needs to support the syntax for display-
only children, which is (:info DESCRIPTION [KEYWORD VALUE...]),
where DESCRIPTION may be a string or a function.

Closes #226.
  • Loading branch information
tarsius committed Oct 24, 2023
1 parent 65db49a commit 9c3d9d7
Showing 1 changed file with 26 additions and 10 deletions.
36 changes: 26 additions & 10 deletions lisp/transient.el
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,12 @@ slot is non-nil."
:documentation "Inapt if major-mode does not derive from value."))
"Superclass for suffix command.")

(defclass transient-information (transient-suffix)
((command :initform nil)
(format :initform " %k %d"))
"Display-only information.
A suffix object with no associated command.")

(defclass transient-infix (transient-suffix)
((transient :initform t)
(argument :initarg :argument)
Expand Down Expand Up @@ -1071,8 +1077,9 @@ example, sets a variable, use `transient-define-infix' instead.
(commandp (cadr spec)))
(setq args (plist-put args :description (macroexp-quote pop)))))
(cond
((eq car :info))
((keywordp car)
(error "Need command, got `%s'" car))
(error "Need command or `:info', got `%s'" car))
((symbolp car)
(setq args (plist-put args :command (macroexp-quote pop))))
((and (commandp car)
Expand Down Expand Up @@ -1128,6 +1135,9 @@ example, sets a variable, use `transient-define-infix' instead.
(val pop))
(cond ((eq key :class) (setq class val))
((eq key :level) (setq level val))
((eq key :info)
(setq class 'transient-information)
(setq args (plist-put args :description val)))
((eq (car-safe val) '\,)
(setq args (plist-put args key (cadr val))))
((or (symbolp val)
Expand Down Expand Up @@ -1871,6 +1881,7 @@ value. Otherwise return CHILDREN as is."
(cl-labels ((s (def)
(cond
((stringp def) nil)
((cl-typep def 'transient-information) nil)
((listp def) (cl-mapcan #'s def))
((cl-typep def 'transient-group)
(cl-mapcan #'s (oref def suffixes)))
Expand Down Expand Up @@ -1908,12 +1919,15 @@ value. Otherwise return CHILDREN as is."
(transient--debug " autoload %s" cmd)
(autoload-do-load fn)))
(when (transient--use-level-p level)
(unless (and cmd (symbolp cmd))
(error "BUG: Non-symbolic suffix command: %s" cmd))
(let ((obj (if-let ((proto (get cmd 'transient--suffix)))
(apply #'clone proto :level level args)
(apply class :command cmd :level level args))))
(cond ((commandp cmd))
(let ((obj (if (child-of-class-p class 'transient-information)
(apply class :level level args)
(unless (and cmd (symbolp cmd))
(error "BUG: Non-symbolic suffix command: %s" cmd))
(if-let ((proto (and cmd (get cmd 'transient--suffix))))
(apply #'clone proto :level level args)
(apply class :command cmd :level level args)))))
(cond ((not cmd))
((commandp cmd))
((or (cl-typep obj 'transient-switch)
(cl-typep obj 'transient-option))
;; As a temporary special case, if the package was compiled
Expand All @@ -1922,7 +1936,8 @@ value. Otherwise return CHILDREN as is."
(defalias cmd #'transient--default-infix-command))
((transient--use-suffix-p obj)
(error "Suffix command %s is not defined or autoloaded" cmd)))
(transient--init-suffix-key obj)
(unless (cl-typep obj 'transient-information)
(transient--init-suffix-key obj))
(when (transient--use-suffix-p obj)
(if (transient--inapt-suffix-p obj)
(oset obj inapt t)
Expand Down Expand Up @@ -3550,7 +3565,7 @@ Optional support for popup buttons is also implemented here."

(cl-defmethod transient-format-key ((obj transient-suffix))
"Format OBJ's `key' for display and return the result."
(let ((key (oref obj key))
(let ((key (if (slot-boundp obj 'key) (oref obj key) ""))
(cmd (oref obj command)))
(when-let ((width (oref transient--pending-group pad-keys)))
(setq key (truncate-string-to-width key width nil ?\s)))
Expand Down Expand Up @@ -3644,7 +3659,8 @@ If the OBJ's `key' is currently unreachable, then apply the face
(funcall (oref transient--prefix suffix-description)
obj))
(propertize "(BUG: no description)" 'face 'error))))
(cond ((transient--key-unreachable-p obj)
(cond ((and (slot-boundp obj 'key)
(transient--key-unreachable-p obj))
(propertize desc 'face 'transient-unreachable))
((and transient-highlight-higher-levels
(> (max (oref obj level) transient--max-group-level)
Expand Down

0 comments on commit 9c3d9d7

Please sign in to comment.