The prompt and autocomplete normally wait for `idle_timeout` before showing
suggestions, however commands like `g`, `v`, or the lead-key show Clippy
instantly.
This fixes the issue by making `on_next_key_with_autoinfo()` wait for
`idle_timeout` before displaying suggestions.
Fixesmawww/kakoune#3365Fixesmawww/kakoune#2066
It seems that when -atomic was implemented for `:write`, the usage
strings were not updated to reflect that a new flag was available.
The `write-all` command didn't benefit from the implementation of
the new flag despite also writing files - this commit fixes that.
The first attempt at a bug fix for @ symbols in selection buffer names
worked, but it was very inefficient. In particular, it allocated three
different vectors, and we really only needed the correct elements.
Manipulating iterators to give us the right slices of the existing
vector is far more efficient.
By reversing the original content and taking the last two, we're able to
get the number of selections and main selection without too much hassle.
The buffer name is everything from the start of the content to the
selection count. This gets us through with only one vector allocation.
Credit to @mawww for the optimization idea and for fixing my types.
The selection descriptions use the format
`<buffer>@<timestamp>@<main_index>`. This fails when file paths have `@`
symbols in them: the parser splits on `@` symbols and finds more values
than it expects.
We here modify the behavior to require *at least* two @ symbols, using
the last two for `<timestamp>` and `<main_index>` and leaving the
remaining text for the <buffer>. This should work for any number of `@`
symbols, since `<timestamp>` and `<main_index>` are numbers and should
never contain `@` symbols.
The description of startup_info_version in the manual says "only messages
relating to a Kakoune version greater than this value will be displayed,"
but showed messages relating to the version equal to that value.
This change aligns the code with the manual and makes a workaround that set
startup_info_version next to the original version (ex. 20200117) unnecessary.
Signed-off-by: Masanori Ogino <masanori.ogino@gmail.com>
When a region calls the regex highlighter, it is incorrect to share
the regex cache as it means we can get matches that span multiple
regions.
Fixes#3041
Do not access Buffer::m_changes to find the inserted range, return
it directly from Buffer::insert and Buffer::replace. This fixes a
wrong behaviour where replacing at eof would lose the selected end
of line (as the implementation does not actually replace that end
of line)
Rxvt emits `\E[23$` and `\E[24$` for `F21` and `F22` (alias `s-F11` and
`s-F12` provided that `ncurses_shift_function_key` is set to `10`),
respectively.
When compiled on Mac with `clang`, the following error occurs at
compile-time:
```
./diff.hh:56:28: error: no member named 'min' in namespace 'std'
const int max_D = std::min((M + N + 1) / 2 + 1, cost_limit);
~~~~~^
```
When compiling the code with `-Wp,-D_GLIBCXX_ASSERTIONS`, the process
gets aborted, likely because iterators to standard containers are
not obtained in a safe way.
Fixes#3226.
This is tricky to fix better than that as tabs make text length
dependent on where it will get displayed and what preceedes it.
Also fix an issue with empty info title
Fixes#2237
Optmize the code to avoid allocating like crazy, unify various
info style rendering, crop content and display markers that there
is more text remaining.
Fixes#2257
We can get this signal while suspending if a parent process (say
git-commit) has already put us in the background. We still need
to reset the termios state to exit raw input mode and make the shell
usable.
Fixes#3069
The `json_ui.cc` file contained both data-parsing and UI-related
code. This commit moves the JSON parsing code to its own `json.cc`
file, to separate concerns, make compilation faster when changes are
made to either UI or parsing code, and make the parsing code more
accessible to fuzzers.
The signature of the following function:
```
auto parse_json(StringView json);
```
was changed to:
```
JsonResult parse_json(StringView json);
```
to avoid `auto` deduction issues at compile-time.
-verbatim will disable argument parsing in evaluate-commands, making
it possible to forward a single command to a different context without
triggering a reparsing of the arguments.
Fixes -try-client support in grep.kak
Closes#3153
This commit allows using the <semicolon> expansion in commands, instead
of `\;`.
It makes commands look more elegant, and prevents new-comers from
falling into the trap of using <a-;> without escaping the semicolon.
Pass an ArrayView<DisplayAtom> instead of a DisplayLine& so that
the newly common case of passing a single atom does not require
constructing a Vector.
When trimming indent, the last line, if only containing
whitespaces does not need to match the indent, so that
this indentation style works:
-docstring %{
indented string
}
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.
Whenever a tool spawns the editor (e.g. Git), suspending it with ^Z is not
enough to be sent back to the calling shell - another ^Z is necessary.
Fixes#3061
The UI now can send a 'Scroll' key, whose value is the scrolling
amount encoded as a signed integer. This replaces the MouseWheelUp
and MouseWheelDown keys.
The NCursesUI now has a ncurses_wheel_scroll_amount ui_option that
controls that amount, it can be negative to swap scrolling direction.
Fixes#3045
First try to break at a whitespace, if that fails (likely because
that last WORD is too long for the wrapping width), then try to
wrap at a 'word' boundary (on a non alphanumeric character).
Fixes#3048
Falls back on old mechanism if `XDG_RUNTIME_DIR` is not set.
The ability to specify a session as "<user>/<name>" was removed, since
it isn't possible to compute the value of `XDG_RUNTIME_DIR` for another
user, we wouldn't have access to it if we could, and it would be awkward
to support this feature only when `XDG_RUNTIME_DIR` is unset. Also,
`rename-session` did not work when another user's session was specified.
Closes#3019
This commit implements formatting behaviour when the first character of a
docstring is a newline. In that case, the exact indentation level of the
next line will be removed from that line and all subsequent non-empty lines.
An error will be returned if a subsequent non-empty line does not have the
same indentation level.
The docstrings are always trimmed (surrounding whitespaces) whether the
first character is a newline or not, as was the case prior to this commit.
Example: the following declaration
```
define-command test -docstring %{
test: do something
Nothing really.
More
indented
lines.
} nop
```
would be rendered as
```
test: do something
Nothing really.
More
indented
lines.
```
Related to #2405
file.cc:390:21: error: use of undeclared identifier 'rename'; did you mean 'devname'?
if (replace and rename(temp_filename, zfilename) != 0)
^~~~~~
devname
/usr/include/stdlib.h:277:7: note: 'devname' declared here
char *devname(__dev_t, __mode_t);
^
file.cc:390:28: error: cannot initialize a parameter of type '__dev_t' (aka 'unsigned long') with an lvalue of type 'char [1024]'
if (replace and rename(temp_filename, zfilename) != 0)
^~~~~~~~~~~~~
/usr/include/stdlib.h:277:22: note: passing argument to parameter here
char *devname(__dev_t, __mode_t);
^
2 errors generated.
---
highlighters.cc:1110:13: error: use of undeclared identifier 'snprintf'; did you mean 'vswprintf'?
snprintf(buffer, 16, format, std::abs(line_to_format));
^~~~~~~~
vswprintf
/usr/include/wchar.h:139:5: note: 'vswprintf' declared here
int vswprintf(wchar_t * __restrict, size_t n, const wchar_t * __restrict,
^
highlighters.cc:1110:22: error: cannot initialize a parameter of type 'wchar_t *' with an lvalue of type 'char [16]'
snprintf(buffer, 16, format, std::abs(line_to_format));
^~~~~~
/usr/include/wchar.h:139:35: note: passing argument to parameter here
int vswprintf(wchar_t * __restrict, size_t n, const wchar_t * __restrict,
^
2 errors generated.
---
json_ui.cc:60:13: error: use of undeclared identifier 'sprintf'; did you mean 'swprintf'?
sprintf(buf, "\\u%04x", *next);
^~~~~~~
swprintf
/usr/include/wchar.h:133:5: note: 'swprintf' declared here
int swprintf(wchar_t * __restrict, size_t n, const wchar_t * __restrict,
^
json_ui.cc:60:21: error: cannot initialize a parameter of type 'wchar_t *' with an lvalue of type 'char [7]'
sprintf(buf, "\\u%04x", *next);
^~~
/usr/include/wchar.h:133:34: note: passing argument to parameter here
int swprintf(wchar_t * __restrict, size_t n, const wchar_t * __restrict,
^
json_ui.cc:74:9: error: use of undeclared identifier 'sprintf'
sprintf(buffer, R"("#%02x%02x%02x")", color.r, color.g, color.b);
^
3 errors generated.
---
regex_impl.cc:1039:9: error: use of undeclared identifier 'sprintf'; did you mean 'swprintf'?
sprintf(buf, " %03d ", count++);
^~~~~~~
swprintf
/usr/include/wchar.h:133:5: note: 'swprintf' declared here
int swprintf(wchar_t * __restrict, size_t n, const wchar_t * __restrict,
^
regex_impl.cc:1039:17: error: cannot initialize a parameter of type 'wchar_t *' with an lvalue of type 'char [20]'
sprintf(buf, " %03d ", count++);
^~~
/usr/include/wchar.h:133:34: note: passing argument to parameter here
int swprintf(wchar_t * __restrict, size_t n, const wchar_t * __restrict,
^
regex_impl.cc:1197:17: error: use of undeclared identifier 'puts'
{ if (dump) puts(dump_regex(*this).c_str()); }
^
regex_impl.cc:1208:18: note: in instantiation of member function 'Kakoune::(anonymous namespace)::TestVM<Kakoune::RegexMode::Forward>::TestVM' requested here
TestVM<> vm{R"(a*b)"};
^
regex_impl.cc:1197:17: error: use of undeclared identifier 'puts'
{ if (dump) puts(dump_regex(*this).c_str()); }
^
regex_impl.cc:1283:56: note: in instantiation of member function 'Kakoune::(anonymous namespace)::TestVM<5>::TestVM' requested here
TestVM<RegexMode::Forward | RegexMode::Search> vm{R"(f.*a(.*o))"};
^
regex_impl.cc:1197:17: error: use of undeclared identifier 'puts'
{ if (dump) puts(dump_regex(*this).c_str()); }
^
regex_impl.cc:1423:57: note: in instantiation of member function 'Kakoune::(anonymous namespace)::TestVM<6>::TestVM' requested here
TestVM<RegexMode::Backward | RegexMode::Search> vm{R"(fo{1,})"};
^
5 errors generated.
---
remote.cc:829:9: error: use of undeclared identifier 'rename'; did you mean 'devname'?
if (rename(old_socket_file.c_str(), new_socket_file.c_str()) != 0)
^~~~~~
devname
/usr/include/stdlib.h:277:7: note: 'devname' declared here
char *devname(__dev_t, __mode_t);
^
remote.cc:829:16: error: cannot initialize a parameter of type '__dev_t' (aka 'unsigned long') with an rvalue of type 'const char *'
if (rename(old_socket_file.c_str(), new_socket_file.c_str()) != 0)
^~~~~~~~~~~~~~~~~~~~~~~
/usr/include/stdlib.h:277:22: note: passing argument to parameter here
char *devname(__dev_t, __mode_t);
^
2 errors generated.
---
string_utils.cc:126:20: error: use of undeclared identifier 'sprintf'; did you mean 'swprintf'?
res.m_length = sprintf(res.m_data, "%i", val);
^~~~~~~
swprintf
/usr/include/wchar.h:133:5: note: 'swprintf' declared here
int swprintf(wchar_t * __restrict, size_t n, const wchar_t * __restrict,
^
string_utils.cc:126:28: error: cannot initialize a parameter of type 'wchar_t *' with an lvalue of type 'char [15]'
res.m_length = sprintf(res.m_data, "%i", val);
^~~~~~~~~~
/usr/include/wchar.h:133:34: note: passing argument to parameter here
int swprintf(wchar_t * __restrict, size_t n, const wchar_t * __restrict,
^
string_utils.cc:133:20: error: use of undeclared identifier 'sprintf'; did you mean 'swprintf'?
res.m_length = sprintf(res.m_data, "%u", val);
^~~~~~~
swprintf
[...]
History registers (for prompt commands, pipe primitive commands etc) are
populated interactively by the users, and currently have no size limit.
This commits silently drops the oldest entries in the storage space to
allow at most 100 entries, to prevent long-running editing sessions from
hogging memory for data most likely never used.
This commit makes the `*` and <a-*> primitives compose a search pattern
comprised of all the current selections, as opposed to only the main one.
All selections are OR'd into the default search register, which makes it
convenient to search for several identifiers already selected.
To retain the old behaviour, the following mappings can be used:
```
map global normal * ': exec -draft -save-regs "" %{<space>*}<ret>'
map global normal <a-*> ': exec -draft -save-regs "" %{<space><a-*>}<ret>'
```
Fixes#2994
The `parse_keys()` function is case insensitive when parsing function keys,
while the `key_to_str()` function always returns a capitalized key
description.
When users hook on the lowercase name of a function key,
e.g. `NormalKey <f10>`, and later hit that same key in normal mode, the
`key_to_str()` will convert it to the uppercase description ("<F10>").
This results into a hook with a lowercase regex predicate being unsuccessfully
matched against an uppercase key description by the hook manager, which
works on a case sensitive basis.
One solution could be to uppercase all function key descriptions passed as
hook filter upon declaration, but detecting that is not trivial as the
filter can contain more than just the simple <f\d+> data, e.g.
---
hook global InsertKey '<(?<name>\w+)>' %{…}
---
Another simpler solution that this commit implements is to allow only <F\d+>
descriptions in `parse_keys()`, and hope users will know not to use the
lowercase notation when declaring hooks.
Fixes#2907
The previous "optimized" history register logic was unfortunately
not restoring correctly as the order of entries in the history
register could have been mutated.
The hook parameter should not be adjusted for the prevention of
scrolling. Also, ensure that the last BufReadFifo is triggered if we
encounter an error or EOF after appending some data to the buffer.
Closes#2946
On my system, some optimizations are on by default (NixOS), resulting in
variables being optimized out on debug builds. It *seems to be*
something about a "_FORTIFY_SOURCE" feature? In any case, `-Og` is
documented as "Optimize debugging experience".
Using <fg>,<bg>+<attr>@<base> will apply the given fg color,
bg color and attributes on top of base dynamically. Simply giving
<base> is a shorthand for default,default@<base>.
Inspired by the discussion in #2862
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.
This permit to choose if files should be written by overwriting their
content (the default), or by writing to a separate temporary file
and rename it to the current file.
As discussed in #2036
The current implementation is wrong as it crosses basic blocks
boundaries. Doing basic block decomposition of regex is probably
a tad too complex for this single optimization.
Fixes#2711
This should reduce the number of allocations as the memory allocated
for the thread stack and the saves can be re-used between runs instead
of being cleared every time.
The current implementation treats left mouse button clicks as a
generic "mouse press" modifier, this commit extends the list of
modifiers by adding a "right mouse click" one.
The proper way to implement this would be to ship the coordinates
of mouse key press events in each `Key` object, and pass whichever
button was clicked as a codepoint value (instead of coordinates
currently), but this would require more work.
This commit allows:
* right clicks to set the cursor of the main selection
* control-right clicks to merge all the selections, and then set
its cursor
Fixes#843
By setting the ncurses_builtin_key_parser ui_option to true, we
can disable ncurses parsing of key strokes to get less portable
parsing but support for more complex modifiers.
Probably, the extra «s» at the end of «exist» was added accidentally. A verb after «does not» in Present Simple definitely shouldn't have this extra «s».
Ideally, something better should be done (re #2554) but this is a decent
intermediate step for some useful keys.
Note: NCurses supports parsing these keys when shifted (KEY_SR,
_SLEFT, S_RIGHT, etc), but it does not do the same thing for the other
modifiers.
Not having the `test` target (in the Makefile) depend on the `kak` one
prevents users from running commands that make use of parallelism, e.g.:
$ make -j all test
The above command sometimes results in the test suite running before
the binary has been compiled and symlinked, resulting in failures.
SIG_IGN is inherited after 'execve' and requires us to reset
that signal handler, which does not work well with vfork on
OSX. Using an empty function does the trick and will be auto
reset to default on exec.
When large buffers have been opened, copying Kakoune's memory
page descriptors can get pretty slow, making fork more expensive
than necessary.
vfork avoids that problem. While not strictly conforming, it seems
the few calls we do before execve (open, close, dup2 and
set_signal_handler) would not cause any problems on platforms we
care about.
the buffer name was not a very interesting information, whereas
the buffer range allows a hook to run only on the appended text
instead of all the buffer.
m_last_setup was not storing the actual position that was used to
redraw the window, but the previous one, leading to an additional
spurious redraw immediatly after (triggered by window position not
believed to be the one at last redraw).
Fixes#2562
As we do at most one push_next per step_thread, and we pop_current
before step_thread, we can avoid a branch there at the expense of
sometimes growing unecessarily (once).
It seems unlikely this would give performance gain, as buffer
lines are always accessed when we read that field, leading to
all the necessary data already being in memory. Removing it
reduces the size of a BufferIterator, which are already pretty
hefty objects.
The RegexHighlighter range cache can get pretty big in nested
regions use cases, and maintaining it can become pretty costly,
so if it hits a certain size, just drop it.
Should improve performances in #2454
This should greatly reduce memory usage by only caching matches
for ranges that needs to be highlighted, in the case where multiple
regions are nested, this means only the topmost region needs to parse
and cache the whole buffer, other regions highlighter will only ensure
the lines for the ranges they are called up are cached.
Fixes#2454
This adds a limitation that capture matching on regions only works
if the regions start/end/recurse match is less than 65635 byte long.
With this limitation we can reduce the RegexMatch struct size to 16
bytes instead of 32.
This is still not good enough,but should slightly improve high memory
usage as reported in #2454
This commit also introduces a regression in that I decided that the best way to
avoid overly long and confusing names was to rename the current shell-*
switches to script-*, and have the shell command completion be
shell-completion.
renamed script-{completion,candidates} to shell-script-*
Updated docs with new switch names
Added -shell-completion switch to x11-repl and kitty-repl
Final is more granular, it consists of FinalFg (f), FinalBg (g)
and FinalAttr (a) which control if a face's fg, bg, or attributes
fully overwrite the previous face (instead of merging) and if
following faces apply on top of this face or not.
Fixes#2388 if the Whitespace face has the FinalFg flag.
Add <c-w> and <a-d> (along with <c-W> and <a-D> that work on WORDs),
and <c-y> which pastes the transient clipboard contant (which saves
big erase, such as word erase and line end/begin erase).
Fixes#2355
In the end, no better solution materialized so far, and custom
Kakoune line editing bindings are hard to remember. Using well
known readline bindings seems just more convenient.
Closes#800, although it does not contain all the binding proposed
by it (I might accept a few additional ones, such as <c-w>, but not
too much, I still see that as a hack pending a nicer solution).
Previously, when wrapping lines at word boundaries, we would iterate forwards
for "wrap-width" characters, then iterate backwards until we found a word-break,
which was horribly slow.
Now we record the last word-boundary we saw as we iterate forwards, getting a
result in one pass.
Fixes#2339.
Due to a copy-paste mistake, the `:kill` command in a session with
multiple clients was the equivalent of a force-kill (`:kill!`).
This commit makes sure all buffers are saved before killing the
session, unless the force flag is specified.
Cast errors in RPC requests currently make the client quit with an
error saying "uncaught exception", since `Kakoune::bad_value_cast`
exceptions are not explicitely handled.
This commit tries to catch ill-formatted requests and return a more
human-friendly error message, without quitting the client.
This commit implements the -once flag on the `:hook` command, which
automatically removes a hook after it was run, to avoid having to
declare a group and remove it in the hook implementation.
Closes#2277
In particular, this make gathering a transformed range to a vector
faster because we can use the random access nature of underlying
iterator to get the size to allocate in the vector upfront.
Creating a window potentially runs hooks, which themselves could
trigger shell evaluation, which could handle urgent input events
such as a resize, while waiting for the shell to finish. When that
happens, the client had a temporarily null window as it had already
released its own window.
Fixes#2225
As discussed in #2186, in the end we need the exit status for the
case where the local client exited first (the server forked to
background) then another client trigger the kill command.
That means every Optimized regex had the Backwards version
compiled as well, which doubled the time it took to compile them
and doubled the memory usage of regex.
This should improve #2152
Previous Implementation was constantly computing byte/column count
from the begining of the line, leading to a non-linear complexity
with respect to the length of a line.
Fixes#2146
Unfortunately Strings that start with a quoted quote (like '''str')
are still incorrectly highlighted, a deeper refactoring of the regions
highlighter will be necessary.
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.
Registers are lists of strings, so this make it possible to set
the whole list instead of forcing registers to a single element
when going through the set-register command.
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..
This commits changes the way `C` behaves when the next line is empty:
instead of stopping the selection, it will now jump to the next line
that can hold a selection as big as the current one.
The primitive's count parameter holds the maximum amount of selections
that should be added to the current one.
Closes#2061
Seems to work on openbsd 6.3-current but needs more testing. Had to
hardcode the binary path as openbsd considers getting the executable
path at runtime a security flaw.