mirror of
https://github.com/neovim/neovim.git
synced 2026-07-19 07:31:35 +00:00
Merge pull request #37251 from zeertzjq/termclose
fix(terminal): crash when TermClose deletes other buffers
This commit is contained in:
@@ -648,10 +648,6 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i
|
||||
return true;
|
||||
}
|
||||
|
||||
if (buf->terminal) {
|
||||
buf_close_terminal(buf);
|
||||
}
|
||||
|
||||
// Always remove the buffer when there is no file name.
|
||||
if (buf->b_ffname == NULL) {
|
||||
del_buf = true;
|
||||
@@ -675,6 +671,18 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i
|
||||
|
||||
buf->b_nwindows = nwindows;
|
||||
|
||||
if (buf->terminal) {
|
||||
buf->b_locked_split++;
|
||||
buf_close_terminal(buf);
|
||||
buf->b_locked_split--;
|
||||
|
||||
// Must check this before calling buf_freeall(), otherwise is_curbuf will be true
|
||||
// in buf_freeall() but still false here, leading to a 0-line buffer.
|
||||
if (buf == curbuf && !is_curbuf) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
buf_freeall(buf, ((del_buf ? BFA_DEL : 0)
|
||||
+ (wipe_buf ? BFA_WIPE : 0)
|
||||
+ (ignore_abort ? BFA_IGNORE_ABORT : 0)));
|
||||
|
||||
@@ -20,13 +20,15 @@ describe('autocmd TermClose', function()
|
||||
clear()
|
||||
api.nvim_set_option_value('shell', testprg('shell-test'), {})
|
||||
command('set shellcmdflag=EXE shellredir= shellpipe= shellquote= shellxquote=')
|
||||
command('autocmd! nvim.terminal TermClose')
|
||||
end)
|
||||
|
||||
local function test_termclose_delete_own_buf()
|
||||
-- The terminal process needs to keep running so that TermClose isn't triggered immediately.
|
||||
api.nvim_set_option_value('shell', string.format('"%s" INTERACT', testprg('shell-test')), {})
|
||||
command('autocmd TermClose * bdelete!')
|
||||
command('terminal')
|
||||
local termbuf = api.nvim_get_current_buf()
|
||||
command(('autocmd TermClose * bdelete! %d'):format(termbuf))
|
||||
matches(
|
||||
'^TermClose Autocommands for "%*": Vim%(bdelete%):E937: Attempt to delete a buffer that is in use: term://',
|
||||
pcall_err(command, 'bdelete!')
|
||||
@@ -34,8 +36,7 @@ describe('autocmd TermClose', function()
|
||||
assert_alive()
|
||||
end
|
||||
|
||||
-- TODO: fixed after merging patches for `can_unload_buffer`?
|
||||
pending('TermClose deleting its own buffer, altbuf = buffer 1 #10386', function()
|
||||
it('TermClose deleting its own buffer, altbuf = buffer 1 #10386', function()
|
||||
test_termclose_delete_own_buf()
|
||||
end)
|
||||
|
||||
@@ -44,6 +45,29 @@ describe('autocmd TermClose', function()
|
||||
test_termclose_delete_own_buf()
|
||||
end)
|
||||
|
||||
it('TermClose deleting all other buffers', function()
|
||||
local oldbuf = api.nvim_get_current_buf()
|
||||
-- The terminal process needs to keep running so that TermClose isn't triggered immediately.
|
||||
api.nvim_set_option_value('shell', string.format('"%s" INTERACT', testprg('shell-test')), {})
|
||||
command(('autocmd TermClose * bdelete! %d'):format(oldbuf))
|
||||
command('horizontal terminal')
|
||||
neq(oldbuf, api.nvim_get_current_buf())
|
||||
command('bdelete!')
|
||||
feed('<C-G>') -- This shouldn't crash due to having a 0-line buffer.
|
||||
assert_alive()
|
||||
end)
|
||||
|
||||
it('TermClose switching back to terminal buffer', function()
|
||||
local buf = api.nvim_get_current_buf()
|
||||
api.nvim_open_term(buf, {})
|
||||
command(('autocmd TermClose * buffer %d | new'):format(buf))
|
||||
eq(
|
||||
'TermClose Autocommands for "*": Vim(buffer):E1546: Cannot switch to a closing buffer',
|
||||
pcall_err(command, 'bwipe!')
|
||||
)
|
||||
assert_alive()
|
||||
end)
|
||||
|
||||
it('triggers when fast-exiting terminal job stops', function()
|
||||
command('autocmd TermClose * let g:test_termclose = 23')
|
||||
command('terminal')
|
||||
|
||||
Reference in New Issue
Block a user