| Age | Commit message (Collapse) | Author |
|
<memory> is a costly header we can avoid by just implementing
UniquePtr ourselves, which is a pretty straightforward in modern
C++, this saves around 10% of the compilation time here.
|
|
If the current buffer is locked, it means we are in the middle of
creating the client or already changing the buffer, error out in this
case instead of getting into an inconsistent state.
Fixes #5338
|
|
`kak -n -E 'hook global WinCreate .* %{ delete-buffer }'` was crashing
because we would delete the buffer during window construction, which
would not be able to delete the window as it was not fully constructed
and registered yet. This led to a window referencing a deleted buffer.
Fixing this by deleting the window later on failed because we can enter
an infinite loop where we constantly create a new *scratch* buffer, then
a window to display it, which deletes that buffer.
Make it an error to try to delete a buffer while a new window is
being setup by adding a Locked flag to buffers and checking that in
BufferManager::delete_buffer
Fixes #5311
|
|
We have only one place where we handle actual keys typed by the user.
|
|
Extract the logic for "waiting for shell to finish" and reuse it for
potentially blocking calls to open() that use the O_WRONLY flags.
|
|
|
|
|
|
|
|
|
|
Lots of code includes buffer_utils.hh just for write_to_debug_buffer
which pulls many unnecessary dependencies. Reorganise to reduce
compile times.
|
|
This makes it possible to remove the pending clears whenever an
info/status line is explicitely added, removing a class of race
conditions introduced by the previous implementation.
|
|
Make last insert and macro recording closer together, paving the
way towards moving last insert to a register.
Use a FunctionRef for insert completer key insertion support.
|
|
As @topisani pointed out in #5131, it is more user friendly to always
provide a %val{register} and %val{count} regardless of the mode.
|
|
This should implement what #5131 proposed in a different way.
Closes #5131
|
|
Overloading SIGTERM like that causes issues; specifically if the
editor is invoked (without exec) from a wrapper script.
By sending SIGTERM to whole process group, we kill our parent process
(the wrapper script) which then sends SIGTERM to Kakoune. By this
time Kakoune has already reset the SIGTERM handler to the default
action and terminates.
We can use a different fix for the problem that some shells don't
cancel "make", see the next patch.
This reverts commit ec44d98347fe5e5bdcaff77db61df636644a1ee2.
|
|
Consider
sh -c 'sleep 5 & sleep inf'
Since the shell is non-interactive, there is no job control.
This makes the shell spawn the "sleep 5" process in the shell's own
process group[1] - presumably, because only interactive shells have
a need to forward signals to all processes in its foreground job.
When this non-interactive shell process is cancelled with SIGINT,
"sleep 5" keeps running [2]. At least the dash shell implements this
by running "signal(SIGINT, SIG_IGN)" in the forked child. Unless the
child process explicitly overrides that (to SIG_DFL for example), it
will ignore SIGINT. Probably the reason for this behavior is to feign
consistency with interactive shells, without needing to actually run
background jobs in a dedicated process group like interactive shells
do. Bash documents this behavior[3]:
> When job control is not in effect, asynchronous commands ignore
> SIGINT and SIGQUIT in addition to these inherited handlers.
Several of our scripts[4] - most prominently ":make" - use the
"</dev/null >/dev/null 2>&1 &" pattern to run potentially long-running
processes in the background, without blocking the editor.
On <c-c>, we send SIGINT to our process group.
As explained above, this will generally not terminate any background processes.
This problem has been masked by a behavior that is unique to using
both Bash and its "eval" builtin. Given
nop %sh{
rm -f /tmp/fifo
mkfifo /tmp/fifo
(
eval make >/tmp/fifo 2>&1 &
) >/dev/null 2>&1 </dev/null
}
edit -fifo /tmp/fifo *my-fifo*
When running this and pressing Control+C, Bash actually terminates
the Make processes. However if I remove the "eval", it no longer does.
This doesn't seems like something we should rely on.
Other commands like ":git blame" don't use "eval" so they cannot be
cancelled today.
Fix these issues by sending SIGTERM instead of SIGINT, which should
apply to the whole process group with pretty much the same effect.
Barely tested, let's see if this breaks some weird build system.
In future we might allow more fine-grained control over which processes
are cancelled by <c-c>.
{{{
Alternative solution:
With the above fix, scripts can opt-out of being terminated by <c-c>
by using setsid (though that's not POSIX unfortunately, and may
require nesting quotes) or the classic Unix double-forking trick to
create a daemon process.
Though it is certainly possible that someone expects commands like
this to survive <c-c>:
nop %sh{ tail -f my-log </dev/null 2>&1 | grep some-error > some-file 2>&1 & }
I think it would be ideal to stick to SIGINT and match semantics of
a noninteractive shell, to avoid muddying the waters.
Background processes could still **opt into** being terminated by
<c-c>. For example by providing a simple program in libexec/ that does
// interruptible.c
int main(int argc, char** argv) {
signal(SIGINT, SIG_DFL);
execv(argv[1], &argv[1]);
}
used as
diff --git a/rc/tools/make.kak b/rc/tools/make.kak
index b88f7e538..f6e041908 100644
--- a/rc/tools/make.kak
+++ b/rc/tools/make.kak
@@ -16,3 +16,3 @@ define-command -params .. \
mkfifo ${output}
- ( eval "${kak_opt_makecmd}" "$@" > ${output} 2>&1 & ) > /dev/null 2>&1 < /dev/null
+ ( eval "interruptible ${kak_opt_makecmd}" "$@" > ${output} 2>&1 & ) > /dev/null 2>&1 < /dev/null
Unfortunately, it's inconvenient to add "interruptible" to commands
like clang-parse and git-blame because they background a whole subshell
with many commands, so we'd need to nest quotes. Also I'm not sure
if this brings any benefit.
So I didn't explore this further yet although we can definitely do that.
}}}
Fixes #3751
[1]: https://stackoverflow.com/questions/45106725/why-do-shells-ignore-sigint-and-sigquit-in-backgrounded-processes/45106961#45106961
[2]: https://unix.stackexchange.com/questions/372541/why-doesnt-sigint-work-on-a-background-process-in-a-script/677742#677742
[3]: https://www.gnu.org/software/bash/manual/html_node/Signals.html
[4]: clang-parse, ctags-*, git blame, git log, gopls references,
grep, jedi-complete, lint-*, make; I don't think any of these
should be uninterruptible.
|
|
For hash map, using fnv1a is faster as it is a much simpler algorithm
we can afford to inline. For files murmur3 should win as it processes
bytes 4 by 4.
|
|
|
|
ensure cursor is visible after user input except if the command
implementation opted-out. Hooks and timers should not enforce
visible cursor.
PageUp/PageDown and `<c-f>` / `<c-b>` commands still move the cursor
as this seemed a desired behaviour.
|
|
This was mostly redundant with Client::force_redraw.
|
|
The current implementation only does this during regex operations,
but should be extensible to other operations that might take a long
time by regularly calling EventManager::handle_urgent_events().
|
|
Handle begin/end paste directly in paste csi, manage paste buffer
out of get_char, filter Key::Invalid earlier.
get_next_key returning Key::Invalid means there was some input but
it could not be represented as a Key. An empty optional means there
was no input at all.
|
|
Text pasted into Kakoune's normal mode is interpreted as command
sequence, which is probably never what the user wants. Text
pasted during insert mode will be inserted fine but may trigger
auto-indentation hooks which is likely not what users want.
Bracketed paste is pair of escape codes sent by terminals that allow
applications to distinguish between pasted text and typed text.
Let's use this feature to always insert pasted text verbatim, skipping
keymap lookup and the InsertChar hook. In future, we could add a
dedicated Paste hook.
We need to make a decision on whether to paste before or after the
selection. I chose "before" because that's what I'm used to.
TerminalUI::set_on_key has
EventManager::instance().force_signal(0);
I'm not sure if we want the same for TerminalUI::set_on_paste?
I assume it doesn't matter because they are always called in tandem.
Closes #2465
|
|
If, for example, the buffer path now is a directory, MappedFile will
throw on construction. Using a try block to explicitely allow errors
fixes the issue.
|
|
|
|
From the issue:
> It often happens to me that I carefully craft a selection with multiple
> cursors, ready to make changes elegantly, only to completely mess it
> up by pressing a wrong key (by merging the cursors for example). Being
> able to undo the last selection change (even if only until the previous
> buffer change) would make this much less painful.
Fix this by recording selection changes and allowing simple linear
undo/redo of selection changes.
The preliminary key bindings are <c-h> and <c-k>.
Here are some other vacant normal mode keys I considered
X Y
<backspace> <minus>
# ^ =
<plus> '
unfortunately none of them is super convenient to type. Maybe we
can kick out some other normal mode command?
---
This feature has some overlap with the jump list (<c-o>/<c-i>) and
with undo (u) but each of the three features have their moment.
Currently there's no special integration with either peer feature;
the three histories are completely independent. In future we might
want to synchronize them so we can implement Sublime Text's "Soft
undo" feature.
Note that it is possible to restore selections that predate a buffer
modification. Depending on the buffer modification, the selections
might look different of course. (When trying to apply an old buffer's
selection to the new buffer, Kakoune computes a diff of the buffers
and updates the selection accordingly. This works quite well for
many practical examples.)
This makes us record the full history of all selections for each
client. This seems wasteful, we could set a limit. I don't expect
excessive memory usage in practice (we also keep the full history of
buffer changes) but I could be wrong.
Closes #898
|
|
This makes the function easier to find for newcomers because
to_string() is the obvious name. It enables format() to do the
conversion automatically which seems like good idea (since there is
no other obvious representation).
Of course this change makes it a bit harder to grep but that's not
a problem with clang tooling.
We need to cast the function in one place when calling transform()
but that's acceptable.
|
|
|
|
Fix atom text at display time, allow tabs/eol/etc... in display
atoms and escape them just-in-time
Fixes #4293
|
|
Fixes #3974
|
|
|
|
WinResize hooks could be triggered during shell evaluation, leading
to any state potentially getting mutated after a shell evaluation
call.
|
|
|
|
Instead of triggering a reload event when the timestamp of a buffer's
underlying file changes, do so when its contents are actually modified.
|
|
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
|
|
Fixes #2552
|
|
Currently expose an additional name, the format is up for
discussion.
Fixes #1855
Fixes #2569
Fixes #2672
|
|
|
|
A bug in client.cc was always forcing full redraws of the windows,
leading to much more terminal output traffic than necessary.
|
|
Fixes #3025
|
|
|
|
Hooks are now an enum class instead of passing strings around.
|
|
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
|
|
|
|
|
|
Window can be resized with an "offset_pos" flag, which means that
the resize took place on the top left corner of the window, leading
to a change in current window position. This is treated as temporary
and the position change is stored in a m_position_offset field.
That allows the ncurses UI to offset the position when it displays
a Search menu, so that the window does not constantly scroll when
the search menu open/closes. The window will only scroll if it needs
to in order to keep the main selectin visible.
|
|
Fixes #2079
|
|
Add a UserInterface::is_ok method and return false on
SIGHUP/stdin closing/socket dropping
This should be cleaner and more robust than the previous SIGHUP
handling code.
Fixes #1594
|
|
set-face now takes a scope argument, and faces can be overridden on
a buffer or window basis.
colorscheme apply on global scope, which should be good enough for
now.
Fixes #1411
|