mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 8.2.4858: K_SPECIAL may be escaped twice
Problem: K_SPECIAL may be escaped twice. Solution: Avoid double escaping. (closes #10340)
This commit is contained in:
parent
f4f579b46b
commit
db08887f24
@ -1356,7 +1356,7 @@ highlight_set_startstop_termcode(int idx, char_u *key, char_u *arg, int init)
|
||||
// Copy characters from arg[] to buf[], translating <> codes.
|
||||
for (p = arg, off = 0; off < 100 - 6 && *p; )
|
||||
{
|
||||
len = trans_special(&p, buf + off, FSK_SIMPLIFY, NULL);
|
||||
len = trans_special(&p, buf + off, FSK_SIMPLIFY, FALSE, NULL);
|
||||
if (len > 0) // recognized special char
|
||||
off += len;
|
||||
else // copy as normal char
|
||||
|
13
src/misc2.c
13
src/misc2.c
@ -1265,6 +1265,7 @@ trans_special(
|
||||
char_u **srcp,
|
||||
char_u *dst,
|
||||
int flags, // FSK_ values
|
||||
int escape_ks, // escape K_SPECIAL bytes in the character
|
||||
int *did_simplify) // FSK_SIMPLIFY and found <C-H> or <A-x>
|
||||
{
|
||||
int modifiers = 0;
|
||||
@ -1274,18 +1275,18 @@ trans_special(
|
||||
if (key == 0)
|
||||
return 0;
|
||||
|
||||
return special_to_buf(key, modifiers, flags & FSK_KEYCODE, dst);
|
||||
return special_to_buf(key, modifiers, escape_ks, dst);
|
||||
}
|
||||
|
||||
/*
|
||||
* Put the character sequence for "key" with "modifiers" into "dst" and return
|
||||
* the resulting length.
|
||||
* When "keycode" is TRUE prefer key code, e.g. K_DEL instead of DEL.
|
||||
* When "escape_ks" is TRUE escape K_SPECIAL bytes in the character.
|
||||
* The sequence is not NUL terminated.
|
||||
* This is how characters in a string are encoded.
|
||||
*/
|
||||
int
|
||||
special_to_buf(int key, int modifiers, int keycode, char_u *dst)
|
||||
special_to_buf(int key, int modifiers, int escape_ks, char_u *dst)
|
||||
{
|
||||
int dlen = 0;
|
||||
|
||||
@ -1303,10 +1304,10 @@ special_to_buf(int key, int modifiers, int keycode, char_u *dst)
|
||||
dst[dlen++] = KEY2TERMCAP0(key);
|
||||
dst[dlen++] = KEY2TERMCAP1(key);
|
||||
}
|
||||
else if (has_mbyte && !keycode)
|
||||
dlen += (*mb_char2bytes)(key, dst + dlen);
|
||||
else if (keycode)
|
||||
else if (escape_ks)
|
||||
dlen = (int)(add_char2buf(key, dst + dlen) - dst);
|
||||
else if (has_mbyte)
|
||||
dlen += (*mb_char2bytes)(key, dst + dlen);
|
||||
else
|
||||
dst[dlen++] = key;
|
||||
|
||||
|
@ -24,8 +24,8 @@ int vim_isspace(int x);
|
||||
int simplify_key(int key, int *modifiers);
|
||||
int handle_x_keys(int key);
|
||||
char_u *get_special_key_name(int c, int modifiers);
|
||||
int trans_special(char_u **srcp, char_u *dst, int flags, int *did_simplify);
|
||||
int special_to_buf(int key, int modifiers, int keycode, char_u *dst);
|
||||
int trans_special(char_u **srcp, char_u *dst, int flags, int escape_ks, int *did_simplify);
|
||||
int special_to_buf(int key, int modifiers, int escape_ks, char_u *dst);
|
||||
int find_special_key(char_u **srcp, int *modp, int flags, int *did_simplify);
|
||||
int may_adjust_key_for_ctrl(int modifiers, int key);
|
||||
int may_remove_shift_modifier(int modifiers, int key);
|
||||
|
@ -6104,7 +6104,7 @@ replace_termcodes(
|
||||
#endif
|
||||
slen = trans_special(&src, result + dlen, FSK_KEYCODE
|
||||
| ((flags & REPTERM_NO_SIMPLIFY) ? 0 : FSK_SIMPLIFY),
|
||||
did_simplify);
|
||||
TRUE, did_simplify);
|
||||
if (slen)
|
||||
{
|
||||
dlen += slen;
|
||||
|
@ -595,4 +595,26 @@ func Test_deep_recursion()
|
||||
call assert_fails("exe 'if ' .. repeat('(', 1002)", 'E1169: Expression too recursive: ((')
|
||||
endfunc
|
||||
|
||||
" K_SPECIAL in the modified character used be escaped, which causes
|
||||
" double-escaping with feedkeys() or as the return value of an <expr> mapping,
|
||||
" and doesn't match what getchar() returns,
|
||||
func Test_modified_char_no_escape_special()
|
||||
nnoremap <M-…> <Cmd>let g:got_m_ellipsis += 1<CR>
|
||||
call feedkeys("\<M-…>", 't')
|
||||
call assert_equal("\<M-…>", getchar())
|
||||
let g:got_m_ellipsis = 0
|
||||
call feedkeys("\<M-…>", 'xt')
|
||||
call assert_equal(1, g:got_m_ellipsis)
|
||||
func Func()
|
||||
return "\<M-…>"
|
||||
endfunc
|
||||
nmap <expr> <F2> Func()
|
||||
call feedkeys("\<F2>", 'xt')
|
||||
call assert_equal(2, g:got_m_ellipsis)
|
||||
delfunc Func
|
||||
nunmap <F2>
|
||||
unlet g:got_m_ellipsis
|
||||
nunmap <M-…>
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@ -23,4 +23,15 @@ func Test_feedkeys_with_abbreviation()
|
||||
iunabbrev trigger
|
||||
endfunc
|
||||
|
||||
func Test_feedkeys_escape_special()
|
||||
nnoremap … <Cmd>let g:got_ellipsis += 1<CR>
|
||||
call feedkeys('…', 't')
|
||||
call assert_equal('…', getcharstr())
|
||||
let g:got_ellipsis = 0
|
||||
call feedkeys('…', 'xt')
|
||||
call assert_equal(1, g:got_ellipsis)
|
||||
unlet g:got_ellipsis
|
||||
nunmap …
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@ -2721,8 +2721,8 @@ func Test_nr2char()
|
||||
call assert_equal('a', nr2char(97, 1))
|
||||
call assert_equal('a', nr2char(97, 0))
|
||||
|
||||
call assert_equal("\x80\xfc\b\xf4\x80\xfeX\x80\xfeX\x80\xfeX", eval('"\<M-' .. nr2char(0x100000) .. '>"'))
|
||||
call assert_equal("\x80\xfc\b\xfd\x80\xfeX\x80\xfeX\x80\xfeX\x80\xfeX\x80\xfeX", eval('"\<M-' .. nr2char(0x40000000) .. '>"'))
|
||||
call assert_equal("\x80\xfc\b" .. nr2char(0x100000), eval('"\<M-' .. nr2char(0x100000) .. '>"'))
|
||||
call assert_equal("\x80\xfc\b" .. nr2char(0x40000000), eval('"\<M-' .. nr2char(0x40000000) .. '>"'))
|
||||
endfunc
|
||||
|
||||
" Test for screenattr(), screenchar() and screenchars() functions
|
||||
|
@ -1643,4 +1643,19 @@ func Test_unmap_simplifiable()
|
||||
unmap <C-I>
|
||||
endfunc
|
||||
|
||||
func Test_expr_map_escape_special()
|
||||
nnoremap … <Cmd>let g:got_ellipsis += 1<CR>
|
||||
func Func()
|
||||
return '…'
|
||||
endfunc
|
||||
nmap <expr> <F2> Func()
|
||||
let g:got_ellipsis = 0
|
||||
call feedkeys("\<F2>", 'xt')
|
||||
call assert_equal(1, g:got_ellipsis)
|
||||
delfunc Func
|
||||
nunmap <F2>
|
||||
unlet g:got_ellipsis
|
||||
nunmap …
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@ -2069,11 +2069,10 @@ eval_string(char_u **arg, typval_T *rettv, int evaluate)
|
||||
{
|
||||
++p;
|
||||
// A "\<x>" form occupies at least 4 characters, and produces up
|
||||
// to 21 characters (3 * 6 for the char and 3 for a modifier):
|
||||
// reserve space for 18 extra.
|
||||
// Each byte in the char could be encoded as K_SPECIAL K_EXTRA x.
|
||||
// to 9 characters (6 for the char and 3 for a modifier):
|
||||
// reserve space for 5 extra.
|
||||
if (*p == '<')
|
||||
extra += 18;
|
||||
extra += 5;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2168,7 +2167,7 @@ eval_string(char_u **arg, typval_T *rettv, int evaluate)
|
||||
|
||||
if (p[1] != '*')
|
||||
flags |= FSK_SIMPLIFY;
|
||||
extra = trans_special(&p, end, flags, NULL);
|
||||
extra = trans_special(&p, end, flags, FALSE, NULL);
|
||||
if (extra != 0)
|
||||
{
|
||||
end += extra;
|
||||
|
@ -746,6 +746,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
4858,
|
||||
/**/
|
||||
4857,
|
||||
/**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user