mirror of
https://github.com/neovim/neovim.git
synced 2026-02-21 09:50:19 +10:00
fix(terminal): inconsistent mode change when switching buffer (#37215)
Problem: When switching to another terminal buffer in Terminal mode,
usually Nvim stays in Terminal mode, but leaves Terminal mode
if the old terminal buffer was deleted.
Solution: Don't always leave Terminal mode when active terminal buffer
is deleted. Instead let terminal_check_focus() decide that.
(cherry picked from commit 3621af9b97)
This commit is contained in:
committed by
github-actions[bot]
parent
c124594b22
commit
bb31e7b345
@@ -868,6 +868,11 @@ static bool terminal_check_focus(TerminalState *const s)
|
||||
if (s->term != curbuf->terminal) {
|
||||
// Active terminal buffer changed, flush terminal's cursor state to the UI.
|
||||
terminal_focus(s->term, false);
|
||||
if (s->close) {
|
||||
s->term->destroy = true;
|
||||
s->term->opts.close_cb(s->term->opts.data);
|
||||
s->close = false;
|
||||
}
|
||||
|
||||
s->term = curbuf->terminal;
|
||||
s->term->pending.cursor = true;
|
||||
@@ -886,6 +891,9 @@ static int terminal_check(VimState *state)
|
||||
{
|
||||
TerminalState *const s = (TerminalState *)state;
|
||||
|
||||
// Shouldn't reach here when pressing a key to close the terminal buffer.
|
||||
assert(!s->close || (s->term->buf_handle == 0 && s->term != curbuf->terminal));
|
||||
|
||||
if (stop_insert_mode || !terminal_check_focus(s)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -905,7 +913,6 @@ static int terminal_check(VimState *state)
|
||||
s->term->refcount--;
|
||||
if (s->term->buf_handle == 0) {
|
||||
s->close = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Autocommands above may have changed focus, scrolled, or moved the cursor.
|
||||
@@ -978,7 +985,6 @@ static int terminal_execute(VimState *state, int key)
|
||||
s->term->refcount--;
|
||||
if (s->term->buf_handle == 0) {
|
||||
s->close = true;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -4,11 +4,12 @@ local Screen = require('test.functional.ui.screen')
|
||||
|
||||
local assert_alive = n.assert_alive
|
||||
local clear, poke_eventloop = n.clear, n.poke_eventloop
|
||||
local testprg, source, eq = n.testprg, n.source, t.eq
|
||||
local testprg, source, eq, neq = n.testprg, n.source, t.eq, t.neq
|
||||
local feed = n.feed
|
||||
local feed_command, eval = n.feed_command, n.eval
|
||||
local fn = n.fn
|
||||
local api = n.api
|
||||
local exec_lua = n.exec_lua
|
||||
local retry = t.retry
|
||||
local ok = t.ok
|
||||
local command = n.command
|
||||
@@ -156,6 +157,33 @@ describe(':terminal', function()
|
||||
feed('<Ignore>') -- Add input to separate two RPC requests
|
||||
eq({ blocking = false, mode = 'nt' }, api.nvim_get_mode())
|
||||
end)
|
||||
|
||||
it('switching to another terminal buffer in Terminal mode', function()
|
||||
command('terminal')
|
||||
local buf0 = api.nvim_get_current_buf()
|
||||
command('terminal')
|
||||
local buf1 = api.nvim_get_current_buf()
|
||||
command('terminal')
|
||||
local buf2 = api.nvim_get_current_buf()
|
||||
neq(buf0, buf1)
|
||||
neq(buf0, buf2)
|
||||
neq(buf1, buf2)
|
||||
feed('i')
|
||||
eq({ blocking = false, mode = 't' }, api.nvim_get_mode())
|
||||
api.nvim_set_current_buf(buf1)
|
||||
eq({ blocking = false, mode = 't' }, api.nvim_get_mode())
|
||||
api.nvim_set_current_buf(buf0)
|
||||
eq({ blocking = false, mode = 't' }, api.nvim_get_mode())
|
||||
exec_lua(function()
|
||||
vim.api.nvim_set_current_buf(buf1)
|
||||
vim.api.nvim_buf_delete(buf0, { force = true })
|
||||
end)
|
||||
eq({ blocking = false, mode = 't' }, api.nvim_get_mode())
|
||||
api.nvim_set_current_buf(buf2)
|
||||
eq({ blocking = false, mode = 't' }, api.nvim_get_mode())
|
||||
api.nvim_set_current_buf(buf1)
|
||||
eq({ blocking = false, mode = 't' }, api.nvim_get_mode())
|
||||
end)
|
||||
end)
|
||||
|
||||
local function test_terminal_with_fake_shell(backslash)
|
||||
|
||||
Reference in New Issue
Block a user