Commit 2289f350 ("Remove command parsing Reader and just track a
ParserState") introduced a small regression in parse_percent_token()
because we failed to recognize a token like %val{ as percent-expansion.
I tried to add a test case but a UI test doesn't seem possible, e.g.
kak -ui json -e "exec ':echo %opt{<tab>}<ret>'"
prints: 'exec': option not found: ''
This fixes an issue where completion would still be provided after
the closing character of a token, which could then get frustrating
combined with auto-insertion of completions.
For example, inserting `%{<newline>}` for a command-completed token
(such as the commands for a hook) would still trigger completion right
after the `}` and that completion would get auto-inserted **replacing**
that closing `}`.
Quote by wrapping in quotes if we are replacing the whole token,
using backspaces if the completion only adds to it.
This ensure that the inserted completion will be correctly parsed
once validated.
Fixes#4121
The menu flag signifies that only the completions are valid arguments,
hence it makes sense to auto insert the best one on space.
Because full match is always considered the best match in completion
ranking, this should always have a reasonable behaviour.
This makes it harder to enter a hidden command, but completion can
always be disabled via <c-o> or by quoting in those rare cases.
Completion candidates are currently escaped with a backslash `\`
character, which leads to ugly interactive commands on the prompt,
especially when they contain space characters.
This commit makes completion candidates be escaped by simple quoting.
Examples:
candidate\ with\ spaces
\%opt{foo}
\"dquote
\'quote
become:
'candidate with spaces'
'%opt{foo}'
'"dquote'
'''quote'
std::function is not necessary when we just want to pass a type
erased callback that does not need to own its target. FunctionRef
provides that functionality for a much lower compile time cost.
Sometimes we really need to have a String instead of a StringView,
but some of those strings might not need to own their data. Make
it possible to explicitely construct a String that does not own
the underlying buffer.
Use it when parsing balanced strings.
Now that we have a nice standard way to express lists of strings,
registers can be fully exposed. An new $kak_main_reg_... env var
was added to provide the previous behaviour which is relied on by
doc.kak.
Option lists and maps are specified using separate arguments, avoiding
the need for additional escaping of their separator and reusing the
existing command line spliting logic instead.
As discussed on #2087, this should make it much easier to work with
list options, and make the general option system feel cleaner.
Command line parsing now works as follow:
* Quoted strings ('...', "..." and %~...~ with '~' non nestable)
use 'doubling-up' for escaping their delimiter, if the delimiter
appears twice in a row, it is considered as part of the string and
represent one delimiter character. So 'abc''def' == "abc'def". No
other escaping takes place in those strings.
* Balanced strings (%{...}) do not support any kind of escaping, but
finds the matching closing delimiter by taking nesting into account.
So %{abc{def}} == "abc{def}".
* Non quoted words support escaping of `;` and whitespaces with `\`,
`%`, `'` and '"` can be escaped with `\` at the start of the word,
they do not need escaping (and will not be escaped) else where in
a word where they are treated literally. Any other use of '\' is a
literal '\'. So \%abc%\;\ def == "%abc%; def"
As discussed in #2046 this should make our command line syntax more
robust, provide a simple programmatic way to escape a string content
(s/<delim>/<delim><delim>/g), be well defined instead of ad-hoc
undocumented behaviour, and interact nicely with other common
escaping by avoiding escaping hell (:grep <regex> can in most case
be written with the regex unquoted).
Automatic reparsing of %sh{...}, while convenient in many cases,
can be surprising as well, and can lead to security problems:
'echo %sh{ printf "foo\necho bar" }' runs 'echo foo', then 'echo bar'.
we make this danger explicit, and we fix the 'nop %sh{...}' pattern.
To reparse %sh{...} strings, they can be passed to evaluate-commands,
which has been fixed to work in every cases where %sh{...} reparsing
was used..