diff --git a/src/nvim/window.c b/src/nvim/window.c index 69c343e94b..7324af4995 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2997,6 +2997,10 @@ bool win_close_othertab(win_T *win, int free_buf, tabpage_T *tp, bool force) || (win->w_buffer != NULL && win->w_buffer->b_locked > 0)) { return false; // window is already being closed } + if (is_aucmd_win(win)) { + emsg(_(e_autocmd_close)); + return false; + } // Check if closing this window would leave only floating windows. if (tp->tp_firstwin == win && win->w_next && win->w_next->w_floating) { diff --git a/test/functional/autocmd/autocmd_spec.lua b/test/functional/autocmd/autocmd_spec.lua index fdf07a2d39..b4317a3e50 100644 --- a/test/functional/autocmd/autocmd_spec.lua +++ b/test/functional/autocmd/autocmd_spec.lua @@ -17,7 +17,6 @@ local pcall_err = t.pcall_err local fn = n.fn local expect = n.expect local command = n.command -local exc_exec = n.exc_exec local exec_lua = n.exec_lua local retry = t.retry local source = n.source @@ -151,7 +150,10 @@ describe('autocmd', function() }) command('autocmd BufLeave * bwipeout yy') - eq('Vim(edit):E143: Autocommands unexpectedly deleted new buffer yy', exc_exec('edit yy')) + eq( + 'Vim(edit):E143: Autocommands unexpectedly deleted new buffer yy', + pcall_err(command, 'edit yy') + ) expect([[ start of test file xx @@ -429,6 +431,23 @@ describe('autocmd', function() ) end) + it('cannot close `aucmd_win` in non-current tabpage', function() + exec([[ + file Xa + tabnew Xb + call setline(1, 'foo') + tabfirst + autocmd BufWriteCmd Xb tablast | bwipe! Xa + ]]) + eq( + 'BufWriteCmd Autocommands for "Xb": Vim(bwipeout):E813: Cannot close autocmd window', + pcall_err(command, 'wall') + ) + -- Sanity check: :bwipe failing to close all windows into Xa should keep it loaded. + -- (So there's no risk of it being left unloaded inside a window) + eq(1, eval('bufloaded("Xa")')) + end) + describe('closing last non-floating window in tab from `aucmd_win`', function() before_each(function() command('edit Xa.txt')