# HG changeset patch # User Christian Brabandt # Date 1504112405 -7200 # Node ID 2738b0cc5f648852bac060e12d6cf86a37309eed # Parent b593a0cc67933867c77d3f027a59a32d185d5a42 patch 8.0.1020: when a timer calls getchar(1) input is overwritten commit https://github.com/vim/vim/commit/0f0f230012f5a9beb6876158a17b432534836c6f Author: Bram Moolenaar Date: Wed Aug 30 18:52:56 2017 +0200 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 https://github.com/vim/vim/issues/1940) diff --git a/src/getchar.c b/src/getchar.c --- a/src/getchar.c +++ b/src/getchar.c @@ -125,7 +125,7 @@ static int vgetorpeek(int); static void map_free(mapblock_T **); static void validate_maphash(void); static void showmap(mapblock_T *mp, int local); -static int inchar(char_u *buf, int maxlen, long wait_time, int tb_change_cnt); +static int inchar(char_u *buf, int maxlen, long wait_time); #ifdef FEAT_EVAL static char_u *eval_map_expr(char_u *str, int c); #endif @@ -462,8 +462,7 @@ flush_buffers(int flush_typeahead) * of an escape sequence. * 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, - typebuf.tb_change_cnt) != 0) + while (inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 10L) != 0) ; typebuf.tb_off = MAXMAPLEN; typebuf.tb_len = 0; @@ -2046,8 +2045,7 @@ vgetorpeek(int advance) if (got_int) { /* flush all input */ - c = inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 0L, - typebuf.tb_change_cnt); + c = inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 0L); /* * If inchar() returns TRUE (script file was active) or we * are inside a mapping, get out of insert mode. @@ -2610,8 +2608,7 @@ vgetorpeek(int advance) && (p_timeout || (keylen == KEYLEN_PART_KEY && p_ttimeout)) && (c = inchar(typebuf.tb_buf + typebuf.tb_off - + typebuf.tb_len, 3, 25L, - typebuf.tb_change_cnt)) == 0) + + typebuf.tb_len, 3, 25L)) == 0) { colnr_T col = 0, vcol; char_u *ptr; @@ -2848,7 +2845,7 @@ vgetorpeek(int advance) ? -1L : ((keylen == KEYLEN_PART_KEY && p_ttm >= 0) ? p_ttm - : p_tm)), typebuf.tb_change_cnt); + : p_tm))); #ifdef FEAT_CMDL_INFO if (i != 0) @@ -2954,12 +2951,12 @@ vgetorpeek(int advance) inchar( char_u *buf, int maxlen, - long wait_time, /* milli seconds */ - int tb_change_cnt) + long wait_time) /* milli seconds */ { int len = 0; /* init for GCC */ int retesc = FALSE; /* return ESC with gotint */ int script_char; + int tb_change_cnt = typebuf.tb_change_cnt; if (wait_time == -1L || wait_time > 100L) /* flush output before waiting */ { @@ -3065,9 +3062,17 @@ inchar( len = ui_inchar(buf, maxlen / 3, 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)) 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); } diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -770,6 +770,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1020, +/**/ 1019, /**/ 1018,