= Command Parsing

Kakoune commands, either loaded from a script or written in the command
prompt, are parsed according to the following rules:

== Basic parsing

- Commands are terminated by a `;` or an end of line.

- Words (command names and parameters) are delimited by whitespaces.

== Quoted Strings

If a word starts with `'`, `"`, or `%X` with `X` a _non-nestable_ punctuation
character (see <<command-parsing#balanced-strings,Balanced Strings>> below for
nestable characters), it is parsed as a quoted string whose delimiter is,
respectively, `'`, `"`, or `X`.

A quoted string contains every character (including whitespaces).  Doubling
a closing delimiter escapes it.  Thus, for example, entering two closing
delimiters at the end of a quoted string will render one of the characters
literally; that is, it will be considered as part of the quoted string's
content.

Inside double quotes, `%`-strings are processed unless the `%` is escaped by
doubling it.  Double quotes inside these nested strings must also be escaped.

No other escaping takes place in quoted strings.

=== Quoted Strings Examples

- `'foo'` contains *foo*.

- `foo'bar'` is read verbatim, so it contains *foo'bar'*.

- `foo%|bar|` is read verbatim, so it contains *foo%|bar|*.

- `'foo''bar'` is a single word whose content is *foo'bar*.

- `"baz"""` is a single word whose content is *baz"*.

- `%|foo||bar|` is a single word whose content is *foo|bar*.

- `"foo %|""bar| %%,baz,"` is a single word whose content is *foo "bar %,baz,*.

== Balanced Strings

If a word starts with `%X` with `X` a _nestable_ punctuation character (one
of `(`, `[`, `{` and `<`), it is parsed as a balanced string whose closing
delimiter matches that of its opening delimiter (respectively, `)`, `]`,
`}`, and `>`).

There is no way to escape the opening and closing characters, even if they
are nested inside some other kind of string. For example, this will **not**
work, because the `{` in the map command interferes with the delimiters for the
hook's command block:

----
# DOES NOT WORK
hook global WinSetOption filetype=latex %{
    map window user b 'o\begin{'
}
----

You can solve this by using a different outer delimiter:

----
hook global WinSetOption filetype=latex %[
    # Note different delimiter used -----^
    map window user b o\begin{
]
----

...or just by including matching delimiters inside comments:

----
hook global WinSetOption filetype=latex %{
    map window user b o\begin{ # matched pair to keep Kakoune happy: }
}
----

=== Balanced Strings Examples

- `%{foo}` contains *foo*.

- `%{foo\{bar}}` contains *foo\{bar}*.

- `foo%{bar}` contains *foo%{bar}*.

- `"foo %{bar}"` is a single word whose content is *foo bar*.

== Non-Quoted words

Other words are non-quoted.  Non-quoted words are terminated by either a
whitespace or a `;`.

If they start with a `\` followed by a `%`, `'`, or `"`, then that leading
`\` escapes those characters and is discarded.

If a whitespace or `;` is preceded by a `\`, then the `\` is discarded, and
the whitespace or `;` becomes part of the word.  Any other `\` is treated
as a literal `\`.

== Typed Expansions

Quoted and Balanced strings starting with `%` might have an optional
alphabetic *expansion type* between the `%` and their delimiter (which is
always a punctuation character).  This *expansion type* defines how the
string's content is going to be expanded.  Rules for expanding and escaping
expansion types are the same as for `%`-strings.

- If the *expansion type* is empty, the string content is used verbatim.

- If the *expansion type* is one of `sh`, `reg`, `opt`, `val` or `arg`,
  the string is expanded as described in <<expansions#,`:doc expansions`>>.

- For any other *expansion type*, a parsing error is raised.
