From e70452990935fedd7de6ca84dde4a0ac16807fd9 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 7 Feb 2026 23:03:21 +0800 Subject: [PATCH] vim-patch:9.1.2136: :tab sbuffer may close old tabpage (#37765) Problem: :tab sbuffer may close old tabpage if BufLeave autocommand splits window (after 9.1.0143). Solution: Only close other windows if the buffer will be unloaded (zeertzjq). related: neovim/neovim#37749 closes: vim/vim#19352 https://github.com/vim/vim/commit/6da9f757c48ce87df381d726b165bed6fa301423 --- src/nvim/buffer.c | 5 +++-- test/old/testdir/test_autocmd.vim | 2 +- test/old/testdir/test_buffer.vim | 33 +++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index ba6e03a729..5a9939c0e6 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1680,6 +1680,7 @@ void set_curbuf(buf_T *buf, int action, bool update_jumplist) bufref_T prevbufref; set_bufref(&prevbufref, prevbuf); set_bufref(&newbufref, buf); + const int prev_nwindows = prevbuf->b_nwindows; // Autocommands may delete the current buffer and/or the buffer we want to // go to. In those cases don't close the buffer. @@ -1692,8 +1693,8 @@ void set_curbuf(buf_T *buf, int action, bool update_jumplist) // autocommands may have opened a new window // with prevbuf, grr if (unload - || (last_winid != get_last_winid() - && strchr("wdu", prevbuf->b_p_bh[0]) != NULL)) { + || (prev_nwindows <= 1 && last_winid != get_last_winid() + && action == DOBUF_GOTO && !buf_hide(prevbuf))) { close_windows(prevbuf, false); } if (bufref_valid(&prevbufref) && !aborting()) { diff --git a/test/old/testdir/test_autocmd.vim b/test/old/testdir/test_autocmd.vim index b110b0f393..45dabcf4ce 100644 --- a/test/old/testdir/test_autocmd.vim +++ b/test/old/testdir/test_autocmd.vim @@ -4247,7 +4247,7 @@ func Test_autocmd_invalidates_undo_on_textchanged() call StopVimInTerminal(buf) endfunc -func Test_autocmd_creates_new_buffer_on_bufleave() +func Test_autocmd_creates_new_window_on_bufleave() e a.txt e b.txt setlocal bufhidden=wipe diff --git a/test/old/testdir/test_buffer.vim b/test/old/testdir/test_buffer.vim index 765faca2f6..997a952a14 100644 --- a/test/old/testdir/test_buffer.vim +++ b/test/old/testdir/test_buffer.vim @@ -882,4 +882,37 @@ func Test_bdelete_skip_closing_bufs() %bw! endfunc +func Test_split_window_in_BufLeave_from_tab_sbuffer() + tabnew Xa + setlocal bufhidden=wipe + let t0 = tabpagenr() + let b0 = bufnr() + let b1 = bufadd('Xb') + autocmd BufLeave Xa ++once split + exe 'tab sbuffer' b1 + call assert_equal(t0 + 1, tabpagenr()) + call assert_equal([b1, b0], tabpagebuflist()) + call assert_equal([b0], tabpagebuflist(t0)) + tabclose + call assert_equal(t0, tabpagenr()) + call assert_equal([b0], tabpagebuflist()) + + bwipe! Xa + bwipe! Xb +endfunc + +func Test_split_window_in_BufLeave_from_switching_buffer() + tabnew Xa + setlocal bufhidden=wipe + split + let b0 = bufnr() + let b1 = bufadd('Xb') + autocmd BufLeave Xa ++once split + exe 'buffer' b1 + call assert_equal([b1, b0, b0], tabpagebuflist()) + + bwipe! Xa + bwipe! Xb +endfunc + " vim: shiftwidth=2 sts=2 expandtab