4.3 Binding Suffix and Infix Commands

The macro transient-define-prefix is used to define a transient. This defines the actual transient prefix command (see Defining Transients) and adds the transient’s infix and suffix bindings, as described below.

Users and third-party packages can add additional bindings using functions such as transient-insert-suffix (see Modifying Existing Transients). These functions take a “suffix specification” as one of their arguments, which has the same form as the specifications used in transient-define-prefix.

4.3.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 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 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.

The ELEMENTs are either all subgroups, or all suffixes and strings. (At least currently no group type exists that would allow mixing subgroups with commands at the same level, though in principle there is nothing that prevents that.)

If the ELEMENTs are not subgroups, then they can be a mixture of lists, which specify commands, and strings. Strings are inserted verbatim into the buffer. The empty string can be used to insert gaps between suffixes, which is particularly useful if the suffixes are outlined as a table.

Inside group specifications, including inside contained suffix specifications, nothing has to be quoted and quoting anyway is invalid. The value following a keyword, can be explicitly unquoted using ,. This feature is experimental and should be avoided.

The form of suffix specifications is documented in the next node.

4.3.2 Suffix Specifications

A transient’s suffix and infix commands are bound when the transient prefix command is defined using transient-define-prefix, see Defining Transients. The commands are organized into groups, see Group Specifications. Here we describe the form used to bind an individual suffix command.

The same form is also used when later binding additional commands using functions such as transient-insert-suffix, see Modifying Existing Transients.

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.

The next element is either a command or an argument. This is the only argument that is mandatory in all cases.

Finally, details can be specified using optional KEYWORD-VALUE pairs. Each keyword has to be a keyword symbol, either :class or a keyword argument supported by the constructor of that class. See Suffix Slots.

If a keyword argument accepts a function as value, you an use a lambda expression. As a special case, the ## macro (which returns a lambda expression and is implemented in the llama package) is also supported. Inside suffix bindings, the use of ## is not supported anywhere but directly following a keyword symbol.