%bwipe!
endfunc
-" This used to trigger WinClosed twice for the same window, and the window's
-" buffer was NULL in the second autocommand.
-func Test_WinClosed_BufUnload_close_other()
- tabnew
+" This used to trigger WinClosed/WinLeave/BufLeave twice for the same window,
+" and the window's buffer was NULL in the second autocommand.
+func Run_test_BufUnload_close_other(extra_cmd)
+ let oldtab = tabpagenr()
+ tabnew Xb1
let g:tab = tabpagenr()
- let g:buf = bufnr()
- new
- setlocal bufhidden=wipe
- augroup test-WinClosed
- autocmd BufUnload * ++once exe g:buf .. 'bwipe!'
- autocmd WinClosed * call tabpagebuflist(g:tab)
+ let g:w1 = win_getid()
+ new Xb2
+ let g:w2 = win_getid()
+ let g:log = []
+ exe a:extra_cmd
+
+ augroup test-BufUnload-close-other
+ autocmd BufUnload * ++nested ++once bwipe! Xb1
+ for event in ['WinClosed', 'BufLeave', 'WinLeave', 'TabLeave']
+ exe $'autocmd {event} * call tabpagebuflist(g:tab)'
+ exe $'autocmd {event} * let g:log += ["{event}:" .. expand("<afile>")]'
+ endfor
augroup END
+
close
+ " WinClosed is triggered once for each of the 2 closed windows.
+ " Others are only triggered once.
+ call assert_equal(['BufLeave:Xb2', 'WinLeave:Xb2', $'WinClosed:{g:w2}',
+ \ $'WinClosed:{g:w1}', 'TabLeave:Xb2'], g:log)
+ call assert_equal(oldtab, tabpagenr())
+ call assert_equal([0, 0], win_id2tabwin(g:w1))
+ call assert_equal([0, 0], win_id2tabwin(g:w2))
unlet g:tab
- unlet g:buf
- autocmd! test-WinClosed
- augroup! test-WinClosed
+ unlet g:w1
+ unlet g:w2
+ unlet g:log
+ autocmd! test-BufUnload-close-other
+ augroup! test-BufUnload-close-other
%bwipe!
endfunc
+func Test_BufUnload_close_other()
+ call Run_test_BufUnload_close_other('')
+ call Run_test_BufUnload_close_other('setlocal bufhidden=wipe')
+endfunc
+
func s:AddAnAutocmd()
augroup vimBarTest
au BufReadCmd * echo 'hello'
* page and then close the window and the tab page. This avoids that
* curwin and curtab are invalid while we are freeing memory, they may
* be used in GUI events.
- * Don't trigger autocommands yet, they may use wrong values, so do
+ * Don't trigger *Enter autocommands yet, they may use wrong values, so do
* that below.
+ * Do trigger *Leave autocommands, unless win->w_buffer is NULL, in which
+ * case they have already been triggered.
*/
- goto_tabpage_tp(alt_tabpage(), FALSE, TRUE);
+ goto_tabpage_tp(alt_tabpage(), FALSE, win->w_buffer != NULL);
// Safety check: Autocommands may have closed the window when jumping
// to the other tab page.
win_comp_pos();
win_fix_scroll(FALSE);
}
+
if (close_curwin)
{
// Pass WEE_ALLOW_PARSE_MESSAGES to decrement dont_parse_messages
apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
}
+ if (ONE_WINDOW && curwin->w_locked && curbuf->b_locked_split
+ && first_tabpage->tp_next != NULL)
+ // The new curwin is the last window in the current tab page, and it is
+ // already being closed. Trigger TabLeave now, as after its buffer is
+ // removed it's no longer safe to do that.
+ apply_autocmds(EVENT_TABLEAVE, NULL, NULL, FALSE, curbuf);
+
--split_disallowed;
#ifdef MESSAGE_QUEUE
if (!did_decrement)