Merge pull request #31932 from bfredl/termtab

fix(getchar): do not simplify keycodes in terminal mode
This commit is contained in:
bfredl
2025-01-14 14:46:34 +01:00
committed by GitHub
3 changed files with 83 additions and 9 deletions

View File

@@ -1518,9 +1518,11 @@ int merge_modifiers(int c_arg, int *modifiers)
if (*modifiers & MOD_MASK_CTRL) {
if ((c >= '`' && c <= 0x7f) || (c >= '@' && c <= '_')) {
c &= 0x1f;
if (c == NUL) {
c = K_ZERO;
if (!(State & MODE_TERMINAL) || !(c == 'I' || c == 'J' || c == 'M' || c == '[')) {
c &= 0x1f;
if (c == NUL) {
c = K_ZERO;
}
}
} else if (c == '6') {
// CTRL-6 is equivalent to CTRL-^

View File

@@ -1011,7 +1011,7 @@ static void terminal_send_key(Terminal *term, int c)
c = Ctrl_AT;
}
VTermKey key = convert_key(c, &mod);
VTermKey key = convert_key(&c, &mod);
if (key) {
vterm_keyboard_key(term->vt, key, mod);
@@ -1415,19 +1415,23 @@ static int term_selection_set(VTermSelectionMask mask, VTermStringFragment frag,
// }}}
// input handling {{{
static void convert_modifiers(int key, VTermModifier *statep)
static void convert_modifiers(int *key, VTermModifier *statep)
{
if (mod_mask & MOD_MASK_SHIFT) {
*statep |= VTERM_MOD_SHIFT;
}
if (mod_mask & MOD_MASK_CTRL) {
*statep |= VTERM_MOD_CTRL;
if (!(mod_mask & MOD_MASK_SHIFT) && *key >= 'A' && *key <= 'Z') {
// vterm interprets CTRL+A as SHIFT+CTRL, change to CTRL+a
*key += ('a' - 'A');
}
}
if (mod_mask & MOD_MASK_ALT) {
*statep |= VTERM_MOD_ALT;
}
switch (key) {
switch (*key) {
case K_S_TAB:
case K_S_UP:
case K_S_DOWN:
@@ -1459,11 +1463,11 @@ static void convert_modifiers(int key, VTermModifier *statep)
}
}
static VTermKey convert_key(int key, VTermModifier *statep)
static VTermKey convert_key(int *key, VTermModifier *statep)
{
convert_modifiers(key, statep);
switch (key) {
switch (*key) {
case K_BS:
return VTERM_KEY_BACKSPACE;
case K_S_TAB:
@@ -1791,7 +1795,7 @@ static bool send_mouse_event(Terminal *term, int c)
}
VTermModifier mod = VTERM_MOD_NONE;
convert_modifiers(c, &mod);
convert_modifiers(&c, &mod);
mouse_action(term, button, row, col - offset, pressed, mod);
return false;
}

View File

@@ -625,6 +625,74 @@ describe('terminal input', function()
]]):format(key))
end
end)
-- TODO(bfredl): getcharstr() erases the distinction between <C-I> and <Tab>.
-- If it was enhanced or replaced this could get folded into the test above.
it('can send TAB/C-I and ESC/C-[ separately', function()
clear()
local screen = tt.setup_child_nvim({
'-u',
'NONE',
'-i',
'NONE',
'--cmd',
'colorscheme vim',
'--cmd',
'set notermguicolors',
'--cmd',
'noremap <Tab> <cmd>echo "Tab!"<cr>',
'--cmd',
'noremap <C-i> <cmd>echo "Ctrl-I!"<cr>',
'--cmd',
'noremap <Esc> <cmd>echo "Esc!"<cr>',
'--cmd',
'noremap <C-[> <cmd>echo "Ctrl-[!"<cr>',
})
screen:expect([[
^ |
{4:~ }|*3
{5:[No Name] 0,0-1 All}|
|
{3:-- TERMINAL --} |
]])
feed('<tab>')
screen:expect([[
^ |
{4:~ }|*3
{5:[No Name] 0,0-1 All}|
Tab! |
{3:-- TERMINAL --} |
]])
feed('<c-i>')
screen:expect([[
^ |
{4:~ }|*3
{5:[No Name] 0,0-1 All}|
Ctrl-I! |
{3:-- TERMINAL --} |
]])
feed('<Esc>')
screen:expect([[
^ |
{4:~ }|*3
{5:[No Name] 0,0-1 All}|
Esc! |
{3:-- TERMINAL --} |
]])
feed('<c-[>')
screen:expect([[
^ |
{4:~ }|*3
{5:[No Name] 0,0-1 All}|
Ctrl-[! |
{3:-- TERMINAL --} |
]])
end)
end)
if is_os('win') then