]> granicus.if.org Git - vim/commitdiff
patch 8.2.4002: first char typed in Select mode can be wrong v8.2.4002
authorzeertzjq <zeertzjq@outlook.com>
Tue, 4 Jan 2022 18:01:21 +0000 (18:01 +0000)
committerBram Moolenaar <Bram@vim.org>
Tue, 4 Jan 2022 18:01:21 +0000 (18:01 +0000)
Problem:    First char typed in Select mode can be wrong.
Solution:   Escape special bytes in the input buffer. (closes #9469)

src/getchar.c
src/testdir/test_utf8.vim
src/version.c

index fa8c574d9f1ec9f6cfb81571ea4922adb2163d2b..6fecc1a2897e28be7a3ba1946e68ba0b1d289055 100644 (file)
@@ -1121,7 +1121,7 @@ ins_typebuf(
     int
 ins_char_typebuf(int c, int modifier)
 {
-    char_u     buf[MB_MAXBYTES + 4];
+    char_u     buf[MB_MAXBYTES * 3 + 4];
     int                len = 0;
 
     if (modifier != 0)
@@ -1142,8 +1142,18 @@ ins_char_typebuf(int c, int modifier)
     }
     else
     {
-       len += (*mb_char2bytes)(c, buf + len);
-       buf[len] = NUL;
+       char_u  *p = buf + len;
+       int     char_len = (*mb_char2bytes)(c, p);
+#ifdef FEAT_GUI
+       int     save_gui_in_use = gui.in_use;
+
+       gui.in_use = FALSE;
+#endif
+       // if the character contains CSI or K_SPECIAL bytes they need escaping
+       len += fix_input_buffer(p, char_len);
+#ifdef FEAT_GUI
+       gui.in_use = save_gui_in_use;
+#endif
     }
     (void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent);
     return len;
@@ -3644,7 +3654,6 @@ fix_input_buffer(char_u *buf, int len)
            p += 2;
            i -= 2;
        }
-# ifndef MSWIN
        // When the GUI is not used CSI needs to be escaped.
        else if (!gui.in_use && p[0] == CSI)
        {
@@ -3654,7 +3663,6 @@ fix_input_buffer(char_u *buf, int len)
            *p = (int)KE_CSI;
            len += 2;
        }
-# endif
        else
 #endif
        if (p[0] == NUL || (p[0] == K_SPECIAL
index 250df0bf9a220e4f1bea9aa3846a979cf75e38de..0210ce63c56d22eb82873579732514862cf632b9 100644 (file)
@@ -1,5 +1,6 @@
 " Tests for Unicode manipulations
  
+source check.vim
 source view_util.vim
 
 " Visual block Insert adjusts for multi-byte char
@@ -206,4 +207,55 @@ func Test_print_overlong()
   bwipe!
 endfunc
 
+func Test_recording_with_select_mode_utf8()
+  call Run_test_recording_with_select_mode_utf8()
+endfunc
+
+func Run_test_recording_with_select_mode_utf8()
+  new
+
+  " No escaping
+  call feedkeys("qacc12345\<Esc>gH哦\<Esc>q", "tx")
+  call assert_equal("哦", getline(1))
+  call assert_equal("cc12345\<Esc>gH哦\<Esc>", @a)
+  call setline(1, 'asdf')
+  normal! @a
+  call assert_equal("哦", getline(1))
+
+  " 固 is 0xE5 0x9B 0xBA where 0x9B is CSI
+  call feedkeys("qacc12345\<Esc>gH固\<Esc>q", "tx")
+  call assert_equal("固", getline(1))
+  call assert_equal("cc12345\<Esc>gH固\<Esc>", @a)
+  call setline(1, 'asdf')
+  normal! @a
+  call assert_equal("固", getline(1))
+
+  " 四 is 0xE5 0x9B 0x9B where 0x9B is CSI
+  call feedkeys("qacc12345\<Esc>gH四\<Esc>q", "tx")
+  call assert_equal("四", getline(1))
+  call assert_equal("cc12345\<Esc>gH四\<Esc>", @a)
+  call setline(1, 'asdf')
+  normal! @a
+  call assert_equal("四", getline(1))
+
+  " 倒 is 0xE5 0x80 0x92 where 0x80 is K_SPECIAL
+  call feedkeys("qacc12345\<Esc>gH倒\<Esc>q", "tx")
+  call assert_equal("倒", getline(1))
+  call assert_equal("cc12345\<Esc>gH倒\<Esc>", @a)
+  call setline(1, 'asdf')
+  normal! @a
+  call assert_equal("倒", getline(1))
+
+  bwipe!
+endfunc
+
+" This must be done as one of the last tests, because it starts the GUI, which
+" cannot be undone.
+func Test_zz_recording_with_select_mode_utf8_gui()
+  CheckCanRunGui
+
+  gui -f
+  call Run_test_recording_with_select_mode_utf8()
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
index e4c5bb839cc9fc9830f2713fd8cb4431c32bb4d9..310a6a40fe35c6f4e05bc2092a84581d46f0032a 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4002,
 /**/
     4001,
 /**/