0
0
mirror of https://github.com/vim/vim.git synced 2025-09-25 03:54:15 -04:00

patch 8.2.2084: CTRL-V U doesn't work to enter a Unicode character

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)
This commit is contained in:
Bram Moolenaar
2020-12-03 19:54:42 +01:00
parent af0df47a76
commit 0684e36a7e
7 changed files with 35 additions and 30 deletions

View File

@@ -1534,7 +1534,6 @@ ins_ctrl_v(void)
{ {
int c; int c;
int did_putchar = FALSE; int did_putchar = FALSE;
int prev_mod_mask = mod_mask;
// may need to redraw when no more chars available now // may need to redraw when no more chars available now
ins_redraw(FALSE); ins_redraw(FALSE);
@@ -1550,7 +1549,9 @@ ins_ctrl_v(void)
add_to_showcmd_c(Ctrl_V); add_to_showcmd_c(Ctrl_V);
#endif #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) if (did_putchar)
// when the line fits in 'columns' the '^' is at the start of the next // when the line fits in 'columns' the '^' is at the start of the next
// line and will not removed by the redraw // line and will not removed by the redraw
@@ -1559,11 +1560,6 @@ ins_ctrl_v(void)
clear_showcmd(); clear_showcmd();
#endif #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); insert_special(c, FALSE, TRUE);
#ifdef FEAT_RIGHTLEFT #ifdef FEAT_RIGHTLEFT
revins_chars++; 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. * 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(). * If one or two digits are entered, the next character is given to vungetc().
* For Unicode a character > 255 may be returned. * 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 int
get_literal(void) get_literal(int noReduceKeys)
{ {
int cc; int cc;
int nc; int nc;
@@ -1878,6 +1876,9 @@ get_literal(void)
for (;;) for (;;)
{ {
nc = plain_vgetc(); nc = plain_vgetc();
if ((nc == ESC || nc == CSI) && !noReduceKeys)
nc = decodeModifyOtherKeys(nc);
#ifdef FEAT_CMDL_INFO #ifdef FEAT_CMDL_INFO
if (!(State & CMDLINE) && MB_BYTE2LEN_CHECK(nc) == 1) if (!(State & CMDLINE) && MB_BYTE2LEN_CHECK(nc) == 1)
add_to_showcmd(nc); add_to_showcmd(nc);
@@ -3812,8 +3813,7 @@ ins_ctrl_o(void)
{ {
if (State & VREPLACE_FLAG) if (State & VREPLACE_FLAG)
restart_edit = 'V'; restart_edit = 'V';
else else if (State & REPLACE_FLAG)
if (State & REPLACE_FLAG)
restart_edit = 'R'; restart_edit = 'R';
else else
restart_edit = 'I'; restart_edit = 'I';

View File

@@ -2206,13 +2206,14 @@ getcmdline_int(
case Ctrl_V: case Ctrl_V:
case Ctrl_Q: case Ctrl_Q:
{ {
int prev_mod_mask = mod_mask;
ignore_drag_release = TRUE; ignore_drag_release = TRUE;
putcmdline('^', TRUE); putcmdline('^', TRUE);
no_reduce_keys = TRUE; // don't merge modifyOtherKeys
c = get_literal(); // get next (two) character(s) // Get next (two) character(s). Do not change any
no_reduce_keys = FALSE; // 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 do_abbr = FALSE; // don't do abbreviation now
extra_char = NUL; extra_char = NUL;
// may need to remove ^ when composing char was typed // may need to remove ^ when composing char was typed
@@ -2223,13 +2224,6 @@ getcmdline_int(
msg_putchar(' '); msg_putchar(' ');
cursorcmd(); 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; break;

View File

@@ -2580,11 +2580,10 @@ handle_mapping(
typebuf.tb_off] == RM_YES)) typebuf.tb_off] == RM_YES))
&& !*timedout) && !*timedout)
{ {
keylen = check_termcode(max_mlen + 1, keylen = check_termcode(max_mlen + 1, NULL, 0, NULL);
NULL, 0, NULL);
// If no termcode matched but 'pastetoggle' matched partially it's // If no termcode matched but 'pastetoggle' matched partially
// like an incomplete key sequence. // it's like an incomplete key sequence.
if (keylen == 0 && save_keylen == KEYLEN_PART_KEY) if (keylen == 0 && save_keylen == KEYLEN_PART_KEY)
keylen = KEYLEN_PART_KEY; keylen = KEYLEN_PART_KEY;
@@ -3680,7 +3679,7 @@ getcmdkeycmd(
// CTRL-V is followed by octal, hex or other characters, reverses // CTRL-V is followed by octal, hex or other characters, reverses
// what AppendToRedobuffLit() does. // what AppendToRedobuffLit() does.
no_reduce_keys = TRUE; // don't merge modifyOtherKeys no_reduce_keys = TRUE; // don't merge modifyOtherKeys
c1 = get_literal(); c1 = get_literal(TRUE);
no_reduce_keys = FALSE; no_reduce_keys = FALSE;
} }

View File

@@ -4927,7 +4927,7 @@ nv_replace(cmdarg_T *cap)
if (cap->nchar == Ctrl_V) if (cap->nchar == Ctrl_V)
{ {
had_ctrl_v = 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. // Don't redo a multibyte character with CTRL-V.
if (cap->nchar > DEL) if (cap->nchar > DEL)
had_ctrl_v = NUL; had_ctrl_v = NUL;
@@ -5208,7 +5208,7 @@ nv_vreplace(cmdarg_T *cap)
else else
{ {
if (cap->extra_char == Ctrl_V) // get another character 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(cap->extra_char);
stuffcharReadbuff(ESC); stuffcharReadbuff(ESC);
if (virtual_active()) if (virtual_active())

View File

@@ -10,7 +10,7 @@ void display_dollar(colnr_T col);
void undisplay_dollar(void); void undisplay_dollar(void);
void truncate_spaces(char_u *line); void truncate_spaces(char_u *line);
void backspace_until_column(int col); 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 insertchar(int c, int flags, int second_indent);
void start_arrow(pos_T *end_insert_pos); void start_arrow(pos_T *end_insert_pos);
int stop_arrow(void); int stop_arrow(void);

View File

@@ -1966,6 +1966,16 @@ func RunTest_modifyOtherKeys(func)
bwipe aaa bwipe aaa
bwipe bbb 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! bwipe!
set timeoutlen& set timeoutlen&
endfunc endfunc

View File

@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
2084,
/**/ /**/
2083, 2083,
/**/ /**/