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.

Raspunde prin e-mail lui