2649 lines
116 KiB
Plaintext
2649 lines
116 KiB
Plaintext
|
This is transient.info, produced by makeinfo version 6.7 from
|
|||
|
transient.texi.
|
|||
|
|
|||
|
Copyright (C) 2018-2022 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.
|
|||
|
|
|||
|
INFO-DIR-SECTION Emacs
|
|||
|
START-INFO-DIR-ENTRY
|
|||
|
* Transient: (transient). Transient Commands.
|
|||
|
END-INFO-DIR-ENTRY
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Top, Next: Introduction, Up: (dir)
|
|||
|
|
|||
|
Transient User and Developer Manual
|
|||
|
***********************************
|
|||
|
|
|||
|
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, 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 a popup buffer
|
|||
|
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.
|
|||
|
|
|||
|
This manual is for Transient version 0.3.7-git.
|
|||
|
|
|||
|
Copyright (C) 2018-2022 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.
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* Introduction::
|
|||
|
* Usage::
|
|||
|
* Modifying Existing Transients::
|
|||
|
* Defining New Commands::
|
|||
|
* Classes and Methods::
|
|||
|
* Related Abstractions and Packages::
|
|||
|
* FAQ::
|
|||
|
* Keystroke Index::
|
|||
|
* Command and Function Index::
|
|||
|
* Variable Index::
|
|||
|
* Concept Index::
|
|||
|
|
|||
|
— 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
|
|||
|
|
|||
|
* 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::
|
|||
|
|
|||
|
|
|||
|
Related Abstractions and Packages
|
|||
|
|
|||
|
* Comparison With Prefix Keys and Prefix Arguments::
|
|||
|
* Comparison With Other Packages::
|
|||
|
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Introduction, Next: Usage, Prev: Top, Up: Top
|
|||
|
|
|||
|
1 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".
|
|||
|
|
|||
|
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.
|
|||
|
|
|||
|
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 ‘pre-command-hook’ and ‘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 ‘transient-current-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 popup buffer while a transient is active
|
|||
|
looks a bit like this:
|
|||
|
|
|||
|
,-----------------------------------------
|
|||
|
|Arguments
|
|||
|
| -f Force (--force)
|
|||
|
| -a Annotate (--annotate)
|
|||
|
|
|
|||
|
|Create
|
|||
|
| t tag
|
|||
|
| r release
|
|||
|
`-----------------------------------------
|
|||
|
|
|||
|
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.
|
|||
|
|
|||
|
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. 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’ (on ‘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 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 *note
|
|||
|
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 *note 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 *note 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).
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Usage, Next: Modifying Existing Transients, Prev: Introduction, Up: Top
|
|||
|
|
|||
|
2 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::
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Invoking Transients, Next: Aborting and Resuming Transients, Up: Usage
|
|||
|
|
|||
|
2.1 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 *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.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Aborting and Resuming Transients, Next: Common Suffix Commands, Prev: Invoking Transients, Up: Usage
|
|||
|
|
|||
|
2.2 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 popup buffer 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’ or ‘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’.
|
|||
|
|
|||
|
‘C-g’ (‘transient-quit-seq’)
|
|||
|
‘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, it returns to the previous transient, if any.
|
|||
|
|
|||
|
Transient’s predecessor bound ‘q’ instead of ‘C-g’ to the quit
|
|||
|
command. To learn how to get that binding back see
|
|||
|
‘transient-bind-q-to-quit’’s doc string.
|
|||
|
|
|||
|
‘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.
|
|||
|
|
|||
|
‘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.
|
|||
|
|
|||
|
‘M-x transient-resume’
|
|||
|
This command resumes the previously suspended stack of transients,
|
|||
|
if any.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Common Suffix Commands, Next: Saving Values, Prev: Aborting and Resuming Transients, Up: Usage
|
|||
|
|
|||
|
2.3 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 ‘C-x
|
|||
|
<key>’. After ‘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.
|
|||
|
|
|||
|
‘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
|
|||
|
commands. 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 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 *note FAQ:: for more information.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Saving Values, Next: Using History, Prev: Common Suffix Commands, Up: Usage
|
|||
|
|
|||
|
2.4 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. (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 *note Using History::).
|
|||
|
|
|||
|
‘C-x s’ (‘transient-set’)
|
|||
|
This command saves the value of the active transient for this Emacs
|
|||
|
session.
|
|||
|
|
|||
|
‘C-x C-s’ (‘transient-save’)
|
|||
|
Save the value of the active transient persistently across Emacs
|
|||
|
sessions.
|
|||
|
|
|||
|
‘C-x C-k’ (‘transient-save’)
|
|||
|
Clear the set and saved value of the active transient.
|
|||
|
|
|||
|
-- User Option: transient-values-file
|
|||
|
This option names the file that is used to persist the values of
|
|||
|
transients between Emacs sessions.
|
|||
|
|
|||
|
---------- Footnotes ----------
|
|||
|
|
|||
|
(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.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Using History, Next: Getting Help for Suffix Commands, Prev: Saving Values, Up: Usage
|
|||
|
|
|||
|
2.5 Using 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.
|
|||
|
|
|||
|
‘C-M-p’ (‘transient-history-prev’)
|
|||
|
‘C-x p’
|
|||
|
This command switches to the previous value used for the active
|
|||
|
transient.
|
|||
|
|
|||
|
‘C-M-n’ (‘transient-history-next’)
|
|||
|
‘C-x n’
|
|||
|
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, 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
|
|||
|
*note Suffix Slots::).
|
|||
|
|
|||
|
Both kinds of history are saved to a file when Emacs is exited.
|
|||
|
|
|||
|
-- User Option: transient-history-file
|
|||
|
This option names the file that 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 is saved in ‘transient-history-file’.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Getting Help for Suffix Commands, Next: Enabling and Disabling Suffixes, Prev: Using History, Up: Usage
|
|||
|
|
|||
|
2.6 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.
|
|||
|
|
|||
|
‘C-h’ (‘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 ‘C-h’ a
|
|||
|
second time shows information about the _prefix_ command.
|
|||
|
|
|||
|
After typing a 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 command’s doc string, for
|
|||
|
non-infix suffixes this is usually appropriate.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Enabling and Disabling Suffixes, Next: Other Commands, Prev: Getting Help for Suffix Commands, Up: Usage
|
|||
|
|
|||
|
2.7 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 needed 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 transients 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.
|
|||
|
|
|||
|
-- 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 option names the file that is used to persist the levels of
|
|||
|
transients and their suffixes between Emacs sessions.
|
|||
|
|
|||
|
‘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 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 ‘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.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Other Commands, Next: Configuration, Prev: Enabling and Disabling Suffixes, Up: Usage
|
|||
|
|
|||
|
2.8 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 ‘scroll-up-command’ and
|
|||
|
‘scroll-down-command’ in other buffers.
|
|||
|
|
|||
|
-- Command: transient-scroll-up arg
|
|||
|
This command scrolls text of transient popup window upward ARG
|
|||
|
lines. If ARG is ‘nil’, then it scrolls near full screen. This is
|
|||
|
a wrapper around ‘scroll-up-command’ (which see).
|
|||
|
|
|||
|
-- Command: transient-scroll-down arg
|
|||
|
This command scrolls text of transient popup window down ARG lines.
|
|||
|
If ARG is ‘nil’, then it scrolls near full screen. This is a
|
|||
|
wrapper around ‘scroll-down-command’ (which see).
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Configuration, Prev: Other Commands, Up: Usage
|
|||
|
|
|||
|
2.9 Configuration
|
|||
|
=================
|
|||
|
|
|||
|
More options are described in *note Common Suffix Commands::, in *note
|
|||
|
Saving Values::, in *note Using History:: and in *note Enabling and
|
|||
|
Disabling Suffixes::.
|
|||
|
|
|||
|
Essential Options
|
|||
|
-----------------
|
|||
|
|
|||
|
Also see *note Common Suffix Commands::.
|
|||
|
|
|||
|
-- User Option: transient-show-popup
|
|||
|
This option controls whether the current transient’s infix and
|
|||
|
suffix commands are shown in the popup buffer.
|
|||
|
|
|||
|
• If ‘t’ (the default) then the popup buffer is shown as soon as
|
|||
|
a transient prefix command is invoked.
|
|||
|
|
|||
|
• If ‘nil’, then the popup buffer is not shown unless the user
|
|||
|
explicitly requests it, by pressing an incomplete prefix key
|
|||
|
sequence.
|
|||
|
|
|||
|
• 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).
|
|||
|
|
|||
|
-- User Option: 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-‘nil’, then the following features are available:
|
|||
|
|
|||
|
• ‘<up>’ moves the cursor to the previous suffix. ‘<down>’
|
|||
|
moves the cursor to the next suffix. ‘RET’ invokes the suffix
|
|||
|
the cursor is on.
|
|||
|
• ‘<mouse-1>’ invokes the clicked on suffix.
|
|||
|
• ‘C-s’ and ‘C-r’ start isearch in the popup buffer.
|
|||
|
|
|||
|
-- User Option: 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 ‘(display-buffer BUFFER transient-display-buffer-action)’.
|
|||
|
|
|||
|
The value of this option has the form ‘(FUNCTION . ALIST)’, where
|
|||
|
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 ALIST. See *note (elisp)Choosing Window::, for
|
|||
|
details.
|
|||
|
|
|||
|
The default is:
|
|||
|
|
|||
|
(display-buffer-in-side-window
|
|||
|
(side . bottom)
|
|||
|
(inhibit-same-window . t)
|
|||
|
(window-parameters (no-other-window . t)))
|
|||
|
|
|||
|
This displays the window at the bottom of the selected frame.
|
|||
|
Another useful FUNCTION is ‘display-buffer-below-selected’, which
|
|||
|
is what ‘magit-popup’ used by default. For more alternatives see
|
|||
|
*note (elisp)Display Action Functions:: and *note (elisp)Buffer
|
|||
|
Display Action Alists::.
|
|||
|
|
|||
|
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 ‘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 ‘transient-mode-line-format’.
|
|||
|
|
|||
|
Accessibility Options
|
|||
|
---------------------
|
|||
|
|
|||
|
-- User Option: 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.
|
|||
|
|
|||
|
Auxiliary Options
|
|||
|
-----------------
|
|||
|
|
|||
|
-- User Option: transient-mode-line-format
|
|||
|
This option controls whether the transient popup buffer has a
|
|||
|
mode-line, separator line, or neither.
|
|||
|
|
|||
|
If ‘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 ‘line’ (the default), then the buffer also has no mode-line, but
|
|||
|
a thin line is drawn instead, using the background color of the
|
|||
|
face ‘transient-separator’. Text-mode frames cannot display thin
|
|||
|
lines, and therefore fall back to treating ‘line’ like ‘nil’.
|
|||
|
|
|||
|
Otherwise this can be any mode-line format. See *note (elisp)Mode
|
|||
|
Line Format::, for details.
|
|||
|
|
|||
|
-- User Option: transient-semantic-coloring
|
|||
|
This option controls whether prefixes and suffixes are colored in a
|
|||
|
Hydra-like fashion.
|
|||
|
|
|||
|
If non-‘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 ‘transient-mode-line-format’ is ‘line’.
|
|||
|
|
|||
|
For more information about how Hydra uses colors see
|
|||
|
<https://github.com/abo-abo/hydra#color> and
|
|||
|
<https://oremacs.com/2015/02/19/hydra-colors-reloaded>.
|
|||
|
|
|||
|
-- 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’, the key binding for an infix
|
|||
|
argument is 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. If 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 the 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.
|
|||
|
|
|||
|
(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))))
|
|||
|
|
|||
|
-- User Option: 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 ‘nil’, there is no initial input and
|
|||
|
the first element has to be accessed the same way as the older
|
|||
|
elements.
|
|||
|
|
|||
|
-- User Option: transient-hide-during-minibuffer-read
|
|||
|
This option controls whether the transient buffer is hidden while
|
|||
|
user input is being read in the minibuffer.
|
|||
|
|
|||
|
-- User Option: transient-align-variable-pitch
|
|||
|
This option controls whether columns are aligned pixel-wise in the
|
|||
|
popup buffer.
|
|||
|
|
|||
|
If this is non-‘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 ‘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 ‘default’ face.
|
|||
|
|
|||
|
-- User Option: 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
|
|||
|
‘default’ face, you might still want to use a monospaced font in
|
|||
|
transient’s popup buffer. Setting this option to ‘t’ causes
|
|||
|
‘default’ to be remapped to ‘fixed-pitch’ in that buffer.
|
|||
|
|
|||
|
Developer Options
|
|||
|
-----------------
|
|||
|
|
|||
|
These options are mainly intended for developers.
|
|||
|
|
|||
|
-- 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, 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.
|
|||
|
|
|||
|
-- User Option: transient-highlight-higher-levels
|
|||
|
This option controls whether suffixes that would not be available
|
|||
|
by default are highlighted.
|
|||
|
|
|||
|
When non-‘nil’ then the descriptions of suffixes are highlighted if
|
|||
|
their level is above 4, the default of ‘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.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Modifying Existing Transients, Next: Defining New Commands, Prev: Usage, Up: Top
|
|||
|
|
|||
|
3 Modifying Existing Transients
|
|||
|
*******************************
|
|||
|
|
|||
|
To an extent, transients can be customized interactively, see *note
|
|||
|
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 ‘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 *note Suffix Specifications::.
|
|||
|
|
|||
|
SUFFIX may also be a group in the same form as expected by
|
|||
|
‘transient-define-prefix’. See *note Group Specifications::.
|
|||
|
|
|||
|
• LOC is a command, a key vector, a key description (a string as
|
|||
|
returned by ‘key-description’), or a list specifying coordinates
|
|||
|
(the last element may also be a command or key). For example ‘(1 0
|
|||
|
-1)’ identifies the last suffix (‘-1’) of the first subgroup (‘0’)
|
|||
|
of the second group (‘1’).
|
|||
|
|
|||
|
If LOC is a list of coordinates, then it can be used to identify a
|
|||
|
group, not just an individual suffix command.
|
|||
|
|
|||
|
The function ‘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.
|
|||
|
|
|||
|
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 or group SUFFIX into PREFIX before
|
|||
|
LOC.
|
|||
|
|
|||
|
-- Function: transient-append-suffix prefix loc suffix
|
|||
|
This function inserts suffix or group SUFFIX into PREFIX after LOC.
|
|||
|
|
|||
|
-- Function: transient-replace-suffix prefix loc suffix
|
|||
|
This function replaces the suffix or group at LOC in PREFIX with
|
|||
|
suffix or group SUFFIX.
|
|||
|
|
|||
|
-- Function: transient-remove-suffix prefix loc
|
|||
|
This function removes the suffix or group at LOC in PREFIX.
|
|||
|
|
|||
|
-- Function: transient-get-suffix prefix loc
|
|||
|
This function returns the suffix or group 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 or group 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 from loading. Among these
|
|||
|
functions only ‘transient-get-suffix’ and ‘transient-suffix-put’ may
|
|||
|
signal an error.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Defining New Commands, Next: Classes and Methods, Prev: Modifying Existing Transients, Up: Top
|
|||
|
|
|||
|
4 Defining New Commands
|
|||
|
***********************
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* Defining Transients::
|
|||
|
* Binding Suffix and Infix Commands::
|
|||
|
* Defining Suffix and Infix Commands::
|
|||
|
* Using Infix Arguments::
|
|||
|
* Transient State::
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Defining Transients, Next: Binding Suffix and Infix Commands, Up: Defining New Commands
|
|||
|
|
|||
|
4.1 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*
|
|||
|
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.
|
|||
|
|
|||
|
-- Macro: transient-define-prefix 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 popup buffer. At least one
|
|||
|
GROUP has to be specified. See *note Binding Suffix and Infix
|
|||
|
Commands::.
|
|||
|
|
|||
|
The BODY is optional. If it is omitted, then ARGLIST is ignored
|
|||
|
and the function definition becomes:
|
|||
|
|
|||
|
(lambda ()
|
|||
|
(interactive)
|
|||
|
(transient-setup 'NAME))
|
|||
|
|
|||
|
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:
|
|||
|
|
|||
|
(transient-setup 'NAME nil nil :scope SCOPE)
|
|||
|
|
|||
|
For example, the scope of the ‘magit-branch-configure’ transient is
|
|||
|
the branch whose variables are being configured.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Binding Suffix and Infix Commands, Next: Defining Suffix and Infix Commands, Prev: Defining Transients, Up: Defining New Commands
|
|||
|
|
|||
|
4.2 Binding Suffix and Infix Commands
|
|||
|
=====================================
|
|||
|
|
|||
|
The macro ‘transient-define-prefix’ is used to define a transient. This
|
|||
|
defines the actual transient prefix command (see *note 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 *note Modifying
|
|||
|
Existing Transients::). These functions take a "suffix specification"
|
|||
|
as one of their arguments, which has the same form as the specifications
|
|||
|
used in ‘transient-define-prefix’.
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* Group Specifications::
|
|||
|
* Suffix Specifications::
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Group Specifications, Next: Suffix Specifications, Up: Binding Suffix and Infix Commands
|
|||
|
|
|||
|
4.2.1 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 *note Group Classes::.
|
|||
|
|
|||
|
Groups are specified in the call to ‘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:
|
|||
|
|
|||
|
[{LEVEL} {DESCRIPTION} {KEYWORD VALUE}... ELEMENT...]
|
|||
|
|
|||
|
The LEVEL is optional and defaults to 4. See *note 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 *note Predicate Slots::.
|
|||
|
|
|||
|
• The value of ‘:hide’, if non-‘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:
|
|||
|
|
|||
|
(lambda ()
|
|||
|
(eq (car transient--redisplay-key)
|
|||
|
?\C-c)) ; the prefix key shared by all bindings
|
|||
|
|
|||
|
• The value of ‘:setup-children’, if non-‘nil’, is a function that
|
|||
|
takes two arguments the group object itself and a list of children.
|
|||
|
The children are given as a (potentially empty) list consisting of
|
|||
|
either group or suffix specifications. It can make arbitrary
|
|||
|
changes to the children including constructing new children from
|
|||
|
scratch. Also see ‘transient-setup-children’.
|
|||
|
|
|||
|
• The boolean ‘:pad-keys’ argument controls whether keys of all
|
|||
|
suffixes contained in a group are right padded, effectively
|
|||
|
aligning the descriptions.
|
|||
|
|
|||
|
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
|
|||
|
principle 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.
|
|||
|
|
|||
|
Variables are supported inside group specifications. For example in
|
|||
|
place of a direct subgroup specification, a variable can be used whose
|
|||
|
value is a vector that qualifies as a group specification. Likewise, a
|
|||
|
variable can be used where a suffix specification is expected. Lists of
|
|||
|
group or suffix specifications are also supported. Indirect
|
|||
|
specifications are resolved when the transient prefix is being defined.
|
|||
|
|
|||
|
The form of suffix specifications is documented in the next node.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Suffix Specifications, Prev: Group Specifications, Up: Binding Suffix and Infix Commands
|
|||
|
|
|||
|
4.2.2 Suffix Specifications
|
|||
|
---------------------------
|
|||
|
|
|||
|
A transient’s suffix and infix commands are bound when the transient
|
|||
|
prefix command is defined using ‘transient-define-prefix’, see *note
|
|||
|
Defining Transients::. The commands are organized into groups, see
|
|||
|
*note 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 *note 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:
|
|||
|
|
|||
|
([LEVEL] [KEY] [DESCRIPTION] COMMAND|ARGUMENT [KEYWORD VALUE]...)
|
|||
|
|
|||
|
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 object’s values just for the binding inside this
|
|||
|
transient.
|
|||
|
|
|||
|
• LEVEL is the suffix level, an integer between 1 and 7. See *note
|
|||
|
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
|
|||
|
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
|
|||
|
‘: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 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 ‘transient-define-suffix’ or
|
|||
|
‘transient-define-infix’ were used to define it).
|
|||
|
|
|||
|
Anonymous, dynamically defined suffix commands are also support.
|
|||
|
See information about the ‘:setup-children’ function in *note Group
|
|||
|
Specifications::.
|
|||
|
|
|||
|
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.
|
|||
|
|
|||
|
As a special case, if you want to add a command that might be
|
|||
|
neither defined nor autoloaded, you can use a workaround like:
|
|||
|
|
|||
|
(transient-insert-suffix 'some-prefix "k"
|
|||
|
'("!" "Ceci n'est pas une commande" no-command
|
|||
|
:if (lambda () (featurep 'no-library))))
|
|||
|
|
|||
|
Instead of ‘featurep’ you could also use ‘require’ with a non-‘nil’
|
|||
|
value for NOERROR.
|
|||
|
|
|||
|
• 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 ‘:shortarg’) and the second as the long
|
|||
|
argument (which can also be specified using ‘:argument’).
|
|||
|
|
|||
|
Only the long argument is displayed in the popup buffer. 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 *note Suffix
|
|||
|
Slots::.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Defining Suffix and Infix Commands, Next: Using Infix Arguments, Prev: Binding Suffix and Infix Commands, Up: Defining New Commands
|
|||
|
|
|||
|
4.3 Defining Suffix and Infix Commands
|
|||
|
======================================
|
|||
|
|
|||
|
Note that an infix is a special kind of suffix. Depending on context
|
|||
|
"suffixes" means "suffixes (including infixes)" or "non-infix suffixes".
|
|||
|
|
|||
|
-- Macro: transient-define-suffix 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. The infix arguments are usually accessed by using
|
|||
|
‘transient-args’ inside ‘interactive’.
|
|||
|
|
|||
|
-- Macro: transient-define-infix 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 definition is always:
|
|||
|
|
|||
|
(lambda ()
|
|||
|
(interactive)
|
|||
|
(let ((obj (transient-suffix-object)))
|
|||
|
(transient-infix-set obj (transient-infix-read obj)))
|
|||
|
(transient--show))
|
|||
|
|
|||
|
‘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-define-suffix’ to define the infix command
|
|||
|
and use ‘t’ as the value of the ‘:transient’ keyword.
|
|||
|
|
|||
|
-- Macro: transient-define-argument name arglist [docstring] [keyword
|
|||
|
value]...
|
|||
|
This macro defines NAME as a transient infix command.
|
|||
|
|
|||
|
This is an alias for ‘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
|
|||
|
‘transient-define-infix’ instead.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Using Infix Arguments, Next: Transient State, Prev: Defining Suffix and Infix Commands, Up: Defining New Commands
|
|||
|
|
|||
|
4.4 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 ‘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 prefix
|
|||
|
This function returns the value of the transient prefix command
|
|||
|
PREFIX.
|
|||
|
|
|||
|
If the current command was invoked from the transient prefix
|
|||
|
command PREFIX, then it returns the active infix arguments. If the
|
|||
|
current command was not invoked from PREFIX, then it returns the
|
|||
|
set, saved or default value for PREFIX.
|
|||
|
|
|||
|
-- Function: transient-arg-value arg args
|
|||
|
This function return the value of ARG as it appears in 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 nil if the option does not appear in ARGS.
|
|||
|
|
|||
|
-- Function: transient-suffixes prefix
|
|||
|
This function returns the suffixes of the transient prefix command
|
|||
|
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 PREFIX.
|
|||
|
|
|||
|
-- Variable: 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 ‘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: transient-current-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: transient-current-command
|
|||
|
The transient from which this suffix command was invoked. The
|
|||
|
returned value is a symbol, the transient prefix command.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Transient State, Prev: Using Infix Arguments, Up: Defining New Commands
|
|||
|
|
|||
|
4.5 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.
|
|||
|
|
|||
|
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 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 ‘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
|
|||
|
------------------------
|
|||
|
|
|||
|
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
|
|||
|
-------------------------
|
|||
|
|
|||
|
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-return
|
|||
|
Call the command after exporting variables and return to 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 suitable for sub-prefixes. Only the
|
|||
|
first should ever explicitly be set as the value of the ‘transient’
|
|||
|
slot.
|
|||
|
|
|||
|
-- 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-replace’ is that it changes the
|
|||
|
value of the ‘transient-suffix’ slot to ‘transient--do-return’.
|
|||
|
|
|||
|
If there is no parent transient, then only call this command and
|
|||
|
skip the second step.
|
|||
|
|
|||
|
-- Function: transient--do-replace
|
|||
|
Call the transient prefix command, replacing the active transient.
|
|||
|
|
|||
|
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
|
|||
|
-----------------------------
|
|||
|
|
|||
|
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
|
|||
|
--------------------
|
|||
|
|
|||
|
-- 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’.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Classes and Methods, Next: Related Abstractions and Packages, Prev: Defining New Commands, Up: Top
|
|||
|
|
|||
|
5 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 *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.
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* Group Classes::
|
|||
|
* Group Methods::
|
|||
|
* Prefix Classes::
|
|||
|
* Suffix Classes::
|
|||
|
* Suffix Methods::
|
|||
|
* Prefix Slots::
|
|||
|
* Suffix Slots::
|
|||
|
* Predicate Slots::
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Group Classes, Next: Group Methods, Up: Classes and Methods
|
|||
|
|
|||
|
5.1 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 ‘transient-define-prefix’.
|
|||
|
|
|||
|
• 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.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Group Methods, Next: Prefix Classes, Prev: Group Classes, Up: Classes and Methods
|
|||
|
|
|||
|
5.2 Group Methods
|
|||
|
=================
|
|||
|
|
|||
|
-- Function: 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 ‘setup-children’ slot of GROUP is non-‘nil’,
|
|||
|
then it calls that function with 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.
|
|||
|
|
|||
|
-- 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
|
|||
|
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 ‘transient--source-buffer’ the current buffer.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Prefix Classes, Next: Suffix Classes, Prev: Group Methods, Up: Classes and Methods
|
|||
|
|
|||
|
5.3 Prefix Classes
|
|||
|
==================
|
|||
|
|
|||
|
Currently the ‘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.
|
|||
|
|
|||
|
-- 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.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Suffix Classes, Next: Suffix Methods, Prev: Prefix Classes, Up: Classes and Methods
|
|||
|
|
|||
|
5.4 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 *note Group Classes::).
|
|||
|
|
|||
|
• All infix classes derive 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 *note
|
|||
|
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 *note Defining Suffix and Infix Commands::).
|
|||
|
|
|||
|
• Classes used for infix commands that represent arguments should be
|
|||
|
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
|
|||
|
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.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Suffix Methods, Next: Prefix Slots, Prev: Suffix Classes, Up: Classes and Methods
|
|||
|
|
|||
|
5.5 Suffix Methods
|
|||
|
==================
|
|||
|
|
|||
|
To get information about the methods implementing these generic
|
|||
|
functions use ‘describe-function’.
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* Suffix Value Methods::
|
|||
|
* Suffix Format Methods::
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Suffix Value Methods, Next: Suffix Format Methods, Up: Suffix Methods
|
|||
|
|
|||
|
5.5.1 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.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Suffix Format Methods, Prev: Suffix Value Methods, Up: Suffix Methods
|
|||
|
|
|||
|
5.5.2 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.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Prefix Slots, Next: Suffix Slots, Prev: Suffix Methods, Up: Classes and Methods
|
|||
|
|
|||
|
5.6 Prefix Slots
|
|||
|
================
|
|||
|
|
|||
|
• ‘show-help’, ‘man-page’ or ‘info-manual’ can be used to specify the
|
|||
|
documentation for the prefix and its suffixes. The command
|
|||
|
‘transient-help’ uses the method ‘transient-show-help’ (which see)
|
|||
|
to lookup and use these values.
|
|||
|
|
|||
|
• ‘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.
|
|||
|
|
|||
|
• ‘transient-suffix’ and ‘transient-non-suffix’ play a part when
|
|||
|
determining whether the currently active transient prefix command
|
|||
|
remains active/transient when a suffix or abitrary non-suffix
|
|||
|
command is invoked. See *note Transient State::.
|
|||
|
|
|||
|
• ‘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.
|
|||
|
|
|||
|
• ‘scope’ For some transients it might be necessary to have a sort of
|
|||
|
secondary value, called a "scope". See ‘transient-define-prefix’.
|
|||
|
|
|||
|
Internal Prefix Slots
|
|||
|
---------------------
|
|||
|
|
|||
|
These slots are mostly intended for internal use. They should not be
|
|||
|
set in calls to ‘transient-define-prefix’.
|
|||
|
|
|||
|
• ‘prototype’ When a transient prefix command is invoked, then a
|
|||
|
clone of that object is stored in the global variable
|
|||
|
‘transient--prefix’ and the prototype is stored in the clone’s
|
|||
|
‘prototype’ slot.
|
|||
|
|
|||
|
• ‘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 ‘transient--prefix’ property
|
|||
|
of the same symbol.
|
|||
|
|
|||
|
• ‘level’ The level of the prefix commands. The suffix commands
|
|||
|
whose layer is equal or lower are displayed. See *note Enabling
|
|||
|
and Disabling Suffixes::.
|
|||
|
|
|||
|
• ‘value’ The likely outdated value of the prefix. Instead of
|
|||
|
accessing this slot directly you should use the function
|
|||
|
‘transient-get-value’, which is guaranteed to return the up-to-date
|
|||
|
value.
|
|||
|
|
|||
|
• ‘history’ and ‘history-pos’ are used to keep track of historic
|
|||
|
values. Unless you implement your own ‘transient-infix-read’
|
|||
|
method you should not have to deal with these slots.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Suffix Slots, Next: Predicate Slots, Prev: Prefix Slots, Up: Classes and Methods
|
|||
|
|
|||
|
5.7 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 *note Predicate Slots::.
|
|||
|
|
|||
|
Also see *note Suffix Classes::.
|
|||
|
|
|||
|
Slots of ‘transient-suffix’
|
|||
|
---------------------------
|
|||
|
|
|||
|
• ‘key’ The key, a key vector or a key description string.
|
|||
|
|
|||
|
• ‘command’ The command, a symbol.
|
|||
|
|
|||
|
• ‘transient’ Whether to stay transient. See *note Transient
|
|||
|
State::.
|
|||
|
|
|||
|
• ‘format’ The format used to display the suffix in the popup buffer.
|
|||
|
It must contain the following %-placeholders:
|
|||
|
|
|||
|
• ‘%k’ For the key.
|
|||
|
• ‘%d’ For the description.
|
|||
|
• ‘%v’ For the infix 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.
|
|||
|
|
|||
|
• ‘show-help’ A function used to display help for the suffix. If
|
|||
|
unspecified, the prefix controls how hlep is displayed for its
|
|||
|
suffixes.
|
|||
|
|
|||
|
Slots of ‘transient-infix’
|
|||
|
--------------------------
|
|||
|
|
|||
|
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’.
|
|||
|
|
|||
|
• ‘value’ The value. Should not be accessed directly.
|
|||
|
|
|||
|
• ‘init-value’ Function that is responsable 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 ‘transient-init-value’ method is called instead.
|
|||
|
|
|||
|
• ‘unsavable’ Whether the value of the suffix is not saved as part of
|
|||
|
the prefixes.
|
|||
|
|
|||
|
• ‘multi-value’ For options, whether the option can have multiple
|
|||
|
values. If this is non-‘nil’, then the values are read using
|
|||
|
‘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-‘nil’ values are:
|
|||
|
|
|||
|
• Use ‘rest’ for an option that can have multiple values. This
|
|||
|
is useful e.g., for an ‘--’ argument that indicates that all
|
|||
|
remaining arguments are files (such as ‘git log -- file1
|
|||
|
file2’).
|
|||
|
|
|||
|
In the list returned by ‘transient-args’ such an option and
|
|||
|
its values are represented by a single list of the form
|
|||
|
‘(ARGUMENT . VALUES)’.
|
|||
|
|
|||
|
• Use ‘repeat’ for an option that can be specified multiple
|
|||
|
times.
|
|||
|
|
|||
|
In the list returned by ‘transient-args’ each instance of the
|
|||
|
option and its value appears separately in the usual from, for
|
|||
|
example: ‘("--another-argument" "--option=first"
|
|||
|
"--option=second")’.
|
|||
|
|
|||
|
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
|
|||
|
‘transient-args’, e.g., ‘("--other" "--o=1" "--o=2" ("--" "f1"
|
|||
|
"f2"))’.
|
|||
|
|
|||
|
• ‘always-read’ For options, whether to read a value on every
|
|||
|
invocation. If this is nil, then options that have a value are
|
|||
|
simply unset and have to be invoked a second time to set a new
|
|||
|
value.
|
|||
|
|
|||
|
• ‘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’
|
|||
|
-----------------------------
|
|||
|
|
|||
|
• ‘variable’ The variable.
|
|||
|
|
|||
|
Slots of ‘transient-switches’
|
|||
|
-----------------------------
|
|||
|
|
|||
|
• ‘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\\)’.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Predicate Slots, Prev: Suffix Slots, Up: Classes and Methods
|
|||
|
|
|||
|
5.8 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 a suffix or a group should be available
|
|||
|
depending on user preference. See *note Enabling and Disabling
|
|||
|
Suffixes::.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Related Abstractions and Packages, Next: FAQ, Prev: Classes and Methods, Up: Top
|
|||
|
|
|||
|
6 Related Abstractions and Packages
|
|||
|
***********************************
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* Comparison With Prefix Keys and Prefix Arguments::
|
|||
|
* Comparison With Other Packages::
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Comparison With Prefix Keys and Prefix Arguments, Next: Comparison With Other Packages, Up: Related Abstractions and Packages
|
|||
|
|
|||
|
6.1 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
|
|||
|
-----------------------
|
|||
|
|
|||
|
See *note (elisp)Prefix Keys::.
|
|||
|
|
|||
|
,--> command1 --> (c)
|
|||
|
|
|
|||
|
(c)-(+)-> prefix command or key --+--> command2 --> (c)
|
|||
|
|
|
|||
|
`--> command3 --> (c)
|
|||
|
|
|||
|
Regular Prefix Arguments
|
|||
|
------------------------
|
|||
|
|
|||
|
See *note (elisp)Prefix Command Arguments::.
|
|||
|
|
|||
|
,----------------------------------,
|
|||
|
| |
|
|||
|
v |
|
|||
|
(c)-(+)---> prefix argument command --(c)-(+)-> any command --> (c)
|
|||
|
| ^ |
|
|||
|
| | |
|
|||
|
`-- sets or changes --, ,-- maybe used --' |
|
|||
|
| | |
|
|||
|
v | |
|
|||
|
prefix argument state |
|
|||
|
^ |
|
|||
|
| |
|
|||
|
`-------- discards --------'
|
|||
|
|
|||
|
Transients
|
|||
|
----------
|
|||
|
|
|||
|
(∩`-´)⊃━☆゚.*・。゚
|
|||
|
|
|||
|
This diagram ignores the infix value and external state:
|
|||
|
|
|||
|
(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)
|
|||
|
|
|||
|
This diagram takes the infix value into account to an extend, while
|
|||
|
still ignoring external state:
|
|||
|
|
|||
|
(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)
|
|||
|
|
|||
|
This diagram provides more information about the infix value and also
|
|||
|
takes external state into account.
|
|||
|
|
|||
|
,----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
|
|||
|
| | initialized maybe | |
|
|||
|
| | from used | |
|
|||
|
| | | | | |
|
|||
|
| | `-- infix ---' | |
|
|||
|
| `---> value -----------------------------> persistent
|
|||
|
| ^ ^ | | across
|
|||
|
| | | | | invocations -,
|
|||
|
| hides | | | |
|
|||
|
| | `----------------------------------------------'
|
|||
|
| | | |
|
|||
|
| `--------------------------<---|
|
|||
|
| | |
|
|||
|
`--> any command --{2}-> {warn} -->--| |
|
|||
|
| | |
|
|||
|
|--> {noop} -->--| |
|
|||
|
| | |
|
|||
|
|--> {call} -->--' ^
|
|||
|
| |
|
|||
|
`------------------> {exit} --> (c)
|
|||
|
|
|||
|
• ‘{1}’ Transients can be configured to be exited when a suffix
|
|||
|
command is invoked. The default is to do so for all suffixes
|
|||
|
except 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 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.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Comparison With Other Packages, Prev: Comparison With Prefix Keys and Prefix Arguments, Up: Related Abstractions and Packages
|
|||
|
|
|||
|
6.2 Comparison With Other Packages
|
|||
|
==================================
|
|||
|
|
|||
|
Magit-Popup
|
|||
|
-----------
|
|||
|
|
|||
|
Transient is the successor to Magit-Popup (see *note
|
|||
|
(magit-popup)Top::).
|
|||
|
|
|||
|
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
|
|||
|
-----
|
|||
|
|
|||
|
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 show the available commands in a popup buffer.
|
|||
|
|
|||
|
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 popup buffer.
|
|||
|
|
|||
|
(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 now this feature is not a
|
|||
|
focus and the interface is a bit more complicated. A very basic
|
|||
|
example using the current interface:
|
|||
|
|
|||
|
(transient-define-prefix outline-navigate ()
|
|||
|
:transient-suffix 'transient--do-stay
|
|||
|
:transient-non-suffix 'transient--do-warn
|
|||
|
[("p" "previous visible heading" outline-previous-visible-heading)
|
|||
|
("n" "next visible heading" outline-next-visible-heading)])
|
|||
|
|
|||
|
• Transient supports 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 supports 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.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: FAQ, Next: Keystroke Index, Prev: Related Abstractions and Packages, Up: Top
|
|||
|
|
|||
|
Appendix A FAQ
|
|||
|
**************
|
|||
|
|
|||
|
A.1 Can I control how the popup buffer is displayed?
|
|||
|
====================================================
|
|||
|
|
|||
|
Yes, see ‘transient-display-buffer-action’ in *note Configuration::.
|
|||
|
|
|||
|
A.2 Why did some of the key bindings change?
|
|||
|
============================================
|
|||
|
|
|||
|
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 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.)
|
|||
|
|
|||
|
A.3 Why does ‘q’ not quit popups anymore?
|
|||
|
=========================================
|
|||
|
|
|||
|
I agree that ‘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 ‘magit-blame’ for example binds ‘q’ to the
|
|||
|
command that turns ‘magit-blame-mode’ off.
|
|||
|
|
|||
|
So I had to decide if ‘q’ should quit the active transient (like
|
|||
|
Magit-Popup used to) or whether ‘C-g’ should do that instead, so that
|
|||
|
‘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 ‘q’.
|
|||
|
|
|||
|
If you want to get ‘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, ‘transient-bind-q-to-quit’ that makes the
|
|||
|
necessary changes. See its doc string for more information.
|
|||
|
|
|||
|
|
|||
|
File: transient.info, Node: Keystroke Index, Next: Command and Function Index, Prev: FAQ, Up: Top
|
|||
|
|
|||
|
Appendix B Keystroke Index
|
|||
|
**************************
|
|||
|
|
|||
|
|