# Expansions

**URL:** <https://discuss.kakoune.com/t/expansions/540>\
**Category:** Manual++\
**Created:** [May 8, 2019, 2:16am UTC](https://discuss.kakoune.com/t/expansions/540 "2019-05-08T02:16:43Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![robertmeta](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/robertmeta/32/833_2.png) [@robertmeta](https://discuss.kakoune.com/u/robertmeta)\
**Post date:** [May 8, 2019, 2:16am UTC](https://discuss.kakoune.com/t/expansions/540/1 "2019-05-08T02:16:43Z")

</div>

While parsing a command (see  
[`:doc command-parsing`](https://discuss.kakoune.com/t/command-parsing/537/2)), Kakoune recognises certain  
patterns and will replace them with their associated value before  
executing the command. These patterns are called expansions.

Every expansion consists of a `%`, followed by the expansion _type_ (one  
or more alphabetic characters), a quoting character, and then all the  
text up to and including its matching character.

If a nestable punctuation character (`(`, `[`, `{`, or `<`) is used as  
the opening quoting character, the expansion will end at its matching  
opposite (`)`, `]`, `}`, or `>`). Nested pairs of the braces used in the  
expansion are allowed, but they must be balanced. Braces other than the  
ones used in the expansion need not be balanced, however. For example,  
`%{nest{ed} non[nested}` is valid and expands to `nest{ed} non[nested`.

If any other character is used, the expansion will end at the next  
occurrence of that character. The quoting character can be escaped  
inside the expansion if it is doubled-up. For example, `%|abc||def|`  
expands to the text `abc|def`.

It doesn’t matter which character is used, but `{}` are most common.

There are 2 types of quoting which can be used to group together words  
separated by whitespace into a single argument or prevent expansions  
from expanding:

“double quoted strings”  
Double quoted strings are mainly for grouping multiple `%` expansions or  
`%` expansions and regular text as a single argument. `%` and `"` can be  
escaped by doubling the characters (i.e. `%%` and `""`).

_single quoted strings_  
Expansions are not processed inside single quoted strings. Single quotes  
can be escaped by doubling up (i.e. `''`).

Expansions are processed when unquoted and anywhere inside double-quoted  
strings, but not inside unquoted words, inside single-quoted strings, or  
inside %-strings or other expansions (see  
[`:doc command-parsing typed-expansions`](https://discuss.kakoune.com/t/command-parsing/537/2#typed-expansions)  
for full details). For example:

- `echo %val{session}` echoes the current session ID

- `echo x%val{session}x` echoes the literal text `x%val{session}x`

- `echo '%val{session}'` echoes the literal text `%val{session}`

- `echo "x%val{session}x"` echoes the current session ID, surrounded  
by `x`

- `echo %{%val{session}}"` echoes the the literal text `%val{session}`

- `echo %sh{ echo %val{session} }"` echoes the literal text  
`%val{session}`

Like “variable expansion” and “command substitution” in shell  
programming, Kakoune expansions can expand to multiple “words” - that  
is, separate arguments on the resulting command-line. However, unlike  
shell programming, Kakoune expansions cannot _accidentally_ expand to  
multiple words because they contain whitespace or other special  
characters. Only expansions which semantically contain a list of values  
(list-type options, registers, selections, etc.) expand to multiple  
arguments. While in shell-programming it’s good practice to always wrap  
expansions in double-quotes, in Kakoune it’s perfectly safe to leave  
expansions unquoted.

# Argument expansions

Expansions with the type `arg` can only be used inside the “commands”  
parameter of the `define-command` command (See [`:doc commands declaring-new-commands`](https://discuss.kakoune.com/t/commands/538/2#declaring-new-commands)).

The following expansions are available:

(where _n_ is a decimal number)  
expands to argument number _n_ of the current command

**%arg{@}**  
expands to all the arguments of the current command, as individual words

# Option expansions

Expansions with the type `opt` expand to the value associated with the  
named option in the current scope (See [`:doc options`](https://discuss.kakoune.com/t/options/549/2)).

For example, `%opt{BOM}` expands to `utf8` or to `none`, according to  
the current state of the `BOM` option.

# Register expansions

Expansions with the type `reg` expand to the contents of the named  
register. For registers named after symbols (like the search register  
`/`), the expansion can use either the symbol or the alphabetic name  
(See [`:doc registers`](https://discuss.kakoune.com/t/registers/551/2)).

For example, `%reg{/}` expands to the content of the `/` register, and  
so does `%reg{slash}`.

# Shell expansions

Expansions with the type `sh` are executed as shell-scripts, and  
whatever the script prints to standard output replaces the expansion.  
For example, the command `echo %sh{date}` will echo the output of the  
`date` command.

> **Tip**
> 
> If a shell expansion writes to standard error, that output is appended  
> to Kakoune’s `\*debug*` buffer. If you’re trying to debug a shell  
> expansion, check the debug buffer with `:buffer \*debug*` to see if  
> anything shows up.

Because Kakoune does not expand expansions inside the text of an  
expansion, you can’t use normal expansions inside `%sh{}`. Instead,  
Kakoune can export expansions as environment variables to make them  
available to the shell. Here’s how expansion patterns map to variable  
names:

(where _n_ is a decimal number)  
becomes `$_n_`. For example, `%arg{3}` becomes `$3`.

**%arg{@}**  
becomes `$@`

becomes `$kak_opt_x`

(where _x_ is the alphabetic name of a register)  
`$kak_reg_x` contains all the selections in register _x_  
`$kak_main_reg_x` contains only the main selection

becomes `$kak_x`

When turned into environment variables, list-type options, `$kak_reg_x`,  
and “quoted list” values will be shell-quoted so the shell doesn’t get  
confused about how many items the list contains. You will need to apply  
`eval` to get back the original values. For example, if you want to  
process the contents of each selection, you can do something like:

```
eval set -- "$kak_selections"
while [$# -gt 0]; do
    # ... do a thing with $1 ...
    shift
done

```

The `eval` command will take the expanded `$kak_selections` and unquote  
them, then execute the resulting `set` command, which sets the shell’s  
argument variables to the items from `$kak_selections`. The `while` loop  
with `shift` iterates through the arguments one by one.

Only variables actually mentioned in the body of the shell expansion  
will be exported into the shell’s environment. For example:

```
echo %sh{ env | grep ^kak_ }

```

1. will find none of Kakoune’s special environment variables, but:

```
echo %sh{ env | grep ^kak_ # kak_session }

```

1. will find the `$kak_session` variable because it was mentioned by  
name in a comment, even though it wasn’t directly used.

> **Tip**
> 
> These environment variables are also available in other contexts where  
> Kakoune uses a shell command, such as the `|`, `!` or `$` normal mode  
> commands (See [`:doc keys`](https://discuss.kakoune.com/t/keys-keybindings/546/2)).

# File expansions

Expansions with the type `file` will expand to the content of the  
filename given in argument as read from the host filesystem.

# Value expansions

Expansions with the type `val` give access to Kakoune internal data that  
is not stored in an option or a register. Some value expansions can only  
be used in certain contexts, like `%val{hook_param}` that expands to the  
parameter string of the currently-executing hook, and is not available  
outside a hook.

The following expansions are supported (with required context _in  
italics_):

_in buffer, window scope_  
full path of the file or same as `%val{bufname}` when there’s no  
associated file

_in buffer, window scope_  
number of lines in the current buffer

quoted list of the names of currently-open buffers (as seen in  
`%val{bufname}`)

_in buffer, window scope_  
name of the current buffer

_in window scope_  
value of the `$X` environment variable in the client displaying the  
current window (e.g. `%val{client_env_SHELL}` is `$SHELL` in the  
client’s environment)

unquoted list of the names of clients (as seen in `%val{client}`)  
connected to the current session

_in window scope_  
name of the client displaying the current window

_in window scope_  
process id of the client displaying the current window

directory containing the user configuration

_in `map` command \<keys\> parameter and `<a-;>` from object menu_  
current count when the mapping was triggered, defaults to 0 if no count  
given

_in window scope_  
offset of the main cursor from the beginning of the buffer (in bytes)

_in window scope_  
1-based offset from the start of the line to the cursor position in  
Unicode codepoints, which may differ from visible columns if the  
document contains full-width codepoints (which occupy two columns) or  
zero-width codepoints

_in window scope_  
1-based offset from the start of the line to the cursor position in  
display column, taking into account tabs and character width.

_in window scope_  
unicode value of the codepoint under the main cursor

_in window scope_  
1-based offset from the start of the line to the first byte of the  
character under the main cursor (in bytes), the fourth component of  
`%val{selection_desc}`

_in window scope_  
line of the main cursor, the third component of `%val{selection_desc}`

_in buffer, window scope_  
history id of the current buffer, an integer value which refers to a  
specific buffer version in the undo tree (see also `%val{timestamp}`)

_in `hook` command \<command\> parameter_  
text captured by capture group _n_, if the executing hook’s filter regex  
used capture groups

_in `hook` command \<command\> parameter_  
the complete parameter string of the executing hook

_in buffer, window scope_  
`true` if the buffer has modifications not saved, otherwise `false`

_for commands executed from the object menu’s `<a-;>` only_  
a pipe-separted list of words including `inner` if the user wants an  
inner selection, `to_begin` if the user wants to select to the  
beginning, and `to_end` if the user wants to select to the end

_in `map` command \<keys\> parameter and `<a-;>` from the object  
menu_  
current register when the mapping was triggered

directory containing the kak support files, determined from Kakoune’s  
binary location

_for commands executed from the object menu’s `<a-;>` only_  
`replace` if the new selection should replace the existing, `extend`  
otherwise

_in window scope_  
content of the main selection

_in window scope_  
quoted list of the contents of all selections

_in window scope_  
range of the main selection, represented as `a.b,c.d` where _a_ is the  
anchor line, _b_ is the number of bytes from the start of the line to  
the anchor, _c_ is the cursor line (like `%val{cursor_line}`), _d_ is  
the number of bytes from the start of the line to the cursor (like  
`%val{cursor_column}`), and all are 1-based decimal integers

_in window scope_  
unquoted list of the ranges of all selections, in the same format as  
`%val{selection_desc}`

_in window scope_  
length (in codepoints) of the main selection

_in window scope_  
unquoted list of the lengths (in codepoints) of the selections

name of the current session

_in `.kak` file_  
path of the file currently getting executed (through the source command)

_in `prompt` command \<command\> parameter_  
the text entered by the user in response to the `prompt` command

_in buffer, window scope_  
timestamp of the current buffer, an integer that increments each time  
the buffer is modified, including undoing and redoing previous  
modifications (see also `%val{history_id}`)

unquoted list of user modes.

version of the current Kakoune server (git hash or release name)

_in window scope_  
height of the current Kakoune window

_in window scope_  
width of the current Kakoune window

Values in the above list that do not mention a context are available  
everywhere.

A value described as a “quoted list” will follow the rules of Kakoune  
string quoting (See [`:doc command-parsing`](https://discuss.kakoune.com/t/command-parsing/537/2)). An  
“unquoted list” cannot contain any special characters that would require  
quoting.
