mirror of
https://github.com/neovim/neovim.git
synced 2025-09-14 15:28:17 +00:00
autocmd: add WinClosed event
- only fire once, just before freeing mem - trigger when on a different buffer - avoid recursive calls in another tab
This commit is contained in:

committed by
Justin M. Keyes

parent
fb8b0503ba
commit
757aad92e8
@@ -2502,9 +2502,10 @@ int win_close(win_T *win, bool free_buf)
|
||||
return FAIL;
|
||||
}
|
||||
win->w_closing = true;
|
||||
apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf);
|
||||
if (!win_valid(win))
|
||||
apply_autocmds(EVENT_WINLEAVE, NULL, NULL, false, curbuf);
|
||||
if (!win_valid(win)) {
|
||||
return FAIL;
|
||||
}
|
||||
win->w_closing = false;
|
||||
if (last_window())
|
||||
return FAIL;
|
||||
@@ -2534,6 +2535,12 @@ int win_close(win_T *win, bool free_buf)
|
||||
}
|
||||
}
|
||||
|
||||
// Fire WinClosed just before starting to free window-related resources.
|
||||
do_autocmd_winclosed(win);
|
||||
// autocmd may have freed the window already.
|
||||
if (!win_valid_any_tab(win)) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Free independent synblock before the buffer is freed. */
|
||||
if (win->w_buffer != NULL)
|
||||
@@ -2576,6 +2583,7 @@ int win_close(win_T *win, bool free_buf)
|
||||
win_close_othertab(win, false, prev_curtab);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// Autocommands may have closed the window already, or closed the only
|
||||
// other window or moved to another tab page.
|
||||
if (!win_valid(win) || (!win->w_floating && last_window())
|
||||
@@ -2585,8 +2593,9 @@ int win_close(win_T *win, bool free_buf)
|
||||
|
||||
// let terminal buffers know that this window dimensions may be ignored
|
||||
win->w_closing = true;
|
||||
/* Free the memory used for the window and get the window that received
|
||||
* the screen space. */
|
||||
|
||||
// Free the memory used for the window and get the window that received
|
||||
// the screen space.
|
||||
wp = win_free_mem(win, &dir, NULL);
|
||||
|
||||
if (help_window) {
|
||||
@@ -2678,6 +2687,19 @@ int win_close(win_T *win, bool free_buf)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void do_autocmd_winclosed(win_T *win)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
static bool recursive = false;
|
||||
if (recursive || !has_event(EVENT_WINCLOSED)) {
|
||||
return;
|
||||
}
|
||||
recursive = true;
|
||||
apply_autocmds(EVENT_WINCLOSED, win->w_buffer->b_fname,
|
||||
win->w_buffer->b_fname, false, win->w_buffer);
|
||||
recursive = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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,
|
||||
@@ -2698,6 +2720,13 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
|
||||
return; // window is already being closed
|
||||
}
|
||||
|
||||
// Fire WinClosed just before starting to free window-related resources.
|
||||
do_autocmd_winclosed(win);
|
||||
// autocmd may have freed the window already.
|
||||
if (!win_valid_any_tab(win)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (win->w_buffer != NULL) {
|
||||
// Close the link to the buffer.
|
||||
close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, false);
|
||||
|
Reference in New Issue
Block a user