]> granicus.if.org Git - vim/commitdiff
patch 8.2.2084: CTRL-V U doesn't work to enter a Unicode character v8.2.2084
authorBram Moolenaar <Bram@vim.org>
Thu, 3 Dec 2020 18:54:42 +0000 (19:54 +0100)
committerBram Moolenaar <Bram@vim.org>
Thu, 3 Dec 2020 18:54:42 +0000 (19:54 +0100)
Problem:    CTRL-V U doesn't work to enter a Unicode character when
            modifyOtherKeys is effective. (Ken Takata)
Solution:   Add a flag to get_literal() for the shift key. (closes #7413)

src/edit.c
src/ex_getln.c
src/getchar.c
src/normal.c
src/proto/edit.pro
src/testdir/test_termcodes.vim
src/version.c

index 8c5cec3a76b046569f7d02be42a1c181bd06dc0c..a152d84499a77f68a2df9b2b8926c85aa293e02f 100644 (file)
@@ -1534,7 +1534,6 @@ ins_ctrl_v(void)
 {
     int                c;
     int                did_putchar = FALSE;
-    int                prev_mod_mask = mod_mask;
 
     // may need to redraw when no more chars available now
     ins_redraw(FALSE);
@@ -1550,7 +1549,9 @@ ins_ctrl_v(void)
     add_to_showcmd_c(Ctrl_V);
 #endif
 
-    c = get_literal();
+    // Do not change any modifyOtherKeys ESC sequence to a normal key for
+    // CTRL-SHIFT-V.
+    c = get_literal(mod_mask & MOD_MASK_SHIFT);
     if (did_putchar)
        // when the line fits in 'columns' the '^' is at the start of the next
        // line and will not removed by the redraw
@@ -1559,11 +1560,6 @@ ins_ctrl_v(void)
     clear_showcmd();
 #endif
 
-    if ((c == ESC || c == CSI) && !(prev_mod_mask & MOD_MASK_SHIFT))
-       // Using CTRL-V: Change any modifyOtherKeys ESC sequence to a normal
-       // key.  Don't do this for CTRL-SHIFT-V.
-       c = decodeModifyOtherKeys(c);
-
     insert_special(c, FALSE, TRUE);
 #ifdef FEAT_RIGHTLEFT
     revins_chars++;
@@ -1845,9 +1841,11 @@ del_char_after_col(int limit_col UNUSED)
  * A one, two or three digit decimal number is interpreted as its byte value.
  * If one or two digits are entered, the next character is given to vungetc().
  * For Unicode a character > 255 may be returned.
+ * If "noReduceKeys" is TRUE do not change any modifyOtherKeys ESC sequence
+ * into a normal key, return ESC.
  */
     int
-get_literal(void)
+get_literal(int noReduceKeys)
 {
     int                cc;
     int                nc;
@@ -1878,6 +1876,9 @@ get_literal(void)
     for (;;)
     {
        nc = plain_vgetc();
+       if ((nc == ESC || nc == CSI) && !noReduceKeys)
+           nc = decodeModifyOtherKeys(nc);
+
 #ifdef FEAT_CMDL_INFO
        if (!(State & CMDLINE) && MB_BYTE2LEN_CHECK(nc) == 1)
            add_to_showcmd(nc);
@@ -3812,8 +3813,7 @@ ins_ctrl_o(void)
 {
     if (State & VREPLACE_FLAG)
        restart_edit = 'V';
-    else
-       if (State & REPLACE_FLAG)
+    else if (State & REPLACE_FLAG)
        restart_edit = 'R';
     else
        restart_edit = 'I';
index 80a920486926c17b0e624a2b5a71c55b3bbf2216..54924c18892d6ec02f864d58e6ae3d6412d47526 100644 (file)
@@ -2206,13 +2206,14 @@ getcmdline_int(
        case Ctrl_V:
        case Ctrl_Q:
                {
-                   int  prev_mod_mask = mod_mask;
-
                    ignore_drag_release = TRUE;
                    putcmdline('^', TRUE);
-                   no_reduce_keys = TRUE;  //  don't merge modifyOtherKeys
-                   c = get_literal();      // get next (two) character(s)
-                   no_reduce_keys = FALSE;
+
+                   // Get next (two) character(s).  Do not change any
+                   // modifyOtherKeys ESC sequence to a normal key for
+                   // CTRL-SHIFT-V.
+                   c = get_literal(mod_mask & MOD_MASK_SHIFT);
+
                    do_abbr = FALSE;        // don't do abbreviation now
                    extra_char = NUL;
                    // may need to remove ^ when composing char was typed
@@ -2223,13 +2224,6 @@ getcmdline_int(
                        msg_putchar(' ');
                        cursorcmd();
                    }
-
-                   if ((c == ESC || c == CSI)
-                                         && !(prev_mod_mask & MOD_MASK_SHIFT))
-                       // Using CTRL-V: Change any modifyOtherKeys ESC
-                       // sequence to a normal key.  Don't do this for
-                       // CTRL-SHIFT-V.
-                       c = decodeModifyOtherKeys(c);
                }
 
                break;
index 42eed4a9e72e990f94fc83e4c3fe32a1f82dbec8..3f2ad3c5f8d4b29fec00e441757e264c424ee2f6 100644 (file)
@@ -2580,11 +2580,10 @@ handle_mapping(
                                                    typebuf.tb_off] == RM_YES))
                && !*timedout)
        {
-           keylen = check_termcode(max_mlen + 1,
-                                              NULL, 0, NULL);
+           keylen = check_termcode(max_mlen + 1, NULL, 0, NULL);
 
-           // If no termcode matched but 'pastetoggle' matched partially it's
-           // like an incomplete key sequence.
+           // If no termcode matched but 'pastetoggle' matched partially
+           // it's like an incomplete key sequence.
            if (keylen == 0 && save_keylen == KEYLEN_PART_KEY)
                keylen = KEYLEN_PART_KEY;
 
@@ -3680,7 +3679,7 @@ getcmdkeycmd(
            // CTRL-V is followed by octal, hex or other characters, reverses
            // what AppendToRedobuffLit() does.
            no_reduce_keys = TRUE;  //  don't merge modifyOtherKeys
-           c1 = get_literal();
+           c1 = get_literal(TRUE);
            no_reduce_keys = FALSE;
        }
 
index d90326feb27572842a614028308ae9bee1e6d6f3..da0ffc1498004fe30972cdbd89fe775e318ec6f3 100644 (file)
@@ -4927,7 +4927,7 @@ nv_replace(cmdarg_T *cap)
     if (cap->nchar == Ctrl_V)
     {
        had_ctrl_v = Ctrl_V;
-       cap->nchar = get_literal();
+       cap->nchar = get_literal(FALSE);
        // Don't redo a multibyte character with CTRL-V.
        if (cap->nchar > DEL)
            had_ctrl_v = NUL;
@@ -5208,7 +5208,7 @@ nv_vreplace(cmdarg_T *cap)
        else
        {
            if (cap->extra_char == Ctrl_V)      // get another character
-               cap->extra_char = get_literal();
+               cap->extra_char = get_literal(FALSE);
            stuffcharReadbuff(cap->extra_char);
            stuffcharReadbuff(ESC);
            if (virtual_active())
index 1b5f46daa428f93d719c9abacd4895872794429a..d1b34c36d86d7129665a86ceebff12aceea2d39e 100644 (file)
@@ -10,7 +10,7 @@ void display_dollar(colnr_T col);
 void undisplay_dollar(void);
 void truncate_spaces(char_u *line);
 void backspace_until_column(int col);
-int get_literal(void);
+int get_literal(int noReduceKeys);
 void insertchar(int c, int flags, int second_indent);
 void start_arrow(pos_T *end_insert_pos);
 int stop_arrow(void);
index 12e4dd3556152ce7d420b2a9fd121604e8fc956a..ec0208645b76286f216bac2385a44838ad4ce245 100644 (file)
@@ -1966,6 +1966,16 @@ func RunTest_modifyOtherKeys(func)
   bwipe aaa
   bwipe bbb
 
+  " Ctrl-V X 33 is 3
+  call setline(1, '')
+  call feedkeys("a\<C-V>" .. a:func('X', 2) .. "33\<Esc>", 'Lx!')
+  call assert_equal("3", getline(1))
+
+  " Ctrl-V U 12345 is Unicode 12345
+  call setline(1, '')
+  call feedkeys("a\<C-V>" .. a:func('U', 2) .. "12345\<Esc>", 'Lx!')
+  call assert_equal("\U12345", getline(1))
+
   bwipe!
   set timeoutlen&
 endfunc
index 0dfe4f064bb4144f41a9317ff0eb646f80e3d013..f3584c1d814b3fa091cbfe68ca65b21090412d69 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2084,
 /**/
     2083,
 /**/