forked from aniani/vim
patch 8.2.3591: no event is triggered when closing a window
Problem: No event is triggered when closing a window. Solution: Add the WinClosed event. (Naohiro Ono, closes #9110)
This commit is contained in:
parent
a0fca17251
commit
23beefed73
@ -348,6 +348,7 @@ Name triggered by ~
|
|||||||
|
|
||||||
|WinNew| after creating a new window
|
|WinNew| after creating a new window
|
||||||
|TabNew| after creating a new tab page
|
|TabNew| after creating a new tab page
|
||||||
|
|WinClosed| after closing a window
|
||||||
|TabClosed| after closing a tab page
|
|TabClosed| after closing a tab page
|
||||||
|WinEnter| after entering another window
|
|WinEnter| after entering another window
|
||||||
|WinLeave| before leaving a window
|
|WinLeave| before leaving a window
|
||||||
@ -1280,6 +1281,12 @@ VimResume When the Vim instance is resumed after being
|
|||||||
VimSuspend When the Vim instance is suspended. Only when
|
VimSuspend When the Vim instance is suspended. Only when
|
||||||
CTRL-Z was typed inside Vim, not when the
|
CTRL-Z was typed inside Vim, not when the
|
||||||
SIGSTOP or SIGTSTP signal was sent to Vim.
|
SIGSTOP or SIGTSTP signal was sent to Vim.
|
||||||
|
*WinClosed*
|
||||||
|
WinClosed After closing a window. The pattern is
|
||||||
|
matched against the |window-ID|. Both
|
||||||
|
<amatch> and <afile> are set to the
|
||||||
|
|window-ID|. Non-recursive (event cannot
|
||||||
|
trigger itself).
|
||||||
*WinEnter*
|
*WinEnter*
|
||||||
WinEnter After entering another window. Not done for
|
WinEnter After entering another window. Not done for
|
||||||
the first window, when Vim has just started.
|
the first window, when Vim has just started.
|
||||||
|
@ -186,6 +186,7 @@ static struct event_name
|
|||||||
{"VimLeave", EVENT_VIMLEAVE},
|
{"VimLeave", EVENT_VIMLEAVE},
|
||||||
{"VimLeavePre", EVENT_VIMLEAVEPRE},
|
{"VimLeavePre", EVENT_VIMLEAVEPRE},
|
||||||
{"WinNew", EVENT_WINNEW},
|
{"WinNew", EVENT_WINNEW},
|
||||||
|
{"WinClosed", EVENT_WINCLOSED},
|
||||||
{"WinEnter", EVENT_WINENTER},
|
{"WinEnter", EVENT_WINENTER},
|
||||||
{"WinLeave", EVENT_WINLEAVE},
|
{"WinLeave", EVENT_WINLEAVE},
|
||||||
{"VimResized", EVENT_VIMRESIZED},
|
{"VimResized", EVENT_VIMRESIZED},
|
||||||
@ -2042,7 +2043,8 @@ apply_autocmds_group(
|
|||||||
|| event == EVENT_OPTIONSET
|
|| event == EVENT_OPTIONSET
|
||||||
|| event == EVENT_QUICKFIXCMDPOST
|
|| event == EVENT_QUICKFIXCMDPOST
|
||||||
|| event == EVENT_DIRCHANGED
|
|| event == EVENT_DIRCHANGED
|
||||||
|| event == EVENT_MODECHANGED)
|
|| event == EVENT_MODECHANGED
|
||||||
|
|| event == EVENT_WINCLOSED)
|
||||||
{
|
{
|
||||||
fname = vim_strsave(fname);
|
fname = vim_strsave(fname);
|
||||||
autocmd_fname_full = TRUE; // don't expand it later
|
autocmd_fname_full = TRUE; // don't expand it later
|
||||||
|
@ -270,6 +270,7 @@ func Test_win_tab_autocmd()
|
|||||||
|
|
||||||
augroup testing
|
augroup testing
|
||||||
au WinNew * call add(g:record, 'WinNew')
|
au WinNew * call add(g:record, 'WinNew')
|
||||||
|
au WinClosed * call add(g:record, 'WinClosed')
|
||||||
au WinEnter * call add(g:record, 'WinEnter')
|
au WinEnter * call add(g:record, 'WinEnter')
|
||||||
au WinLeave * call add(g:record, 'WinLeave')
|
au WinLeave * call add(g:record, 'WinLeave')
|
||||||
au TabNew * call add(g:record, 'TabNew')
|
au TabNew * call add(g:record, 'TabNew')
|
||||||
@ -286,8 +287,8 @@ func Test_win_tab_autocmd()
|
|||||||
call assert_equal([
|
call assert_equal([
|
||||||
\ 'WinLeave', 'WinNew', 'WinEnter',
|
\ 'WinLeave', 'WinNew', 'WinEnter',
|
||||||
\ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
|
\ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
|
||||||
\ 'WinLeave', 'TabLeave', 'TabClosed', 'WinEnter', 'TabEnter',
|
\ 'WinLeave', 'TabLeave', 'WinClosed', 'TabClosed', 'WinEnter', 'TabEnter',
|
||||||
\ 'WinLeave', 'WinEnter'
|
\ 'WinLeave', 'WinClosed', 'WinEnter'
|
||||||
\ ], g:record)
|
\ ], g:record)
|
||||||
|
|
||||||
let g:record = []
|
let g:record = []
|
||||||
@ -298,7 +299,7 @@ func Test_win_tab_autocmd()
|
|||||||
call assert_equal([
|
call assert_equal([
|
||||||
\ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
|
\ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
|
||||||
\ 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter',
|
\ 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter',
|
||||||
\ 'TabClosed'
|
\ 'WinClosed', 'TabClosed'
|
||||||
\ ], g:record)
|
\ ], g:record)
|
||||||
|
|
||||||
augroup testing
|
augroup testing
|
||||||
@ -307,6 +308,45 @@ func Test_win_tab_autocmd()
|
|||||||
unlet g:record
|
unlet g:record
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_WinClosed()
|
||||||
|
" Test that the pattern is matched against the closed window's ID, and both
|
||||||
|
" <amatch> and <afile> are set to it.
|
||||||
|
new
|
||||||
|
let winid = win_getid()
|
||||||
|
let g:matched = v:false
|
||||||
|
augroup test-WinClosed
|
||||||
|
autocmd!
|
||||||
|
execute 'autocmd WinClosed' winid 'let g:matched = v:true'
|
||||||
|
autocmd WinClosed * let g:amatch = str2nr(expand('<amatch>'))
|
||||||
|
autocmd WinClosed * let g:afile = str2nr(expand('<afile>'))
|
||||||
|
augroup END
|
||||||
|
close
|
||||||
|
call assert_true(g:matched)
|
||||||
|
call assert_equal(winid, g:amatch)
|
||||||
|
call assert_equal(winid, g:afile)
|
||||||
|
|
||||||
|
" Test that WinClosed is non-recursive.
|
||||||
|
new
|
||||||
|
new
|
||||||
|
call assert_equal(3, winnr('$'))
|
||||||
|
let g:triggered = 0
|
||||||
|
augroup test-WinClosed
|
||||||
|
autocmd!
|
||||||
|
autocmd WinClosed * let g:triggered += 1
|
||||||
|
autocmd WinClosed * 2 wincmd c
|
||||||
|
augroup END
|
||||||
|
close
|
||||||
|
call assert_equal(1, winnr('$'))
|
||||||
|
call assert_equal(1, g:triggered)
|
||||||
|
|
||||||
|
autocmd! test-WinClosed
|
||||||
|
augroup! test-WinClosed
|
||||||
|
unlet g:matched
|
||||||
|
unlet g:amatch
|
||||||
|
unlet g:afile
|
||||||
|
unlet g:triggered
|
||||||
|
endfunc
|
||||||
|
|
||||||
func s:AddAnAutocmd()
|
func s:AddAnAutocmd()
|
||||||
augroup vimBarTest
|
augroup vimBarTest
|
||||||
au BufReadCmd * echo 'hello'
|
au BufReadCmd * echo 'hello'
|
||||||
|
@ -757,6 +757,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 */
|
||||||
|
/**/
|
||||||
|
3591,
|
||||||
/**/
|
/**/
|
||||||
3590,
|
3590,
|
||||||
/**/
|
/**/
|
||||||
|
@ -1379,6 +1379,7 @@ enum auto_event
|
|||||||
EVENT_WINENTER, // after entering a window
|
EVENT_WINENTER, // after entering a window
|
||||||
EVENT_WINLEAVE, // before leaving a window
|
EVENT_WINLEAVE, // before leaving a window
|
||||||
EVENT_WINNEW, // when entering a new window
|
EVENT_WINNEW, // when entering a new window
|
||||||
|
EVENT_WINCLOSED, // after closing a window
|
||||||
EVENT_VIMSUSPEND, // before Vim is suspended
|
EVENT_VIMSUSPEND, // before Vim is suspended
|
||||||
EVENT_VIMRESUME, // after Vim is resumed
|
EVENT_VIMRESUME, // after Vim is resumed
|
||||||
|
|
||||||
|
28
src/window.c
28
src/window.c
@ -19,6 +19,7 @@ static void win_exchange(long);
|
|||||||
static void win_rotate(int, int);
|
static void win_rotate(int, int);
|
||||||
static void win_totop(int size, int flags);
|
static void win_totop(int size, int flags);
|
||||||
static void win_equal_rec(win_T *next_curwin, int current, frame_T *topfr, int dir, int col, int row, int width, int height);
|
static void win_equal_rec(win_T *next_curwin, int current, frame_T *topfr, int dir, int col, int row, int width, int height);
|
||||||
|
static void trigger_winclosed(win_T *win);
|
||||||
static win_T *win_free_mem(win_T *win, int *dirp, tabpage_T *tp);
|
static win_T *win_free_mem(win_T *win, int *dirp, tabpage_T *tp);
|
||||||
static frame_T *win_altframe(win_T *win, tabpage_T *tp);
|
static frame_T *win_altframe(win_T *win, tabpage_T *tp);
|
||||||
static tabpage_T *alt_tabpage(void);
|
static tabpage_T *alt_tabpage(void);
|
||||||
@ -2566,6 +2567,13 @@ win_close(win_T *win, int free_buf)
|
|||||||
if (popup_win_closed(win) && !win_valid(win))
|
if (popup_win_closed(win) && !win_valid(win))
|
||||||
return FAIL;
|
return FAIL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Trigger WinClosed just before starting to free window-related resources.
|
||||||
|
trigger_winclosed(win);
|
||||||
|
// autocmd may have freed the window already.
|
||||||
|
if (!win_valid_any_tab(win))
|
||||||
|
return OK;
|
||||||
|
|
||||||
win_close_buffer(win, free_buf ? DOBUF_UNLOAD : 0, TRUE);
|
win_close_buffer(win, free_buf ? DOBUF_UNLOAD : 0, TRUE);
|
||||||
|
|
||||||
if (only_one_window() && win_valid(win) && win->w_buffer == NULL
|
if (only_one_window() && win_valid(win) && win->w_buffer == NULL
|
||||||
@ -2710,6 +2718,20 @@ win_close(win_T *win, int free_buf)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
trigger_winclosed(win_T *win)
|
||||||
|
{
|
||||||
|
static int recursive = FALSE;
|
||||||
|
char_u winid[NUMBUFLEN];
|
||||||
|
|
||||||
|
if (recursive)
|
||||||
|
return;
|
||||||
|
recursive = TRUE;
|
||||||
|
vim_snprintf((char *)winid, sizeof(winid), "%i", win->w_id);
|
||||||
|
apply_autocmds(EVENT_WINCLOSED, winid, winid, FALSE, win->w_buffer);
|
||||||
|
recursive = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Close window "win" in tab page "tp", which is not the current tab page.
|
* Close window "win" in tab page "tp", which is not the current tab page.
|
||||||
* This may be the last window in that tab page and result in closing the tab,
|
* This may be the last window in that tab page and result in closing the tab,
|
||||||
@ -2731,6 +2753,12 @@ win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
|
|||||||
&& win->w_buffer->b_locked > 0))
|
&& win->w_buffer->b_locked > 0))
|
||||||
return; // window is already being closed
|
return; // window is already being closed
|
||||||
|
|
||||||
|
// Trigger WinClosed just before starting to free window-related resources.
|
||||||
|
trigger_winclosed(win);
|
||||||
|
// autocmd may have freed the window already.
|
||||||
|
if (!win_valid_any_tab(win))
|
||||||
|
return;
|
||||||
|
|
||||||
if (win->w_buffer != NULL)
|
if (win->w_buffer != NULL)
|
||||||
// Close the link to the buffer.
|
// Close the link to the buffer.
|
||||||
close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0,
|
close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user