diff options
Diffstat (limited to 'src/nvim/window.c')
-rw-r--r-- | src/nvim/window.c | 95 |
1 files changed, 58 insertions, 37 deletions
diff --git a/src/nvim/window.c b/src/nvim/window.c index 5dd35537fa..1f80f14f26 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -1046,8 +1046,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) { win_T *wp = new_wp; - // aucmd_win should always remain floating - if (new_wp != NULL && new_wp == aucmd_win) { + // aucmd_win[] should always remain floating + if (new_wp != NULL && is_aucmd_win(new_wp)) { return FAIL; } @@ -1505,7 +1505,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) // equalize the window sizes. if (do_equal || dir != 0) { win_equal(wp, true, (flags & WSP_VERT) ? (dir == 'v' ? 'b' : 'h') : (dir == 'h' ? 'b' : 'v')); - } else if (*p_spk != 'c' && wp != aucmd_win) { + } else if (*p_spk != 'c' && !is_aucmd_win(wp)) { win_fix_scroll(false); } @@ -1644,11 +1644,20 @@ bool win_valid_floating(const win_T *win) /// @param win window to check bool win_valid(const win_T *win) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { + return tabpage_win_valid(curtab, win); +} + +/// Check if "win" is a pointer to an existing window in tabpage "tp". +/// +/// @param win window to check +static bool tabpage_win_valid(const tabpage_T *tp, const win_T *win) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT +{ if (win == NULL) { return false; } - FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + FOR_ALL_WINDOWS_IN_TAB(wp, tp) { if (wp == win) { return true; } @@ -1940,7 +1949,7 @@ static void win_totop(int size, int flags) beep_flush(); return; } - if (curwin == aucmd_win) { + if (is_aucmd_win(curwin)) { return; } if (check_split_disallowed() == FAIL) { @@ -2086,7 +2095,7 @@ void win_equal(win_T *next_curwin, bool current, int dir) win_equal_rec(next_curwin == NULL ? curwin : next_curwin, current, topframe, dir, 0, tabline_height(), Columns, topframe->fr_height); - if (*p_spk != 'c' && next_curwin != aucmd_win) { + if (*p_spk != 'c' && !is_aucmd_win(next_curwin)) { win_fix_scroll(true); } } @@ -2459,7 +2468,7 @@ void close_windows(buf_T *buf, bool keep_curwin) // Start from lastwin to close floating windows with the same buffer first. // When the autocommand window is involved win_close() may need to print an error message. - for (win_T *wp = lastwin; wp != NULL && (lastwin == aucmd_win || !one_window(wp));) { + for (win_T *wp = lastwin; wp != NULL && (is_aucmd_win(lastwin) || !one_window(wp));) { if (wp->w_buffer == buf && (!keep_curwin || wp != curwin) && !(wp->w_closing || wp->w_buffer->b_locked > 0)) { if (win_close(wp, false, false) == FAIL) { @@ -2508,14 +2517,14 @@ bool last_window(win_T *win) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT return one_window(win) && first_tabpage->tp_next == NULL; } -/// Check that current tab page contains no more then one window other than `aucmd_win`. -/// @param counted_float counted even if floating, but not if it is `aucmd_win` +/// Check if current tab page contains no more than one window other than `aucmd_win[]`. +/// @param counted_float counted even if floating, but not if it is `aucmd_win[]` bool one_window(win_T *counted_float) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { bool seen_one = false; FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if (wp != aucmd_win && (!wp->w_floating || wp == counted_float)) { + if (!is_aucmd_win(wp) && (!wp->w_floating || wp == counted_float)) { if (seen_one) { return false; } @@ -2545,7 +2554,7 @@ bool last_nonfloat(win_T *wp) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT /// @return true if all floating windows can be closed static bool can_close_floating_windows(void) { - assert(lastwin != aucmd_win); + assert(!is_aucmd_win(lastwin)); for (win_T *wp = lastwin; wp->w_floating; wp = wp->w_prev) { buf_T *buf = wp->w_buffer; int need_hide = (bufIsChanged(buf) && buf->b_nwindows <= 1); @@ -2663,12 +2672,12 @@ int win_close(win_T *win, bool free_buf, bool force) || (win->w_buffer != NULL && win->w_buffer->b_locked > 0)) { return FAIL; // window is already being closed } - if (win == aucmd_win) { + if (is_aucmd_win(win)) { emsg(_(e_autocmd_close)); return FAIL; } if (lastwin->w_floating && one_window(win)) { - if (lastwin == aucmd_win) { + if (is_aucmd_win(lastwin)) { emsg(_("E814: Cannot close window, only autocmd window would remain")); return FAIL; } @@ -2760,6 +2769,7 @@ int win_close(win_T *win, bool free_buf, bool force) if (win->w_floating) { ui_comp_remove_grid(&win->w_grid_alloc); + assert(first_tabpage != NULL); // suppress clang "Dereference of NULL pointer" if (win->w_float_config.external) { for (tabpage_T *tp = first_tabpage; tp != NULL; tp = tp->tp_next) { if (tp == curtab) { @@ -3048,6 +3058,7 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) static win_T *win_free_mem(win_T *win, int *dirp, tabpage_T *tp) { win_T *wp; + tabpage_T *win_tp = tp == NULL ? curtab : tp; if (!win->w_floating) { // Remove the window and its frame from the tree of frames. @@ -3056,22 +3067,26 @@ static win_T *win_free_mem(win_T *win, int *dirp, tabpage_T *tp) xfree(frp); } else { *dirp = 'h'; // Dummy value. - if (win_valid(prevwin) && prevwin != win) { - wp = prevwin; + if (tp == NULL) { + if (win_valid(prevwin) && prevwin != win) { + wp = prevwin; + } else { + wp = firstwin; + } } else { - wp = firstwin; + if (tabpage_win_valid(tp, tp->tp_prevwin) && tp->tp_prevwin != win) { + wp = tp->tp_prevwin; + } else { + wp = tp->tp_firstwin; + } } } win_free(win, tp); - // When deleting the current window of another tab page select a new - // current window. - if (tp != NULL && win == tp->tp_curwin) { - if (win_valid(tp->tp_prevwin) && tp->tp_prevwin != win) { - tp->tp_curwin = tp->tp_prevwin; - } else { - tp->tp_curwin = tp->tp_firstwin; - } + // When deleting the current window in the tab, select a new current + // window. + if (win == win_tp->tp_curwin) { + win_tp->tp_curwin = wp; } return wp; @@ -3092,17 +3107,23 @@ void win_free_all(void) win_remove(lastwin, NULL); int dummy; (void)win_free_mem(wp, &dummy, NULL); - if (wp == aucmd_win) { - aucmd_win = NULL; + for (int i = 0; i < AUCMD_WIN_COUNT; i++) { + if (aucmd_win[i].auc_win == wp) { + aucmd_win[i].auc_win = NULL; + } } } - if (aucmd_win != NULL) { - int dummy; - (void)win_free_mem(aucmd_win, &dummy, NULL); - aucmd_win = NULL; + for (int i = 0; i < AUCMD_WIN_COUNT; i++) { + if (aucmd_win[i].auc_win != NULL) { + int dummy; + (void)win_free_mem(aucmd_win[i].auc_win, &dummy, NULL); + aucmd_win[i].auc_win = NULL; + } } + kv_destroy(aucmd_win_vec); + while (firstwin != NULL) { int dummy; (void)win_free_mem(firstwin, &dummy, NULL); @@ -3904,18 +3925,18 @@ void win_alloc_first(void) unuse_tabpage(first_tabpage); } -// Init `aucmd_win`. This can only be done after the first window +// Init `aucmd_win[idx]`. This can only be done after the first window // is fully initialized, thus it can't be in win_alloc_first(). -void win_alloc_aucmd_win(void) +void win_alloc_aucmd_win(int idx) { Error err = ERROR_INIT; FloatConfig fconfig = FLOAT_CONFIG_INIT; fconfig.width = Columns; fconfig.height = 5; fconfig.focusable = false; - aucmd_win = win_new_float(NULL, true, fconfig, &err); - aucmd_win->w_buffer->b_nwindows--; - RESET_BINDING(aucmd_win); + aucmd_win[idx].auc_win = win_new_float(NULL, true, fconfig, &err); + aucmd_win[idx].auc_win->w_buffer->b_nwindows--; + RESET_BINDING(aucmd_win[idx].auc_win); } // Allocate the first window or the first window in a new tab page. @@ -5108,7 +5129,7 @@ static void win_free(win_T *wp, tabpage_T *tp) win_free_grid(wp, false); - if (wp != aucmd_win) { + if (win_valid_any_tab(wp)) { win_remove(wp, tp); } if (autocmd_busy) { @@ -7059,7 +7080,7 @@ bool only_one_window(void) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { if (wp->w_buffer != NULL && (!((bt_help(wp->w_buffer) && !bt_help(curbuf)) || wp->w_floating - || wp->w_p_pvw) || wp == curwin) && wp != aucmd_win) { + || wp->w_p_pvw) || wp == curwin) && !is_aucmd_win(wp)) { count++; } } |