vim-patch:8.0.1020: when a timer calls getchar(1) input is overwritten

Problem:    When a timer calls getchar(1) input is overwritten.
Solution:   Increment tb_change_cnt in inchar(). (closes vim/vim#1940)
0f0f230012
This commit is contained in:
Jan Edmund Lazo 2018-08-22 15:05:09 -04:00
parent 90519107f2
commit c87510b0e8

View File

@ -434,8 +434,7 @@ void flush_buffers(int flush_typeahead)
* of an escape sequence. * of an escape sequence.
* In an xterm we get one char at a time and we have to get them all. * In an xterm we get one char at a time and we have to get them all.
*/ */
while (inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 10L, while (inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 10L) != 0)
typebuf.tb_change_cnt) != 0)
; ;
typebuf.tb_off = MAXMAPLEN; typebuf.tb_off = MAXMAPLEN;
typebuf.tb_len = 0; typebuf.tb_len = 0;
@ -1698,8 +1697,7 @@ static int vgetorpeek(int advance)
keylen = 0; keylen = 0;
if (got_int) { if (got_int) {
/* flush all input */ /* flush all input */
c = inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 0L, c = inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 0L);
typebuf.tb_change_cnt);
/* /*
* If inchar() returns TRUE (script file was active) or we * If inchar() returns TRUE (script file was active) or we
* are inside a mapping, get out of insert mode. * are inside a mapping, get out of insert mode.
@ -2085,8 +2083,7 @@ static int vgetorpeek(int advance)
&& (p_timeout && (p_timeout
|| (keylen == KEYLEN_PART_KEY && p_ttimeout)) || (keylen == KEYLEN_PART_KEY && p_ttimeout))
&& (c = inchar(typebuf.tb_buf + typebuf.tb_off && (c = inchar(typebuf.tb_buf + typebuf.tb_off
+ typebuf.tb_len, 3, 25L, + typebuf.tb_len, 3, 25L)) == 0) {
typebuf.tb_change_cnt)) == 0) {
colnr_T col = 0, vcol; colnr_T col = 0, vcol;
char_u *ptr; char_u *ptr;
@ -2269,7 +2266,7 @@ static int vgetorpeek(int advance)
? -1L ? -1L
: ((keylen == KEYLEN_PART_KEY && p_ttm >= 0) : ((keylen == KEYLEN_PART_KEY && p_ttm >= 0)
? p_ttm ? p_ttm
: p_tm)), typebuf.tb_change_cnt); : p_tm)));
if (i != 0) if (i != 0)
pop_showcmd(); pop_showcmd();
@ -2350,16 +2347,15 @@ static int vgetorpeek(int advance)
* Return the number of obtained characters. * Return the number of obtained characters.
* Return -1 when end of input script reached. * Return -1 when end of input script reached.
*/ */
int int inchar(
inchar (
char_u *buf, char_u *buf,
int maxlen, int maxlen,
long wait_time, /* milli seconds */ long wait_time // milli seconds
int tb_change_cnt
) )
{ {
int len = 0; // Init for GCC. int len = 0; // Init for GCC.
int retesc = false; // Return ESC with gotint. int retesc = false; // Return ESC with gotint.
const int tb_change_cnt = typebuf.tb_change_cnt;
if (wait_time == -1L || wait_time > 100L) { if (wait_time == -1L || wait_time > 100L) {
// flush output before waiting // flush output before waiting
@ -2430,10 +2426,19 @@ inchar (
len = os_inchar(buf, maxlen / 3, (int)wait_time, tb_change_cnt); len = os_inchar(buf, maxlen / 3, (int)wait_time, tb_change_cnt);
} }
// If the typebuf was changed further down, it is like nothing was added by
// this call.
if (typebuf_changed(tb_change_cnt)) { if (typebuf_changed(tb_change_cnt)) {
return 0; return 0;
} }
// Note the change in the typeahead buffer, this matters for when
// vgetorpeek() is called recursively, e.g. using getchar(1) in a timer
// function.
if (len > 0 && ++typebuf.tb_change_cnt == 0) {
typebuf.tb_change_cnt = 1;
}
return fix_input_buffer(buf, len); return fix_input_buffer(buf, len);
} }