The x11-terminal command spawns a potentially long-lived terminal
process. The terminal can is completely independent of the Kakoune
session that created it.
Due to how it's implemented, the spawned terminals will have
environment variables "kak_opt_termcmd" and "kak_quoted_reg_a"
set. This can be surprising, especially since, by convention, the
environment contains no lowercase variables. Let's stop exporting them.
Change the initial <c-h>/<c-k> bindings to the recently freed-up
<a-u></a-U>.
Pros:
- easier to remember
- the redo binding is logical.
- works on legacy terminals, unlike <c-h>
Cons:
- It's less convenient to toggle between selection undo and redo
keys. I think this is okay since this scenario does not happen that
often in practice.
When launch matches using `id` kitty tries to match against tab id
before matching windows. When there are multiple tabs it's likely to
match a tab before matching a window.
Use `window_id` directly to avoid any possiblity of matching tabs.
This is only needed for `kitty @ launch` for other commands there is
no specific `window_id` field.
%exp{...} just expands its content the same way double quoted strings
do, but using a named expansion type makes it possible to use the
more quoting mechanism to avoid quoting hell.
This continues the work started by 0a9c90fec (rc: use a separate
*-insert hook to auto-insert comments, 2021-04-17).
The one that's left is Rust but that one is trickier.
When Kakoune's terminal is shown on my laptop monitor and I plug
in my external monitor, the terminal's workspace will move to that
external monitor. When this happens, Kakoune may segfault.
There are multiple resize events (SIGWINCH) in quick succession;
it crashes because we handle SIGWINCH during rendering.
The problem happens during execution of "TerminalUI::Screen::output"
(frame #18). When we receive SIGWINCH while writing to stdout, write(2)
fails with EAGAIN, prompting us to handle pending events (See ae001a1f9
(Run EventManager whenever writing to a file descriptor would block,
2022-05-10)). We update the screen size in check_resize() here:
#4 Kakoune::TerminalUI::check_resize (force=<optimized out>) at terminal_ui.cc:683
#5 Kakoune::TerminalUI::get_next_key () at terminal_ui.cc:719
#6 operator() (__closure=0x555555984198) at terminal_ui.cc:484
#7 std::__invoke_impl<void, Kakoune::TerminalUI::TerminalUI()::<lambda(Kakoune::FDWatcher&, Kakoune::FdEvents, Kakoune::EventMode)>&, Kakoune::FDWatcher&, Kakoune::FdEvents, Kakoune::EventMode> (__f=...) at /usr/include/c++/12.2.1/bits/invoke.h:61
#8 std::__invoke_r<void, Kakoune::TerminalUI::TerminalUI()::<lambda(Kakoune::FDWatcher&, Kakoune::FdEvents, Kakoune::EventMode)>&, Kakoune::FDWatcher&, Kakoune::FdEvents, Kakoune::EventMode> (__fn=...) at /usr/include/c++/12.2.1/bits/invoke.h:111
#9 std::_Function_handler<void(Kakoune::FDWatcher&, Kakoune::FdEvents, Kakoune::EventMode), Kakoune::TerminalUI::TerminalUI()::<lambda(Kakoune::FDWatcher&, Kakoune::FdEvents, Kakoune::EventMode)> >::_M_invoke(const std::_Any_data &, Kakoune::FDWatcher &, Kakoune::FdEvents &&, Kakoune::EventMode &&) (__functor=..., __args#0=..., __args#1=<optimized out>, __args#2=<optimized out>) at /usr/include/c++/12.2.1/bits/std_function.h:290
#10 std::function<void (Kakoune::FDWatcher&, Kakoune::FdEvents, Kakoune::EventMode)>::operator()(Kakoune::FDWatcher&, Kakoune::FdEvents, Kakoune::EventMode) const (__args#2=<optimized out>, __args#1=<optimized out>, __args#0=...) at /usr/include/c++/12.2.1/bits/std_function.h:591
#11 Kakoune::FDWatcher::run (mode=Kakoune::EventMode::Urgent, events=<optimized out>) at event_manager.cc:28
#12 Kakoune::EventManager::handle_next_events (mode=mode@entry=Kakoune::EventMode::Urgent, sigmask=sigmask@entry=0x0, block=<optimized out>, block@entry=false) at event_manager.cc:143
#13 Kakoune::write (fd=1, data=...) at file.cc:273
#14 Kakoune::BufferedWriter<4096>::flush () at string.hh:236
#15 Kakoune::BufferedWriter<4096>::write (data="t file.hh:145
#16 Kakoune::TerminalUI::Screen::set_face (face=..., writer=...) at terminal_ui.cc:255
#17 operator() (line=..., __closure=<synthetic pointer>) at terminal_ui.cc:326
#18 Kakoune::TerminalUI::Screen::output (force=force@entry=true, synchronized=<optimized out>, writer=...) at terminal_ui.cc:402
#19 Kakoune::TerminalUI::redraw (force=force@entry=true) at terminal_ui.cc:571
#20 Kakoune::TerminalUI::refresh (force=<optimized out>) at terminal_ui.cc:592
#21 Kakoune::Client::redraw_ifn () at client.cc:282
#22 Kakoune::ClientManager::redraw_clients () at client_manager.cc:232
#23 Kakoune::run_server (session=..., server_init=..., client_init=..., init_buffer="fish-rust/src/ast.rs", init_coord=..., flags=Kakoune::ServerFlags::None, ui_type=Kakoune::UIType::Terminal,
debug_flags=<optimized out>, files=ArrayView<Kakoune::StringView> = {...}) at main.cc:893
#24 main (argc=<optimized out>, argv=<optimized out>) at main.cc:1243
Thereafter, "TerminalUI::Screen::output" resumes and crashes due to
a buffer overflow in "lines" which has been resized.
input_handler.cc:1476:16: error: alias template 'ConstArrayView' requires template arguments; argument deduction only allowed for class templates
insert(ConstArrayView{content});
^
input_handler.cc:1522:16: error: alias template 'ConstArrayView' requires template arguments; argument deduction only allowed for class templates
insert(ConstArrayView{str});
^
Whenever a new history node is committed after some undo steps, instead
of creating a new branch in the undo graph, we first append the inverse
modifications starting from the end of the undo list up to the current
position before adding the new node.
For example let's assume that the undo history is A-B-C, that a single undo
has been done (bringing us to state B) and that a new change D is committed.
Instead of creating a new branch starting at B, we add the inverse of C
(noted ^C) at the end, and D afterwards. This results in the undo history
A-B-C-^C-D. Since C-^C collapses to a null change, this is equivalent to
A-B-D but without having lost the C branch of the history.
If a new change is committed while no undo has been done, the new history
node is simply appended to the list, as was the case previously.
This results in a simplification of the user interaction, as two bindings
are now sufficient to walk the entire undo history, as opposed to needing
extra bindings to switch branches whenever they occur.
The <a-u> and <a-U> bindings are now free.
It also simplifies the implementation, as the graph traversal and
branching code are not needed anymore. The parent and child of a node are
now respectively the previous and the next elements in the list, so there
is no need to store their ID as part of the node.
Only the committing of an undo group is slightly more complex, as inverse
history nodes need to be added depending on the current position in the
undo list.
The following article was the initial motivation for this change:
https://github.com/zaboople/klonk/blob/master/TheGURQ.md
The previous code was assuming it was fine to push_next without
growing, which used to be the case with the previous implementation
because we always have poped the current thread that we try to push.
However now that we use a ring-buffer, m_next_begin == m_next_end can
either mean full, or empty. We solve this by assuming it means empty
and never allowing the buffer to become full, which means we need
to grow after pushing to next if we get full.
Fixes#4859
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