branch: externals/transient commit f4aac8443c63ac47795fba12db193ff4da0279f0 Author: Jonas Bernoulli <jo...@bernoul.li> Commit: Jonas Bernoulli <jo...@bernoul.li>
No longer track generated transient.texi That also means that we can use the (updated) {{{version}}} macro again. --- docs/.orgconfig | 2 +- docs/transient.org | 4 +- docs/transient.texi | 2521 --------------------------------------------------- 3 files changed, 3 insertions(+), 2524 deletions(-) diff --git a/docs/.orgconfig b/docs/.orgconfig index ec583bb199..cba8e54ce0 100644 --- a/docs/.orgconfig +++ b/docs/.orgconfig @@ -5,7 +5,7 @@ #+macro: kbd (eval (let ((case-fold-search nil) (regexp (regexp-opt '("SPC" "RET" "LFD" "TAB" "BS" "ESC" "DELETE" "SHIFT" "Ctrl" "Meta" "Alt" "Cmd" "Super" "UP" "LEFT" "RIGHT" "DOWN") 'words))) (format "@@texinfo:@kbd{@@%s@@texinfo:}@@" (replace-regexp-in-string regexp "@@texinfo:@key{@@\\&@@texinfo:}@@" $1 t)))) #+macro: year (eval (format-time-string "%Y")) -#+macro: version (eval (or (getenv "PACKAGE_REVDESC") (getenv "PACKAGE_VERSION") (ignore-errors (car (process-lines "git" "describe" "--exact"))) (ignore-errors (concat (car (process-lines "git" "describe" (if (getenv "AMEND") "HEAD~" "HEAD"))) "+1")))) +#+macro: version (eval (if-let ((tag (ignore-errors (car (process-lines "git" "describe" "--exact-match"))))) (concat "version " (substring tag 1)) (or (ignore-errors (car (process-lines "git" "describe"))) "version (unknown)"))) #+macro: var @@texinfo:@var{@@$1@@texinfo:}@@ #+macro: kbdvar (eval (format "@@texinfo:@kbd{@@%s@@texinfo:}@@" (let (case-fold-search) (replace-regexp-in-string "<\\([a-zA-Z-]+\\)>" "@@texinfo:@var{@@\\1@@texinfo:}@@" (replace-regexp-in-string org-texinfo--quoted-keys-regexp "@@texinfo:@key{@@\\&@@texinfo:}@@" $1 t) t)))) diff --git a/docs/transient.org b/docs/transient.org index e77cceeda5..8dadc66966 100644 --- a/docs/transient.org +++ b/docs/transient.org @@ -7,7 +7,7 @@ #+texinfo_dir_category: Emacs misc features #+texinfo_dir_title: Transient: (transient). #+texinfo_dir_desc: Transient Commands -#+subtitle: for version 0.7.4 +#+subtitle: for {{{version}}} #+setupfile: .orgconfig @@ -20,7 +20,7 @@ resource to get over that hurdle is Psionic K's interactive tutorial, available at https://github.com/positron-solutions/transient-showcase. #+texinfo: @noindent -This manual is for Transient version 0.7.4. +This manual is for Transient {{{version}}}. #+texinfo: @insertcopying :END: diff --git a/docs/transient.texi b/docs/transient.texi deleted file mode 100644 index 5ec765351a..0000000000 --- a/docs/transient.texi +++ /dev/null @@ -1,2521 +0,0 @@ -\input texinfo @c -*- texinfo -*- -@c %**start of header -@setfilename transient.info -@settitle Transient User and Developer Manual -@documentencoding UTF-8 -@documentlanguage en -@c %**end of header - -@copying -@quotation -Copyright (C) 2018--2024 Free Software Foundation, Inc. - -You can redistribute this document and/or modify it under the terms -of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any -later version. - -This document is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE@. See the GNU -General Public License for more details. - -@end quotation -@end copying - -@dircategory Emacs misc features -@direntry -* Transient: (transient). Transient Commands. -@end direntry - -@finalout -@titlepage -@title Transient User and Developer Manual -@subtitle for version 0.7.4 -@author Jonas Bernoulli -@page -@vskip 0pt plus 1filll -@insertcopying -@end titlepage - -@contents - -@ifnottex -@node Top -@top Transient User and Developer Manual - -Transient is the library used to implement the keyboard-driven ``menus'' -in Magit. It is distributed as a separate package, so that it can be -used to implement similar menus in other packages. - -This manual can be bit hard to digest when getting started. A useful -resource to get over that hurdle is Psionic K's interactive tutorial, -available at @uref{https://github.com/positron-solutions/transient-showcase}. - -@noindent -This manual is for Transient version 0.7.4. - -@insertcopying -@end ifnottex - -@menu -* Introduction:: -* Usage:: -* Modifying Existing Transients:: -* Defining New Commands:: -* Classes and Methods:: -* FAQ:: -* Keystroke Index:: -* Command and Function Index:: -* Variable Index:: -* Concept Index:: -* GNU General Public License:: - -@detailmenu ---- The Detailed Node Listing --- - -Usage - -* Invoking Transients:: -* Aborting and Resuming Transients:: -* Common Suffix Commands:: -* Saving Values:: -* Using History:: -* Getting Help for Suffix Commands:: -* Enabling and Disabling Suffixes:: -* Other Commands:: -* Configuration:: - -Defining New Commands - -* Technical Introduction:: -* Defining Transients:: -* Binding Suffix and Infix Commands:: -* Defining Suffix and Infix Commands:: -* Using Infix Arguments:: -* Transient State:: - -Binding Suffix and Infix Commands - -* Group Specifications:: -* Suffix Specifications:: - - -Classes and Methods - -* Group Classes:: -* Group Methods:: -* Prefix Classes:: -* Suffix Classes:: -* Suffix Methods:: -* Prefix Slots:: -* Suffix Slots:: -* Predicate Slots:: - -Suffix Methods - -* Suffix Value Methods:: -* Suffix Format Methods:: - - -@end detailmenu -@end menu - -@node Introduction -@chapter Introduction - -Transient is the library used to implement the keyboard-driven @dfn{menus} -in Magit. It is distributed as a separate package, so that it can be -used to implement similar menus in other packages. - -This manual can be bit hard to digest when getting started. A useful -resource to get over that hurdle is Psionic K's interactive tutorial, -available at @uref{https://github.com/positron-solutions/transient-showcase}. - -@anchor{Some things that Transient can do} -@heading Some things that Transient can do - -@itemize -@item -Display current state of arguments -@item -Display and manage lifecycle of modal bindings -@item -Contextual user interface -@item -Flow control for wizard-like composition of interactive forms -@item -History & persistence -@item -Rendering arguments for controlling CLI programs -@end itemize - -@anchor{Complexity in CLI programs} -@heading Complexity in CLI programs - -Complexity tends to grow with time. How do you manage the complexity -of commands? Consider the humble shell command @samp{ls}. It now has over -@emph{fifty} command line options. Some of these are boolean flags (@samp{ls -l}). -Some take arguments (@samp{ls --sort=s}). Some have no effect unless paired -with other flags (@samp{ls -lh}). Some are mutually exclusive. Some shell -commands even have so many options that they introduce @emph{subcommands} -(@samp{git branch}, @samp{git commit}), each with their own rich set of options -(@samp{git branch -f}). - -@anchor{Using Transient for composing interactive commands} -@heading Using Transient for composing interactive commands - -What about Emacs commands used interactively? How do these handle -options? One solution is to make many versions of the same command, -so you don't need to! Consider: @samp{delete-other-windows} vs. -@samp{delete-other-windows-vertically} (among many similar examples). - -Some Emacs commands will simply prompt you for the next "argument" -(@samp{M-x switch-to-buffer}). Another common solution is to use prefix -arguments which usually start with @samp{C-u}. Sometimes these are sensibly -numerical in nature (@samp{C-u 4 M-x forward-paragraph} to move forward 4 -paragraphs). But sometimes they function instead as boolean -"switches" (@samp{C-u C-SPACE} to jump to the last mark instead of just -setting it, @samp{C-u C-u C-SPACE} to unconditionally set the mark). Since -there aren't many standards for the use of prefix options, you have to -read the command's documentation to find out what the possibilities -are. - -But when an Emacs command grows to have a truly large set of options -and arguments, with dependencies between them, lots of option values, -etc., these simple approaches just don't scale. Transient is designed -to solve this issue. Think of it as the humble prefix argument @samp{C-u}, -@emph{raised to the power of 10}. Like @samp{C-u}, it is key driven. Like the -shell, it supports boolean "flag" options, options that take -arguments, and even "sub-commands", with their own options. But -instead of searching through a man page or command documentation, -well-designed transients @emph{guide} their users to the relevant set of -options (and even their possible values!) directly, taking into -account any important pre-existing Emacs settings. And while for -shell commands like @samp{ls}, there is only one way to "execute" (hit -@samp{Return}!), transients can "execute" using multiple different keys tied -to one of many self-documenting @emph{actions} (imagine having 5 different -colored return keys on your keyboard!). Transients make navigating -and setting large, complex groups of command options and arguments -easy. Fun even. Once you've tried it, it's hard to go back to the -@samp{C-u what can I do here again?} way. - -@node Usage -@chapter Usage - -@menu -* Invoking Transients:: -* Aborting and Resuming Transients:: -* Common Suffix Commands:: -* Saving Values:: -* Using History:: -* Getting Help for Suffix Commands:: -* Enabling and Disabling Suffixes:: -* Other Commands:: -* Configuration:: -@end menu - -@node Invoking Transients -@section Invoking Transients - -@cindex invoking transients - -A transient prefix command is invoked like any other command by -pressing the key that is bound to that command. The main difference -to other commands is that a transient prefix command activates a -transient keymap, which temporarily binds the transient's infix and -suffix commands. Bindings from other keymaps may, or may not, be -disabled while the transient state is in effect. - -There are two kinds of commands that are available after invoking a -transient prefix command; infix and suffix commands. Infix commands -set some value (which is then shown in a popup buffer), without -leaving the transient. Suffix commands, on the other hand, usually -quit the transient and they may use the values set by the infix -commands, i.e., the infix @strong{arguments}. - -Instead of setting arguments to be used by a suffix command, infix -commands may also set some value by side-effect, e.g., by setting the -value of some variable. - -@node Aborting and Resuming Transients -@section Aborting and Resuming Transients - -@cindex aborting transients -@cindex resuming transients - -@cindex quit transient -To quit the transient without invoking a suffix command press @kbd{C-g}. - -Key bindings in transient keymaps may be longer than a single event. -After pressing a valid prefix key, all commands whose bindings do not -begin with that prefix key are temporarily unavailable and grayed out. -To abort the prefix key press @kbd{C-g} (which in this case only quits the -prefix key, but not the complete transient). - -A transient prefix command can be bound as a suffix of another -transient. Invoking such a suffix replaces the current transient -state with a new transient state, i.e., the available bindings change -and the information displayed in the popup buffer is updated -accordingly. Pressing @kbd{C-g} while a nested transient is active only -quits the innermost transient, causing a return to the previous -transient. - -@kbd{C-q} or @kbd{C-z} on the other hand always exits all transients. If you use -the latter, then you can later resume the stack of transients using -@kbd{M-x transient-resume}. - -@table @asis -@item @kbd{C-g} (@code{transient-quit-seq}) -@itemx @kbd{C-g} (@code{transient-quit-one}) -@kindex C-g -@kindex C-g -@findex transient-quit-seq -@findex transient-quit-one -This key quits the currently active incomplete key sequence, if any, -or else the current transient. When quitting the current transient, -it returns to the previous transient, if any. -@end table - -Transient's predecessor bound @kbd{q} instead of @kbd{C-g} to the quit command. -To learn how to get that binding back see @code{transient-bind-q-to-quit}'s -documentation string. - -@table @asis -@item @kbd{C-q} (@code{transient-quit-all}) -@kindex C-q -@findex transient-quit-all -This command quits the currently active incomplete key sequence, if -any, and all transients, including the active transient and all -suspended transients, if any. - -@item @kbd{C-z} (@code{transient-suspend}) -@kindex C-z -@findex transient-suspend -Like @code{transient-quit-all}, this command quits an incomplete key -sequence, if any, and all transients. Additionally, it saves the -stack of transients so that it can easily be resumed (which is -particularly useful if you quickly need to do ``something else'' and -the stack is deeper than a single transient, and/or you have already -changed the values of some infix arguments). - -Note that only a single stack of transients can be saved at a time. -If another stack is already saved, then saving a new stack discards -the previous stack. - -@item @kbd{M-x transient-resume} -@findex transient-resume -This command resumes the previously suspended stack of transients, -if any. -@end table - -@node Common Suffix Commands -@section Common Suffix Commands - -@cindex common suffix commands - -A few shared suffix commands are available in all transients. These -suffix commands are not shown in the popup buffer by default. - -This includes the aborting commands mentioned in the previous section, -as well as some other commands that are all bound to @kbd{C-x @var{KEY}}. After -@kbd{C-x} is pressed, a section featuring all these common commands is -temporarily shown in the popup buffer. After invoking one of them, -the section disappears again. Note, however, that one of these -commands is described as ``Show common permanently''; invoke that if you -want the common commands to always be shown for all transients. - -@table @asis -@item @kbd{C-x t} (@code{transient-toggle-common}) -@kindex C-x t -@findex transient-toggle-common -This command toggles whether the generic commands that are common to -all transients are always displayed or only after typing the -incomplete prefix key sequence @kbd{C-x}. This only affects the current -Emacs session. -@end table - -@defopt transient-show-common-commands -This option controls whether shared suffix commands are shown -alongside the transient-specific infix and suffix commands. By -default, the shared commands are not shown to avoid overwhelming -the user with too many options. - -While a transient is active, pressing @kbd{C-x} always shows the common -commands. The value of this option can be changed for the current -Emacs session by typing @kbd{C-x t} while a transient is active. -@end defopt - -The other common commands are described in either the previous or in -one of the following sections. - -Some of Transient's key bindings differ from the respective bindings -of Magit-Popup; see @ref{FAQ} for more information. - -@node Saving Values -@section Saving Values - -@cindex saving values of arguments - -After setting the infix arguments in a transient, the user can save -those arguments for future invocations. - -Most transients will start out with the saved arguments when they are -invoked. There are a few exceptions, though. Some transients are -designed so that the value that they use is stored externally as the -buffer-local value of some variable. Invoking such a transient again -uses the buffer-local value. @footnote{@code{magit-diff} and @code{magit-log} are two prominent examples, and their -handling of buffer-local values is actually a bit more complicated -than outlined above and even customizable.} - -If the user does not save the value and just exits using a regular -suffix command, then the value is merely saved to the transient's -history. That value won't be used when the transient is next invoked, -but it is easily accessible (see @ref{Using History}). - -@table @asis -@item @kbd{C-x s} (@code{transient-set}) -@kindex C-x s -@findex transient-set -This command saves the value of the active transient for this Emacs -session. - -@item @kbd{C-x C-s} (@code{transient-save}) -@kindex C-x C-s -@findex transient-save -Save the value of the active transient persistently across Emacs -sessions. - -@item @kbd{C-x C-k} (@code{transient-reset}) -@kindex C-x C-k -@findex transient-reset -Clear the set and saved values of the active transient. -@end table - -@defopt transient-values-file -This option names the file that is used to persist the values of -transients between Emacs sessions. -@end defopt - -@node Using History -@section Using History - -@cindex value history - -Every time the user invokes a suffix command the transient's current -value is saved to its history. These values can be cycled through the -same way one can cycle through the history of commands that read -user-input in the minibuffer. - -@table @asis -@item @kbd{C-M-p} (@code{transient-history-prev}) -@itemx @kbd{C-x p} -@kindex C-M-p -@kindex C-x p -@findex transient-history-prev -This command switches to the previous value used for the active -transient. - -@item @kbd{C-M-n} (@code{transient-history-next}) -@itemx @kbd{C-x n} -@kindex C-M-n -@kindex C-x n -@findex transient-history-next -This command switches to the next value used for the active -transient. -@end table - -In addition to the transient-wide history, Transient of course -supports per-infix history. When an infix reads user-input using the -minibuffer, the user can use the regular minibuffer history commands -to cycle through previously used values. Usually the same keys as -those mentioned above are bound to those commands. - -Authors of transients should arrange for different infix commands that -read the same kind of value to also use the same history key (see -@ref{Suffix Slots}). - -Both kinds of history are saved to a file when Emacs is exited. - -@defopt transient-history-file -This option names the file that is used to persist the history of -transients and their infixes between Emacs sessions. -@end defopt - -@defopt transient-history-limit -This option controls how many history elements are kept at the time -the history is saved in @code{transient-history-file}. -@end defopt - -@node Getting Help for Suffix Commands -@section Getting Help for Suffix Commands - -@cindex getting help - -Transients can have many suffixes and infixes that the user might not -be familiar with. To make it trivial to get help for these, Transient -provides access to the documentation directly from the active -transient. - -@table @asis -@item @kbd{C-h} (@code{transient-help}) -@kindex C-h -@findex transient-help -This command enters help mode. When help mode is active, typing a -key shows information about the suffix command that the key normally -is bound to (instead of invoking it). Pressing @kbd{C-h} a second time -shows information about the @emph{prefix} command. - -After typing a key, the stack of transient states is suspended and -information about the suffix command is shown instead. Typing @kbd{q} in -the help buffer buries that buffer and resumes the transient state. -@end table - -What sort of documentation is shown depends on how the transient was -defined. For infix commands that represent command-line arguments -this ideally shows the appropriate manpage. @code{transient-help} then tries -to jump to the correct location within that. Info manuals are also -supported. The fallback is to show the command's documentation -string, for non-infix suffixes this is usually appropriate. - -@node Enabling and Disabling Suffixes -@section Enabling and Disabling Suffixes - -@cindex enabling suffixes -@cindex disabling suffixes - -The user base of a package that uses transients can be very diverse. -This is certainly the case for Magit; some users have been using it and -Git for a decade, while others are just getting started now. - -@cindex levels -For that reason a mechanism is needed that authors can use to classify a -transient's infixes and suffixes along the essentials@dots{}everything -spectrum. We use the term @dfn{levels} to describe that mechanism. - -@cindex transient-level -Each suffix command is placed on a level and each transient has a -level (called @dfn{transient-level}), which controls which suffix commands -are available. Integers between 1 and 7 (inclusive) are valid levels. -For suffixes, 0 is also valid; it means that the suffix is not -displayed at any level. - -The levels of individual transients and/or their individual suffixes -can be changed interactively, by invoking the transient and then -pressing @kbd{C-x l} to enter the ``edit'' mode, see below. - -The default level for both transients and their suffixes is 4. The -@code{transient-default-level} option only controls the default for -transients. The default suffix level is always 4. The authors of -transients should place certain suffixes on a higher level, if they -expect that it won't be of use to most users, and they should place -very important suffixes on a lower level, so that they remain -available even if the user lowers the transient level. - -@defopt transient-default-level -This option controls which suffix levels are made available by -default. It sets the transient-level for transients for which the -user has not set that individually. -@end defopt - -@defopt transient-levels-file -This option names the file that is used to persist the levels of -transients and their suffixes between Emacs sessions. -@end defopt - -@table @asis -@item @kbd{C-x l} (@code{transient-set-level}) -@kindex C-x l -@findex transient-set-level -This command enters edit mode. When edit mode is active, then all -infixes and suffixes that are currently usable are displayed along -with their levels. The colors of the levels indicate whether they -are enabled or not. The level of the transient is also displayed -along with some usage information. - -In edit mode, pressing the key that would usually invoke a certain -suffix instead prompts the user for the level that suffix should be -placed on. - -Help mode is available in edit mode. - -To change the transient level press @kbd{C-x l} again. - -To exit edit mode press @kbd{C-g}. - -Note that edit mode does not display any suffixes that are not -currently usable. @code{magit-rebase}, for example, shows different -suffixes depending on whether a rebase is already in progress or -not. The predicates also apply in edit mode. - -Therefore, to control which suffixes are available given a certain -state, you have to make sure that that state is currently active. - -@item @kbd{C-x a} (@code{transient-toggle-level-limit}) -@kindex C-x a -@findex transient-toggle-level-limit -This command toggle whether suffixes that are on levels higher than -the level specified by @code{transient-default-level} are temporarily -available anyway. -@end table - -@node Other Commands -@section Other Commands - -When invoking a transient in a small frame, the transient window may -not show the complete buffer, making it necessary to scroll, using the -following commands. These commands are never shown in the transient -window, and the key bindings are the same as for @code{scroll-up-command} and -@code{scroll-down-command} in other buffers. - -@deffn Command transient-scroll-up arg -This command scrolls text of transient popup window upward @var{ARG} -lines. If @var{ARG} is @code{nil}, then it scrolls near full screen. This -is a wrapper around @code{scroll-up-command} (which see). -@end deffn - -@deffn Command transient-scroll-down arg -This command scrolls text of transient popup window down @var{ARG} -lines. If @var{ARG} is @code{nil}, then it scrolls near full screen. This -is a wrapper around @code{scroll-down-command} (which see). -@end deffn - -@node Configuration -@section Configuration - -More options are described in @ref{Common Suffix Commands}, in @ref{Saving Values}, in @ref{Using History} and in @ref{Enabling and Disabling Suffixes}. - -@anchor{Essential Options} -@subheading Essential Options - -Also see @ref{Common Suffix Commands}. - -@defopt transient-show-popup -This option controls whether the current transient's infix and -suffix commands are shown in the popup buffer. - -@itemize -@item -If @code{t} (the default) then the popup buffer is shown as soon as a -transient prefix command is invoked. - -@item -If @code{nil}, then the popup buffer is not shown unless the user -explicitly requests it, by pressing an incomplete prefix key -sequence. - -@item -If a number, then the a brief one-line summary is shown instead of -the popup buffer. If zero or negative, then not even that summary -is shown; only the pressed key itself is shown. - -The popup is shown when the user explicitly requests it by -pressing an incomplete prefix key sequence. Unless this is zero, -the popup is shown after that many seconds of inactivity (using -the absolute value). -@end itemize -@end defopt - -@defopt transient-enable-popup-navigation -This option controls whether navigation commands are enabled in the -transient popup buffer. - -While a transient is active the transient popup buffer is not the -current buffer, making it necessary to use dedicated commands to act -on that buffer itself. This is disabled by default. If this option -is non-@code{nil}, then the following features are available: - -@itemize -@item -@kbd{@key{UP}} moves the cursor to the previous suffix. -@item -@kbd{@key{DOWN}} moves the cursor to the next suffix. -@item -@kbd{@key{RET}} invokes the suffix the cursor is on. -@item -@kbd{mouse-1} invokes the clicked on suffix. -@item -@kbd{C-s} and @kbd{C-r} start isearch in the popup buffer. -@end itemize -@end defopt - -@defopt transient-display-buffer-action -This option specifies the action used to display the transient popup -buffer. The transient popup buffer is displayed in a window using -@code{(display-buffer @var{BUFFER} transient-display-buffer-action)}. - -The value of this option has the form @code{(@var{FUNCTION} . @var{ALIST})}, -where @var{FUNCTION} is a function or a list of functions. Each such -function should accept two arguments: a buffer to display and an -alist of the same form as @var{ALIST}. See @ref{Choosing Window,,,elisp,}, -for details. - -The default is: - -@lisp -(display-buffer-in-side-window - (side . bottom) - (inhibit-same-window . t) - (window-parameters (no-other-window . t))) -@end lisp - -This displays the window at the bottom of the selected frame. -Another useful @var{FUNCTION} is @code{display-buffer-below-selected}, which -is what @code{magit-popup} used by default. For more alternatives see -@ref{Buffer Display Action Functions,,,elisp,}, and @ref{Buffer Display Action Alists,,,elisp,}. - -Note that the buffer that was current before the transient buffer -is shown should remain the current buffer. Many suffix commands -act on the thing at point, if appropriate, and if the transient -buffer became the current buffer, then that would change what is -at point. To that effect @code{inhibit-same-window} ensures that the -selected window is not used to show the transient buffer. - -It may be possible to display the window in another frame, but -whether that works in practice depends on the window-manager. -If the window manager selects the new window (Emacs frame), -then that unfortunately changes which buffer is current. - -If you change the value of this option, then you might also -want to change the value of @code{transient-mode-line-format}. -@end defopt - -@anchor{Accessibility Options} -@subheading Accessibility Options - -@defopt transient-force-single-column -This option controls whether the use of a single column to display -suffixes is enforced. This might be useful for users with low -vision who use large text and might otherwise have to scroll in two -dimensions. -@end defopt - -@anchor{Auxiliary Options} -@subheading Auxiliary Options - -@defopt transient-mode-line-format -This option controls whether the transient popup buffer has a -mode-line, separator line, or neither. - -If @code{nil}, then the buffer has no mode-line. If the buffer is not -displayed right above the echo area, then this probably is not a -good value. - -If @code{line} (the default) or a natural number, then the buffer -has no mode-line, but a line is drawn is drawn in its place. -If a number is used, that specifies the thickness of the line. -On termcap frames we cannot draw lines, so there @code{line} and -numbers are synonyms for @code{nil}. - -The color of the line is used to indicate if non-suffixes are -allowed and whether they exit the transient. The foreground -color of @code{transient-key-noop} (if non-suffix are disallowed), -@code{transient-key-stay} (if allowed and transient stays active), or -@code{transient-key-exit} (if allowed and they exit the transient) is -used to draw the line. - -Otherwise this can be any mode-line format. See @ref{Mode Line Format,,,elisp,}, for details. -@end defopt - -@defopt transient-semantic-coloring -This option controls whether colors are used to indicate the -transient behavior of commands. - -If non-@code{nil}, then the key binding of each suffix is colorized to -indicate whether it exits the transient state or not. The color of -the prefix is indicated using the line that is drawn when the value -of @code{transient-mode-line-format} is @code{line}. -@end defopt - -@defopt transient-highlight-mismatched-keys -This option controls whether key bindings of infix commands that do -not match the respective command-line argument should be highlighted. -For other infix commands this option has no effect. - -When this option is non-@code{nil}, the key binding for an infix argument -is highlighted when only a long argument (e.g., @code{--verbose}) is -specified but no shorthand (e.g., @code{-v}). In the rare case that a -shorthand is specified but the key binding does not match, then it -is highlighted differently. - -Highlighting mismatched key bindings is useful when learning the -arguments of the underlying command-line tool; you wouldn't want to -learn any short-hands that do not actually exist. - -The highlighting is done using one of the faces -@code{transient-mismatched-key} and @code{transient-nonstandard-key}. -@end defopt - -@defopt transient-substitute-key-function -This function is used to modify key bindings. If the value of this -option is @code{nil} (the default), then no substitution is performed. - -This function is called with one argument, the prefix object, and -must return a key binding description, either the existing key -description it finds in the @code{key} slot, or the key description that -replaces the prefix key. It could be used to make other -substitutions, but that is discouraged. - -For example, @kbd{=} is hard to reach using my custom keyboard layout, -so I substitute @kbd{(} for that, which is easy to reach using a layout -optimized for lisp. - -@lisp -(setq transient-substitute-key-function - (lambda (obj) - (let ((key (oref obj key))) - (if (string-match "\\`\\(=\\)[a-zA-Z]" key) - (replace-match "(" t t key 1) - key)))) -@end lisp -@end defopt - -@defopt transient-read-with-initial-input -This option controls whether the last history element is used as the -initial minibuffer input when reading the value of an infix argument -from the user. If @code{nil}, there is no initial input and the first -element has to be accessed the same way as the older elements. -@end defopt - -@defopt transient-hide-during-minibuffer-read -This option controls whether the transient buffer is hidden while -user input is being read in the minibuffer. -@end defopt - -@defopt transient-align-variable-pitch -This option controls whether columns are aligned pixel-wise in the -popup buffer. - -If this is non-@code{nil}, then columns are aligned pixel-wise to support -variable-pitch fonts. Keys are not aligned, so you should use a -fixed-pitch font for the @code{transient-key} face. Other key faces -inherit from that face unless a theme is used that breaks that -relationship. - -This option is intended for users who use a variable-pitch font for -the @code{default} face. -@end defopt - -@defopt transient-force-fixed-pitch -This option controls whether to force the use of a monospaced font -in popup buffer. Even if you use a proportional font for the -@code{default} face, you might still want to use a monospaced font in -transient's popup buffer. Setting this option to @code{t} causes @code{default} -to be remapped to @code{fixed-pitch} in that buffer. -@end defopt - -@anchor{Developer Options} -@subheading Developer Options - -These options are mainly intended for developers. - -@defopt transient-detect-key-conflicts -This option controls whether key binding conflicts should be -detected at the time the transient is invoked. If so, this results -in an error, which prevents the transient from being used. Because -of that, conflicts are ignored by default. - -Conflicts cannot be determined earlier, i.e., when the transient is -being defined and when new suffixes are being added, because at that -time there can be false-positives. It is actually valid for -multiple suffixes to share a common key binding, provided the -predicates of those suffixes prevent that more than one of them is -enabled at a time. -@end defopt - -@defopt transient-highlight-higher-levels -This option controls whether suffixes that would not be available by -default are highlighted. - -When non-@code{nil} then the descriptions of suffixes are highlighted if -their level is above 4, the default of @code{transient-default-level}. -Assuming you have set that variable to 7, this highlights all -suffixes that won't be available to users without them making the -same customization. -@end defopt - -@node Modifying Existing Transients -@chapter Modifying Existing Transients - -@cindex modifying existing transients - -To an extent, transients can be customized interactively, see -@ref{Enabling and Disabling Suffixes}. This section explains how existing -transients can be further modified non-interactively. Let's begin -with an example: - -@lisp -(transient-append-suffix 'magit-patch-apply "-3" - '("-R" "Apply in reverse" "--reverse")) -@end lisp - -This inserts a new infix argument to toggle the @code{--reverse} argument -after the infix argument that toggles @code{-3} in @code{magit-patch-apply}. - -The following functions share a few arguments: - -@itemize -@item -@var{PREFIX} is a transient prefix command, a symbol. - -@item -@var{SUFFIX} is a transient infix or suffix specification in the same form -as expected by @code{transient-define-prefix}. Note that an infix is a -special kind of suffix. Depending on context ``suffixes'' means -``suffixes (including infixes)'' or ``non-infix suffixes''. Here it -means the former. See @ref{Suffix Specifications}. - -@var{SUFFIX} may also be a group in the same form as expected by -@code{transient-define-prefix}. See @ref{Group Specifications}. - -@item -@var{LOC} is a command, a key vector, a key description (a string as -returned by @code{key-description}), or a list specifying coordinates (the -last element may also be a command or key). For example @code{(1 0 -1)} -identifies the last suffix (@code{-1}) of the first subgroup (@code{0}) of the -second group (@code{1}). - -If @var{LOC} is a list of coordinates, then it can be used to identify a -group, not just an individual suffix command. - -The function @code{transient-get-suffix} can be useful to determine whether -a certain coordination list identifies the suffix or group that you -expect it to identify. In hairy cases it may be necessary to look -at the definition of the transient prefix command. -@end itemize - -These functions operate on the information stored in the -@code{transient--layout} property of the @var{PREFIX} symbol. Suffix entries in -that tree are not objects but have the form @code{(@var{LEVEL} @var{CLASS} @var{PLIST})}, where -@var{PLIST} should set at least @code{:key}, @code{:description} and @code{:command}. - -@defun transient-insert-suffix prefix loc suffix &optional keep-other -@end defun -@defun transient-append-suffix prefix loc suffix &optional keep-other -These functions insert the suffix or group @var{SUFFIX} into @var{PREFIX} before -or after @var{LOC}. - -Conceptually adding a binding to a transient prefix is similar to -adding a binding to a keymap, but this is complicated by the fact -that multiple suffix commands can be bound to the same key, provided -they are never active at the same time, see @ref{Predicate Slots}. - -Unfortunately both false-positives and false-negatives are possible. -To deal with the former use non-@code{nil} @var{KEEP-OTHER@.} To deal with the -latter remove the conflicting binding explicitly. -@end defun - -@defun transient-replace-suffix prefix loc suffix -This function replaces the suffix or group at @var{LOC} in @var{PREFIX} with -suffix or group @var{SUFFIX}. -@end defun - -@defun transient-remove-suffix prefix loc -This function removes the suffix or group at @var{LOC} in @var{PREFIX}. -@end defun - -@defun transient-get-suffix prefix loc -This function returns the suffix or group at @var{LOC} in @var{PREFIX}. The -returned value has the form mentioned above. -@end defun - -@defun transient-suffix-put prefix loc prop value -This function edits the suffix or group at @var{LOC} in @var{PREFIX}, by setting -the @var{PROP} of its plist to @var{VALUE}. -@end defun - -Most of these functions do not signal an error if they cannot perform -the requested modification. The functions that insert new suffixes -show a warning if @var{LOC} cannot be found in @var{PREFIX} without signaling an -error. The reason for doing it like this is that establishing a key -binding (and that is what we essentially are trying to do here) should -not prevent the rest of the configuration from loading. Among these -functions only @code{transient-get-suffix} and @code{transient-suffix-put} may -signal an error. - -@node Defining New Commands -@chapter Defining New Commands - -@menu -* Technical Introduction:: -* Defining Transients:: -* Binding Suffix and Infix Commands:: -* Defining Suffix and Infix Commands:: -* Using Infix Arguments:: -* Transient State:: -@end menu - -@node Technical Introduction -@section Technical Introduction - -Taking inspiration from prefix keys and prefix arguments, Transient -implements a similar abstraction involving a prefix command, infix -arguments and suffix commands. - -When the user calls a transient prefix command, a transient -(temporary) keymap is activated, which binds the transient's infix and -suffix commands, and functions that control the transient state are -added to @code{pre-command-hook} and @code{post-command-hook}. The available suffix -and infix commands and their state are shown in a popup buffer until -the transient state is exited by invoking a suffix command. - -Calling an infix command causes its value to be changed. How that is -done depends on the type of the infix command. The simplest case is -an infix command that represents a command-line argument that does not -take a value. Invoking such an infix command causes the switch to be -toggled on or off. More complex infix commands may read a value from -the user, using the minibuffer. - -Calling a suffix command usually causes the transient to be exited; -the transient keymaps and hook functions are removed, the popup buffer -no longer shows information about the (no longer bound) suffix -commands, the values of some public global variables are set, while -some internal global variables are unset, and finally the command is -actually called. Suffix commands can also be configured to not exit -the transient. - -A suffix command can, but does not have to, use the infix arguments in -much the same way any command can choose to use or ignore the prefix -arguments. For a suffix command that was invoked from a transient, the -variable @code{transient-current-suffixes} and the function @code{transient-args} -serve about the same purpose as the variables @code{prefix-arg} and -@code{current-prefix-arg} do for any command that was called after the prefix -arguments have been set using a command such as @code{universal-argument}. - -@cindex command dispatchers -Transient can be used to implement simple ``command dispatchers''. The -main benefit then is that the user can see all the available commands -in a popup buffer, which can be thought of as a ``menus''. That is -useful by itself because it frees the user from having to remember all -the keys that are valid after a certain prefix key or command. -Magit's @code{magit-dispatch} (on @kbd{C-x M-g}) command is an example of using -Transient to merely implement a command dispatcher. - -In addition to that, Transient also allows users to interactively pass -arguments to commands. These arguments can be much more complex than -what is reasonable when using prefix arguments. There is a limit to -how many aspects of a command can be controlled using prefix -arguments. Furthermore, what a certain prefix argument means for -different commands can be completely different, and users have to read -documentation to learn and then commit to memory what a certain prefix -argument means to a certain command. - -Transient suffix commands, on the other hand, can accept dozens of -different arguments without the user having to remember anything. -When using Transient, one can call a command with arguments that are -just as complex as when calling the same function non-interactively -from Lisp. - -Invoking a transient suffix command with arguments is similar to -invoking a command in a shell with command-line completion and history -enabled. One benefit of the Transient interface is that it remembers -history not only on a global level (``this command was invoked using -these arguments, and previously it was invoked using those other -arguments''), but also remembers the values of individual arguments -independently. See @ref{Using History}. - -After a transient prefix command is invoked, @kbd{C-h @var{KEY}} can be used to -show the documentation for the infix or suffix command that @kbd{@var{KEY}} is -bound to (see @ref{Getting Help for Suffix Commands}), and infixes and -suffixes can be removed from the transient using @kbd{C-x l @var{KEY}}. Infixes -and suffixes that are disabled by default can be enabled the same way. -See @ref{Enabling and Disabling Suffixes}. - -Transient ships with support for a few different types of specialized -infix commands. A command that sets a command line option, for example, -has different needs than a command that merely toggles a boolean flag. -Additionally, Transient provides abstractions for defining new types, -which the author of Transient did not anticipate (or didn't get around -to implementing yet). - -Note that suffix commands also support regular prefix arguments. A -suffix command may even be called with both infix and prefix arguments -at the same time. If you invoke a command as a suffix of a transient -prefix command, but also want to pass prefix arguments to it, then -first invoke the prefix command, and only after doing that invoke the -prefix arguments, before finally invoking the suffix command. If you -instead began by providing the prefix arguments, then those would -apply to the prefix command, not the suffix command. Likewise, if you -want to change infix arguments before invoking a suffix command with -prefix arguments, then change the infix arguments before invoking the -prefix arguments. In other words, regular prefix arguments always -apply to the next command, and since transient prefix, infix and -suffix commands are just regular commands, the same applies to them. -(Regular prefix keys behave differently because they are not commands -at all, instead they are just incomplete key sequences, and those -cannot be interrupted with prefix commands.) - -@node Defining Transients -@section Defining Transients - -A transient consists of a prefix command and at least one suffix -command, though usually a transient has several infix and suffix -commands. The below macro defines the transient prefix command @strong{and} -binds the transient's infix and suffix commands. In other words, it -defines the complete transient, not just the transient prefix command -that is used to invoke that transient. - -@defmac transient-define-prefix name arglist [docstring] [keyword value]... group... [body...] -This macro defines @var{NAME} as a transient prefix command and binds the -transient's infix and suffix commands. - -@var{ARGLIST} are the arguments that the prefix command takes. -@var{DOCSTRING} is the documentation string and is optional. - -These arguments can optionally be followed by keyword-value pairs. -Each key has to be a keyword symbol, either @code{:class} or a keyword -argument supported by the constructor of that class. The -@code{transient-prefix} class is used if the class is not specified -explicitly. - -@var{GROUP}s add key bindings for infix and suffix commands and specify -how these bindings are presented in the popup buffer. At least one -@var{GROUP} has to be specified. See @ref{Binding Suffix and Infix Commands}. - -The @var{BODY} is optional. If it is omitted, then @var{ARGLIST} is ignored and -the function definition becomes: - -@lisp -(lambda () - (interactive) - (transient-setup 'NAME)) -@end lisp - -If @var{BODY} is specified, then it must begin with an @code{interactive} form -that matches @var{ARGLIST}, and it must call @code{transient-setup}. It may, -however, call that function only when some condition is satisfied. - -@cindex scope of a transient -All transients have a (possibly @code{nil}) value, which is exported when -suffix commands are called, so that they can consume that value. -For some transients it might be necessary to have a sort of -secondary value, called a ``scope''. Such a scope would usually be -set in the command's @code{interactive} form and has to be passed to the -setup function: - -@lisp -(transient-setup 'NAME nil nil :scope SCOPE) -@end lisp - -For example, the scope of the @code{magit-branch-configure} transient is -the branch whose variables are being configured. -@end defmac - -@node Binding Suffix and Infix Commands -@section Binding Suffix and Infix Commands - -The macro @code{transient-define-prefix} is used to define a transient. -This defines the actual transient prefix command (see @ref{Defining Transients}) and adds the transient's infix and suffix bindings, as -described below. - -Users and third-party packages can add additional bindings using -functions such as @code{transient-insert-suffix} (see @ref{Modifying Existing Transients}). These functions take a ``suffix specification'' as one of -their arguments, which has the same form as the specifications used in -@code{transient-define-prefix}. - -@menu -* Group Specifications:: -* Suffix Specifications:: -@end menu - -@node Group Specifications -@subsection Group Specifications - -@cindex group specifications - -The suffix and infix commands of a transient are organized in groups. -The grouping controls how the descriptions of the suffixes are -outlined visually but also makes it possible to set certain properties -for a set of suffixes. - -Several group classes exist, some of which organize suffixes in -subgroups. In most cases the class does not have to be specified -explicitly, but see @ref{Group Classes}. - -Groups are specified in the call to @code{transient-define-prefix}, using -vectors. Because groups are represented using vectors, we cannot use -square brackets to indicate an optional element and instead use curly -brackets to do the latter. - -Group specifications then have this form: - -@lisp -[@{LEVEL@} @{DESCRIPTION@} @{KEYWORD VALUE@}... ELEMENT...] -@end lisp - -The @var{LEVEL} is optional and defaults to 4. See @ref{Enabling and Disabling Suffixes}. - -The @var{DESCRIPTION} is optional. If present, it is used as the heading of -the group. - -The @var{KEYWORD}-@var{VALUE} pairs are optional. Each keyword has to be a -keyword symbol, either @code{:class} or a keyword argument supported by the -constructor of that class. - -@itemize -@item -One of these keywords, @code{:description}, is equivalent to specifying -@var{DESCRIPTION} at the very beginning of the vector. The recommendation -is to use @code{:description} if some other keyword is also used, for -consistency, or @var{DESCRIPTION} otherwise, because it looks better. - -@item -Likewise @code{:level} is equivalent to @var{LEVEL}. - -@item -Other important keywords include the @code{:if...} keywords. These -keywords control whether the group is available in a certain -situation. - -For example, one group of the @code{magit-rebase} transient uses @code{:if - magit-rebase-in-progress-p}, which contains the suffixes that are -useful while rebase is already in progress; and another that uses -@code{:if-not magit-rebase-in-progress-p}, which contains the suffixes that -initiate a rebase. - -These predicates can also be used on individual suffixes and are -only documented once, see @ref{Predicate Slots}. - -@item -The value of @code{:hide}, if non-@code{nil}, is a predicate that controls -whether the group is hidden by default. The key bindings for -suffixes of a hidden group should all use the same prefix key. -Pressing that prefix key should temporarily show the group and its -suffixes, which assumes that a predicate like this is used: - -@lisp -(lambda () - (eq (car transient--redisplay-key) - ?\C-c)) ; the prefix key shared by all bindings -@end lisp - -@item -The value of @code{:setup-children}, if non-@code{nil}, is a function that takes -one argument, a potentially list of children, and must return a list -of children or an empty list. This can either be used to somehow -transform the group's children that were defined the normal way, or -to dynamically create the children from scratch. - -The returned children must have the same form as stored in the -prefix's @code{transient--layout} property, but it is often more convenient -to use the same form as understood by @code{transient-define-prefix}, -described below. If you use the latter approach, you can use the -@code{transient-parse-suffixes} and @code{transient-parse-suffix} functions to -transform them from the convenient to the expected form. Depending -on the used group class, @code{transient-parse-suffixes}'s SUFFIXES must be -a list of group vectors (for @code{transient-columns}) or a list of suffix -lists (for all other group classes). - -If you explicitly specify children and then transform them using -@code{:setup-children}, then the class of the group is determined as usual, -based on explicitly specified children. - -If you do not explicitly specify children and thus rely solely on -@code{:setup-children}, then you must specify the class using @code{:class}. -For backward compatibility, if you fail to do so, @code{transient-column} -is used and a warning is displayed. This warning will eventually -be replaced with an error. - -@lisp -(transient-define-prefix my-finder-by-keyword () - "Select a keyword and list matching packages." - ;; The real `finder-by-keyword' is more convenient - ;; of course, but that is not the point here. - [:class transient-columns - :setup-children - (lambda (_) - (transient-parse-suffixes - 'my-finder-by-keyword - (let ((char (1- ?A))) - (mapcar ; a list ... - (lambda (partition) - (vconcat ; of group vectors ... - (mapcar (lambda (elt) - (let ((keyword (symbol-name (car elt)))) - ; ... where each suffix is a list - (list (format "%c" (cl-incf char)) - keyword - (lambda () - (interactive) - (finder-list-matches keyword))))) - partition))) - (seq-partition finder-known-keywords 7)))))]) -@end lisp - -@item -The boolean @code{:pad-keys} argument controls whether keys of all suffixes -contained in a group are right padded, effectively aligning the -descriptions. -@end itemize - -The @var{ELEMENT}s are either all subgroups, or all suffixes and strings. -(At least currently no group type exists that would allow mixing -subgroups with commands at the same level, though in principle there -is nothing that prevents that.) - -If the @var{ELEMENT}s are not subgroups, then they can be a mixture of -lists, which specify commands, and strings. Strings are inserted -verbatim into the buffer. The empty string can be used to insert gaps -between suffixes, which is particularly useful if the suffixes are -outlined as a table. - -Inside group specifications, including inside contained suffix -specifications, nothing has to be quoted and quoting anyway is -invalid. The value following a keyword, can be explicitly unquoted -using @code{,}. This feature is experimental and should be avoided. - -The form of suffix specifications is documented in the next node. - -@node Suffix Specifications -@subsection Suffix Specifications - -@cindex suffix specifications - -A transient's suffix and infix commands are bound when the transient -prefix command is defined using @code{transient-define-prefix}, see -@ref{Defining Transients}. The commands are organized into groups, see -@ref{Group Specifications}. Here we describe the form used to bind an -individual suffix command. - -The same form is also used when later binding additional commands -using functions such as @code{transient-insert-suffix}, see @ref{Modifying Existing Transients}. - -Note that an infix is a special kind of suffix. Depending on context -``suffixes'' means ``suffixes (including infixes)'' or ``non-infix -suffixes''. Here it means the former. - -Suffix specifications have this form: - -@lisp -([LEVEL] [KEY [DESCRIPTION]] COMMAND|ARGUMENT [KEYWORD VALUE]...) -@end lisp - -@var{LEVEL}, @var{KEY} and @var{DESCRIPTION} can also be specified using the @var{KEYWORD}s -@code{:level}, @code{:key} and @code{:description}. If the object that is associated with -@var{COMMAND} sets these properties, then they do not have to be specified -here. You can however specify them here anyway, possibly overriding -the object's values just for the binding inside this transient. - -@itemize -@item -@var{LEVEL} is the suffix level, an integer between 1 and 7. See -@ref{Enabling and Disabling Suffixes}. - -@item -@var{KEY} is the key binding, either a vector or key description string. - -@item -@var{DESCRIPTION} is the description, either a string or a function that -takes zero or one arguments (the suffix object) and returns a string. -The function should be a lambda expression to avoid ambiguity. In -some cases a symbol that is bound as a function would also work but -to be safe you should use @code{:description} in that case. -@end itemize - -The next element is either a command or an argument. This is the only -argument that is mandatory in all cases. - -@itemize -@item -@var{COMMAND} should be a symbol that is bound as a function, which has -to be defined or at least autoloaded as a command by the time the -containing prefix command is invoked. - -Any command will do; it does not need to have an object associated -with it (as would be the case if @code{transient-define-suffix} or -@code{transient-define-infix} were used to define it). - -COMMAND can also be a @code{lambda} expression. - -As mentioned above, the object that is associated with a command can -be used to set the default for certain values that otherwise have to -be set in the suffix specification. Therefore if there is no object, -then you have to make sure to specify the @var{KEY} and the @var{DESCRIPTION}. - -As a special case, if you want to add a command that might be neither -defined nor autoloaded, you can use a workaround like: - -@lisp -(transient-insert-suffix 'some-prefix "k" - '("!" "Ceci n'est pas une commande" no-command - :if (lambda () (featurep 'no-library)))) -@end lisp - -Instead of @code{featurep} you could also use @code{require} with a non-@code{nil} value -for @var{NOERROR}. - -@item -The mandatory argument can also be a command-line argument, a -string. In that case an anonymous command is defined and bound. - -Instead of a string, this can also be a list of two strings, in -which case the first string is used as the short argument (which can -also be specified using @code{:shortarg}) and the second as the long argument -(which can also be specified using @code{:argument}). - -Only the long argument is displayed in the popup buffer. See -@code{transient-detect-key-conflicts} for how the short argument may be -used. - -Unless the class is specified explicitly, the appropriate class is -guessed based on the long argument. If the argument ends with @samp{=} -(e.g., @samp{--format=}) then @code{transient-option} is used, otherwise -@code{transient-switch}. -@end itemize - -Finally, details can be specified using optional @var{KEYWORD}-@var{VALUE} pairs. -Each keyword has to be a keyword symbol, either @code{:class} or a keyword -argument supported by the constructor of that class. See @ref{Suffix Slots}. - -@node Defining Suffix and Infix Commands -@section Defining Suffix and Infix Commands - -@cindex defining suffix commands -@cindex defining infix commands - -Note that an infix is a special kind of suffix. Depending on context -``suffixes'' means ``suffixes (including infixes)'' or ``non-infix -suffixes''. - -@defmac transient-define-suffix name arglist [docstring] [keyword value]... body... -This macro defines @var{NAME} as a transient suffix command. - -@var{ARGLIST} are the arguments that the command takes. -@var{DOCSTRING} is the documentation string and is optional. - -These arguments can optionally be followed by keyword-value pairs. -Each keyword has to be a keyword symbol, either @code{:class} or a keyword -argument supported by the constructor of that class. The -@code{transient-suffix} class is used if the class is not specified -explicitly. - -The @var{BODY} must begin with an @code{interactive} form that matches @var{ARGLIST}. -The infix arguments are usually accessed by using @code{transient-args} -inside @code{interactive}. -@end defmac - -@defmac transient-define-infix name arglist [docstring] [keyword value]... -This macro defines @var{NAME} as a transient infix command. - -@var{ARGLIST} is always ignored (but mandatory never-the-less) and -reserved for future use. @var{DOCSTRING} is the documentation string and -is optional. - -At least one key-value pair is required. All transient infix -commands are @code{equal} to each other (but not @code{eq}). It is meaningless -to define an infix command, without providing at least one keyword -argument (usually @code{:argument} or @code{:variable}, depending on the class). -The suffix class defaults to @code{transient-switch} and can be set using -the @code{:class} keyword. - -The function definition is always: - -@lisp -(lambda () - (interactive) - (let ((obj (transient-suffix-object))) - (transient-infix-set obj (transient-infix-read obj))) - (transient--show)) -@end lisp - -@code{transient-infix-read} and @code{transient-infix-set} are generic functions. -Different infix commands behave differently because the concrete -methods are different for different infix command classes. In rare -cases the above command function might not be suitable, even if you -define your own infix command class. In that case you have to use -@code{transient-define-suffix} to define the infix command and use @code{t} as the -value of the @code{:transient} keyword. -@end defmac - -@defmac transient-define-argument name arglist [docstring] [keyword value]... -This macro defines @var{NAME} as a transient infix command. - -This is an alias for @code{transient-define-infix}. Only use this alias -to define an infix command that actually sets an infix argument. -To define an infix command that, for example, sets a variable, use -@code{transient-define-infix} instead. -@end defmac - -@node Using Infix Arguments -@section Using Infix Arguments - -The functions and the variables described below allow suffix commands -to access the value of the transient from which they were invoked; -which is the value of its infix arguments. These variables are set -when the user invokes a suffix command that exits the transient, but -before actually calling the command. - -When returning to the command-loop after calling the suffix command, -the arguments are reset to @code{nil} (which causes the function to return -@code{nil} too). - -Like for Emacs's prefix arguments, it is advisable, but not mandatory, -to access the infix arguments inside the command's @code{interactive} form. -The preferred way of doing that is to call the @code{transient-args} -function, which for infix arguments serves about the same purpose as -@code{prefix-arg} serves for prefix arguments. - -@defun transient-args prefix -This function returns the value of the transient prefix command -@var{PREFIX}. - -If the current command was invoked from the transient prefix command -@var{PREFIX}, then it returns the active infix arguments. If the current -command was not invoked from @var{PREFIX}, then it returns the set, saved -or default value for @var{PREFIX}. -@end defun - -@defun transient-arg-value arg args -This function return the value of @var{ARG} as it appears in @var{ARGS}. - -For a switch a boolean is returned. For an option the value is -returned as a string, using the empty string for the empty value, -or @code{nil} if the option does not appear in @var{ARGS}. -@end defun - -@defun transient-suffixes prefix -This function returns the suffixes of the transient prefix command -@var{PREFIX}. This is a list of objects. This function should only be -used if you need the objects (as opposed to just their values) and -if the current command is not being invoked from @var{PREFIX}. -@end defun - -@defvar transient-current-suffixes -The suffixes of the transient from which this suffix command was -invoked. This is a list of objects. Usually it is sufficient to -instead use the function @code{transient-args}, which returns a list of -values. In complex cases it might be necessary to use this variable -instead, i.e., if you need access to information beside the value. -@end defvar - -@defvar transient-current-command -The transient from which this suffix command was invoked. The -returned value is a symbol, the transient prefix command. -@end defvar - -@defvar transient-current-prefix -The transient from which this suffix command was invoked. The -returned value is a @code{transient-prefix} object, which holds information -associated with the transient prefix command. -@end defvar - -@defvar transient-active-prefix -This function returns the active transient object. Return @code{nil} if -there is no active transient, if the transient buffer isn't shown, -and while the active transient is suspended (e.g., while the -minibuffer is in use). - -Unlike @code{transient-current-prefix}, which is only ever non-@code{nil} in code -that is run directly by a command that is invoked while a transient -is current, this function is also suitable for use in asynchronous -code, such as timers and callbacks (this function's main use-case). - -If optional PREFIXES is non-@code{nil}, it must be a list of prefix command -symbols, in which case the active transient object is only returned -if it matches one of the PREFIXES." -@end defvar - -@node Transient State -@section Transient State - -@cindex transient state - -Invoking a transient prefix command ``activates'' the respective -transient, i.e., it puts a transient keymap into effect, which binds -the transient's infix and suffix commands. - -The default behavior while a transient is active is as follows: - -@itemize -@item -Invoking an infix command does not affect the transient state; the -transient remains active. - -@item -Invoking a (non-infix) suffix command ``deactivates'' the transient -state by removing the transient keymap and performing some -additional cleanup. - -@item -Invoking a command that is bound in a keymap other than the -transient keymap is disallowed and trying to do so results in a -warning. This does not ``deactivate'' the transient. -@end itemize - -The behavior can be changed for all suffixes of a particular prefix -and/or for individual suffixes. The values should nearly always be -booleans, but certain functions, called ``pre-commands'', can also be -used. These functions are named @code{transient--do-VERB}, and the symbol -@code{VERB} can be used as a shorthand. - -A boolean is interpreted as answering the question "does the -transient stay active, when this command is invoked?" @code{t} means that -the transient stays active, while @code{nil} means that invoking the command -exits the transient. - -Note that when the suffix is a ``sub-prefix'', invoking that command -always activates that sub-prefix, causing the outer prefix to no -longer be active and displayed. Here @code{t} means that when you exit the -inner prefix, then the outer prefix becomes active again, while @code{nil} -means that all outer prefixes are exited at once. - -@itemize -@item -The behavior for non-suffixes can be set for a particular prefix, -by the prefix's @code{transient-non-suffix} slot to a boolean, a suitable -pre-command function, or a shorthand for such a function. See -@ref{Pre-commands for Non-Suffixes}. - -@item -The common behavior for the suffixes of a particular prefix can be -set using the prefix's @code{transient-suffixes} slot. - -The value specified in this slot does @strong{not} affect infixes. Because -it affects both regular suffixes as well as sub-prefixes, which -have different needs, it is best to avoid explicitly specifying a -function. - -@item -The behavior of an individual suffix can be changed using its -@code{transient} slot. While it is usually best to use a boolean, for this -slot it can occasionally make sense to specify a function explicitly. - -Note that this slot can be set when defining a suffix command using -@code{transient-define-suffix} and/or in the definition of the prefix. If -set in both places, then the latter takes precedence, as usual. -@end itemize - -The available pre-command functions are documented in the following -sub-sections. They are called by @code{transient--pre-command}, a function -on @code{pre-command-hook}, and the value that they return determines whether -the transient is exited. To do so the value of one of the constants -@code{transient--exit} or @code{transient--stay} is used (that way we don't have to -remember if @code{t} means ``exit'' or ``stay''). - -Additionally, these functions may change the value of @code{this-command} -(which explains why they have to be called using @code{pre-command-hook}), -call @code{transient-export}, @code{transient--stack-zap} or @code{transient--stack-push}; -and set the values of @code{transient--exitp}, @code{transient--helpp} or -@code{transient--editp}. - -For completeness sake, some notes about complications: - -@itemize -@item -The transient-ness of certain built-in suffix commands is specified -using @code{transient-predicate-map}. This is a special keymap, which -binds commands to pre-commands (as opposed to keys to commands) and -takes precedence over the prefix's @code{transient-suffix} slot, but not -the suffix's @code{transient} slot. - -@item -While a sub-prefix is active we nearly always want @kbd{C-g} to take the -user back to the ``super-prefix'', even when the other suffixes don't -do that. However, in rare cases this may not be desirable, and that -makes the following complication necessary: - -For @code{transient-suffix} objects the @code{transient} slot is unbound. We can -ignore that for the most part because @code{nil} and the slot being unbound -are treated as equivalent, and mean ``do exit''. That isn't actually -true for suffixes that are sub-prefixes though. For such suffixes -unbound means ``do exit but allow going back'', which is the default, -while @code{nil} means ``do exit permanently'', which requires that slot to -be explicitly set to that value. -@end itemize - -@anchor{Pre-commands for Infixes} -@subheading Pre-commands for Infixes - -The default for infixes is @code{transient--do-stay}. This is also the only -function that makes sense for infixes, which is why this predicate is -used even if the value of the prefix's @code{transient-suffix} slot is @code{t}. In -extremely rare cases, one might want to use something else, which can -be done by setting the infix's @code{transient} slot directly. - -@defun transient--do-stay -Call the command without exporting variables and stay transient. -@end defun - -@anchor{Pre-commands for Suffixes} -@subheading Pre-commands for Suffixes - -By default, invoking a suffix causes the transient to be exited. - -The behavior for an individual suffix command can be changed by -setting its @code{transient} slot to a boolean (which is highly recommended), -or to one of the following pre-commands. - -@defun transient--do-exit -Call the command after exporting variables and exit the transient. -@end defun - -@defun transient--do-return -Call the command after exporting variables and return to the parent -prefix. If there is no parent prefix, then call @code{transient--do-exit}. -@end defun - -@defun transient--do-call -Call the command after exporting variables and stay transient. -@end defun - -The following pre-commands are only suitable for sub-prefixes. It is -not necessary to explicitly use these predicates because the correct -predicate is automatically picked based on the value of the @code{transient} -slot for the sub-prefix itself. - -@defun transient--do-recurse -Call the transient prefix command, preparing for return to active -transient. - -Whether we actually return to the parent transient is ultimately -under the control of each invoked suffix. The difference between -this pre-command and @code{transient--do-stack} is that it changes the -value of the @code{transient-suffix} slot to @code{t}. - -If there is no parent transient, then only call this command and -skip the second step. -@end defun - -@defun transient--do-stack -Call the transient prefix command, stacking the active transient. -Push the active transient to the transient stack. - -Unless @code{transient--do-recurse} is explicitly used, this pre-command -is automatically used for suffixes that are prefixes themselves, -i.e., for sub-prefixes. -@end defun - -@defun transient--do-replace -Call the transient prefix command, replacing the active transient. -Do not push the active transient to the transient stack. - -Unless @code{transient--do-recurse} is explicitly used, this pre-command -is automatically used for suffixes that are prefixes themselves, -i.e., for sub-prefixes. -@end defun - -@defun transient--do-suspend -Suspend the active transient, saving the transient stack. - -This is used by the command @code{transient-suspend} and optionally also by -``external events'' such as @code{handle-switch-frame}. Such bindings should -be added to @code{transient-predicate-map}. -@end defun - -@anchor{Pre-commands for Non-Suffixes} -@subheading Pre-commands for Non-Suffixes - -By default, non-suffixes (commands that are bound in other keymaps -beside the transient keymap) cannot be invoked. Trying to invoke -such a command results in a warning and the transient stays active. - -If you want a different behavior, then set the @code{transient-non-suffix} -slot of the transient prefix command. The value should be a boolean, -answering the question, "is it allowed to invoke non-suffix commands?, -a pre-command function, or a shorthand for such a function. - -If the value is @code{t}, then non-suffixes can be invoked, when it is @code{nil} -(the default) then they cannot be invoked. - -The only other recommended value is @code{leave}. If that is used, then -non-suffixes can be invoked, but if one is invoked, then that exits -the transient. - -@defun transient--do-warn -Call @code{transient-undefined} and stay transient. -@end defun - -@defun transient--do-stay -Call the command without exporting variables and stay transient. -@end defun - -@defun transient--do-leave -Call the command without exporting variables and exit the transient. -@end defun - -@anchor{Special Pre-Commands} -@subheading Special Pre-Commands - -@defun transient--do-quit-one -If active, quit help or edit mode, else exit the active transient. - -This is used when the user pressed @kbd{C-g}. -@end defun - -@defun transient--do-quit-all -Exit all transients without saving the transient stack. - -This is used when the user pressed @kbd{C-q}. -@end defun - -@defun transient--do-suspend -Suspend the active transient, saving the transient stack. - -This is used when the user pressed @kbd{C-z}. -@end defun - -@node Classes and Methods -@chapter Classes and Methods - -@cindex classes and methods - -Transient uses classes and generic functions to make it possible to -define new types of suffix commands that are similar to existing -types, but behave differently in some aspects. It does the same for -groups and prefix commands, though at least for prefix commands that -@strong{currently} appears to be less important. - -Every prefix, infix and suffix command is associated with an object, -which holds information that controls certain aspects of its behavior. -This happens in two ways. - -@itemize -@item -Associating a command with a certain class gives the command a type. -This makes it possible to use generic functions to do certain things -that have to be done differently depending on what type of command -it acts on. - -That in turn makes it possible for third-parties to add new types -without having to convince the maintainer of Transient that that new -type is important enough to justify adding a special case to a dozen -or so functions. - -@item -Associating a command with an object makes it possible to easily -store information that is specific to that particular command. - -Two commands may have the same type, but obviously their key -bindings and descriptions still have to be different, for example. - -The values of some slots are functions. The @code{reader} slot for example -holds a function that is used to read a new value for an infix -command. The values of such slots are regular functions. - -Generic functions are used when a function should do something -different based on the type of the command, i.e., when all commands -of a certain type should behave the same way but different from the -behavior for other types. Object slots that hold a regular function -as value are used when the task that they perform is likely to -differ even between different commands of the same type. -@end itemize - -@menu -* Group Classes:: -* Group Methods:: -* Prefix Classes:: -* Suffix Classes:: -* Suffix Methods:: -* Prefix Slots:: -* Suffix Slots:: -* Predicate Slots:: -@end menu - -@node Group Classes -@section Group Classes - -The type of a group can be specified using the @code{:class} property at the -beginning of the class specification, e.g., @code{[:class transient-columns -...]} in a call to @code{transient-define-prefix}. - -@itemize -@item -The abstract @code{transient-child} class is the base class of both -@code{transient-group} (and therefore all groups) as well as of -@code{transient-suffix} (and therefore all suffix and infix commands). - -This class exists because the elements (or ``children'') of certain -groups can be other groups instead of suffix and infix commands. - -@item -The abstract @code{transient-group} class is the superclass of all other -group classes. - -@item -The @code{transient-column} class is the simplest group. - -This is the default ``flat'' group. If the class is not specified -explicitly and the first element is not a vector (i.e., not a group), -then this class is used. - -This class displays each element on a separate line. - -@item -The @code{transient-row} class displays all elements on a single line. - -@item -The @code{transient-columns} class displays commands organized in columns. - -Direct elements have to be groups whose elements have to be commands -or strings. Each subgroup represents a column. This class takes -care of inserting the subgroups' elements. - -This is the default ``nested'' group. If the class is not specified -explicitly and the first element is a vector (i.e., a group), then -this class is used. - -@item -The @code{transient-subgroups} class wraps other groups. - -Direct elements have to be groups whose elements have to be commands -or strings. This group inserts an empty line between subgroups. -The subgroups themselves are responsible for displaying their -elements. -@end itemize - -@node Group Methods -@section Group Methods - -@defun transient-setup-children group children -This generic function can be used to setup the children or a group. - -The default implementation usually just returns the children -unchanged, but if the @code{setup-children} slot of @var{GROUP} is non-@code{nil}, then -it calls that function with @var{CHILDREN} as the only argument and -returns the value. - -The children are given as a (potentially empty) list consisting of -either group or suffix specifications. These functions can make -arbitrary changes to the children including constructing new -children from scratch. -@end defun - -@defun transient--insert-group group -This generic function formats the group and its elements and inserts -the result into the current buffer, which is a temporary buffer. -The contents of that buffer are later inserted into the popup buffer. - -Functions that are called by this function may need to operate in -the buffer from which the transient was called. To do so they can -temporarily make the @code{transient--source-buffer} the current buffer. -@end defun - -@node Prefix Classes -@section Prefix Classes - -Currently the @code{transient-prefix} class is being used for all prefix -commands and there is only a single generic function that can be -specialized based on the class of a prefix command. - -@defun transient--history-init obj -This generic function is called while setting up the transient and -is responsible for initializing the @code{history} slot. This is the -transient-wide history; many individual infixes also have a history -of their own. - -The default (and currently only) method extracts the value from the -global variable @code{transient-history}. -@end defun - -A transient prefix command's object is stored in the @code{transient--prefix} -property of the command symbol. While a transient is active, a clone -of that object is stored in the variable @code{transient--prefix}. A clone -is used because some changes that are made to the active transient's -object should not affect later invocations. - -@node Suffix Classes -@section Suffix Classes - -@itemize -@item -All suffix and infix classes derive from @code{transient-suffix}, which in -turn derives from @code{transient-child}, from which @code{transient-group} also -derives (see @ref{Group Classes}). - -@item -All infix classes derive from the abstract @code{transient-infix} class, -which in turn derives from the @code{transient-suffix} class. - -Infixes are a special type of suffixes. The primary difference is -that infixes always use the @code{transient--do-stay} pre-command, while -non-infix suffixes use a variety of pre-commands (see @ref{Transient State}). Doing that is most easily achieved by using this class, -though theoretically it would be possible to define an infix class -that does not do so. If you do that then you get to implement many -methods. - -Also, infixes and non-infix suffixes are usually defined using -different macros (see @ref{Defining Suffix and Infix Commands}). - -@item -Classes used for infix commands that represent arguments should -be derived from the abstract @code{transient-argument} class. - -@item -The @code{transient-switch} class (or a derived class) is used for infix -arguments that represent command-line switches (arguments that do -not take a value). - -@item -The @code{transient-option} class (or a derived class) is used for infix -arguments that represent command-line options (arguments that do -take a value). - -@item -The @code{transient-switches} class can be used for a set of mutually -exclusive command-line switches. - -@item -The @code{transient-files} class can be used for a @samp{--} argument that -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 -fancy things you can do without modifying Transient. Some of these -classes will likely get generalized and added to Transient. For now -they are very much subject to change and not documented. - -@node Suffix Methods -@section Suffix Methods - -To get information about the methods implementing these generic -functions use @code{describe-function}. - -@menu -* Suffix Value Methods:: -* Suffix Format Methods:: -@end menu - -@node Suffix Value Methods -@subsection Suffix Value Methods - -@defun transient-init-value obj -This generic function sets the initial value of the object @var{OBJ}. - -This function is called for all suffix commands, but unless a -concrete method is implemented this falls through to the default -implementation, which is a noop. In other words this usually -only does something for infix commands, but note that this is -not implemented for the abstract class @code{transient-infix}, so if -your class derives from that directly, then you must implement -a method. -@end defun - -@defun transient-infix-read obj -This generic function determines the new value of the infix object -@var{OBJ}. - -This function merely determines the value; @code{transient-infix-set} is -used to actually store the new value in the object. - -For most infix classes this is done by reading a value from the -user using the reader specified by the @code{reader} slot (using the -@code{transient-infix-value} method described below). - -For some infix classes the value is changed without reading -anything in the minibuffer, i.e., the mere act of invoking the -infix command determines what the new value should be, based -on the previous value. -@end defun - -@defun transient-prompt obj -This generic function returns the prompt to be used to read infix -object @var{OBJ}'s value. -@end defun - -@defun transient-infix-set obj value -This generic function sets the value of infix object @var{OBJ} to @var{VALUE}. -@end defun - -@defun transient-infix-value obj -This generic function returns the value of the suffix object @var{OBJ}. - -This function is called by @code{transient-args} (which see), meaning this -function is how the value of a transient is determined so that the -invoked suffix command can use it. - -Currently most values are strings, but that is not set in stone. -@code{nil} is not a value, it means ``no value''. - -Usually only infixes have a value, but see the method for -@code{transient-suffix}. -@end defun - -@defun transient-init-scope obj -This generic function sets the scope of the suffix object @var{OBJ}. - -The scope is actually a property of the transient prefix, not of -individual suffixes. However it is possible to invoke a suffix -command directly instead of from a transient. In that case, if -the suffix expects a scope, then it has to determine that itself -and store it in its @code{scope} slot. - -This function is called for all suffix commands, but unless a -concrete method is implemented this falls through to the default -implementation, which is a noop. -@end defun - -@node Suffix Format Methods -@subsection Suffix Format Methods - -@defun transient-format obj -This generic function formats and returns @var{OBJ} for display. - -When this function is called, then the current buffer is some -temporary buffer. If you need the buffer from which the prefix -command was invoked to be current, then do so by temporarily -making @code{transient--source-buffer} current. -@end defun - -@defun transient-format-key obj -This generic function formats @var{OBJ}'s @code{key} for display and returns the -result. -@end defun - -@defun transient-format-description obj -This generic function formats @var{OBJ}'s @code{description} for display and -returns the result. -@end defun - -@defun transient-format-value obj -This generic function formats @var{OBJ}'s value for display and returns -the result. -@end defun - -@defun transient-show-help obj -Show help for the prefix, infix or suffix command represented by -@var{OBJ}. - -For prefixes, show the info manual, if that is specified using the -@code{info-manual} slot. Otherwise, show the manpage if that is specified -using the @code{man-page} slot. Otherwise, show the command's -documentation string. - -For suffixes, show the command's documentation string. - -For infixes, show the manpage if that is specified. Otherwise show -the command's documentation string. -@end defun - -@node Prefix Slots -@section Prefix Slots - -@itemize -@item -@code{show-help}, @code{man-page} or @code{info-manual} can be used to specify the -documentation for the prefix and its suffixes. The command -@code{transient-help} uses the method @code{transient-show-help} (which see) to -lookup and use these values. - -@item -@code{history-key} If multiple prefix commands should share a single value, -then this slot has to be set to the same value for all of them. You -probably don't want that. - -@item -@code{transient-suffix} and @code{transient-non-suffix} play a part when -determining whether the currently active transient prefix command -remains active/transient when a suffix or arbitrary non-suffix -command is invoked. See @ref{Transient State}. - -@item -@code{refresh-suffixes} Normally suffix objects and keymaps are only setup -once, when the prefix is invoked. Setting this to @code{t}, causes them to -be recreated after every command. This is useful when using @code{:if...} -predicates, and those need to be rerun for some reason. Doing this -is somewhat costly, and there is a risk of losing state, so this is -disabled by default and still considered experimental. - -@item -@code{incompatible} A list of lists. Each sub-list specifies a set of -mutually exclusive arguments. Enabling one of these arguments -causes the others to be disabled. An argument may appear in -multiple sub-lists. Arguments must me given in the same form as -used in the @code{argument} or @code{argument-format} slot of the respective -suffix objects, usually something like @code{--switch} or @code{--option=%s}. For -options and @code{transient-switches} suffixes it is also possible to match -against a specific value, as returned by @code{transient-infix-value}, -for example, @code{--option=one}. - -@item -@code{scope} For some transients it might be necessary to have a sort of -secondary value, called a ``scope''. See @code{transient-define-prefix}. -@end itemize - -@anchor{Internal Prefix Slots} -@subheading Internal Prefix Slots - -These slots are mostly intended for internal use. They should not be -set in calls to @code{transient-define-prefix}. - -@itemize -@item -@code{prototype} When a transient prefix command is invoked, then a clone -of that object is stored in the global variable @code{transient--prefix} -and the prototype is stored in the clone's @code{prototype} slot. - -@item -@code{command} The command, a symbol. Each transient prefix command -consists of a command, which is stored in a symbol's function slot -and an object, which is stored in the @code{transient--prefix} property -of the same symbol. - -@item -@code{level} The level of the prefix commands. The suffix commands whose -layer is equal or lower are displayed. See @ref{Enabling and Disabling Suffixes}. - -@item -@code{value} The likely outdated value of the prefix. Instead of accessing -this slot directly you should use the function @code{transient-get-value}, -which is guaranteed to return the up-to-date value. - -@item -@code{history} and @code{history-pos} are used to keep track of historic values. -Unless you implement your own @code{transient-infix-read} method you should -not have to deal with these slots. -@end itemize - -@node Suffix Slots -@section Suffix Slots - -Here we document most of the slots that are only available for suffix -objects. Some slots are shared by suffix and group objects, they are -documented in @ref{Predicate Slots}. - -Also see @ref{Suffix Classes}. - -@anchor{Slots of @code{transient-suffix}} -@subheading Slots of @code{transient-suffix} - -@itemize -@item -@code{key} The key, a key vector or a key description string. - -@item -@code{command} The command, a symbol. - -@item -@code{transient} Whether to stay transient. See @ref{Transient State}. - -@item -@code{format} The format used to display the suffix in the popup buffer. -It must contain the following %-placeholders: - -@itemize -@item -@code{%k} For the key. -@item -@code{%d} For the description. -@item -@code{%v} For the infix value. Non-infix suffixes don't have a value. -@end itemize - -@item -@code{description} The description, either a string or a function, which is -called with zero or one argument (the suffix object), and returns a -string. - -@item -@code{face} Face used for the description. In simple cases it is easier -to use this instead of using a function as @code{description} and adding -the styling there. @code{face} is appended using @code{add-face-text-property}. - -@item -@code{show-help} A function used to display help for the suffix. If -unspecified, the prefix controls how help is displayed for its -suffixes. -@end itemize - -@anchor{Slots of @code{transient-infix}} -@subheading Slots of @code{transient-infix} - -Some of these slots are only meaningful for some of the subclasses. -They are defined here anyway to allow sharing certain methods. - -@itemize -@item -@code{argument} The long argument, e.g., @code{--verbose}. - -@item -@code{shortarg} The short argument, e.g., @code{-v}. - -@item -@code{value} The value. Should not be accessed directly. - -@item -@code{init-value} Function that is responsible for setting the object's -value. If bound, then this is called with the object as the only -argument. Usually this is not bound, in which case the object's -primary @code{transient-init-value} method is called instead. - -@item -@code{unsavable} Whether the value of the suffix is not saved as part of -the prefixes. - -@item -@code{multi-value} For options, whether the option can have multiple -values. If this is non-@code{nil}, then the values are read using -@code{completing-read-multiple} by default and if you specify your own -reader, then it should read the values using that function or -similar. - -Supported non-@code{nil} values are: - -@itemize -@item -Use @code{rest} for an option that can have multiple values. This is -useful e.g., for an @code{--} argument that indicates that all remaining -arguments are files (such as @code{git log -- file1 file2}). - -In the list returned by @code{transient-args} such an option and its -values are represented by a single list of the form @code{(ARGUMENT - . VALUES)}. - -@item -Use @code{repeat} for an option that can be specified multiple times. - -In the list returned by @code{transient-args} each instance of the option -and its value appears separately in the usual from, for example: -@code{("--another-argument" "--option=first" "--option=second")}. -@end itemize - -In both cases the option's values have to be specified in the -default value of a prefix using the same format as returned by -@code{transient-args}, e.g., @code{("--other" "--o=1" "--o=2" ("--" "f1" "f2"))}. - -@item -@code{always-read} For options, whether to read a value on every invocation. -If this is @code{nil}, then options that have a value are simply unset and -have to be invoked a second time to set a new value. - -@item -@code{allow-empty} For options, whether the empty string is a valid value. - -@item -@code{history-key} The key used to store the history. This defaults to the -command name. This is useful when multiple infixes should share the -same history because their values are of the same kind. - -@item -@code{reader} The function used to read the value of an infix. Not used -for switches. The function takes three arguments, @var{PROMPT}, -@var{INITIAL-INPUT} and @var{HISTORY}, and must return a string. - -@item -@code{prompt} The prompt used when reading the value, either a string or a -function that takes the object as the only argument and which -returns a prompt string. - -@item -@code{choices} A list of valid values, or a function that returns such a -list. The latter is not implemented for @code{transient-switches}, because -I couldn't think of a use-case. How exactly the choices are used -varies depending on the class of the suffix. -@end itemize - -@anchor{Slots of @code{transient-variable}} -@subheading Slots of @code{transient-variable} - -@itemize -@item -@code{variable} The variable. -@end itemize - -@anchor{Slots of @code{transient-switches}} -@subheading Slots of @code{transient-switches} - -@itemize -@item -@code{argument-format} The display format. Must contain @code{%s}, one of the -@code{choices} is substituted for that. E.g., @code{--%s-order}. - -@item -@code{argument-regexp} The regexp used to match any one of the switches. -E.g., @code{\\(--\\(topo\\|author-date\\|date\\)-order\\)}. -@end itemize - -@node Predicate Slots -@section Predicate Slots - -Suffix and group objects share some predicate slots that control -whether a group or suffix should be available depending on some state. -Only one of these slots can be used at the same time. It is undefined -what happens if you use more than one. - -@itemize -@item -@code{if} Enable if predicate returns non-@code{nil}. -@item -@code{if-not} Enable if predicate returns @code{nil}. -@item -@code{if-non-nil} Enable if variable's value is non-@code{nil}. -@item -@code{if-nil} Enable if variable's value is @code{nil}. -@item -@code{if-mode} Enable if major-mode matches value. -@item -@code{if-not-mode} Enable if major-mode does not match value. -@item -@code{if-derived} Enable if major-mode derives from value. -@item -@code{if-not-derived} Enable if major-mode does not derive from value. -@end itemize - -By default these predicates run when the prefix command is invoked, -but this can be changes, using the @code{refresh-suffixes} prefix slot. -See @ref{Prefix Slots}. - -One more slot is shared between group and suffix classes, @code{level}. Like -the slots documented above, it is a predicate, but it is used for a -different purpose. The value has to be an integer between 1 -and 7. @code{level} controls whether a suffix or a group should be -available depending on user preference. -See @ref{Enabling and Disabling Suffixes}. - -@node FAQ -@appendix FAQ - -@anchor{Can I control how the popup buffer is displayed?} -@appendixsec Can I control how the popup buffer is displayed? - -Yes, see @code{transient-display-buffer-action} in @ref{Configuration}. - -@anchor{How can I copy text from the popup buffer?} -@appendixsec How can I copy text from the popup buffer? - -To be able to mark text in Transient's popup buffer using the mouse, -you have to add the below binding. Note that for technical reasons, -the region won't be visualized, while doing so. After you have quit -the transient popup, you will be able to yank it in another buffer. - -@lisp -(keymap-set transient-predicate-map - "<mouse-set-region>" - #'transient--do-stay) -@end lisp - -@anchor{How can I autoload prefix and suffix commands?} -@appendixsec How can I autoload prefix and suffix commands? - -If your package only supports Emacs 30, just prefix the definition -with @code{;;;###autoload}. If your package supports released versions of -Emacs, you unfortunately have to use a long form autoload comment -as described in @ref{Autoload,,,elisp,}. - -@lisp -;;;###autoload (autoload 'magit-dispatch "magit" nil t) -(transient-define-prefix magit-dispatch () - ...) -@end lisp - -@anchor{How does Transient compare to prefix keys and universal arguments?} -@appendixsec How does Transient compare to prefix keys and universal arguments? - -See @uref{https://github.com/magit/transient/wiki/Comparison-with-prefix-keys-and-universal-arguments}. - -@anchor{How does Transient compare to Magit-Popup and Hydra?} -@appendixsec How does Transient compare to Magit-Popup and Hydra? - -See @uref{https://github.com/magit/transient/wiki/Comparison-with-other-packages}. - -@anchor{Why did some of the key bindings change?} -@appendixsec Why did some of the key bindings change? - -You may have noticed that the bindings for some of the common commands -do @strong{not} have the prefix @kbd{C-x} and that furthermore some of these commands -are grayed out while others are not. That unfortunately is a bit -confusing if the section of common commands is not shown permanently, -making the following explanation necessary. - -The purpose of usually hiding that section but showing it after the -user pressed the respective prefix key is to conserve space and not -overwhelm users with too much noise, while allowing the user to -quickly list common bindings on demand. - -That however should not keep us from using the best possible key -bindings. The bindings that do use a prefix do so to avoid wasting -too many non-prefix bindings, keeping them available for use in -individual transients. The bindings that do not use a prefix and that -are @strong{not} grayed out are very important bindings that are @strong{always} -available, even when invoking the ``common command key prefix'' or @strong{any -other} transient-specific prefix. The non-prefix keys that @strong{are} grayed -out however, are not available when any incomplete prefix key sequence -is active. They do not use the ``common command key prefix'' because it -is likely that users want to invoke them several times in a row and -e.g., @kbd{M-p M-p M-p} is much more convenient than @kbd{C-x M-p C-x M-p C-x M-p}. - -You may also have noticed that the ``Set'' command is bound to @kbd{C-x s}, -while Magit-Popup used to bind @kbd{C-c C-c} instead. I have seen several -users praise the latter binding (sic), so I did not change it -willy-nilly. The reason that I changed it is that using different -prefix keys for different common commands, would have made the -temporary display of the common commands even more confusing, i.e., -after pressing @kbd{C-c} all the bindings that begin with the @kbd{C-x} prefix -would be grayed out. - -Using a single prefix for common commands key means that all other -potential prefix keys can be used for transient-specific commands -@strong{without} the section of common commands also popping up. @kbd{C-c} in -particular is a prefix that I want to (and already do) use for Magit, and -also using that for a common command would prevent me from doing so. - -(Also see the next question.) - -@anchor{Why does @kbd{q} not quit popups anymore?} -@appendixsec Why does @kbd{q} not quit popups anymore? - -I agree that @kbd{q} is a good binding for commands that quit something. -This includes quitting whatever transient is currently active, but it -also includes quitting whatever it is that some specific transient is -controlling. The transient @code{magit-blame} for example binds @kbd{q} to the -command that turns @code{magit-blame-mode} off. - -So I had to decide if @kbd{q} should quit the active transient (like -Magit-Popup used to) or whether @kbd{C-g} should do that instead, so that @kbd{q} -could be bound in individual transient to whatever commands make sense -for them. Because all other letters are already reserved for use by -individual transients, I have decided to no longer make an exception -for @kbd{q}. - -If you want to get @kbd{q}'s old binding back then you can do so. Doing -that is a bit more complicated than changing a single key binding, so -I have implemented a function, @code{transient-bind-q-to-quit} that makes the -necessary changes. See its documentation string for more information. - -@node Keystroke Index -@appendix Keystroke Index - -@printindex ky - -@node Command and Function Index -@appendix Command and Function Index - -@printindex fn - -@node Variable Index -@appendix Variable Index - -@printindex vr - -@node Concept Index -@appendix Concept Index - -@printindex cp - -@node GNU General Public License -@appendix GNU General Public License - -@include gpl.texi - -@bye