neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit 4b5364b4231815ca1ba750068a68816e539d318f
parent 1fb0126a086de32daf800b773337bc8fc7996221
Author: zeertzjq <zeertzjq@outlook.com>
Date:   Fri,  2 May 2025 17:40:24 +0800

fix(tui): forward C0 control codes literally (#33759)

This fixes the problem that sending a raw C0 control code to trigger a
mapping for it does not work in Terminal mode.

Note: this isn't done for 00 or 7F, as that'll be backward-incompatible.
Diffstat:
Msrc/nvim/tui/input.c | 4++--
Msrc/nvim/tui/termkey/termkey.c | 4++--
Msrc/nvim/tui/termkey/termkey_defs.h | 1+
Mtest/functional/terminal/tui_spec.lua | 33++++++++++++++++++++++++++++++++-
4 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c @@ -145,8 +145,8 @@ void tinput_init(TermInput *input, Loop *loop) term = ""; // termkey_new_abstract assumes non-null (#2745) } - input->tk = termkey_new_abstract(term, - TERMKEY_FLAG_UTF8 | TERMKEY_FLAG_NOSTART); + input->tk = termkey_new_abstract(term, (TERMKEY_FLAG_UTF8 | TERMKEY_FLAG_NOSTART + | TERMKEY_FLAG_KEEPC0)); termkey_set_buffer_size(input->tk, INPUT_BUFFER_SIZE); termkey_hook_terminfo_getstr(input->tk, input->tk_ti_hook_fn, input); termkey_start(input->tk); diff --git a/src/nvim/tui/termkey/termkey.c b/src/nvim/tui/termkey/termkey.c @@ -719,7 +719,7 @@ static void emit_codepoint(TermKey *tk, int codepoint, TermKeyKey *key) key->type = TERMKEY_TYPE_KEYSYM; key->code.sym = TERMKEY_SYM_SPACE; key->modifiers = TERMKEY_KEYMOD_CTRL; - } else if (codepoint < 0x20) { + } else if (codepoint < 0x20 && !(tk->flags & TERMKEY_FLAG_KEEPC0)) { // C0 range key->code.codepoint = 0; key->modifiers = 0; @@ -750,7 +750,7 @@ static void emit_codepoint(TermKey *tk, int codepoint, TermKeyKey *key) key->type = TERMKEY_TYPE_KEYSYM; key->code.sym = TERMKEY_SYM_DEL; key->modifiers = 0; - } else if (codepoint >= 0x20 && codepoint < 0x80) { + } else if (codepoint > 0 && codepoint < 0x80) { // ASCII lowbyte range key->type = TERMKEY_TYPE_UNICODE; key->code.codepoint = codepoint; diff --git a/src/nvim/tui/termkey/termkey_defs.h b/src/nvim/tui/termkey/termkey_defs.h @@ -151,6 +151,7 @@ enum { TERMKEY_FLAG_CTRLC = 1 << 6, // Allow Ctrl-C to be read as normal, disabling SIGINT TERMKEY_FLAG_EINTR = 1 << 7, // Return ERROR on signal (EINTR) rather than retry TERMKEY_FLAG_NOSTART = 1 << 8, // Do not call termkey_start() in constructor + TERMKEY_FLAG_KEEPC0 = 1 << 9, // Keep raw C0 control codes }; enum { diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua @@ -486,6 +486,38 @@ describe('TUI', function() {3:-- INSERT --} | {3:-- TERMINAL --} | ]]) + child_session:request('nvim_set_keymap', 'i', '\031', '!!!', {}) + feed_data('\031') + screen:expect([[ + {6:^G^V^M}!!!^ | + {4:~ }|*3 + {5:[No Name] [+] }| + {3:-- INSERT --} | + {3:-- TERMINAL --} | + ]]) + child_session:request('nvim_buf_delete', 0, { force = true }) + child_session:request('nvim_set_option_value', 'laststatus', 0, {}) + child_session:request( + 'nvim_call_function', + 'jobstart', + { { testprg('shell-test'), 'INTERACT' }, { term = true } } + ) + screen:expect([[ + interact $ ^ | + |*4 + {3:-- TERMINAL --} |*2 + ]]) + -- mappings for C0 control codes should work in Terminal mode #33750 + child_session:request('nvim_set_keymap', 't', '\031', '<Cmd>new<CR>', {}) + feed_data('\031') + screen:expect([[ + ^ | + {4:~ }| + {5:[No Name] }| + interact $ | + |*2 + {3:-- TERMINAL --} | + ]]) end) local function test_mouse_wheel(esc) @@ -1198,7 +1230,6 @@ describe('TUI', function() pending('tty-test complains about not owning the terminal -- actions/runner#241') end screen:set_default_attr_ids({ - [1] = { reverse = true }, -- focused cursor [3] = { bold = true }, [19] = { bold = true, background = 121, foreground = 0 }, -- StatusLineTerm })