Patch 8.2.4858
Problem: K_SPECIAL may be escaped twice.
Solution: Avoid double escaping. (closes #10340)
Files: src/highlight.c, src/misc2.c, src/proto/misc2.pro, src/term.c,
src/typval.c, src/testdir/test_eval_stuff.vim,
src/testdir/test_feedkeys.vim, src/testdir/test_functions.vim,
src/testdir/test_mapping.vim
*** ../vim-8.2.4857/src/highlight.c 2022-04-15 13:53:30.052708679 +0100
--- src/highlight.c 2022-05-02 22:44:31.680262165 +0100
***************
*** 1356,1362 ****
// 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);
if (len > 0) // recognized special char
off += len;
else // copy as normal char
--- 1356,1362 ----
// 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, FALSE, NULL);
if (len > 0) // recognized special char
off += len;
else // copy as normal char
*** ../vim-8.2.4857/src/misc2.c 2022-04-26 12:51:01.074682254 +0100
--- src/misc2.c 2022-05-02 22:44:31.680262165 +0100
***************
*** 1265,1270 ****
--- 1265,1271 ----
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,1291 ****
if (key == 0)
return 0;
! return special_to_buf(key, modifiers, flags & FSK_KEYCODE, 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.
* 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)
{
int dlen = 0;
--- 1275,1292 ----
if (key == 0)
return 0;
! 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 "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 escape_ks, char_u *dst)
{
int dlen = 0;
***************
*** 1303,1312 ****
dst[dlen++] = KEY2TERMCAP0(key);
dst[dlen++] = KEY2TERMCAP1(key);
}
! else if (has_mbyte && !keycode)
! dlen += (*mb_char2bytes)(key, dst + dlen);
! else if (keycode)
dlen = (int)(add_char2buf(key, dst + dlen) - dst);
else
dst[dlen++] = key;
--- 1304,1313 ----
dst[dlen++] = KEY2TERMCAP0(key);
dst[dlen++] = KEY2TERMCAP1(key);
}
! 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;
*** ../vim-8.2.4857/src/proto/misc2.pro 2021-08-06 20:51:33.896689086 +0100
--- src/proto/misc2.pro 2022-05-02 22:44:31.680262165 +0100
***************
*** 24,31 ****
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 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);
--- 24,31 ----
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 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);
*** ../vim-8.2.4857/src/term.c 2022-05-02 00:06:48.178821209 +0100
--- src/term.c 2022-05-02 22:44:31.680262165 +0100
***************
*** 6104,6110 ****
#endif
slen = trans_special(&src, result + dlen, FSK_KEYCODE
| ((flags & REPTERM_NO_SIMPLIFY) ? 0 : FSK_SIMPLIFY),
! did_simplify);
if (slen)
{
dlen += slen;
--- 6104,6110 ----
#endif
slen = trans_special(&src, result + dlen, FSK_KEYCODE
| ((flags & REPTERM_NO_SIMPLIFY) ? 0 : FSK_SIMPLIFY),
! TRUE, did_simplify);
if (slen)
{
dlen += slen;
*** ../vim-8.2.4857/src/typval.c 2022-03-27 16:29:49.880153368 +0100
--- src/typval.c 2022-05-02 22:44:31.684262162 +0100
***************
*** 2069,2079 ****
{
++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.
if (*p == '<')
! extra += 18;
}
}
--- 2069,2078 ----
{
++p;
// A "\<x>" form occupies at least 4 characters, and produces up
! // to 9 characters (6 for the char and 3 for a modifier):
! // reserve space for 5 extra.
if (*p == '<')
! extra += 5;
}
}
***************
*** 2168,2174 ****
if (p[1] != '*')
flags |= FSK_SIMPLIFY;
! extra = trans_special(&p, end, flags, NULL);
if (extra != 0)
{
end += extra;
--- 2167,2173 ----
if (p[1] != '*')
flags |= FSK_SIMPLIFY;
! extra = trans_special(&p, end, flags, FALSE,
NULL);
if (extra != 0)
{
end += extra;
*** ../vim-8.2.4857/src/testdir/test_eval_stuff.vim 2022-01-24
18:16:08.740970105 +0000
--- src/testdir/test_eval_stuff.vim 2022-05-02 22:44:31.680262165 +0100
***************
*** 595,598 ****
--- 595,620 ----
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
*** ../vim-8.2.4857/src/testdir/test_feedkeys.vim 2022-01-01
12:42:52.650052077 +0000
--- src/testdir/test_feedkeys.vim 2022-05-02 22:44:31.680262165 +0100
***************
*** 23,26 ****
--- 23,37 ----
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
*** ../vim-8.2.4857/src/testdir/test_functions.vim 2022-04-28
15:26:29.214947839 +0100
--- src/testdir/test_functions.vim 2022-05-02 22:44:31.680262165 +0100
***************
*** 2721,2728 ****
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) .. '>"'))
endfunc
" Test for screenattr(), screenchar() and screenchars() functions
--- 2721,2728 ----
call assert_equal('a', nr2char(97, 1))
call assert_equal('a', nr2char(97, 0))
! 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
*** ../vim-8.2.4857/src/testdir/test_mapping.vim 2022-04-26
12:29:38.960587911 +0100
--- src/testdir/test_mapping.vim 2022-05-02 22:44:31.680262165 +0100
***************
*** 1643,1646 ****
--- 1643,1661 ----
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
*** ../vim-8.2.4857/src/version.c 2022-05-02 10:45:58.663761912 +0100
--- src/version.c 2022-05-02 22:46:21.204248360 +0100
***************
*** 748,749 ****
--- 748,751 ----
{ /* Add new patch number below this line */
+ /**/
+ 4858,
/**/
--
>From "know your smileys":
:-& Eating spaghetti
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/vim_dev/20220502215438.9675F1C19BB%40moolenaar.net.