diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index f264446f15..1a8ab92195 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -125,6 +125,7 @@ static PMap(int) kitty_key_map = MAP_INIT; void tinput_init(TermInput *input, Loop *loop, TerminfoEntry *ti) { + assert(input->loop == NULL); input->loop = loop; input->paste = 0; input->in_fd = STDIN_FILENO; @@ -163,6 +164,7 @@ void tinput_destroy(TermInput *input) uv_close((uv_handle_t *)&input->bg_query_timer, NULL); rstream_may_close(&input->read_stream); termkey_destroy(input->tk); + input->loop = NULL; } void tinput_start(TermInput *input) diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index f457fc15c5..4da08a2209 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -596,7 +596,9 @@ static void tui_terminal_start(TUIData *tui) { tui->print_attr_id = -1; terminfo_start(tui); - tinput_init(&tui->input, &main_loop, &tui->ti); + if (tui->input.loop == NULL) { + tinput_init(&tui->input, &main_loop, &tui->ti); + } tui_guess_size(tui); tinput_start(&tui->input); } diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index 419b99e2b6..26f3867bd8 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -53,6 +53,48 @@ describe('TUI', function() end screen:expect({ any = vim.pesc('[Process exited 1]'), unchanged = true }) end) + + it('suspending does not crash or hang', function() + clear() + local screen = tt.setup_child_nvim({ '--clean', '--cmd', 'set notermguicolors' }) + local s0 = [[ + ^ | + ~ |*3 + {2:[No Name] 0,0-1 All}| + | + {5:-- TERMINAL --} | + ]] + screen:expect(s0) + feed_data(':') + local s1 = [[ + | + ~ |*3 + {2:[No Name] 0,0-1 All}| + :^ | + {5:-- TERMINAL --} | + ]] + screen:expect(s1) + feed_data('suspend\r') + if is_os('win') then -- no-op on Windows + screen:expect([[ + ^ | + ~ |*3 + {2:[No Name] 0,0-1 All}| + :suspend | + {5:-- TERMINAL --} | + ]]) + else -- resuming works on other platforms + screen:expect([[ + ^ | + |*5 + {5:-- TERMINAL --} | + ]]) + exec_lua([[vim.uv.kill(vim.fn.jobpid(vim.bo.channel), 'sigcont')]]) + screen:expect(s0) + end + feed_data(':') + screen:expect(s1) + end) end) describe('TUI :detach', function()