diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 69751a6903..6deb45ed27 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -21,6 +21,7 @@ #include "nvim/tui/input_defs.h" #include "nvim/tui/termkey/driver-csi.h" #include "nvim/tui/termkey/termkey.h" +#include "nvim/tui/termkey/termkey_defs.h" #include "nvim/tui/tui.h" #include "nvim/ui_client.h" @@ -248,6 +249,13 @@ static size_t handle_termkey_modifiers(TermKeyKey *key, char *buf, size_t buflen return len; } +enum { + KEYMOD_SUPER = 1 << 3, + KEYMOD_META = 1 << 5, + KEYMOD_RECOGNIZED = (TERMKEY_KEYMOD_SHIFT | TERMKEY_KEYMOD_ALT | TERMKEY_KEYMOD_CTRL + | KEYMOD_SUPER | KEYMOD_META), +}; + /// Handle modifiers not handled by libtermkey. /// Currently only Super ("D-") and Meta ("T-") are supported in Nvim. /// @@ -256,10 +264,10 @@ static size_t handle_more_modifiers(TermKeyKey *key, char *buf, size_t buflen) FUNC_ATTR_WARN_UNUSED_RESULT { size_t len = 0; - if (key->modifiers & 8) { // Super + if (key->modifiers & KEYMOD_SUPER) { len += (size_t)snprintf(buf + len, buflen - len, "D-"); } - if (key->modifiers & 32) { // Meta + if (key->modifiers & KEYMOD_META) { len += (size_t)snprintf(buf + len, buflen - len, "T-"); } assert(len < buflen); @@ -444,7 +452,7 @@ static void tk_getkeys(TermInput *input, bool force) continue; } - if (key.type == TERMKEY_TYPE_UNICODE && !key.modifiers) { + if (key.type == TERMKEY_TYPE_UNICODE && !(key.modifiers & KEYMOD_RECOGNIZED)) { forward_simple_utf8(input, &key); } else if (key.type == TERMKEY_TYPE_UNICODE || key.type == TERMKEY_TYPE_FUNCTION diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index b65f2cf0c0..99f8693235 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -440,19 +440,32 @@ describe('TUI', function() ]]) end) - it('interprets [27u as ', function() + it('interprets encoded with kitty keyboard protocol', function() child_session:request( 'nvim_exec2', [[ nnoremap nnoremap AESC + nnoremap ACtrlEsc + nnoremap ASuperEsc nnoremap ; Asemicolon ]], {} ) + -- Works with no modifier feed_data('\027[27u;') + expect_child_buf_lines({ 'ESCsemicolon' }) + -- Works with Ctrl modifier + feed_data('\027[27;5u') + expect_child_buf_lines({ 'ESCsemicolonCtrlEsc' }) + -- Works with Super modifier + feed_data('\027[27;9u') + expect_child_buf_lines({ 'ESCsemicolonCtrlEscSuperEsc' }) + -- Works with NumLock modifier (which should be the same as no modifier) #33799 + feed_data('\027[27;129u') + expect_child_buf_lines({ 'ESCsemicolonCtrlEscSuperEscESC' }) screen:expect([[ - ESCsemicolo^n | + ESCsemicolonCtrlEscSuperEscES^C | {4:~ }|*3 {5:[No Name] [+] }| | @@ -461,6 +474,7 @@ describe('TUI', function() -- ; should be recognized as when is mapped feed_data('\027;') screen:expect_unchanged() + expect_child_buf_lines({ 'ESCsemicolonCtrlEscSuperEscESC' }) end) it('interprets as #17198', function()