From 8103527da7f12ff21c2566222748518ee093432c Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 16 Dec 2021 18:02:07 +0000 Subject: [PATCH] patch 8.2.3828: when opening a terminal from a timer first typed char is lost Problem: when opening a terminal from a timer the first typed character is lost. (Virginia Senioria) Solution: When opening a terminal while waiting for a character put K_IGNORE in the input buffer. --- src/edit.c | 9 +++++++-- src/terminal.c | 17 +++++++++++++++++ src/testdir/test_terminal.vim | 26 ++++++++++++++++++++++++++ src/version.c | 2 ++ 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/edit.c b/src/edit.c index 40d5c4e58..9ff1c184e 100644 --- a/src/edit.c +++ b/src/edit.c @@ -598,9 +598,14 @@ edit( { c = safe_vgetc(); - if (stop_insert_mode) + if (stop_insert_mode +#ifdef FEAT_TERMINAL + || (c == K_IGNORE && term_use_loop()) +#endif + ) { - // Insert mode ended, possibly from a callback. + // Insert mode ended, possibly from a callback, or a timer + // must have opened a terminal window. if (c != K_IGNORE && c != K_NOP) vungetc(c); count = 0; diff --git a/src/terminal.c b/src/terminal.c index 7efe071eb..8f80f9fa2 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -739,6 +739,23 @@ term_start( curwin->w_buffer = curbuf; ++curbuf->b_nwindows; } + else if (vgetc_busy +#ifdef FEAT_TIMERS + || timer_busy +#endif + || input_busy) + { + char_u ignore[4]; + + // When waiting for input need to return and possibly end up in + // terminal_loop() instead. + ignore[0] = K_SPECIAL; + ignore[1] = KS_EXTRA; + ignore[2] = KE_IGNORE; + ignore[3] = NUL; + ins_typebuf(ignore, REMAP_NONE, 0, TRUE, FALSE); + typebuf_was_filled = TRUE; + } } else { diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim index 3dc7776a9..3fda75dfb 100644 --- a/src/testdir/test_terminal.vim +++ b/src/testdir/test_terminal.vim @@ -1596,6 +1596,7 @@ endfunc " 4. 0.5 sec later: should be done, clean up func Test_terminal_statusline() CheckUnix + CheckFeature timers set statusline=x terminal @@ -1611,6 +1612,31 @@ func Test_terminal_statusline() set statusline= endfunc +func CheckTerminalWindowWorks(buf) + call WaitForAssert({-> assert_match('!sh \[running\]', term_getline(a:buf, 10))}) + call term_sendkeys(a:buf, "exit\") + call WaitForAssert({-> assert_match('!sh \[finished\]', term_getline(a:buf, 10))}) + call term_sendkeys(a:buf, ":q\") + call WaitForAssert({-> assert_match('^\~', term_getline(a:buf, 10))}) +endfunc + +func Test_start_terminal_from_timer() + CheckUnix + CheckFeature timers + + " Open a terminal window from a timer, typed text goes to the terminal + call writefile(["call timer_start(100, { -> term_start('sh') })"], 'XtimerTerm') + let buf = RunVimInTerminal('-S XtimerTerm', {}) + call CheckTerminalWindowWorks(buf) + + " do the same in Insert mode + call term_sendkeys(buf, ":call timer_start(200, { -> term_start('sh') })\a") + call CheckTerminalWindowWorks(buf) + + call StopVimInTerminal(buf) + call delete('XtimerTerm') +endfunc + func Test_terminal_window_focus() let winid1 = win_getid() terminal diff --git a/src/version.c b/src/version.c index c95477604..f7187769c 100644 --- a/src/version.c +++ b/src/version.c @@ -749,6 +749,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 3828, /**/ 3827, /**/ -- 2.40.0