diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-07-14 06:50:36 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-14 06:50:36 +0800 |
commit | 49ba36becd0bbf1052802b846f418aee673b28a5 (patch) | |
tree | 78bb307b3e04463c54682510be43c1799672419f | |
parent | 1f748d46c3ef288b2d9a8b7dd2c9c931ed4f0059 (diff) | |
download | rneovim-49ba36becd0bbf1052802b846f418aee673b28a5.tar.gz rneovim-49ba36becd0bbf1052802b846f418aee673b28a5.tar.bz2 rneovim-49ba36becd0bbf1052802b846f418aee673b28a5.zip |
vim-patch:9.1.0580: :lmap mapping for keypad key not applied when typed in Select mode (#29693)
Problem: An :lmap mapping for a printable keypad key is not applied
when typing it in Select mode.
Solution: Change keypad key to ASCII after setting vgetc_char.
(zeertzjq)
closes: vim/vim#15245
https://github.com/vim/vim/commit/90a800274ded86d5d79dbea7ba647cd69b029b4e
-rw-r--r-- | src/nvim/getchar.c | 88 | ||||
-rw-r--r-- | test/old/testdir/test_selectmode.vim | 16 |
2 files changed, 60 insertions, 44 deletions
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 20c53703da..d6534a08ff 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -1634,6 +1634,50 @@ int vgetc(void) c = TO_SPECIAL(c2, c); } + // For a multi-byte character get all the bytes and return the + // converted character. + // Note: This will loop until enough bytes are received! + int n; + if ((n = MB_BYTE2LEN_CHECK(c)) > 1) { + no_mapping++; + buf[0] = (uint8_t)c; + for (int i = 1; i < n; i++) { + buf[i] = (uint8_t)vgetorpeek(true); + if (buf[i] == K_SPECIAL) { + // Must be a K_SPECIAL - KS_SPECIAL - KE_FILLER sequence, + // which represents a K_SPECIAL (0x80). + vgetorpeek(true); // skip KS_SPECIAL + vgetorpeek(true); // skip KE_FILLER + } + } + no_mapping--; + c = utf_ptr2char((char *)buf); + } + + // If mappings are enabled (i.e., not i_CTRL-V) and the user directly typed + // something with MOD_MASK_ALT (<M-/<A- modifier) that was not mapped, interpret + // <M-x> as <Esc>x rather than as an unbound <M-x> keypress. #8213 + // In Terminal mode, however, this is not desirable. #16202 #16220 + // Also do not do this for mouse keys, as terminals encode mouse events as + // CSI sequences, and MOD_MASK_ALT has a meaning even for unmapped mouse keys. + if (!no_mapping && KeyTyped && mod_mask == MOD_MASK_ALT + && !(State & MODE_TERMINAL) && !is_mouse_key(c)) { + mod_mask = 0; + int len = ins_char_typebuf(c, 0, false); + ins_char_typebuf(ESC, 0, false); + int old_len = len + 3; // K_SPECIAL KS_MODIFIER MOD_MASK_ALT takes 3 more bytes + ungetchars(old_len); + if (on_key_buf.size >= (size_t)old_len) { + on_key_buf.size -= (size_t)old_len; + } + continue; + } + + if (vgetc_char == 0) { + vgetc_mod_mask = mod_mask; + vgetc_char = c; + } + // a keypad or special function key was not mapped, use it like // its ASCII equivalent switch (c) { @@ -1713,50 +1757,6 @@ int vgetc(void) c = K_RIGHT; break; } - // For a multi-byte character get all the bytes and return the - // converted character. - // Note: This will loop until enough bytes are received! - int n; - if ((n = MB_BYTE2LEN_CHECK(c)) > 1) { - no_mapping++; - buf[0] = (uint8_t)c; - for (int i = 1; i < n; i++) { - buf[i] = (uint8_t)vgetorpeek(true); - if (buf[i] == K_SPECIAL) { - // Must be a K_SPECIAL - KS_SPECIAL - KE_FILLER sequence, - // which represents a K_SPECIAL (0x80). - vgetorpeek(true); // skip KS_SPECIAL - vgetorpeek(true); // skip KE_FILLER - } - } - no_mapping--; - c = utf_ptr2char((char *)buf); - } - - if (vgetc_char == 0) { - vgetc_mod_mask = mod_mask; - vgetc_char = c; - } - - // If mappings are enabled (i.e., not i_CTRL-V) and the user directly typed something with - // MOD_MASK_ALT (<M-/<A- modifier) that was not mapped, interpret <M-x> as <Esc>x rather - // than as an unbound <M-x> keypress. #8213 - // In Terminal mode, however, this is not desirable. #16202 #16220 - // Also do not do this for mouse keys, as terminals encode mouse events as CSI sequences, and - // MOD_MASK_ALT has a meaning even for unmapped mouse keys. - if (!no_mapping && KeyTyped && mod_mask == MOD_MASK_ALT && !(State & MODE_TERMINAL) - && !is_mouse_key(c)) { - mod_mask = 0; - int len = ins_char_typebuf(c, 0, false); - ins_char_typebuf(ESC, 0, false); - int old_len = len + 3; // K_SPECIAL KS_MODIFIER MOD_MASK_ALT takes 3 more bytes - ungetchars(old_len); - if (on_key_buf.size >= (size_t)old_len) { - on_key_buf.size -= (size_t)old_len; - } - continue; - } - break; } diff --git a/test/old/testdir/test_selectmode.vim b/test/old/testdir/test_selectmode.vim index 59a1deba65..34ccdae7d8 100644 --- a/test/old/testdir/test_selectmode.vim +++ b/test/old/testdir/test_selectmode.vim @@ -323,4 +323,20 @@ func Test_ins_ctrl_o_in_insert_mode_resets_selectmode() bwipe! endfunc +" Test that an :lmap mapping for a printable keypad key is applied when typing +" it in Select mode. +func Test_selectmode_keypad_lmap() + new + lnoremap <buffer> <kPoint> ??? + lnoremap <buffer> <kEnter> !!! + setlocal iminsert=1 + call setline(1, 'abcdef') + call feedkeys("gH\<kPoint>\<Esc>", 'tx') + call assert_equal(['???'], getline(1, '$')) + call feedkeys("gH\<kEnter>\<Esc>", 'tx') + call assert_equal(['!!!'], getline(1, '$')) + + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab |