summaryrefslogtreecommitdiff
path: root/src/client.cc
AgeCommit message (Collapse)Author
2025-07-08Replace std::unique_ptr with a custom implementationMaxime Coste
<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.
2025-06-27Prevent changing Client's buffer while lockedMaxime Coste
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
2025-06-03Prevent deletion of buffers while creating new windowsMaxime Coste
`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
2025-03-24Default InputHandler::handle_key() synthesized argumentJohannes Altmanninger
We have only one place where we handle actual keys typed by the user.
2024-12-09Print elapsed time when blocked on opening file for writingJohannes Altmanninger
Extract the logic for "waiting for shell to finish" and reuse it for potentially blocking calls to open() that use the O_WRONLY flags.
2024-09-16Rename Window::display_position to display_coordMaxime Coste
2024-08-19Merge remote-tracking branch 'arrufat/includes-cleanup'Maxime Coste
2024-08-16include headers cleanupAdrià Arrufat
2024-08-14Reduce number of included headersMaxime Coste
2024-08-12Move debug utils to debug.hh/debug.ccMaxime Coste
Lots of code includes buffer_utils.hh just for write_to_debug_buffer which pulls many unnecessary dependencies. Reorganise to reduce compile times.
2024-08-12Move most info/status clear logic to clientMaxime Coste
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.
2024-07-22Handle word completion when recording macrosMaxime Coste
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.
2024-04-01Change mode_info to contain an optional NormalParamsMaxime Coste
As @topisani pointed out in #5131, it is more user friendly to always provide a %val{register} and %val{count} regardless of the mode.
2024-03-31Support exposing some env vars as part of the mode informationMaxime Coste
This should implement what #5131 proposed in a different way. Closes #5131
2024-03-31Revert "Send SIGTERM on <c-c>, to more reliably kill background jobs"Johannes Altmanninger
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.
2024-03-08Send SIGTERM on <c-c>, to more reliably kill background jobsJohannes Altmanninger
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.
2024-02-06Use different hash algorithms for strings and file hashingMaxime Coste
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.
2023-09-28Add an InlineInformation face distinct from InformationLoric Brevet
2023-09-02Do not make cursor visible after mouse scrolling and view commandsMaxime Coste
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.
2023-08-27Remove Window::force_redraw()Maxime Coste
This was mostly redundant with Client::force_redraw.
2023-05-21Add <c-g> to cancel current operationMaxime Coste
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().
2023-03-13Slight refactoring of bracketed paste featureMaxime Coste
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.
2023-03-11Implement bracketed pasteJohannes Altmanninger
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
2023-02-21Fix fatal exception when checking if buffer needs to be reloadedMaxime Coste
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.
2022-11-10Merge remote-tracking branch 'krobelus/undo-selection-change'Maxime Coste
2022-09-02Allow to undo and redo selection changesJohannes Altmanninger
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
2022-08-17Rename key_to_str() to the more idiomatic to_string()Johannes Altmanninger
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.
2021-09-21src: Show a `readonly` modeline tag when relevantFrank LENORMAND
2021-08-17Move control character escaping responsibility to the terminal UIMaxime Coste
Fix atom text at display time, allow tabs/eol/etc... in display atoms and escape them just-in-time Fixes #4293
2021-07-12Quit server on SIGINT when it was not signaled by Kakoune itselfMaxime Coste
Fixes #3974
2019-12-28Redraw relevant clients after adding/removing highlightersMaxime Coste
2019-12-16Fix WinResize hook getting triggered during urgent event processingMaxime Coste
WinResize hooks could be triggered during shell evaluation, leading to any state potentially getting mutated after a shell evaluation call.
2019-12-04Merge remote-tracking branch 'lenormf/reload-buffer-hash'Maxime Coste
2019-12-03src: Reload buffers when their contents' hash changesFrank LENORMAND
Instead of triggering a reload event when the timestamp of a buffer's underlying file changes, do so when its contents are actually modified.
2019-11-24Replace tab characters with spaces in info/echoMaxime Coste
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
2019-11-24Rework ncurses info display, crop content when overlflowingMaxime Coste
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
2019-11-22Add support for markup in info boxesMaxime Coste
Fixes #2552
2019-11-11Add mode information to next-key mode nameMaxime Coste
Currently expose an additional name, the format is up for discussion. Fixes #1855 Fixes #2569 Fixes #2672
2019-11-09Add static or const where usefulJason Felice
2019-09-26Remove unneeded NCursesUI::Window::mark_dirty and redrawsMaxime Coste
A bug in client.cc was always forcing full redraws of the windows, leading to much more terminal output traffic than necessary.
2019-07-22Ensure current context switches away from buffer on delete-bufferMaxime Coste
Fixes #3025
2019-02-27Fixed all reorder warningsJustin Frank
2018-10-23Refactor Hook management to have a well defined list of hooksMaxime Coste
Hooks are now an enum class instead of passing strings around.
2018-07-25Obtain a new window for a client before releasing the current oneMaxime Coste
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
2018-07-09Add BufReload hook which is triggered on buffer reloadChristopher Fredén
2018-06-19Change Search completion to display on top of the modelineMaxime Coste
2018-06-11Add position offset to Window to limit moves with search menu styleMaxime Coste
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.
2018-05-26Do not expose C++ typeid().name to user facing errors on wrong option typeMaxime Coste
Fixes #2079
2018-04-29Rework the way UI can trigger a client quittingMaxime Coste
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
2018-04-07Make FaceRegistry scopedMaxime Coste
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