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:
- 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.
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 transient--do-VERB, and the symbol 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?" t means that the transient stays active, while 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 t means that when you exit the inner prefix, then the outer prefix becomes active again, while nil means that all outer prefixes are exited at once.
The behavior for non-suffixes can be set for a particular prefix, by the prefix’s
transient-non-suffixslot to a boolean, a suitable pre-command function, or a shorthand for such a function. See Pre-commands for Non-Suffixes.The common behavior for the suffixes of a particular prefix can be set using the prefix’s
transient-suffixesslot.The value specified in this slot does 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.
The behavior of an individual suffix can be changed using its
transientslot. 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
transient-define-suffixand/or in the definition of the prefix. If set in both places, then the latter takes precedence, as usual.
The available pre-command functions are documented in the following sub-sections. 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.
For completeness sake, some notes about complications:
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 prefix’stransient-suffixslot, but not the suffix’stransientslot.While a sub-prefix is active we nearly always want 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
transient-suffixobjects thetransientslot is unbound. We can ignore that for the most part becauseniland 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, whilenilmeans “do exit permanently”, which requires that slot to be explicitly set to that value.
Pre-commands for Infixes
The default for infixes is 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 transient-suffix slot is t. In extremely rare cases, one might want to use something else, which can be done by setting the infix’s transient slot directly.
Function: transient--do-stay
Call the command without exporting variables and stay transient.
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 transient slot to a boolean (which is highly recommended), or to one of the following pre-commands.
Function: transient--do-exit
Call the command after exporting variables and exit the transient.
Function: transient--do-return
Call the command after exporting variables and return to the parent prefix. If there is no parent prefix, then call transient--do-exit.
Function: transient--do-call
Call the command after exporting variables and stay transient.
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 transient slot for the sub-prefix itself.
Function: 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 transient--do-stack is that it changes the value of the transient-suffix slot to t.
If there is no parent transient, then only call this command and skip the second step.
Function: transient--do-stack
Call the transient prefix command, stacking the active transient. Push the active transient to the transient stack.
Unless transient--do-recurse is explicitly used, this pre-command is automatically used for suffixes that are prefixes themselves, i.e., for sub-prefixes.
Function: transient--do-replace
Call the transient prefix command, replacing the active transient. Do not push the active transient to the transient stack.
Unless transient--do-recurse is explicitly used, this pre-command is automatically used for suffixes that are prefixes themselves, i.e., for sub-prefixes.
Function: transient--do-suspend
Suspend the active transient, saving the transient stack.
This is used by the command transient-suspend and optionally also by “external events” such as handle-switch-frame. Such bindings should be added to transient-predicate-map.
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 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 t, then non-suffixes can be invoked, when it is nil (the default) then they cannot be invoked.
The only other recommended value is leave. If that is used, then non-suffixes can be invoked, but if one is invoked, then that exits the transient.
Function: transient--do-warn
Call transient-undefined and stay transient.
Function: transient--do-stay
Call the command without exporting variables and stay transient.
Function: transient--do-leave
Call the command without exporting variables and exit the transient.
Special Pre-Commands
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.