From 757aad92e84709a08320a06870b6acb086bc6876 Mon Sep 17 00:00:00 2001 From: Marcos ALMEIDA Date: Sat, 29 Sep 2018 20:40:53 +0200 Subject: autocmd: add WinClosed event - only fire once, just before freeing mem - trigger when on a different buffer - avoid recursive calls in another tab --- src/nvim/auevents.lua | 2 ++ src/nvim/window.c | 37 +++++++++++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua index a52789c795..d596edf551 100644 --- a/src/nvim/auevents.lua +++ b/src/nvim/auevents.lua @@ -110,6 +110,7 @@ return { 'WinEnter', -- after entering a window 'WinLeave', -- before leaving a window 'WinNew', -- when entering a new window + 'WinClosed', -- after closing a window }, aliases = { BufCreate = 'BufAdd', @@ -129,5 +130,6 @@ return { TermOpen=true, UIEnter=true, UILeave=true, + WinClosed=true, }, } diff --git a/src/nvim/window.c b/src/nvim/window.c index e913d33de0..4743dca3ff 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -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); -- cgit From 2b8e66c6ce0a5ccae09023732c06da90f96ed5f5 Mon Sep 17 00:00:00 2001 From: notomo Date: Tue, 14 Jan 2020 22:34:05 +0900 Subject: autocmd: WinClosed exposes window id as --- src/nvim/fileio.c | 3 ++- src/nvim/window.c | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 865da25009..7a46957151 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -6862,7 +6862,8 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io, || event == EVENT_SPELLFILEMISSING || event == EVENT_SYNTAX || event == EVENT_SIGNAL - || event == EVENT_TABCLOSED) { + || event == EVENT_TABCLOSED + || event == EVENT_WINCLOSED) { fname = vim_strsave(fname); } else { fname = (char_u *)FullName_save((char *)fname, false); diff --git a/src/nvim/window.c b/src/nvim/window.c index 4743dca3ff..9efed49e70 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2695,8 +2695,10 @@ static void do_autocmd_winclosed(win_T *win) return; } recursive = true; - apply_autocmds(EVENT_WINCLOSED, win->w_buffer->b_fname, - win->w_buffer->b_fname, false, win->w_buffer); + + char_u winid[10]; + vim_snprintf((char *)winid, sizeof(winid), "%i", win->handle); + apply_autocmds(EVENT_WINCLOSED, winid, winid, false, win->w_buffer); recursive = false; } -- cgit From 156c25e4983d4c106ba70e5e3bcc6bbb012d8065 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 13 Jan 2020 00:19:20 -0800 Subject: WinClosed: sort auevents.lua; improve tests - test: reduce verbosity, condense redundancy, improve readability - auevents.lua: keep events sorted by name. ref afd1d412fa91 --- src/nvim/auevents.lua | 10 +++++----- src/nvim/window.c | 3 +-- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua index d596edf551..96e170a9e1 100644 --- a/src/nvim/auevents.lua +++ b/src/nvim/auevents.lua @@ -21,12 +21,12 @@ return { 'BufWritePre', -- before writing a buffer 'ChanInfo', -- info was received about channel 'ChanOpen', -- channel was opened - 'CmdlineChanged', -- command line was modified - 'CmdlineEnter', -- after entering cmdline mode - 'CmdlineLeave', -- before leaving cmdline mode 'CmdUndefined', -- command undefined 'CmdWinEnter', -- after entering the cmdline window 'CmdWinLeave', -- before leaving the cmdline window + 'CmdlineChanged', -- command line was modified + 'CmdlineEnter', -- after entering cmdline mode + 'CmdlineLeave', -- before leaving cmdline mode 'ColorScheme', -- after loading a colorscheme 'ColorSchemePre', -- before loading a colorscheme 'CompleteChanged', -- after popup menu changed @@ -76,8 +76,8 @@ return { 'ShellFilterPost', -- after ":1,2!cmd", ":w !cmd", ":r !cmd". 'Signal', -- after nvim process received a signal 'SourceCmd', -- sourcing a Vim script using command - 'SourcePre', -- before sourcing a Vim script 'SourcePost', -- after sourcing a Vim script + 'SourcePre', -- before sourcing a Vim script 'SpellFileMissing', -- spell file missing 'StdinReadPost', -- after reading from stdin 'StdinReadPre', -- before reading from stdin @@ -107,10 +107,10 @@ return { 'VimResized', -- after Vim window was resized 'VimResume', -- after Nvim is resumed 'VimSuspend', -- before Nvim is suspended + 'WinClosed', -- after closing a window 'WinEnter', -- after entering a window 'WinLeave', -- before leaving a window 'WinNew', -- when entering a new window - 'WinClosed', -- after closing a window }, aliases = { BufCreate = 'BufAdd', diff --git a/src/nvim/window.c b/src/nvim/window.c index 9efed49e70..8181883426 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2695,8 +2695,7 @@ static void do_autocmd_winclosed(win_T *win) return; } recursive = true; - - char_u winid[10]; + char_u winid[NUMBUFLEN]; vim_snprintf((char *)winid, sizeof(winid), "%i", win->handle); apply_autocmds(EVENT_WINCLOSED, winid, winid, false, win->w_buffer); recursive = false; -- cgit