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

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

[elpa] externals/transient 4f67a033fd 20/20: Support display-only inform


From: Jonas Bernoulli
Subject: [elpa] externals/transient 4f67a033fd 20/20: Support display-only information in place of a suffix
Date: Tue, 24 Oct 2023 13:42:18 -0400 (EDT)

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

    Support display-only information in place of a suffix
    
    Group headings are also display-only information and raw strings
    can be used anywhere a suffix can appear, but this class makes it
    possible to display arbitrary information anywhere *and* to style
    it in any way one fancies.
    
    By inheriting from `transient-suffix' (instead of `transient-child')
    we avoid having to implement many new methods, but semantically this
    is a bit questionable.  Leaving the `command' and `key' slots
    undefined, means that we have to use `slot-boundp' in a few places,
    but on the other hand that helps dealing the semantic inconsistency.
    
    Closes #226.
---
 docs/transient.org  | 17 +++++++++++++++++
 docs/transient.texi | 18 ++++++++++++++++++
 lisp/transient.el   | 37 ++++++++++++++++++++++++++-----------
 3 files changed, 61 insertions(+), 11 deletions(-)

diff --git a/docs/transient.org b/docs/transient.org
index 8351af28bd..1ddc011e1c 100644
--- a/docs/transient.org
+++ b/docs/transient.org
@@ -1612,6 +1612,23 @@ object should not affect later invocations.
 - Classes used for infix commands that represent variables should
   derived from the abstract ~transient-variable~ class.
 
+- The ~transient-information~ class is special in that suffixes that use
+  this class are not associated with a command and thus also not with
+  any key binding.  Such suffixes are only used to display arbitrary
+  information, and that anywhere a suffix can appear.  Display-only
+  suffix specifications take this form:
+
+  #+begin_src emacs-lisp
+    ([LEVEL] :info DESCRIPTION [KEYWORD VALUE]...)
+  #+end_src
+
+  The ~:info~ keyword argument replaces the ~:description~ keyword used for
+  other suffix classes.  Other keyword arguments that you might want to
+  set, include ~:face~, predicate keywords (such as ~:if~), and ~:format~.
+  By default the value of ~:format~ includes ~%k~, which for this class is
+  replaced with the empty string or spaces, if keys are being padded in
+  the containing group.
+
 Magit defines additional classes, which can serve as examples for the
 fancy things you can do without modifying Transient.  Some of these
 classes will likely get generalized and added to Transient.  For now
diff --git a/docs/transient.texi b/docs/transient.texi
index c20f56d799..b03f540ae0 100644
--- a/docs/transient.texi
+++ b/docs/transient.texi
@@ -1841,6 +1841,24 @@ indicates that all remaining arguments are files.
 @item
 Classes used for infix commands that represent variables should
 derived from the abstract @code{transient-variable} class.
+
+@item
+The @code{transient-information} class is special in that suffixes that use
+this class are not associated with a command and thus also not with
+any key binding.  Such suffixes are only used to display arbitrary
+information, and that anywhere a suffix can appear.  Display-only
+suffix specifications take this form:
+
+@lisp
+([LEVEL] :info DESCRIPTION [KEYWORD VALUE]...)
+@end lisp
+
+The @code{:info} keyword argument replaces the @code{:description} keyword 
used for
+other suffix classes.  Other keyword arguments that you might want to
+set, include @code{:face}, predicate keywords (such as @code{:if}), and 
@code{:format}.
+By default the value of @code{:format} includes @code{%k}, which for this 
class is
+replaced with the empty string or spaces, if keys are being padded in
+the containing group.
 @end itemize
 
 Magit defines additional classes, which can serve as examples for the
diff --git a/lisp/transient.el b/lisp/transient.el
index 83ddefaf6d..142fe9ebd1 100644
--- a/lisp/transient.el
+++ b/lisp/transient.el
@@ -737,6 +737,11 @@ slot is non-nil."
     :documentation "Inapt if major-mode does not derive from value."))
   "Superclass for suffix command.")
 
+(defclass transient-information (transient-suffix)
+  ((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)
@@ -1071,8 +1076,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)
@@ -1128,6 +1134,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)
@@ -1871,6 +1880,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)))
@@ -1908,12 +1918,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
@@ -1922,7 +1935,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)
@@ -3548,8 +3562,8 @@ 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))
-        (cmd (oref obj command)))
+  (let ((key (if (slot-boundp obj 'key) (oref obj key) ""))
+        (cmd (and (slot-boundp obj 'command) (oref obj command))))
     (when-let ((width (oref transient--pending-group pad-keys)))
       (setq key (truncate-string-to-width key width nil ?\s)))
     (if transient--redisplay-key
@@ -3642,7 +3656,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)



reply via email to

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