diff options
Diffstat (limited to 'src/nvim/window.c')
-rw-r--r-- | src/nvim/window.c | 56 |
1 files changed, 41 insertions, 15 deletions
diff --git a/src/nvim/window.c b/src/nvim/window.c index 03a2e9a842..9c6a2e26a6 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -1065,6 +1065,23 @@ bool win_valid(win_T *win) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT return false; } +/// Check if "win" is a pointer to an existing window in any tabpage. +/// +/// @param win window to check +bool win_valid_any_tab(win_T *win) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT +{ + if (win == NULL) { + return false; + } + + FOR_ALL_TAB_WINDOWS(tp, wp) { + if (wp == win) { + return true; + } + } + return false; +} + /* * Return the number of windows. */ @@ -1918,7 +1935,7 @@ int win_close(win_T *win, int free_buf) if (win->w_buffer != NULL) { win->w_closing = true; close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, true); - if (win_valid(win)) { + if (win_valid_any_tab(win)) { win->w_closing = false; } @@ -1938,11 +1955,19 @@ int win_close(win_T *win, int free_buf) curwin->w_buffer = curbuf; getout(0); } - /* Autocommands may have closed the window already, or closed the only - * other window or moved to another tab page. */ - else if (!win_valid(win) || last_window() || curtab != prev_curtab - || close_last_window_tabpage(win, free_buf, prev_curtab)) + // Autocommands may have moved to another tab page. + if (curtab != prev_curtab && win_valid_any_tab(win) + && win->w_buffer == NULL) { + // Need to close the window anyway, since the buffer is NULL. + 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) || last_window() + || close_last_window_tabpage(win, free_buf, prev_curtab)) { + return FAIL; + } // let terminal buffers know that this window dimensions may be ignored win->w_closing = true; @@ -2019,12 +2044,16 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) tabpage_T *ptp = NULL; int free_tp = FALSE; - assert(win->w_buffer); // to avoid np dereference warning in next line - if (win->w_closing || win->w_buffer->b_closing) - return; /* window is already being closed */ + // Get here with win->w_buffer == NULL when win_close() detects the tab page + // changed. + if (win->w_closing || (win->w_buffer != NULL && win->w_buffer->b_closing)) { + return; // window is already being closed + } - /* Close the link to the buffer. */ - close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, FALSE); + if (win->w_buffer != NULL) { + // Close the link to the buffer. + close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, false); + } /* Careful: Autocommands may have closed the tab page or made it the * current tab page. */ @@ -3213,11 +3242,8 @@ void goto_tabpage(int n) int i; if (text_locked()) { - /* Not allowed when editing the command line. */ - if (cmdwin_type != 0) - EMSG(_(e_cmdwin)); - else - EMSG(_(e_secure)); + // Not allowed when editing the command line. + text_locked_msg(); return; } |