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

6da9f757c4
(cherry picked from commit e704529909)
This commit is contained in:
zeertzjq
2026-02-07 23:03:21 +08:00
committed by github-actions[bot]
parent 37738d5ae0
commit 5f6b195402
3 changed files with 37 additions and 3 deletions

View File

@@ -1638,6 +1638,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.
@@ -1650,8 +1651,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()) {

View File

@@ -4008,7 +4008,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

View File

@@ -868,4 +868,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