0
0
mirror of https://github.com/vim/vim.git synced 2025-09-27 04:14:06 -04:00

patch 8.2.4691: solution for <Cmd> in a mapping causes trouble

Problem:    Solution for <Cmd> in a mapping causes trouble.
Solution:   Use another solution: put back CTRL-O after reading the <Cmd>
            sequence.
This commit is contained in:
Bram Moolenaar
2022-04-04 22:09:30 +01:00
parent 1b76a8dfe2
commit ca9d8d2cb9
2 changed files with 31 additions and 23 deletions

View File

@@ -96,10 +96,6 @@ static void updatescript(int c);
static int vgetorpeek(int); static int vgetorpeek(int);
static int inchar(char_u *buf, int maxlen, long wait_time); static int inchar(char_u *buf, int maxlen, long wait_time);
// flags for vgetorpeek()
#define VGOP_ADVANCE 1 // really get the character
#define VGOP_NO_STUFF 2 // do not use the stuff buffer
/* /*
* Free and clear a buffer. * Free and clear a buffer.
*/ */
@@ -1724,7 +1720,7 @@ vgetc(void)
++allow_keys; ++allow_keys;
did_inc = TRUE; // mod_mask may change value did_inc = TRUE; // mod_mask may change value
} }
c = vgetorpeek(VGOP_ADVANCE); c = vgetorpeek(TRUE);
if (did_inc) if (did_inc)
{ {
--no_mapping; --no_mapping;
@@ -1742,8 +1738,8 @@ vgetc(void)
++no_mapping; ++no_mapping;
allow_keys = 0; // make sure BS is not found allow_keys = 0; // make sure BS is not found
c2 = vgetorpeek(VGOP_ADVANCE); // no mapping for these chars c2 = vgetorpeek(TRUE); // no mapping for these chars
c = vgetorpeek(VGOP_ADVANCE); c = vgetorpeek(TRUE);
--no_mapping; --no_mapping;
allow_keys = save_allow_keys; allow_keys = save_allow_keys;
if (c2 == KS_MODIFIER) if (c2 == KS_MODIFIER)
@@ -1766,7 +1762,7 @@ vgetc(void)
int j; int j;
// get menu path, it ends with a <CR> // get menu path, it ends with a <CR>
for (j = 0; (c = vgetorpeek(VGOP_ADVANCE)) != '\r'; ) for (j = 0; (c = vgetorpeek(TRUE)) != '\r'; )
{ {
name[j] = c; name[j] = c;
if (j < 199) if (j < 199)
@@ -1876,7 +1872,7 @@ vgetc(void)
buf[0] = c; buf[0] = c;
for (i = 1; i < n; ++i) for (i = 1; i < n; ++i)
{ {
buf[i] = vgetorpeek(VGOP_ADVANCE); buf[i] = vgetorpeek(TRUE);
if (buf[i] == K_SPECIAL if (buf[i] == K_SPECIAL
#ifdef FEAT_GUI #ifdef FEAT_GUI
|| (buf[i] == CSI) || (buf[i] == CSI)
@@ -1889,8 +1885,8 @@ vgetc(void)
// represents a CSI (0x9B), // represents a CSI (0x9B),
// or a K_SPECIAL - KS_EXTRA - KE_CSI, which is CSI // or a K_SPECIAL - KS_EXTRA - KE_CSI, which is CSI
// too. // too.
c = vgetorpeek(VGOP_ADVANCE); c = vgetorpeek(TRUE);
if (vgetorpeek(VGOP_ADVANCE) == KE_CSI && c == KS_EXTRA) if (vgetorpeek(TRUE) == KE_CSI && c == KS_EXTRA)
buf[i] = CSI; buf[i] = CSI;
} }
} }
@@ -1993,7 +1989,7 @@ vpeekc(void)
{ {
if (old_char != -1) if (old_char != -1)
return old_char; return old_char;
return vgetorpeek(0); return vgetorpeek(FALSE);
} }
#if defined(FEAT_TERMRESPONSE) || defined(FEAT_TERMINAL) || defined(PROTO) #if defined(FEAT_TERMRESPONSE) || defined(FEAT_TERMINAL) || defined(PROTO)
@@ -2968,11 +2964,11 @@ vungetc(int c)
* 3. from the user * 3. from the user
* This may do a blocking wait if "advance" is TRUE. * This may do a blocking wait if "advance" is TRUE.
* *
* if "flags & VGOP_ADVANCE" is non-zero (vgetc()): * if "advance" is TRUE (vgetc()):
* Really get the character. * Really get the character.
* KeyTyped is set to TRUE in the case the user typed the key. * KeyTyped is set to TRUE in the case the user typed the key.
* KeyStuffed is TRUE if the character comes from the stuff buffer. * KeyStuffed is TRUE if the character comes from the stuff buffer.
* if "flags & VGOP_ADVANCE" is zero (vpeekc()): * if "advance" is FALSE (vpeekc()):
* Just look whether there is a character available. * Just look whether there is a character available.
* Return NUL if not. * Return NUL if not.
* *
@@ -2981,9 +2977,8 @@ vungetc(int c)
* K_SPECIAL and CSI may be escaped, need to get two more bytes then. * K_SPECIAL and CSI may be escaped, need to get two more bytes then.
*/ */
static int static int
vgetorpeek(int flags) vgetorpeek(int advance)
{ {
int advance = flags & VGOP_ADVANCE;
int c, c1; int c, c1;
int timedout = FALSE; // waited for more than 1 second int timedout = FALSE; // waited for more than 1 second
// for mapping to complete // for mapping to complete
@@ -3027,9 +3022,7 @@ vgetorpeek(int flags)
/* /*
* get a character: 1. from the stuffbuffer * get a character: 1. from the stuffbuffer
*/ */
if (flags & VGOP_NO_STUFF) if (typeahead_char != 0)
c = 0;
else if (typeahead_char != 0)
{ {
c = typeahead_char; c = typeahead_char;
if (advance) if (advance)
@@ -3762,6 +3755,8 @@ getcmdkeycmd(
int c2; int c2;
int cmod = 0; int cmod = 0;
int aborted = FALSE; int aborted = FALSE;
int first = TRUE;
int got_ctrl_o = FALSE;
ga_init2(&line_ga, 1, 32); ga_init2(&line_ga, 1, 32);
@@ -3777,7 +3772,7 @@ getcmdkeycmd(
break; break;
} }
if (vgetorpeek(0 | VGOP_NO_STUFF) == NUL) if (vgetorpeek(FALSE) == NUL)
{ {
// incomplete <Cmd> is an error, because there is not much the user // incomplete <Cmd> is an error, because there is not much the user
// could do in this state. // could do in this state.
@@ -3787,13 +3782,22 @@ getcmdkeycmd(
} }
// Get one character at a time. // Get one character at a time.
c1 = vgetorpeek(VGOP_ADVANCE | VGOP_NO_STUFF); c1 = vgetorpeek(TRUE);
// do not use Ctrl_O at the start, stuff it back later
if (first && c1 == Ctrl_O)
{
got_ctrl_o = TRUE;
first = FALSE;
continue;
}
first = FALSE;
// Get two extra bytes for special keys // Get two extra bytes for special keys
if (c1 == K_SPECIAL) if (c1 == K_SPECIAL)
{ {
c1 = vgetorpeek(VGOP_ADVANCE | VGOP_NO_STUFF); c1 = vgetorpeek(TRUE);
c2 = vgetorpeek(VGOP_ADVANCE | VGOP_NO_STUFF); c2 = vgetorpeek(TRUE);
if (c1 == KS_MODIFIER) if (c1 == KS_MODIFIER)
{ {
cmod = c2; cmod = c2;
@@ -3840,6 +3844,8 @@ getcmdkeycmd(
} }
no_mapping--; no_mapping--;
if (got_ctrl_o)
stuffcharReadbuff(Ctrl_O);
if (aborted) if (aborted)
ga_clear(&line_ga); ga_clear(&line_ga);

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 */
/**/
4691,
/**/ /**/
4690, 4690,
/**/ /**/