diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-03-10 10:33:10 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-10 10:33:10 +0800 |
commit | 6052b346f1b7a3fb616dfcefe3bc05cb6fe3f2f3 (patch) | |
tree | 2c2ba70720c195ad5133865102a28dbbd6128b13 | |
parent | 9bd4a2807960ea3e82b0454861b399f4ac6d8a92 (diff) | |
download | rneovim-6052b346f1b7a3fb616dfcefe3bc05cb6fe3f2f3.tar.gz rneovim-6052b346f1b7a3fb616dfcefe3bc05cb6fe3f2f3.tar.bz2 rneovim-6052b346f1b7a3fb616dfcefe3bc05cb6fe3f2f3.zip |
revert: "fix(window): :close crash with autocmd, floats and tabpage" (#27796)
This reverts PR #27793.
On second thought, this solution may still crash, because it can leave a
window with a NULL buffer if there are autocommand windows or if closing
a floating window fails. It also makes close_last_window_tabpage() more
complicated, so revert it.
-rw-r--r-- | src/nvim/window.c | 60 | ||||
-rw-r--r-- | test/functional/ui/float_spec.lua | 5 |
2 files changed, 30 insertions, 35 deletions
diff --git a/src/nvim/window.c b/src/nvim/window.c index a76953d900..ff40a9adef 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2539,47 +2539,21 @@ bool can_close_in_cmdwin(win_T *win, Error *err) return true; } -/// Close the possibly last non-floating window in a tab page. +/// Close the possibly last window in a tab page. /// /// @param win window to close /// @param free_buf whether to free the window's current buffer -/// @param force close floating windows even if they are modified /// @param prev_curtab previous tabpage that will be closed if "win" is the /// last window in the tabpage /// -/// @return false if there are other non-floating windows and nothing is done, true otherwise. -static bool close_last_window_tabpage(win_T *win, bool free_buf, bool force, tabpage_T *prev_curtab) +/// @return false if there are other windows and nothing is done, true otherwise. +static bool close_last_window_tabpage(win_T *win, bool free_buf, tabpage_T *prev_curtab) FUNC_ATTR_NONNULL_ARG(1) { - if (!one_window(win)) { + if (!ONE_WINDOW) { return false; } - if (lastwin->w_floating && one_window(win)) { - if (is_aucmd_win(lastwin)) { - emsg(_("E814: Cannot close window, only autocmd window would remain")); - return true; - } - - if (force || can_close_floating_windows()) { - // close the last window until the there are no floating windows - while (lastwin->w_floating) { - // `force` flag isn't actually used when closing a floating window. - if (win_close(lastwin, free_buf, true) == FAIL) { - // If closing the window fails give up, to avoid looping forever. - return true; - } - } - } else { - emsg(e_floatonly); - return true; - } - - if (!win_valid_any_tab(win)) { - return true; // window already closed by autocommands - } - } - buf_T *old_curbuf = curbuf; Terminal *term = win->w_buffer ? win->w_buffer->terminal : NULL; @@ -2675,11 +2649,33 @@ int win_close(win_T *win, bool free_buf, bool force) emsg(_(e_autocmd_close)); return FAIL; } + if (lastwin->w_floating && one_window(win)) { + if (is_aucmd_win(lastwin)) { + emsg(_("E814: Cannot close window, only autocmd window would remain")); + return FAIL; + } + if (force || can_close_floating_windows()) { + // close the last window until the there are no floating windows + while (lastwin->w_floating) { + // `force` flag isn't actually used when closing a floating window. + if (win_close(lastwin, free_buf, true) == FAIL) { + // If closing the window fails give up, to avoid looping forever. + return FAIL; + } + } + if (!win_valid_any_tab(win)) { + return FAIL; // window already closed by autocommands + } + } else { + emsg(e_floatonly); + return FAIL; + } + } // When closing the last window in a tab page first go to another tab page // and then close the window and the tab page to avoid that curwin and // curtab are invalid while we are freeing memory. - if (close_last_window_tabpage(win, free_buf, force, prev_curtab)) { + if (close_last_window_tabpage(win, free_buf, prev_curtab)) { return FAIL; } @@ -2774,7 +2770,7 @@ int win_close(win_T *win, bool free_buf, bool force) // 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(win)) - || close_last_window_tabpage(win, free_buf, force, prev_curtab)) { + || close_last_window_tabpage(win, free_buf, prev_curtab)) { return FAIL; } diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua index 6bc3fd14ec..65a7d359af 100644 --- a/test/functional/ui/float_spec.lua +++ b/test/functional/ui/float_spec.lua @@ -893,7 +893,7 @@ describe('float window', function() assert_alive() end) - it('does not crash if BufUnload makes it the only non-float in tabpage', function() + pending('does not crash if BufUnload makes it the only non-float in tabpage', function() exec([[ tabnew let g:buf = bufnr() @@ -909,10 +909,9 @@ describe('float window', function() assert_alive() end) - it('does not crash if WinClosed from floating windows closes it', function() + it('does not crash if WinClosed from floating window closes it', function() exec([[ tabnew - let g:buf = bufnr() new let s:win = win_getid() call nvim_win_set_config(s:win, |