mirror of
https://github.com/neovim/neovim
synced 2025-07-16 17:21:49 +00:00
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#1524590a800274d
(cherry picked from commit49ba36becd
)
This commit is contained in:
committed by
github-actions[bot]
parent
ae9aa58f9c
commit
07de890de6
@ -1633,6 +1633,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) {
|
||||
@ -1712,50 +1756,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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user