From c87510b0e803f44ca06b16f831d6fa5c196da1de Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Wed, 22 Aug 2018 15:05:09 -0400 Subject: 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) https://github.com/vim/vim/commit/0f0f230012f5a9beb6876158a17b432534836c6f --- src/nvim/getchar.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index df185f1a5b..17168e7ca2 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -434,8 +434,7 @@ void 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; @@ -1698,8 +1697,7 @@ static int vgetorpeek(int advance) keylen = 0; 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. @@ -2085,8 +2083,7 @@ static int 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; @@ -2269,7 +2266,7 @@ static int vgetorpeek(int advance) ? -1L : ((keylen == KEYLEN_PART_KEY && p_ttm >= 0) ? p_ttm - : p_tm)), typebuf.tb_change_cnt); + : p_tm))); if (i != 0) pop_showcmd(); @@ -2350,16 +2347,15 @@ static int vgetorpeek(int advance) * Return the number of obtained characters. * Return -1 when end of input script reached. */ -int -inchar ( +int 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. + const int tb_change_cnt = typebuf.tb_change_cnt; if (wait_time == -1L || wait_time > 100L) { // flush output before waiting @@ -2430,10 +2426,19 @@ inchar ( 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)) { 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); } -- cgit From efa132da827f7df03ba9041e0db5b824fbacde6c Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Wed, 22 Aug 2018 15:39:38 -0400 Subject: vim-patch:8.0.1048: no test for what 8.0.1020 fixes Problem: No test for what 8.0.1020 fixes. Solution: Add test_feedinput(). Add a test. (Ozaki Kiichi, closes vim/vim#2046) https://github.com/vim/vim/commit/5e80de3f3e572805fe734b66bc42c13303ad9bdb --- src/nvim/testdir/test_timers.vim | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src') diff --git a/src/nvim/testdir/test_timers.vim b/src/nvim/testdir/test_timers.vim index 81ac2b6171..6450bf02e8 100644 --- a/src/nvim/testdir/test_timers.vim +++ b/src/nvim/testdir/test_timers.vim @@ -169,5 +169,25 @@ func Test_stop_all_in_callback() call assert_equal(0, len(info)) endfunc +func FeedAndPeek(timer) + call test_feedinput('a') + call getchar(1) +endfunc + +func Interrupt(timer) + call test_feedinput("\") +endfunc + +func Test_peek_and_get_char() + throw 'skipped: Nvim does not support test_feedinput()' + if !has('unix') && !has('gui_running') + return + endif + call timer_start(0, 'FeedAndPeek') + let intr = timer_start(100, 'Interrupt') + let c = getchar() + call assert_equal(char2nr('a'), c) + call timer_stop(intr) +endfunc " vim: shiftwidth=2 sts=2 expandtab -- cgit From 3b744f1ea273949069523a7d66d43f9ac1115317 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Thu, 23 Aug 2018 22:51:10 -0400 Subject: vim-patch:8.1.0052: when mapping to times out the next mapping is skipped Problem: When a mapping to times out the next mapping is skipped. Solution: Reset "timedout" when waiting for a character. (Christian Brabandt, closes vim/vim#2921) https://github.com/vim/vim/commit/83f4cbd973731872b633d6ba0caf850fb708d70c --- src/nvim/getchar.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 17168e7ca2..eb4146d8a5 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -2255,6 +2255,11 @@ static int vgetorpeek(int advance) /* * get a character: 3. from the user - get it */ + if (typebuf.tb_len == 0) { + // timedout may have been set while waiting for a mapping + // that has a RHS. + timedout = false; + } wait_tb_len = typebuf.tb_len; c = inchar(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len, typebuf.tb_buflen - typebuf.tb_off - typebuf.tb_len - 1, -- cgit From 96b3dbcea552313919095b73082be018c0530f84 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Wed, 22 Aug 2018 15:32:27 -0400 Subject: lint --- src/nvim/getchar.c | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index eb4146d8a5..f13bede076 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -434,8 +434,8 @@ void 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) != 0) - ; + while (inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 10L) != 0) { + } typebuf.tb_off = MAXMAPLEN; typebuf.tb_len = 0; // Reset the flag that text received from a client or from feedkeys() @@ -1696,21 +1696,20 @@ static int vgetorpeek(int advance) os_breakcheck(); /* check for CTRL-C */ keylen = 0; if (got_int) { - /* flush all input */ + // flush all input 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. - * Otherwise we behave like having gotten a CTRL-C. - * As a result typing CTRL-C in insert mode will - * really insert a CTRL-C. - */ + // If inchar() returns TRUE (script file was active) or we + // are inside a mapping, get out of insert mode. + // Otherwise we behave like having gotten a CTRL-C. + // As a result typing CTRL-C in insert mode will + // really insert a CTRL-C. if ((c || typebuf.tb_maplen) - && (State & (INSERT + CMDLINE))) + && (State & (INSERT + CMDLINE))) { c = ESC; - else + } else { c = Ctrl_C; - flush_buffers(TRUE); /* flush all typeahead */ + } + flush_buffers(true); // flush all typeahead if (advance) { /* Also record this character, it might be needed to @@ -2073,17 +2072,17 @@ static int vgetorpeek(int advance) c = 0; new_wcol = curwin->w_wcol; new_wrow = curwin->w_wrow; - if ( advance - && typebuf.tb_len == 1 - && typebuf.tb_buf[typebuf.tb_off] == ESC - && !no_mapping - && ex_normal_busy == 0 - && typebuf.tb_maplen == 0 - && (State & INSERT) - && (p_timeout - || (keylen == KEYLEN_PART_KEY && p_ttimeout)) - && (c = inchar(typebuf.tb_buf + typebuf.tb_off - + typebuf.tb_len, 3, 25L)) == 0) { + if (advance + && typebuf.tb_len == 1 + && typebuf.tb_buf[typebuf.tb_off] == ESC + && !no_mapping + && ex_normal_busy == 0 + && typebuf.tb_maplen == 0 + && (State & INSERT) + && (p_timeout + || (keylen == KEYLEN_PART_KEY && p_ttimeout)) + && (c = inchar(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len, + 3, 25L)) == 0) { colnr_T col = 0, vcol; char_u *ptr; -- cgit