aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-07-14 06:50:36 +0800
committerGitHub <noreply@github.com>2024-07-14 06:50:36 +0800
commit49ba36becd0bbf1052802b846f418aee673b28a5 (patch)
tree78bb307b3e04463c54682510be43c1799672419f
parent1f748d46c3ef288b2d9a8b7dd2c9c931ed4f0059 (diff)
downloadrneovim-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.c88
-rw-r--r--test/old/testdir/test_selectmode.vim16
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