diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2018-09-05 09:38:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-05 09:38:34 +0200 |
commit | bfe82d465035a1b792c4a17d7f7a759b61205e15 (patch) | |
tree | ae5a9585f80e4094a660bc8d65dc4917325597a5 /src | |
parent | 73849ceeb977c855af484b8bcb772b71e293768e (diff) | |
parent | f8e042f73242fe7395c415c611491303df474e3d (diff) | |
download | rneovim-bfe82d465035a1b792c4a17d7f7a759b61205e15.tar.gz rneovim-bfe82d465035a1b792c4a17d7f7a759b61205e15.tar.bz2 rneovim-bfe82d465035a1b792c4a17d7f7a759b61205e15.zip |
Merge #8888 from janlazo/vim-8.0.1020
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/getchar.c | 75 | ||||
-rw-r--r-- | src/nvim/testdir/test_timers.vim | 20 |
2 files changed, 62 insertions, 33 deletions
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index df185f1a5b..f13bede076 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -434,9 +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, - typebuf.tb_change_cnt) != 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() @@ -1697,22 +1696,20 @@ static int vgetorpeek(int advance) os_breakcheck(); /* check for CTRL-C */ keylen = 0; if (got_int) { - /* flush all input */ - c = inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 0L, - typebuf.tb_change_cnt); - /* - * 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. - */ + // 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 ((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 @@ -2075,18 +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, - typebuf.tb_change_cnt)) == 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; @@ -2258,6 +2254,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 <Nop> 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, @@ -2269,7 +2270,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 +2351,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 +2430,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); } 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("\<C-C>") +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 |