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.
(cherry picked from commit 4b5364b423)
This commit is contained in:
zeertzjq
2025-05-02 17:40:24 +08:00
committed by github-actions[bot]
parent 710d561f88
commit 465c181581
4 changed files with 37 additions and 5 deletions

View File

@ -144,8 +144,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);

View File

@ -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;

View File

@ -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 {

View File

@ -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
})