summaryrefslogtreecommitdiff
path: root/docs/transient.org
diff options
context:
space:
mode:
authorJonas Bernoulli <jonas@bernoul.li>2018-06-21 12:20:13 -0500
committerJonas Bernoulli <jonas@bernoul.li>2019-02-14 21:50:55 +0100
commit33f538a0bb83c8d4abc8f4c2db0dfbb9b09c4f92 (patch)
tree1d7afa205e484dbac95be4e0f30f729f09110c16 /docs/transient.org
Release version 0.1.0v0.1.0
Diffstat (limited to 'docs/transient.org')
-rw-r--r--docs/transient.org1862
1 files changed, 1862 insertions, 0 deletions
diff --git a/docs/transient.org b/docs/transient.org
new file mode 100644
index 0000000..065fc7a
--- /dev/null
+++ b/docs/transient.org
@@ -0,0 +1,1862 @@
+#+TITLE: Transient User and Developer Manual
+:PREAMBLE:
+#+AUTHOR: Jonas Bernoulli
+#+EMAIL: jonas@bernoul.li
+#+DATE: 2018-2019
+#+LANGUAGE: en
+
+#+TEXINFO_DIR_CATEGORY: Emacs
+#+TEXINFO_DIR_TITLE: Transient: (transient).
+#+TEXINFO_DIR_DESC: Transient Commands
+#+SUBTITLE: for version 0.1.0
+
+#+TEXINFO_DEFFN: t
+#+OPTIONS: H:4 num:4 toc:2
+#+BIND: ox-texinfo+-before-export-hook ox-texinfo+-update-version-strings
+
+Taking inspiration from prefix keys and prefix arguments, Transient
+implements a similar abstraction involving a prefix command, infix
+arguments and suffix commands. We could call this abstraction a
+"transient command", but because it always involves at least two
+commands (a prefix and a suffix) we prefer to call it just a
+"transient".
+
+When the user calls a transient prefix command, then 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 ~pre-command-hook~ and ~post-command-hook~. The available
+suffix and infix commands and their state are shown in the echo area
+until the transient is exited by invoking a suffix command.
+
+Calling an infix command causes its value to be changed, possibly by
+reading a new value in the minibuffer.
+
+Calling a suffix command usually causes the transient to be exited
+but suffix commands can also be configured to not exit the transient.
+
+#+TEXINFO: @noindent
+This manual is for Transient version 0.1.0.
+
+#+BEGIN_QUOTE
+Copyright (C) 2018-2019 Jonas Bernoulli <jonas@bernoul.li>
+
+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_QUOTE
+:END:
+* Introduction
+
+Taking inspiration from prefix keys and prefix arguments, Transient
+implements a similar abstraction involving a prefix command, infix
+arguments and suffix commands. We could call this abstraction a
+"transient command", but because it always involves at least two
+commands (a prefix and a suffix) we prefer to call it just a
+"transient".
+
+#+BEGIN_QUOTE
+Transient keymaps are a feature provided by Emacs. Transients as
+implemented by this package involve the use of transient keymaps.
+
+Emacs provides a feature that it calls "prefix commands". When we
+talk about "prefix commands" in this manual, then we mean our own kind
+of "prefix commands", unless specified otherwise. To avoid ambiguity
+we sometimes use the terms "transient prefix command" for our kind and
+"regular prefix command" for Emacs' kind.
+#+END_QUOTE
+
+When the user calls a transient prefix command, then 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 ~pre-command-hook~ and ~post-command-hook~. The available suffix
+and infix commands and their state are shown in the echo area 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 echo area 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 it can choose to use or ignore the prefix arguments.
+For a suffix command that was invoked from a transient the variable
+~current-transient-suffixes~ and the function ~transient-args~ serve about
+the same purpose as the variables ~prefix-arg~ and ~current-prefix-arg~ do
+for any command that was called after the prefix arguments have been
+set using a command such as ~universal-argument~.
+
+The information shown in the echo area while a transient is active
+looks a bit like this:
+
+#+BEGIN_EXAMPLE
+,-----------------------------------------
+|Arguments
+| -f Force (--force)
+| -a Annotate (--annotate)
+|
+|Create
+| t tag
+| r telease
+`-----------------------------------------
+#+END_EXAMPLE
+
+#+BEGIN_QUOTE
+This is a simplified version of ~magit-tag~. Info manuals do not
+support images or colored text, so the above "screenshot" lacks some
+information; in practice you would be able to tell whether the
+arguments ~--force~ and ~--annotate~ are enabled or not based on their
+color.
+#+END_QUOTE
+
+Transient can be used to implement simple "command dispatchers". The
+main benefit then is that the user can see all the available commands
+in the echo area. 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 ~magit-dispatch~ 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, then one can call a command with arguments that
+are just as complex as when calling the same function non-interactively
+using code.
+
+Invoking a transient 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 [[*Using History]].
+
+After a transient prefix command is invoked ~C-h <key>~ can be used to
+show the documentation for the infix or suffix command that ~<key>~ is
+bound to (see [[*Getting Help for Suffix Commands]]) and infixes and
+suffixes can be removed from the transient using ~C-x l <key>~. Infixes
+and suffixes that are disabled by default can be enabled the same way.
+See [[*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 implement yet).
+
+* Usage
+** 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 commands activates a
+transient keymap, which temporarily binds the transients 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 the echo area), 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 *arguments*.
+
+Instead of setting arguments to be used by a suffix command, infix
+commands may also set some value by side-effect.
+
+** Aborting and Resuming Transients
+
+To quit the transient without invoking a suffix command press ~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 ~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 echo area is updated accordingly.
+Pressing ~C-g~ while a nested transient is active only quits the
+innermost transient, causing a return to the previous transient.
+
+~C-q~ and ~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
+~M-x transient-resume~.
+
+- Key: C-g, transient-quit-seq
+- Key: C-g, transient-quit-one
+
+ This key quits the currently active incomplete key sequence, if any,
+ or else the current transient. When quitting the current transient,
+ then it returns to the previous transient, if any.
+
+- Key: C-q, 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.
+
+- Key: C-z, transient-suspend
+
+ Like ~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.
+
+- Key: M-x transient-resume, transient-resume
+
+ This command resumes the previously suspended stack of transients,
+ if any.
+
+** Common Suffix Commands
+*** _ :ignore:
+
+A few shared suffix commands are available in all transients. These
+suffix commands are not shown in the echo area by default.
+
+Most of these commands are bound to ~C-x <key>~ and after pressing ~C-x~ a
+section featuring all common commands is temporarily show in the echo
+area. After invoking one of these commands that 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.
+
+- Key: C-x t, 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 ~C-x~. This only affects the current
+ Emacs session.
+
+- User Option: 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 to many options.
+
+ While a transient is active, pressing ~C-x~ always shows the common
+ command. The value of this option can be changed for the current
+ Emacs session by typing ~C-x t~ while a transient is active.
+
+The other common commands are describe in either the previous node or
+in one of the following nodes.
+
+*** Notes on Common Key Bindings
+:PROPERTIES:
+:NONODE: t
+:END:
+
+You may have noticed that the bindings for some of the common commands
+do *not* have the prefix ~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 *not* grayed out are very important bindings that are *always*
+available, even when invoking the "common command key prefix" or *any
+other* transient-specific prefix. The non-prefix keys that *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. ~M-p M-p M-p~ is much more convenient than ~C-x M-p C-x M-p C-x M-p~.
+
+You may also have noticed that the "Set" command is bound to ~C-x s~,
+while Magit-Popup used to bind ~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 ~C-c~ all the ~C-x ...~ bindings 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
+*without* the section of common commands also popping up. ~C-c~ in
+particular is a prefix that I want (and already do) use for Magit, and
+also using that for a common command would prevent me from doing so.
+
+** Saving Values
+
+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. [fn:1]
+
+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 [[*Using History]]).
+
+- Key: C-x s, transient-set
+
+ This command saves the value of the active transient for this Emacs
+ session.
+
+- Key: C-x C-s, transient-save
+
+ Save the value of the active transient persistently across Emacs
+ sessions.
+
+- User Option: transient-values-file
+
+ This file is used to persist the values of transients between Emacs
+ sessions.
+
+[fn:1] ~magit-diff~ and ~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. This is something I am
+rethinking, but I don't want to rush any changes.)
+
+** Using History
+
+Every time the user invokes a suffix command the transient's current
+value is saved to its history. This values can be cycled through the
+same way one can cycle through the history of commands that read
+user-input in the minibuffer.
+
+- Key: M-p, transient-history-prev
+
+ This command switches to the previous value used for the active
+ transient.
+
+- Key: M-n, transient-history-next
+
+ This command switches to the next value used for the active
+ transient.
+
+In addition to the transient-wide history, Transient of course
+supports per-infix history. When an infix reads user-input using the
+minibuffer, then 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
+[[*Suffix Slots]]).
+
+Both kinds of history are saved to a file when Emacs is exited.
+
+- User Option: transient-history-file
+
+ This file is used to persist the history of transients and their
+ infixes between Emacs sessions.
+
+- User Option: transient-history-limit
+
+ This option controls how many history elements are kept at the time
+ the history in saved in ~transient-history-file~.
+
+** Getting Help for Suffix Commands
+
+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.
+
+- Key: C-h, transient-help
+
+ This command enters help mode. When help mode is active, then
+ typing ~<key>~ shows information about the suffix command that ~<key>~
+ normally is bound to (instead of invoking it). Pressing ~C-h~ a
+ second time shows information about the /prefix/ command.
+
+ After typing ~<key>~ the stack of transient states is suspended and
+ information about the suffix command is shown instead. Typing ~q~ in
+ the help buffer buries that buffer and resumes the transient state.
+
+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. ~transient-help~ then tries
+to jump to the correct location within that. Info manuals are also
+supported. The fallback is to show the commands doc-string, for
+non-infix suffixes this is usually appropriate.
+
+** Enabling and 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.
+
+For that reason a mechanism is that authors can use to classify a
+transient's infixes and suffixes along the essentials...everything
+spectrum. We use the term "levels" to describe that mechanism.
+
+Each suffix command is placed on a level and each transient has a
+level (called 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 transient and/or their individual suffixes
+can be changed interactively, by invoking the transient and then
+pressing ~C-x l~ to enter the "edit" mode, see below.
+
+The default level for both transients and their suffixes is 4. The
+~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.
+
+(Magit currently places nearly all suffixes on level 4 and lower
+levels are not used at all yet. So for the time being you should not
+set a lower default level and using a higher level might not give you
+as many additional suffixes as you hoped.)
+
+- User Option: 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.
+
+- User Option: transient-levels-file
+
+ This file is used to persist the levels of transients and their
+ suffix between Emacs sessions.
+
+- Key: C-x l, 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 does instead prompt the user for the level that that suffix
+ should be placed on.
+
+ Help mode is available in edit mode.
+
+ To change the transient level press ~C-x l~ again.
+
+ To exit edit mode press ~C-g~.
+
+ Note that edit mode does not display any suffixes that are not
+ currently usable. ~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.
+
+* Other Options
+
+- User Option: transient-show-popup
+
+ This option controls whether the current transient's infix and
+ suffix commands are shown in the echo area.
+
+ If ~t~ (the default), then the infix and suffix commands are shown as
+ soon as the transient is invoked. If ~nil~, only a one line summary
+ is shown until the user presses a key that forms an incomplete key
+ sequence. If a number, behave as for ~nil~ but also show the commands
+ after that many seconds of inactivity.
+
+- User Option: 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-nil, then the key binding for infix argument
+ are highlighted when only a long argument (e.g. ~--verbose~) is
+ specified but no shorthand (e.g ~-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
+ ~transient-mismatched-key~ and ~transient-nonstandard-key~.
+
+- User Option: transient-substitute-key-function
+
+ This function is used to modify key bindings. It the value of this
+ option is 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 ~key~ slot, or key description that
+ replaces the prefix key. It could be used to make other
+ substitutions, but that is discouraged.
+
+ For example, ~=~ is hard to reach using my custom keyboard layout,
+ so I substitute ~(~ for that, which is easy to reach using a layout
+ optimized for lisp.
+
+ #+BEGIN_SRC emacs-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_SRC
+
+- User Option: transient-detect-key-conflicts
+
+ This option controls whether key binding conflicts should be
+ detected at the time the transient is invoked. If so, then 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.
+
+* Modifying Existing Transients
+
+To an extend transients can be customized interactively, see [[*Enabling
+and Disabling Suffixes]]. This section explains how existing transients
+can be further modified non-interactively.
+
+The following functions share a few arguments:
+
+- PREFIX is a transient prefix command, a symbol.
+- SUFFIX is a transient infix or suffix specification in the same form
+ as expected by ~define-transient-command~. See [[*Suffix Specifications]].
+- LOC is a command, a key vector or a key description (a string as
+ returned by ~key-description~).
+
+These functions operate on the information stored in the
+~transient--layout~ property of the PREFIX symbol. Suffix entries in
+that tree are not objects but have the form ~(LEVEL CLASS PLIST)~, where
+plist should set at least ~:key~, ~:description~ and ~:command~.
+
+- Function: transient-insert-suffix prefix loc suffix
+
+ This function inserts SUFFIX into PREFIX before LOC.
+
+- Function: transient-append-suffix prefix loc suffix
+
+ This function inserts SUFFIX into PREFIX after LOC.
+
+- Function: transient-replace-suffix prefix loc suffix
+
+ This function replaces the suffix at LOC in PREFIX with SUFFIX.
+
+- Function: transient-remove-suffix prefix loc
+
+ This function removes the suffix at LOC in PREFIX.
+
+- Function: transient-get-suffix prefix loc
+
+ This function returns the suffix at LOC in PREFIX. The returned
+ value has the form mentioned above.
+
+- Function: transient-suffix-put prefix loc prop value
+
+ This function edits the suffix at LOC in PREFIX, by setting the
+ PROP of its plist to VALUE.
+
+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 LOC cannot be found in 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 to fail also. Among these
+functions only ~transient-get-suffix~ and ~transient-suffix-put~ may
+signal an error.
+
+* Defining New Commands
+** 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 *and* it
+binds the transient's infix and suffix commands. In other works, it
+defines the complete transient, not just the transient prefix command
+that is used to invoke that transient.
+
+- Macro: define-transient-command name arglist [docstring] [keyword value]... group... [body...]
+
+ This macro defines NAME as a transient prefix command and binds the
+ transient's infix and suffix commands.
+
+ ARGLIST are the arguments that the prefix command takes.
+ 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 ~:class~ or a keyword
+ argument supported by the constructor of that class. The
+ ~transient-prefix~ class is used if the class is not specified
+ explicitly.
+
+ GROUPs add key bindings for infix and suffix commands and specify
+ how these bindings are presented in the echo area. At least one
+ GROUP has to be specified. See [[*Binding Suffix and Infix Commands]].
+
+ The BODY is optional. If it is omitted, then ARGLIST is ignored and
+ the function definition becomes:
+
+ #+BEGIN_SRC emacs-lisp
+ (lambda ()
+ (interactive)
+ (transient-setup 'NAME))
+ #+END_SRC
+
+ If BODY is specified, then it must begin with an ~interactive~ form
+ that matches ARGLIST, and it must call ~transient-setup~. It may
+ however call that function only when some condition is satisfied.
+
+ All transients have a (possibly ~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 ~interactive~ form and has to be passed to the
+ setup function:
+
+ #+BEGIN_SRC emacs-lisp
+ (transient-setup 'NAME nil nil :scope SCOPE)
+ #+END_SRC
+
+ For example, the scope of the ~magit-branch-configure~ transient is
+ the branch whose variables are being configured.
+
+** Binding Suffix and Infix Commands
+*** _ :ignore:
+
+The macro ~define-transient-command~ is used to define a transient.
+This defines the actual transient prefix command (see [[*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 ~transient-insert-suffix~ (See [[*Modifying Existing
+Transients]]). These functions take a "suffix specification" as one of
+their arguments, which has the same form as the specifications used in
+~define-transient-command~.
+
+*** 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 [[*Group Classes]].
+
+Groups are specified in the call to ~define-transient-command~, 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:
+
+#+BEGIN_SRC emacs-lisp
+ [{LEVEL} {DESCRIPTION} {KEYWORD VALUE}... ELEMENT...]
+#+END_SRC
+
+The LEVEL is optional and defaults to 4. See [[*Enabling and Disabling
+Suffixes]].
+
+The DESCRIPTION is optional. If present it is used as the heading of
+the group.
+
+The KEYWORD-VALUE pairs are optional. Each keyword has to be a
+keyword symbol, either ~:class~ or a keyword argument supported by the
+constructor of that class.
+
+- One of these keywords, ~:description~, is equivalent to specifying
+ DESCRIPTION at the very beginning of the vector. The recommendation
+ is to use ~:description~ if some other keyword is also used, for
+ consistency, or DESCRIPTION otherwise, because it looks better.
+
+- Likewise ~:level~ is equivalent to LEVEL.
+
+- Other important keywords include the ~:if...~ keywords. These
+ keywords control whether the group is available in a certain
+ situation.
+
+ For example, one group of the ~magit-rebase~ transient uses ~:if
+ magit-rebase-in-progress-p~, which contains the suffixes that are
+ useful while rebase is already in progress; and another that uses
+ ~: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 [[*Predicate Slots]].
+
+- Finally the value of ~:hide~, if non-nil, is a predicate that control
+ 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:
+
+ #+BEGIN_SRC emacs-lisp
+ (lambda ()
+ (eq (car transient--redisplay-key)
+ ?\C-c)) ; the prefix key shared by all bindings
+ #+END_SRC
+
+The ELEMENTs are either all subgroups (vectors), or all suffixes
+(lists) and strings. (At least currently no group type exists that
+would allow mixing subgroups with commands at the same level, though
+in principal there is nothing that prevents that.)
+
+If the ELEMENTs are not subgroups, then they can be a mixture of lists
+that specify commands and strings. Strings are inserted verbatim.
+The empty string can be used to insert gaps between suffixes, which is
+particularly useful if the suffixes are outlined as a table.
+
+The form of suffix specifications is documented in the next node.
+
+*** Suffix Specifications
+
+A transient's suffix and infix commands are bound when the transient
+prefix command is defined using ~define-transient-command~, see
+[[*Defining Transients]]. The commands are organized into groups, see
+[[*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 ~transient-insert-suffix~, see [[*Modifying
+Existing Transients]].
+
+Suffix specifications have this form:
+
+#+BEGIN_SRC emacs-lisp
+ ([LEVEL] [KEY] [DESCRIPTION] COMMAND|ARGUMENT [KEYWORD VALUE]...)
+#+END_SRC
+
+LEVEL, KEY and DESCRIPTION can also be specified using the KEYWORDs
+~:level~, ~:key~ and ~:description~. If the object that is associated with
+COMMAND sets these properties, then they do not have to be specified
+here. You can however specify them here anyway, possibly overriding
+the objects value just for the binding inside this transient.
+
+- LEVEL is the suffix level, an integer between 1 and 7. See
+ [[*Enabling and Disabling Suffixes]].
+
+- KEY is the key binding, either a vector or key description string.
+
+- DESCRIPTION is the description, either a string or a function that
+ return a string. The function should to 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 ~:description~ in that
+ case.
+
+The next element is either a command or an argument. This is the only
+argument that is mandatory in all cases.
+
+- COMMAND is a symbol that is bound as a function, which has to be a
+ command. Any command will do; it does not need to have an object
+ associated with it (as would be the case if ~define-suffix-command~
+ or ~define-infix-command~ were used to define it).
+
+ 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 KEY and the DESCRIPTION.
+
+- The mandatory argument can also be an 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 ~:shortarg~) and the second the long argument
+ (which can also be specified using ~:argument~).
+
+ Only the long argument is displayed in the echo area. See
+ ~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 "="
+ (e.g. "--format=") then ~transient-option~ is used, otherwise
+ ~transient-switch~.
+
+Finally details can be specified using optional KEYWORD-VALUE pairs.
+Each keyword has to be a keyword symbol, either ~:class~ or a keyword
+argument supported by the constructor of that class. See [[*Suffix
+Slots]].
+
+** Defining Suffix and Infix Commands
+
+- Macro: define-suffix-command name arglist [docstring] [keyword value]... body...
+
+ This macro defines NAME as a transient suffix command.
+
+ ARGLIST are the arguments that the command takes.
+ 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 ~:class~ or a keyword
+ argument supported by the constructor of that class. The
+ ~transient-suffix~ class is used if the class is not specified
+ explicitly.
+
+ The BODY must begin with an ~interactive~ form that matches ARGLIST.
+ Use the function ~transient-args~ or the low-level variable
+ ~current-transient-suffixes~ if the former does not give you all the
+ required details. This should, but does not necessarily have to be,
+ done inside the ~interactive~ form; just like for ~prefix-arg~ and
+ ~current-prefix-arg~.
+
+- Macro: define-infix-command name arglist [docstring] [keyword value]...
+
+ This macro defines NAME as a transient infix command.
+
+ ARGLIST is always ignored (but mandatory never-the-less) and
+ reserved for future use. DOCSTRING is the documentation string and
+ is optional.
+
+ The keyword-value pairs are mandatory. All transient infix commands
+ are ~equal~ to each other (but not ~eq~), so it is meaningless to define
+ an infix command without also setting at least ~:class~ and one other
+ keyword (which it is depends on the used class, usually ~:argument~ or
+ ~:variable~).
+
+ Each keyword has to be a keyword symbol, either ~:class~ or a keyword
+ argument supported by the constructor of that class. The
+ ~transient-switch~ class is used if the class is not specified
+ explicitly.
+
+ The function definitions is always:
+
+ #+BEGIN_SRC emacs-lisp
+ (lambda (obj value)
+ (interactive
+ (let ((obj (transient-suffix-object)))
+ (list obj (transient-infix-read obj))))
+ (transient-infix-set obj value)
+ (transient--show))
+ #+END_SRC
+
+ ~transient-infix-read~ and ~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
+ ~transient-suffix-command~ to define the infix command and use ~t~ as
+ the value of the ~:transient~ keyword.
+
+- Macro: define-infix-argument name arglist [docstring] [keyword value]...
+
+ This macro defines NAME as a transient infix command.
+
+ It is an alias for ~define-infix-command~. Only use this alias
+ to define an infix command that actually sets an infix argument.
+ To define a infix command that, for example, sets a variable use
+ ~define-infix-command~ instead.
+
+** Using Infix Arguments
+
+The function 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 ~nil~ (which causes the function to return
+~nil~ too).
+
+Like for Emacs' prefix arguments it is advisable, but not mandatory,
+to access the infix arguments inside the command's ~interactive~ form.
+The preferred way of doing that is to call the ~transient-args~
+function, which for infix arguments serves about the same purpose as
+~prefix-arg~ serves for prefix arguments.
+
+- Function: transient-args &optional prefix separate
+
+ This function returns the value of the transient from which the
+ current suffix was called. If the current suffix command was not
+ called from a transient, then it returns ~nil~.
+
+ If optional PREFIX is non-~nil~, then it should be a symbol, a
+ transient prefix command. In that case the value of the transient
+ is only returned if the suffix was invoked from *that* transient.
+ Otherwise ~nil~ is returned. This function is also used internally,
+ in which PREFIX can also be a ~transient-prefix~ object.
+
+ If optional SEPARATE is non-~nil~, then the arguments are separated
+ into two groups. If SEPARATE is ~t~, they are separated into atoms
+ and conses (~nil~ isn't a valid value, so it doesn't matter that that
+ is both an atom and a cons).
+
+ SEPARATE can also be a predicate function, in which case the first
+ element is a list of the values for which it returns non-~nil~ and the
+ second element is a list of the values for which it returns ~nil~.
+
+ For transients that are used to pass arguments to a subprocess (such
+ as ~git~), ~stringp~ is a useful value for SEPARATE, it separates
+ non-positional arguments from positional arguments. The value of
+ Magit's file argument (~"--"~) for example looks like this: ~("--"
+ file...)~."
+
+- Variable: current-transient-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 ~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.
+
+- Variable: current-transient-prefix
+
+ The transient from which this suffix command was invoked. The
+ returned value is a ~transient-prefix~ object, which holds information
+ associated with the transient prefix command.
+
+- Variable: current-transient-command
+
+ The transient from which this suffix command was invoked. The
+ returned value is a symbol, the transient prefix command.
+
+** Transient State
+*** _ :ignore:
+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:
+
+- Invoking an infix command does not affect the transient state; the
+ transient remains active.
+
+- Invoking a (non-infix) suffix command "deactivates" the transient
+ state by removing the transient keymap and performing some
+ additional cleanup.
+
+- 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.
+
+But these are just the defaults. Whether a certain command
+deactivates or "exits" the transient is configurable. There is more
+than one way in which a command can be "transient" or "non-transient";
+the exact behavior is implemented by calling a so-called "pre-command"
+function. Whether non-suffix commands are allowed to be called is
+configurable per transient.
+
+- The transient-ness of suffix commands (including infix commands) is
+ controlled by the value of their ~transient~ slot, which can be set
+ either when defining the command or when adding a binding to a
+ transient while defining the respective transient prefix command.
+
+ Valid values are booleans and the pre-commands described below.
+
+ - ~t~ is equivalent to ~transient--do-stay~.
+ - ~nil~ is equivalent to ~transient--do-exit~.
+ - If ~transient~ is unbound (and that is actually the default for
+ non-infix suffixes) then the value of the prefix's
+ ~transient-suffix~ slot is used instead. The default value of that
+ slot is ~nil~, so the suffix's ~transient~ slot being unbound is
+ essentially equivalent to it being ~nil~.
+
+- A suffix command can be a prefix command itself, i.e. a
+ "sub-prefix". While a sub-prefix is active we nearly always want
+ ~C-g~ to take the user back to the "super-prefix". However in rare
+ cases this may not be desirable, and that makes the following
+ complication necessary:
+
+ For ~transient-suffix~ objects the ~transient~ slot is unbound. We can
+ ignore that for the most part because, as stated above, ~nil~ and the
+ slot being unbound are equivalent, and means "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 ~nil~ means "do exit permanently", which requires that
+ slot to be explicitly set to that value.
+
+- The transient-ness of certain built-in suffix commands is specified
+ using ~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 ~transient~ slot.
+
+The available pre-command functions are documented below. They are
+called by ~transient--pre-command~, a function on ~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 ~transient--exit~ or
+~transient--stay~ is used (that way we don't have to remember if ~t~ means
+"exit" or "stay").
+
+Additionally these functions may change the value of ~this-command~
+(which explains why they have to be called using ~pre-command-hook~),
+call ~transient-export~, ~transient--stack-zap~ or ~transient--stack-push~;
+and set the values of ~transient--exitp~, ~transient--helpp~ or
+~transient--editp~.
+
+*** Pre-commands for Infixes
+:PROPERTIES:
+:NONODE: t
+:END:
+
+The default for infixes is ~transient--do-stay~. This is also the only
+function that makes sense for infixes.
+
+- Function: transient--do-stay
+
+ Call the command without exporting variables and stay transient.
+
+*** Pre-commands for Suffixes
+:PROPERTIES:
+:NONODE: t
+:END:
+
+The default for suffixes is ~transient--do-exit~.
+
+- Function: transient--do-exit
+
+ Call the command after exporting variables and exit the transient.
+
+- Function: transient--do-call
+
+ Call the command after exporting variables and stay transient.
+
+- Function: transient--do-replace
+
+ Call the transient prefix command, replacing the active transient.
+
+ This is used for suffix that are prefixes themselves, i.e. for
+ sub-prefixes.
+
+*** Pre-commands for Non-Suffixes
+:PROPERTIES:
+:NONODE: t
+:END:
+
+The default for non-suffixes, i.e commands that are bound in other
+keymaps beside the transient keymap, is ~transient--do-warn~. Silently
+ignoring the user-error is also an option, though probably not a good
+one.
+
+If you want to let the user invoke non-suffix commands, then use
+~transient--do-stay~ as the value of the prefix's ~transient-non-suffix~
+slot.
+
+- Function: transient--do-warn
+
+ Call ~transient-undefined~ and stay transient.
+
+- Function: transient--do-noop
+
+ Call ~transient-noop~ and stay transient.
+
+*** Special Pre-Commands
+:PROPERTIES:
+:NONODE: t
+:END:
+
+- Function: transient--do-quit-one
+
+ If active, quit help or edit mode, else exit the active transient.
+
+ This is used when the user pressed ~C-g~.
+
+- Function: transient--do-quit-all
+
+ Exit all transients without saving the transient stack.
+
+ This is used when the user pressed ~C-q~.
+
+- Function: transient--do-suspend
+
+ Suspend the active transient, saving the transient stack.
+
+ This is used when the user pressed ~C-z~.
+
+* Classes and Methods
+** _ :ignore:
+
+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
+*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.
+
+- 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.
+
+- 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 ~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.
+
+** Group Classes
+
+The type of a group can be specified using the ~:class~ property at the
+beginning of the class specification, e.g. ~[:class transient-columns
+...]~ in a call to ~define-transient-command~.
+
+- The abstract ~transient-child~ class is the base class of both
+ ~transient-group~ (and therefore all groups) as well as of
+ ~transient-suffix~ (and therefore all suffix and infix commands).
+
+ This class exists because the elements (aka "children") of certain
+ groups can be other groups instead of suffix and infix commands.
+
+- The abstract ~transient-group~ class is the superclass of all other
+ group classes.
+
+- The ~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.
+
+- The ~transient-row~ class displays all elements on a single line.
+
+- The ~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.
+
+- The ~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.
+
+** Group Methods
+
+- Function: 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 echo area.
+
+ 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
+ temporally make the ~transient--source-buffer~ the current buffer.
+
+** Prefix Classes
+
+Currently the ~transient-prefix~ class is being used for all prefix
+command and there is only a single generic functions that can be
+specialized based on the class of a prefix command.
+
+- Function: transient--history-init obj
+
+ This generic function is called while setting up the transient and
+ is responsible for initializing the ~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 ~transient-history~.
+
+A transient prefix command's object is stored in the ~transient--prefix~
+property of the command symbol. While a transient is active, a clone
+of that object is stored in the variable ~transient--prefix~. A clone
+is used because some changes that are made to the active transient's
+object should not affect later invocations.
+
+** Suffix Classes
+
+- All suffix and infix classes derive from ~transient-suffix~, which in
+ turn derives from ~transient-child~, from which ~transient-group~ also
+ derives (see [[*Group Classes]]).
+
+- All infix classes derived from the abstract ~transient-infix~ class,
+ which in turn derives from the ~transient-suffix~ class.
+
+ Infixes are a special type of suffixes. The primary difference is
+ that infixes always use the ~transient--do-stay~ pre-command, while
+ non-infix suffixes use a variety of pre-commands (see [[*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 [[*Defining Suffix and Infix Commands]]).
+
+- Classes used for infix commands that represent arguments should
+ derived from the abstract ~transient-argument~ class.
+
+- The ~transient-switch~ class (or a derived class) is used for infix
+ arguments that represent command-line switches (arguments that do
+ not take a value).
+
+- The ~transient-option~ class (or a derived class) is used for infix
+ arguments that represent command-line options (arguments that do
+ not take a value).
+
+- The ~transient-switches~ class can be used for a set of mutually
+ exclusive command-line switches.
+
+- The ~transient-files~ class can be used for a "--" argument that
+ indicates that all remaining arguments are files.
+
+- Classes used for infix commands that represent variables should
+ derived from the abstract ~transient-variables~ class.
+
+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.
+
+** Suffix Methods
+*** _ :ignore:
+
+To get information about the methods implementing these generic
+functions use ~describe-function~.
+
+*** Suffix Value Methods
+
+- Function: transient-init-value obj
+
+ This generic function sets the initial value of the object 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 ~transient-infix~, so if
+ your class derives from that directly, then you must implement
+ a method.
+
+- Function: transient-infix-read obj
+
+ This generic function determines the new value of the infix object
+ OBJ.
+
+ This function merely determines the value; ~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 ~reader~ slot (using the
+ ~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.
+
+- Function: transient-prompt obj
+
+ This generic function returns the prompt to be used to read infix
+ object OBJ's value.
+
+- Function: transient-infix-set obj value
+
+ This generic function sets the value of infix object OBJ to value.
+
+- Function: transient-infix-value obj
+
+ This generic function returns the value of the suffix object OBJ.
+
+ This function is called by ~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.
+ ~nil~ is not a value, it means "no value".
+
+ Usually only infixes have a value, but see the method for
+ ~transient-suffix~.
+
+- Function: transient-init-scope obj
+
+ This generic function sets the scope of the suffix object 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 ~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.
+
+*** Suffix Format Methods
+
+- Function: transient-format obj
+
+ This generic function formats and returns 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 ~transient--source-buffer~ current.
+
+- Function: transient-format-key obj
+
+ This generic function formats OBJ's ~key~ for display and returns the
+ result.
+
+- Function: transient-format-description obj
+
+ This generic function formats OBJ's ~description~ for display and
+ returns the result.
+
+- Function: transient-format-value obj
+
+ This generic function formats OBJ's value for display and returns
+ the result.
+
+- Function: transient-show-help obj
+
+ Show help for the prefix, infix or suffix command represented by
+ OBJ.
+
+ For prefixes show the info manual, if that is specified using the
+ ~info-manual~ slot. Otherwise show the manpage if that is specified
+ using the ~man-page~ slot. Otherwise show the command's doc-string.
+
+ For suffixes show the command's doc-string.
+
+ For infixes show the manpage if that is specified. Otherwise show
+ the command's doc-string.
+
+** TODO Prefix Slots
+
+** 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 [[*Predicate Slots]].
+
+Also see [[*Suffix Classes]].
+
+*** Slots of ~transient-suffix~
+:PROPERTIES:
+:NONODE: t
+:END:
+
+- ~key~ The key, a key vector or a key description string.
+
+- ~command~ The command, a symbol.
+
+- ~transient~ Whether to stay transient. See [[*Transient State]].
+
+- ~format~ The format used to display the suffix in the echo area. Must
+ contain the following %-placeholders:
+
+ - ~%k~ For the key.
+ - ~%d~ For the description.
+ - ~%v~ For the value. Non-infix suffixes don't have a value.
+
+- ~description~ The description, either a string or a function that is
+ called with no argument and returns a string.
+
+*** Slots of ~transient-infix~
+:PROPERTIES:
+:NONODE: t
+:END:
+
+Some of these slots are only meaningful for some of the subclasses.
+They are defined here anyway to allow sharing certain methods.
+
+- ~argument~ The long argument, e.g. ~--verbose~.
+
+- ~shortarg~ The short argument, e.g. ~-v~.
+
+- ~multi-value~ For options, whether the option can have multiple
+ values. If non-nil, then default to use ~completing-read-multiple~.
+
+- ~allow-empty~ For options, whether the empty string is a valid value.
+
+- ~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.
+
+- ~reader~ The function used to read the value of an infix. Not used
+ for switches. The function takes three arguments, PROMPT,
+ INITIAL-INPUT and HISTORY, and must return a string.
+
+- ~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.
+
+- ~choices~ A list of valid values. How exactly that is used depends on
+ the class of the object.
+
+*** Slots of ~transient-variable~
+:PROPERTIES:
+:NONODE: t
+:END:
+
+- ~variable~ The variable.
+
+*** Slots of ~transient-switches~
+:PROPERTIES:
+:NONODE: t
+:END:
+
+- ~argument-format~ The display format. Must contain ~%s~, one of the
+ ~choices~ is substituted for that. E.g. ~--%s-order~.
+
+- ~argument-regexp~ The regexp used to match any one of the switches.
+ E.g. ~\\(--\\(topo\\|author-date\\|date\\)-order\\)~.
+
+** 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.
+
+- ~if~ Enable if predicate returns non-nil.
+- ~if-not~ Enable if predicate returns nil.
+- ~if-non-nil~ Enable if variable's value is non-nil.
+- ~if-nil~ Enable if variable's value is nil.
+- ~if-mode~ Enable if major-mode matches value.
+- ~if-not-mode~ Enable if major-mode does not match value.
+- ~if-derived~ Enable if major-mode derives from value.
+- ~if-not-derived~ Enable if major-mode does not derive from value.
+
+One more slot is shared between group and suffix classes, ~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. ~level~ controls whether it should be available depending on
+whether the user wants that or not. See [[*Enabling and Disabling
+Suffixes]].
+
+* Related Abstractions and Packages
+** Comparison With Prefix Keys and Prefix Arguments
+
+While transient commands were inspired by regular prefix keys and
+prefix arguments, they are also quite different and much more complex.
+
+The following diagrams illustrate some of the differences.
+
+- ~(c)~ represents a return to the command loop.
+- ~(+)~ represents the user's choice to press one key or another.
+- ~{WORD}~ are possible behaviors.
+- ~{NUMBER}~ is a footnote.
+
+*** Regular Prefix Commands
+:PROPERTIES:
+:NONODE: t
+:END:
+
+See [[info:elisp#Prefix Keys]].
+
+#+BEGIN_EXAMPLE
+ ,--> command1 --> (c)
+ |
+ (c)-(+)-> prefix command or key --+--> command2 --> (c)
+ |
+ `--> command3 --> (c)
+#+END_EXAMPLE
+
+*** Regular Prefix Arguments
+:PROPERTIES:
+:NONODE: t
+:END:
+
+See [[info:elisp#Prefix Command Arguments]].
+
+#+BEGIN_EXAMPLE
+ ,----------------------------------,
+ | |
+ v |
+ (c)-(+)---> prefix argument command --(c)-(+)-> any command --> (c)
+ | ^ |
+ | | |
+ `-- sets or changes --, ,-- maybe used --' |
+ | | |
+ v | |
+ prefix argument state |
+ ^ |
+ | |
+ `-------- discards --------'
+#+END_EXAMPLE
+
+*** Transients
+:PROPERTIES:
+:NONODE: t
+:END:
+
+(∩`-´)⊃━☆゚.*・。゚
+
+This diagram ignores the infix value and external state:
+
+#+BEGIN_EXAMPLE
+ (c)
+ | ,- {stay} ------<-,-<------------<-,-<---,
+ (+) | | | |
+ | | | | |
+ | | ,--> infix1 --| | |
+ | | | | | |
+ | | |--> infix2 --| | |
+ v v | | | |
+ prefix -(c)-(+)-> infix3 --' ^ |
+ | | |
+ |---------------> suffix1 -->--| |
+ | | |
+ |---------------> suffix2 ----{1}------> {exit} --> (c)
+ | |
+ |---------------> suffix3 -------------> {exit} --> (c)
+ | |
+ `--> any command --{2}-> {warn} -->--|
+ | |
+ |--> {noop} -->--|
+ | |
+ |--> {call} -->--'
+ |
+ `------------------> {exit} --> (c)
+#+END_EXAMPLE
+
+This diagram takes the infix value into account to an extend, while
+still ignoring external state:
+
+#+BEGIN_EXAMPLE
+ (c)
+ | ,- {stay} ------<-,-<------------<-,-<---,
+ (+) | | | |
+ | | | | |
+ | | ,--> infix1 --| | |
+ | | | | | | |
+ | | ,--> infix2 --| | |
+ v v | | | | |
+ prefix -(c)-(+)-> infix3 --' | |
+ | | ^ |
+ | | | |
+ |---------------> suffix1 -->--| |
+ | | ^ | |
+ | | | | |
+ |---------------> suffix2 ----{1}------> {exit} --> (c)
+ | | ^ | |
+ | | | | v
+ | | | | |
+ |---------------> suffix3 -------------> {exit} --> (c)
+ | | ^ | |
+ | sets | | v
+ | | maybe | |
+ | | used | |
+ | | | | |
+ | | infix --' | |
+ | `---> value | |
+ | ^ | |
+ | | | |
+ | hides | |
+ | | | |
+ | `--------------------------<---|
+ | | |
+ `--> any command --{2}-> {warn} -->--| |
+ | | |
+ |--> {noop} -->--| |
+ | | |
+ |--> {call} -->--' ^
+ | |
+ `------------------> {exit} --> (c)
+#+END_EXAMPLE
+
+This diagram provides more information about the infix value
+and also takes external state into account.
+
+#+BEGIN_EXAMPLE
+ ,----sets--- "anything"
+ |
+ v
+ ,---------> external
+ | state
+ | | |
+ | initialized | ☉‿⚆
+ sets from |
+ | | maybe
+ | ,----------' used
+ | | |
+ (c) | | v
+ | ,- {stay} --|---<-,-<------|-----<-,-<---,
+ (+) | | | | | | |
+ | | | v | | | |
+ | | ,--> infix1 --| | | |
+ | | | | | | | | |
+ | | | | v | | | |
+ | | ,--> infix2 --| | | |
+ | | | | ^ | | | |
+ v v | | | | | | |
+ prefix -(c)-(+)-> infix3 --' | | |
+ | | ^ | ^ |
+ | | | v | |
+ |---------------> suffix1 -->--| |
+ | | | ^ | | |
+ | | | | v | |
+ |---------------> suffix2 ----{1}------> {exit} --> (c)
+ | | | ^ | | |
+ | | | | | | v
+ | | | | v | |
+ |---------------> suffix3 -------------> {exit} --> (c)
+ | | | ^ | |
+ | sets | | | v
+ | | initalized maybe | |
+ | | from used | |
+ | | | | | |
+ | | `-- infix --' | |
+ | `---> value -----------------------------> persistent
+ | ^ ^ | | across
+ | | | | | invocations -,
+ | hides | | | |
+ | | `----------------------------------------------'
+ | | | |
+ | `--------------------------<---|
+ | | |
+ `--> any command --{2}-> {warn} -->--| |
+ | | |
+ |--> {noop} -->--| |
+ | | |
+ |--> {call} -->--' ^
+ | |
+ `------------------> {exit} --> (c)
+#+END_EXAMPLE
+
+- ~{1}~ Transients can be configured to be exited when a suffix command
+ is invoked. The default is to do so for all suffixes expect for
+ those that are common to all transients and which are used to
+ perform tasks such as providing help and saving the value of the
+ infix arguments for future invocations. The behavior can also be
+ specified for individual suffix commands individually and may even
+ depend on state.
+
+- ~{2}~ Transients can be configured to allow the user to invoke
+ non-suffix commands. The default is to not allow that and instead
+ warn the user.
+
+Despite already being rather complex, even the last diagram leaves out
+many details. Most importantly it implies that the decision whether
+to remain transient is made later than it actually is made (for the
+most part a function on ~pre-command-hook~ is responsible). But such
+implementation details are of little relevance to users and are
+covered elsewhere.
+
+** Comparison With Other Packages
+*** Magit-Popup
+:PROPERTIES:
+:NONODE: t
+:END:
+
+Transient is the successor to Magit-Popup (see [[info:magit-popup]]).
+
+One major difference between these two implementations of the same
+ideas is that while Transient uses transient keymaps and embraces the
+command-loop, Magit-Popup implemented an inferior mechanism that does
+not use transient keymaps and that instead of using the command-loop
+implements a naive alternative based on ~read-char~.
+
+Magit-Popup does not use classes and generic functions and defining a
+new command type is near impossible as it involves adding hard-coded
+special-cases to many functions. Because of that only a single new
+type was added, which was not already part of Magit-Popup's initial
+release.
+
+A lot of things are hard-coded in Magit-Popup. One random example is
+that the key bindings for switches must begin with "-" and those for
+options must begin with "=".
+
+*** Hydra
+:PROPERTIES:
+:NONODE: t
+:END:
+
+Hydra (see https://github.com/abo-abo/hydra) is another package that
+provides features similar to those of Transient.
+
+Both packages use transient keymaps to make a set of commands
+temporarily available and the ~lv~ library to show these commands in the
+echo area. (The author of Hydra is also the author of ~lv~, which is
+maintained in the same repository.)
+
+A Hydra "body" is equivalent to a Transient "prefix" and a Hydra
+"head" is equivalent to a Transient "suffix". Hydra has no equivalent
+of a Transient "infix".
+
+Both hydras and transients can be used as simple command dispatchers.
+Used like this they are similar to regular prefix commands and prefix
+keys, except that the available commands are shown in the echo area.
+
+(Another package that does this is ~which-key~. It does so automatically
+for any incomplete key sequence. The advantage of that approach is
+that no additional work is necessary; the disadvantage is that the
+available commands are not organized semantically.)
+
+Both Hydra and Transient provide features that go beyond simple
+command dispatchers:
+
+- Invoking a command from a hydra does not necessarily exit the hydra.
+ That makes it possible to invoke the same command again, but using a
+ shorter key sequence (i.e. the key that was used to enter the hydra
+ does not have to be pressed again).
+
+ Transient supports that too, but for not this feature is not a focus
+ and the interface is a bit more complicated. A very basic example
+ using the current interface:
+
+ #+BEGIN_SRC emacs-lisp
+ (define-transient-command outline-navigate ()
+ :transient-suffix 'transient--do-stay
+ :transient-non-suffix 'transient--do-warn
+ [("p" "next visible heading" outline-previous-visible-heading)
+ ("n" "next visible heading" outline-next-visible-heading)])
+ #+END_SRC
+
+- Transient support infix arguments; values that are set by infix
+ commands and then consumed by the invoked suffix command(s).
+
+ To my knowledge, Hydra does not support that.
+
+Both packages make it possible to specify how exactly the available
+commands are outlined:
+
+- With Hydra this is often done using an explicit format string, which
+ gives authors a lot of flexibility and makes it possible to do fancy
+ things.
+
+ The downside of this is that it becomes harder for a user to add
+ additional commands to an existing hydra and to change key bindings.
+
+- Transient allows the author of a transient to organize the commands
+ into groups and the use of generic functions allows authors of
+ transients to control exactly how a certain command type is
+ displayed.
+
+ However while Transient support giving sections a heading it does
+ not currently support giving the displayed information more
+ structure by, for example, using box-drawing characters.
+
+ That could be implemented by defining a new group class, which lets
+ the author specify a format string. It should be possible to
+ implement that without modifying any existing code, but it does not
+ currently exist.
+
+* Keystroke Index
+:PROPERTIES:
+:APPENDIX: t
+:INDEX: ky
+:COOKIE_DATA: recursive
+:END:
+* Command Index
+:PROPERTIES:
+:APPENDIX: t
+:INDEX: cp
+:END:
+* Function Index
+:PROPERTIES:
+:APPENDIX: t
+:INDEX: fn
+:END:
+* Variable Index
+:PROPERTIES:
+:APPENDIX: t
+:INDEX: vr
+:END:
+
+* _ Copying
+:PROPERTIES:
+:COPYING: t
+:END:
+
+#+BEGIN_QUOTE
+Copyright (C) 2018-2019 Jonas Bernoulli <jonas@bernoul.li>
+
+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_QUOTE
+
+* _ :ignore:
+
+# LocalWords: ARGLIST ARGS DOCSTRING ELEMENTs EVAL GROUPs Infixes
+# LocalWords: Infixes KEYWORDs LOC LocalWords MERCHANTABILITY Magit
+# LocalWords: Magit's Magit-Popup Makefile OBJ OBJ's Pre arglist
+# LocalWords: args boolean booleans customizable docstring eval
+# LocalWords: featurep infixes init keymap keymaps loc magit manpage
+# LocalWords: minibuffer ness nilly noop plist pre pre-command prev
+# LocalWords: rebase src subclass subclasses subprocess superclass
+# LocalWords: texinfo+ utils
+
+# IMPORTANT: Also update ORG_ARGS and ORG_EVAL in the Makefile.
+# Local Variables:
+# eval: (require 'magit-utils nil t)
+# eval: (require 'org-man nil t)
+# eval: (require 'ox-extra nil t)
+# eval: (require 'ox-texinfo+ nil t)
+# eval: (and (featurep 'ox-extra) (ox-extras-activate '(ignore-headlines)))
+# indent-tabs-mode: nil
+# org-src-preserve-indentation: nil
+# End: