summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-12-16 18:02:07 +0000
committerBram Moolenaar <Bram@vim.org>2021-12-16 18:02:07 +0000
commit8103527da7f12ff21c2566222748518ee093432c (patch)
tree5840fd003b0c0eb5852dfa683ac058efa224dddc
parentf79cbf6512863c167bc794035df067e3a3e474f3 (diff)
patch 8.2.3828: when opening a terminal from a timer first typed char is lostv8.2.3828
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.
-rw-r--r--src/edit.c9
-rw-r--r--src/terminal.c17
-rw-r--r--src/testdir/test_terminal.vim26
-rw-r--r--src/version.c2
4 files changed, 52 insertions, 2 deletions
diff --git a/src/edit.c b/src/edit.c
index 40d5c4e583..9ff1c184e2 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 7efe071eb5..8f80f9fa26 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 3dc7776a9d..3fda75dfb6 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\<CR>")
+ call WaitForAssert({-> assert_match('!sh \[finished\]', term_getline(a:buf, 10))})
+ call term_sendkeys(a:buf, ":q\<CR>")
+ 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') })\<CR>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 c95477604e..f7187769c8 100644
--- a/src/version.c
+++ b/src/version.c
@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3828,
+/**/
3827,
/**/
3826,