Parsing a (non-valid) font with a comma in the name of the base colour
makes Kakoune crash. It is not a valid face, but Kakoune should just
return an error message instead.
Reproducer:
:set-face global foo ,red@,blue
Note the comma "," after the "@". This is not a valid base name, and it
leads to a crash. Let's see what happens.
At the beginning of parse_face(), we have the following code:
auto bg_it = find(facedesc, ',');
auto underline_it = bg_it == facedesc.end() ? bg_it : std::find(bg_it+1, facedesc.end(), ',');
auto attr_it = find(facedesc, '+');
auto base_it = find(facedesc, '@');
[...]
auto colors_end = std::min(attr_it, base_it);
After this:
- bg_it points to ",red@,blue"
- bg_it != facedesc.end(), so we have underline_it pointing to the first
comma after bg_it. This means that underline_it points to ",blue"
- base_it points to "@,blue"
- attr_it points to the end of facedesc (no "+" marker), so colors_end
points to base_it, "@,blue"
Later in the code, just after parsing the foreground and background
colours, we have:
if (underline_it != facedesc.end())
face.underline = parse_color({underline_it+1, colors_end});
When passing {underline_it+1, colors_end} to parse_color(), we pass in
fact iterators pointing to {",blue", "@,blue"}. Because the second one
starts _before_ the first one in the string, this means that the
resulting string is considered to have a _negative_ length.
parse_color() passes the string to str_to_color(), who fails to turn up
the colour, and attempts to throw:
throw runtime_error(format("unable to parse color: '{}'", color));
The variable "color" still has this negative length, and this goes all
the way down to an assert in src/units.hh where we expect that string to
be >= 0, and we crash on the assertion failure.
For similar reasons, we also get a crash if the comma comes after the
marker for the face attributes:
:set-face global foo ,red+,a
To fix both cases, let's add a check to make sure that the underline_it,
marked with a comma, never gets detected as present and pointing after
colors_end, be it "@" or "+".
The ThreadedRegexVM implementation does not execute split opcodes as
expected: on split the pending thread is pushed on top of the thread
stack, which means that when multiple splits are executed in a row
(such as with a disjunction with 3 or more branches) the last split
target gets on top of the thread stack and gets executed next (when the
thread from the first split target would be the expected one)
Fixing this in the ThreadedRegexVM would have a performance impact as
we would not be able to use a plain stack for current threads, so the
best solution at the moment is to reverse the order of splits generated
by a disjunction.
Fixes#4519
This will unfortunately break some use case which will require
using wrapper scripts to add the necessary newline. It is however
harder to do the contrary, and it makes a lot of other use case
possible, such as checksuming.
Fixes#3669
After a while it seems clear changing this is much more ergonomic
and restoring it with pure config is impractical as we need to map
all lower case keys.
As reported in [1], completions provided by "set global completers
option=my_completion" activate insert mode autocompletion, even when
the autocomplete option does not have the insert mode flag.
This happens because InsertCompleter::on_option_changed() calls
InsertCompleter::setup_ifn(), which shows the completion pager.
Fix this by computing whether the completion pager is enabled;
otherwise we can return early from setup_ifn().
The completion pager is enabled if the autocompletion bit is set,
or if the user has requested explicit completion.
[1]: https://github.com/kak-lsp/kak-lsp/issues/585
In normal mode, the mode line contains "1 sel" or "n sels (k)" when n > 1,
whereas in insert mode, it contains "n sels (k)" even for n == 1. Change
the contents in insert mode to match normal mode.
trim_indent call was incorrect, trim_indent is intended to work
on multi-line strings and trims trailing whitespace as well (could
benefit from a better name).
Fixes#4378
Merge all lookarounds into the same instruction, merge splits, merge
literal ignore case with literal...
Besides reducing the amount of almost duplicated code, this improves
performance by reducing pressure on the (often failing) branch target
prediction for instruction dispatching by moving branches into the
instruction code themselves where they are more likely to be well
predicted.
Only ui type Terminal is intended to be a user interactive session.
If your ui type is not Terminal, don't worry about making
the tty your stdin if fd 0 is not a tty.
This allows json-rpc commands sent via stdin to be acted up rather
than sent to a fifo (which is the default behavior for kakoune).
Does not change the behavior for Terminal ui sessions
Now that Kakoune opts into extended key reporting, <c-i> is correctly
reported and hence needs to be mapped to forward jump.
We still need to keep <tab> mapped to it for legacy terminals.
Should fix#4333
Closing/reopening the read side seems to sometimes lead to
end-of-file not being received, leaving some extra data unexecuted.
The FDWatcher stays disabled during the executing of the fifo
commands so this should not enable any more commands to be executed
until we get back from the CommandManager and reset the FDWatcher
fd to to fifo read end.
Fixes#4410
ARM uses @ as a comment character, so %progbits must be
used in place of @progbits here. This change fixes the
build on armv7 FreeBSD 13.0.
Fixes mawww/kakoune/issues#4385
See also https://bugs.freebsd.org/259434