mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 03:18:16 +00:00
vim-patch:8.2.4867: listing of mapping with K_SPECIAL is wrong (#18419)
Problem: Listing of mapping with K_SPECIAL is wrong.
Solution: Adjust escaping of special characters. (closes vim/vim#10351)
ac402f4d64
Avoid overshadowing.
Cherry-pick Test_list_mapping() from Vim patches 8.2.{0148,2994}.
Fix rhs_is_noop.
This commit is contained in:
@@ -2902,7 +2902,8 @@ void set_maparg_lhs_rhs(const char_u *const orig_lhs, const size_t orig_lhs_len,
|
|||||||
replaced = replace_termcodes(orig_rhs, orig_rhs_len, &rhs_buf,
|
replaced = replace_termcodes(orig_rhs, orig_rhs_len, &rhs_buf,
|
||||||
REPTERM_DO_LT | REPTERM_NO_SIMPLIFY, NULL, cpo_flags);
|
REPTERM_DO_LT | REPTERM_NO_SIMPLIFY, NULL, cpo_flags);
|
||||||
mapargs->rhs_len = STRLEN(replaced);
|
mapargs->rhs_len = STRLEN(replaced);
|
||||||
mapargs->rhs_is_noop = false;
|
// XXX: even when orig_rhs is non-empty, replace_termcodes may produce an empty string.
|
||||||
|
mapargs->rhs_is_noop = orig_rhs[0] != NUL && mapargs->rhs_len == 0;
|
||||||
mapargs->rhs = xcalloc(mapargs->rhs_len + 1, sizeof(char_u));
|
mapargs->rhs = xcalloc(mapargs->rhs_len + 1, sizeof(char_u));
|
||||||
STRLCPY(mapargs->rhs, replaced, mapargs->rhs_len + 1);
|
STRLCPY(mapargs->rhs, replaced, mapargs->rhs_len + 1);
|
||||||
}
|
}
|
||||||
@@ -3765,12 +3766,7 @@ static void showmap(mapblock_T *mp, bool local)
|
|||||||
} else if (mp->m_str[0] == NUL) {
|
} else if (mp->m_str[0] == NUL) {
|
||||||
msg_puts_attr("<Nop>", HL_ATTR(HLF_8));
|
msg_puts_attr("<Nop>", HL_ATTR(HLF_8));
|
||||||
} else {
|
} else {
|
||||||
// Remove escaping of K_SPECIAL, because "m_str" is in a format to be used
|
msg_outtrans_special(mp->m_str, false, 0);
|
||||||
// as typeahead.
|
|
||||||
char_u *s = vim_strsave(mp->m_str);
|
|
||||||
vim_unescape_ks(s);
|
|
||||||
msg_outtrans_special(s, false, 0);
|
|
||||||
xfree(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp->m_desc != NULL) {
|
if (mp->m_desc != NULL) {
|
||||||
|
@@ -1671,11 +1671,13 @@ const char *str2special(const char **const sp, const bool replace_spaces, const
|
|||||||
{
|
{
|
||||||
static char buf[7];
|
static char buf[7];
|
||||||
|
|
||||||
// Try to un-escape a multi-byte character. Return the un-escaped
|
{
|
||||||
// string if it is a multi-byte character.
|
// Try to un-escape a multi-byte character. Return the un-escaped
|
||||||
const char *const p = mb_unescape(sp);
|
// string if it is a multi-byte character.
|
||||||
if (p != NULL) {
|
const char *const p = mb_unescape(sp);
|
||||||
return p;
|
if (p != NULL) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *str = *sp;
|
const char *str = *sp;
|
||||||
@@ -1698,18 +1700,24 @@ const char *str2special(const char **const sp, const bool replace_spaces, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!IS_SPECIAL(c)) {
|
if (!IS_SPECIAL(c)) {
|
||||||
const int len = utf_ptr2len((const char_u *)str);
|
*sp = str;
|
||||||
|
// Try to un-escape a multi-byte character after modifiers.
|
||||||
|
const char *p = mb_unescape(sp);
|
||||||
|
|
||||||
// Check for an illegal byte.
|
if (p == NULL) {
|
||||||
if (MB_BYTE2LEN((uint8_t)(*str)) > len) {
|
const int len = utf_ptr2len((const char_u *)str);
|
||||||
transchar_nonprint(curbuf, (char_u *)buf, c);
|
// Check for an illegal byte.
|
||||||
*sp = str + 1;
|
if (MB_BYTE2LEN((uint8_t)(*str)) > len) {
|
||||||
return buf;
|
transchar_nonprint(curbuf, (char_u *)buf, c);
|
||||||
|
*sp = str + 1;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
*sp = str + len;
|
||||||
|
p = str;
|
||||||
}
|
}
|
||||||
// Since 'special' is TRUE the multi-byte character 'c' will be
|
// Since 'special' is true the multi-byte character 'c' will be
|
||||||
// processed by get_special_key_name().
|
// processed by get_special_key_name().
|
||||||
c = utf_ptr2char((const char_u *)str);
|
c = utf_ptr2char((const char_u *)p);
|
||||||
*sp = str + len;
|
|
||||||
} else {
|
} else {
|
||||||
*sp = str + 1;
|
*sp = str + 1;
|
||||||
}
|
}
|
||||||
|
@@ -464,6 +464,40 @@ func Test_list_mappings()
|
|||||||
call assert_equal(['n ,n <Nop>'],
|
call assert_equal(['n ,n <Nop>'],
|
||||||
\ execute('nmap ,n')->trim()->split("\n"))
|
\ execute('nmap ,n')->trim()->split("\n"))
|
||||||
|
|
||||||
|
" verbose map
|
||||||
|
call assert_match("\tLast set from .*/test_mapping.vim line \\d\\+$",
|
||||||
|
\ execute('verbose map ,n')->trim()->split("\n")[1])
|
||||||
|
|
||||||
|
" character with K_SPECIAL byte in rhs
|
||||||
|
nmap foo …
|
||||||
|
call assert_equal(['n foo …'],
|
||||||
|
\ execute('nmap foo')->trim()->split("\n"))
|
||||||
|
|
||||||
|
" modified character with K_SPECIAL byte in rhs
|
||||||
|
nmap foo <M-…>
|
||||||
|
call assert_equal(['n foo <M-…>'],
|
||||||
|
\ execute('nmap foo')->trim()->split("\n"))
|
||||||
|
|
||||||
|
" character with K_SPECIAL byte in lhs
|
||||||
|
nmap … foo
|
||||||
|
call assert_equal(['n … foo'],
|
||||||
|
\ execute('nmap …')->trim()->split("\n"))
|
||||||
|
|
||||||
|
" modified character with K_SPECIAL byte in lhs
|
||||||
|
nmap <M-…> foo
|
||||||
|
call assert_equal(['n <M-…> foo'],
|
||||||
|
\ execute('nmap <M-…>')->trim()->split("\n"))
|
||||||
|
|
||||||
|
" map to CTRL-V
|
||||||
|
exe "nmap ,k \<C-V>"
|
||||||
|
call assert_equal(['n ,k <Nop>'],
|
||||||
|
\ execute('nmap ,k')->trim()->split("\n"))
|
||||||
|
|
||||||
|
" map with space at the beginning
|
||||||
|
exe "nmap \<C-V> w <Nop>"
|
||||||
|
call assert_equal(['n <Space>w <Nop>'],
|
||||||
|
\ execute("nmap \<C-V> w")->trim()->split("\n"))
|
||||||
|
|
||||||
nmapclear
|
nmapclear
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user