aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2018-09-05 09:38:34 +0200
committerGitHub <noreply@github.com>2018-09-05 09:38:34 +0200
commitbfe82d465035a1b792c4a17d7f7a759b61205e15 (patch)
treeae5a9585f80e4094a660bc8d65dc4917325597a5 /src
parent73849ceeb977c855af484b8bcb772b71e293768e (diff)
parentf8e042f73242fe7395c415c611491303df474e3d (diff)
downloadrneovim-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.c75
-rw-r--r--src/nvim/testdir/test_timers.vim20
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