mirror of
https://github.com/neovim/neovim.git
synced 2026-03-31 21:02:11 +00:00
vim-patch:9.1.1211: TabClosedPre is triggered just before the tab is being freed
Problem: TabClosedPre is triggered just before the tab is being freed,
which limited its functionality.
Solution: Trigger it a bit earlier and also on :tabclose and :tabonly
(Jim Zhou)
closes: vim/vim#16890
bcf66e0141
Co-authored-by: Jim Zhou <jimzhouzzy@gmail.com>
This commit is contained in:
@@ -5150,6 +5150,8 @@ void tabpage_close(int forceit)
|
||||
return;
|
||||
}
|
||||
|
||||
trigger_tabclosedpre(curtab, true);
|
||||
|
||||
// First close all the windows but the current one. If that worked then
|
||||
// close the last window in this tab, that will close it.
|
||||
while (curwin->w_floating) {
|
||||
@@ -5172,6 +5174,8 @@ void tabpage_close_other(tabpage_T *tp, int forceit)
|
||||
int done = 0;
|
||||
char prev_idx[NUMBUFLEN];
|
||||
|
||||
trigger_tabclosedpre(tp, true);
|
||||
|
||||
// Limit to 1000 windows, autocommands may add a window while we close
|
||||
// one. OK, so I'm paranoid...
|
||||
while (++done < 1000) {
|
||||
|
||||
@@ -3102,9 +3102,12 @@ static void do_autocmd_winclosed(win_T *win)
|
||||
recursive = false;
|
||||
}
|
||||
|
||||
static void trigger_tabclosedpre(tabpage_T *tp)
|
||||
/// directly is true if the window is closed by ':tabclose' or ':tabonly'.
|
||||
/// This allows saving the session before closing multi-window tab.
|
||||
void trigger_tabclosedpre(tabpage_T *tp, bool directly)
|
||||
{
|
||||
static bool recursive = false;
|
||||
static bool skip = false;
|
||||
tabpage_T *ptp = curtab;
|
||||
|
||||
// Quickly return when no TabClosedPre autocommands to be executed or
|
||||
@@ -3113,8 +3116,17 @@ static void trigger_tabclosedpre(tabpage_T *tp)
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip if the event have been triggered by ':tabclose' recently
|
||||
if (skip) {
|
||||
skip = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (valid_tabpage(tp)) {
|
||||
goto_tabpage_tp(tp, false, false);
|
||||
if (directly) {
|
||||
skip = true;
|
||||
}
|
||||
}
|
||||
recursive = true;
|
||||
window_layout_lock();
|
||||
@@ -3187,7 +3199,7 @@ bool win_close_othertab(win_T *win, int free_buf, tabpage_T *tp, bool force)
|
||||
}
|
||||
|
||||
if (tp->tp_firstwin == tp->tp_lastwin) {
|
||||
trigger_tabclosedpre(tp);
|
||||
trigger_tabclosedpre(tp, false);
|
||||
// autocmd may have freed the window already.
|
||||
if (!win_valid_any_tab(win)) {
|
||||
return false;
|
||||
|
||||
@@ -4760,7 +4760,7 @@ func Test_autocmd_tabclosedpre()
|
||||
call ClearAutomcdAndCreateTabs()
|
||||
au TabClosedPre * tabmove 0
|
||||
tabclose
|
||||
call assert_equal('1Z2A3>B', GetTabs())
|
||||
call assert_equal('1>Z2A3B', GetTabs())
|
||||
call ClearAutomcdAndCreateTabs()
|
||||
au TabClosedPre * tabmove 0
|
||||
tabclose 1
|
||||
@@ -4788,7 +4788,33 @@ func Test_autocmd_tabclosedpre()
|
||||
au TabClosedPre * new X | new Y | new Z
|
||||
call assert_fails('tabclose 1', 'E242')
|
||||
|
||||
" Test directly closing the tab page with ':tabclose'
|
||||
au!
|
||||
tabonly
|
||||
bw!
|
||||
e Z
|
||||
au TabClosedPre * mksession!
|
||||
tabnew A
|
||||
sp
|
||||
tabclose
|
||||
source Session.vim
|
||||
call assert_equal('1Z2>AA', GetTabs())
|
||||
|
||||
" Test directly closing the tab page with ':tabonly'
|
||||
" Z is closed before A. Hence A overwrites the session.
|
||||
au!
|
||||
tabonly
|
||||
bw!
|
||||
e Z
|
||||
au TabClosedPre * mksession!
|
||||
tabnew A
|
||||
tabnew B
|
||||
tabonly
|
||||
source Session.vim
|
||||
call assert_equal('1>A2B', GetTabs())
|
||||
|
||||
" Clean up
|
||||
call delete('Session.vim')
|
||||
au!
|
||||
only
|
||||
tabonly
|
||||
|
||||
Reference in New Issue
Block a user