aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/window.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/window.c')
-rw-r--r--src/nvim/window.c95
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++;
}
}