forked from aniani/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: #16890 Signed-off-by: Jim Zhou <jimzhouzzy@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
21ac3a49b5
commit
bcf66e0141
@@ -6536,6 +6536,8 @@ tabpage_close(int forceit)
|
|||||||
if (window_layout_locked(CMD_tabclose))
|
if (window_layout_locked(CMD_tabclose))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
trigger_tabclosedpre(curtab, TRUE);
|
||||||
|
|
||||||
// First close all the windows but the current one. If that worked then
|
// First close all the windows but the current one. If that worked then
|
||||||
// close the last window in this tab, that will close it.
|
// close the last window in this tab, that will close it.
|
||||||
if (!ONE_WINDOW)
|
if (!ONE_WINDOW)
|
||||||
@@ -6559,6 +6561,8 @@ tabpage_close_other(tabpage_T *tp, int forceit)
|
|||||||
int done = 0;
|
int done = 0;
|
||||||
win_T *wp;
|
win_T *wp;
|
||||||
|
|
||||||
|
trigger_tabclosedpre(tp, TRUE);
|
||||||
|
|
||||||
// Limit to 1000 windows, autocommands may add a window while we close
|
// Limit to 1000 windows, autocommands may add a window while we close
|
||||||
// one. OK, so I'm paranoid...
|
// one. OK, so I'm paranoid...
|
||||||
while (++done < 1000)
|
while (++done < 1000)
|
||||||
|
@@ -102,4 +102,5 @@ int get_tab_number(tabpage_T *tp);
|
|||||||
char *check_colorcolumn(char_u *cc, win_T *wp);
|
char *check_colorcolumn(char_u *cc, win_T *wp);
|
||||||
int get_last_winid(void);
|
int get_last_winid(void);
|
||||||
int win_locked(win_T *wp);
|
int win_locked(win_T *wp);
|
||||||
|
void trigger_tabclosedpre(tabpage_T *tp, int directly);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
@@ -5109,7 +5109,7 @@ func Test_autocmd_tabclosedpre()
|
|||||||
call ClearAutomcdAndCreateTabs()
|
call ClearAutomcdAndCreateTabs()
|
||||||
au TabClosedPre * tabmove 0
|
au TabClosedPre * tabmove 0
|
||||||
tabclose
|
tabclose
|
||||||
call assert_equal('1Z2A3>B', GetTabs())
|
call assert_equal('1>Z2A3B', GetTabs())
|
||||||
call ClearAutomcdAndCreateTabs()
|
call ClearAutomcdAndCreateTabs()
|
||||||
au TabClosedPre * tabmove 0
|
au TabClosedPre * tabmove 0
|
||||||
tabclose 1
|
tabclose 1
|
||||||
@@ -5137,7 +5137,33 @@ func Test_autocmd_tabclosedpre()
|
|||||||
au TabClosedPre * new X | new Y | new Z
|
au TabClosedPre * new X | new Y | new Z
|
||||||
call assert_fails('tabclose 1', 'E242')
|
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
|
" Clean up
|
||||||
|
call delete('Session.vim')
|
||||||
au!
|
au!
|
||||||
only
|
only
|
||||||
tabonly
|
tabonly
|
||||||
|
@@ -704,6 +704,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1211,
|
||||||
/**/
|
/**/
|
||||||
1210,
|
1210,
|
||||||
/**/
|
/**/
|
||||||
|
22
src/window.c
22
src/window.c
@@ -2978,10 +2978,15 @@ trigger_winclosed(win_T *win)
|
|||||||
recursive = FALSE;
|
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, int directly)
|
||||||
{
|
{
|
||||||
static int recursive = FALSE;
|
static int recursive = FALSE;
|
||||||
|
static int skip = FALSE;
|
||||||
tabpage_T *ptp = curtab;
|
tabpage_T *ptp = curtab;
|
||||||
|
|
||||||
// Quickly return when no TabClosedPre autocommands to be executed or
|
// Quickly return when no TabClosedPre autocommands to be executed or
|
||||||
@@ -2989,8 +2994,19 @@ trigger_tabclosedpre(tabpage_T *tp)
|
|||||||
if (!has_tabclosedpre() || recursive)
|
if (!has_tabclosedpre() || recursive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Skip if the event have been triggered by ':tabclose' recently
|
||||||
|
if (skip)
|
||||||
|
{
|
||||||
|
skip = FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (valid_tabpage(tp))
|
if (valid_tabpage(tp))
|
||||||
|
{
|
||||||
goto_tabpage_tp(tp, FALSE, FALSE);
|
goto_tabpage_tp(tp, FALSE, FALSE);
|
||||||
|
if (directly)
|
||||||
|
skip = TRUE;
|
||||||
|
}
|
||||||
recursive = TRUE;
|
recursive = TRUE;
|
||||||
window_layout_lock();
|
window_layout_lock();
|
||||||
apply_autocmds(EVENT_TABCLOSEDPRE, NULL, NULL, FALSE, NULL);
|
apply_autocmds(EVENT_TABCLOSEDPRE, NULL, NULL, FALSE, NULL);
|
||||||
@@ -3382,7 +3398,7 @@ win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
|
|||||||
|
|
||||||
if (tp->tp_firstwin == tp->tp_lastwin)
|
if (tp->tp_firstwin == tp->tp_lastwin)
|
||||||
{
|
{
|
||||||
trigger_tabclosedpre(tp);
|
trigger_tabclosedpre(tp, FALSE);
|
||||||
// autocmd may have freed the window already.
|
// autocmd may have freed the window already.
|
||||||
if (!win_valid_any_tab(win))
|
if (!win_valid_any_tab(win))
|
||||||
return;
|
return;
|
||||||
|
Reference in New Issue
Block a user