To: vim_dev@googlegroups.com Subject: Patch 8.2.4858 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 or { 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 "\" 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 "\" 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 mapping, + " and doesn't match what getchar() returns, + func Test_modified_char_no_escape_special() + nnoremap let g:got_m_ellipsis += 1 + call feedkeys("\", 't') + call assert_equal("\", getchar()) + let g:got_m_ellipsis = 0 + call feedkeys("\", 'xt') + call assert_equal(1, g:got_m_ellipsis) + func Func() + return "\" + endfunc + nmap Func() + call feedkeys("\", 'xt') + call assert_equal(2, g:got_m_ellipsis) + delfunc Func + nunmap + unlet g:got_m_ellipsis + nunmap + 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 … let g:got_ellipsis += 1 + 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('"\"')) ! call assert_equal("\x80\xfc\b\xfd\x80\xfeX\x80\xfeX\x80\xfeX\x80\xfeX\x80\xfeX", eval('"\"')) 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('"\"')) ! call assert_equal("\x80\xfc\b" .. nr2char(0x40000000), eval('"\"')) 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 endfunc + func Test_expr_map_escape_special() + nnoremap … let g:got_ellipsis += 1 + func Func() + return '…' + endfunc + nmap Func() + let g:got_ellipsis = 0 + call feedkeys("\", 'xt') + call assert_equal(1, g:got_ellipsis) + delfunc Func + nunmap + 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 -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///