summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-11-28 18:51:43 +0000
committerBram Moolenaar <Bram@vim.org>2022-11-28 18:51:43 +0000
commite76062c078debed0df818f70e4db14ad7a7cb53a (patch)
treee43b3b076fdea909c460219e896237a8924ccb6b /src
parent74a694dbe20bb7dea4e06f474cf62e20f9c92f1d (diff)
downloadvim-git-e76062c078debed0df818f70e4db14ad7a7cb53a.tar.gz
patch 9.0.0965: using one window for executing autocommands is insufficientv9.0.0965
Problem: Using one window for executing autocommands is insufficient. Solution: Use up to five windows for executing autocommands.
Diffstat (limited to 'src')
-rw-r--r--src/autocmd.c115
-rw-r--r--src/buffer.c43
-rw-r--r--src/bufwrite.c42
-rw-r--r--src/channel.c8
-rw-r--r--src/diff.c6
-rw-r--r--src/eval.c7
-rw-r--r--src/evalbuffer.c5
-rw-r--r--src/evalvars.c13
-rw-r--r--src/evalwindow.c2
-rw-r--r--src/ex_cmds2.c7
-rw-r--r--src/ex_docmd.c2
-rw-r--r--src/fileio.c8
-rw-r--r--src/globals.h14
-rw-r--r--src/if_perl.xs62
-rw-r--r--src/if_py_both.h7
-rw-r--r--src/if_ruby.c75
-rw-r--r--src/main.c2
-rw-r--r--src/os_unix.c33
-rw-r--r--src/os_win32.c33
-rw-r--r--src/proto/autocmd.pro2
-rw-r--r--src/quickfix.c94
-rw-r--r--src/screen.c35
-rw-r--r--src/structs.h2
-rw-r--r--src/term.c9
-rw-r--r--src/terminal.c21
-rw-r--r--src/testdir/test_autocmd.vim23
-rw-r--r--src/version.c2
-rw-r--r--src/window.c27
28 files changed, 445 insertions, 254 deletions
diff --git a/src/autocmd.c b/src/autocmd.c
index 11dc707d7..3a0812813 100644
--- a/src/autocmd.c
+++ b/src/autocmd.c
@@ -629,28 +629,52 @@ do_augroup(char_u *arg, int del_group)
}
}
+ void
+autocmd_init(void)
+{
+ CLEAR_FIELD(aucmd_win);
+}
+
#if defined(EXITFREE) || defined(PROTO)
void
free_all_autocmds(void)
{
- int i;
char_u *s;
for (current_augroup = -1; current_augroup < augroups.ga_len;
++current_augroup)
do_autocmd(NULL, (char_u *)"", TRUE);
- for (i = 0; i < augroups.ga_len; ++i)
+ for (int i = 0; i < augroups.ga_len; ++i)
{
s = ((char_u **)(augroups.ga_data))[i];
if (s != get_deleted_augroup())
vim_free(s);
}
ga_clear(&augroups);
+
+ for (int i = 0; i < AUCMD_WIN_COUNT; ++i)
+ if (aucmd_win[i].auc_win_used)
+ {
+ aucmd_win[i].auc_win_used = FALSE;
+ win_remove(aucmd_win[i].auc_win, NULL);
+ }
}
#endif
/*
+ * Return TRUE if "win" is an active entry in aucmd_win[].
+ */
+ int
+is_aucmd_win(win_T *win)
+{
+ for (int i = 0; i < AUCMD_WIN_COUNT; ++i)
+ if (aucmd_win[i].auc_win_used && aucmd_win[i].auc_win == win)
+ return TRUE;
+ return FALSE;
+}
+
+/*
* Return the event number for event name "start".
* Return NUM_EVENTS if the event name was not found.
* Return a pointer to the next event name in "end".
@@ -1438,8 +1462,16 @@ ex_doautoall(exarg_T *eap)
if (buf->b_ml.ml_mfp == NULL || buf == curbuf)
continue;
- // find a window for this buffer and save some values
+ // Find a window for this buffer and save some values.
aucmd_prepbuf(&aco, buf);
+ if (curbuf != buf)
+ {
+ // Failed to find a window for this buffer. Better not execute
+ // autocommands then.
+ retval = FAIL;
+ break;
+ }
+
set_bufref(&bufref, buf);
// execute the autocommands for this buffer
@@ -1449,7 +1481,7 @@ ex_doautoall(exarg_T *eap)
// Execute the modeline settings, but don't set window-local
// options if we are using the current window for another
// buffer.
- do_modelines(curwin == aucmd_win ? OPT_NOWIN : 0);
+ do_modelines(is_aucmd_win(curwin) ? OPT_NOWIN : 0);
// restore the current window
aucmd_restbuf(&aco);
@@ -1490,8 +1522,9 @@ check_nomodeline(char_u **argp)
/*
* Prepare for executing autocommands for (hidden) buffer "buf".
* Search for a visible window containing the current buffer. If there isn't
- * one then use "aucmd_win".
+ * one then use an entry in "aucmd_win[]".
* Set "curbuf" and "curwin" to match "buf".
+ * When this fails "curbuf" is not equal "buf".
*/
void
aucmd_prepbuf(
@@ -1512,18 +1545,29 @@ aucmd_prepbuf(
if (win->w_buffer == buf)
break;
- // Allocate "aucmd_win" when needed. If this fails (out of memory) fall
- // back to using the current window.
- if (win == NULL && aucmd_win == NULL)
+ // Allocate a window when needed.
+ win_T *auc_win = NULL;
+ int auc_idx = AUCMD_WIN_COUNT;
+ if (win == NULL)
{
- aucmd_win = win_alloc_popup_win();
- if (aucmd_win == NULL)
- win = curwin;
+ for (auc_idx = 0; auc_idx < AUCMD_WIN_COUNT; ++auc_idx)
+ if (!aucmd_win[auc_idx].auc_win_used)
+ {
+ auc_win = win_alloc_popup_win();
+ if (auc_win != NULL)
+ {
+ aucmd_win[auc_idx].auc_win = auc_win;
+ aucmd_win[auc_idx].auc_win_used = TRUE;
+ }
+ break;
+ }
+
+ // If this fails (out of memory or using all AUCMD_WIN_COUNT
+ // entries) then we can't reliable execute the autocmd, return with
+ // "curbuf" unequal "buf".
+ if (auc_win == NULL)
+ return;
}
- if (win == NULL && aucmd_win_used)
- // Strange recursive autocommand, fall back to using the current
- // window. Expect a few side effects...
- win = curwin;
aco->save_curwin_id = curwin->w_id;
aco->save_curbuf = curbuf;
@@ -1533,24 +1577,23 @@ aucmd_prepbuf(
// There is a window for "buf" in the current tab page, make it the
// curwin. This is preferred, it has the least side effects (esp. if
// "buf" is curbuf).
- aco->use_aucmd_win = FALSE;
+ aco->use_aucmd_win_idx = -1;
curwin = win;
}
else
{
- // There is no window for "buf", use "aucmd_win". To minimize the side
+ // There is no window for "buf", use "auc_win". To minimize the side
// effects, insert it in the current tab page.
// Anything related to a window (e.g., setting folds) may have
// unexpected results.
- aco->use_aucmd_win = TRUE;
- aucmd_win_used = TRUE;
+ aco->use_aucmd_win_idx = auc_idx;
- win_init_popup_win(aucmd_win, buf);
+ win_init_popup_win(auc_win, buf);
aco->globaldir = globaldir;
globaldir = NULL;
- // Split the current window, put the aucmd_win in the upper half.
+ // Split the current window, put the auc_win in the upper half.
// We don't want the BufEnter or WinEnter autocommands.
block_autocmds();
make_snapshot(SNAP_AUCMD_IDX);
@@ -1565,7 +1608,7 @@ aucmd_prepbuf(
// no redrawing and don't set the window title
++RedrawingDisabled;
- (void)win_split_ins(0, WSP_TOP, aucmd_win, 0);
+ (void)win_split_ins(0, WSP_TOP, auc_win, 0);
--RedrawingDisabled;
(void)win_comp_pos(); // recompute window positions
p_ea = save_ea;
@@ -1573,7 +1616,7 @@ aucmd_prepbuf(
p_acd = save_acd;
#endif
unblock_autocmds();
- curwin = aucmd_win;
+ curwin = auc_win;
}
curbuf = buf;
aco->new_curwin_id = curwin->w_id;
@@ -1595,24 +1638,26 @@ aucmd_restbuf(
int dummy;
win_T *save_curwin;
- if (aco->use_aucmd_win)
+ if (aco->use_aucmd_win_idx >= 0)
{
+ win_T *awp = aucmd_win[aco->use_aucmd_win_idx].auc_win;
+
--curbuf->b_nwindows;
- // Find "aucmd_win", it can't be closed, but it may be in another tab
+ // Find "awp", it can't be closed, but it may be in another tab
// page. Do not trigger autocommands here.
block_autocmds();
- if (curwin != aucmd_win)
+ if (curwin != awp)
{
tabpage_T *tp;
win_T *wp;
FOR_ALL_TAB_WINDOWS(tp, wp)
{
- if (wp == aucmd_win)
+ if (wp == awp)
{
if (tp != curtab)
goto_tabpage_tp(tp, TRUE, TRUE);
- win_goto(aucmd_win);
+ win_goto(awp);
goto win_found;
}
}
@@ -1622,7 +1667,7 @@ win_found:
// Remove the window and frame from the tree of frames.
(void)winframe_remove(curwin, &dummy, NULL);
win_remove(curwin, NULL);
- aucmd_win_used = FALSE;
+ aucmd_win[aco->use_aucmd_win_idx].auc_win_used = FALSE;
last_status(FALSE); // may need to remove last status line
if (!valid_tabpage_win(curtab))
@@ -1646,8 +1691,8 @@ win_found:
#endif
prevwin = win_find_by_id(aco->save_prevwin_id);
#ifdef FEAT_EVAL
- vars_clear(&aucmd_win->w_vars->dv_hashtab); // free all w: variables
- hash_init(&aucmd_win->w_vars->dv_hashtab); // re-use the hashtab
+ vars_clear(&awp->w_vars->dv_hashtab); // free all w: variables
+ hash_init(&awp->w_vars->dv_hashtab); // re-use the hashtab
#endif
vim_free(globaldir);
globaldir = aco->globaldir;
@@ -1664,11 +1709,9 @@ win_found:
#if defined(FEAT_GUI)
if (gui.in_use)
{
- // Hide the scrollbars from the aucmd_win and update.
- gui_mch_enable_scrollbar(
- &aucmd_win->w_scrollbars[SBAR_LEFT], FALSE);
- gui_mch_enable_scrollbar(
- &aucmd_win->w_scrollbars[SBAR_RIGHT], FALSE);
+ // Hide the scrollbars from the "awp" and update.
+ gui_mch_enable_scrollbar(&awp->w_scrollbars[SBAR_LEFT], FALSE);
+ gui_mch_enable_scrollbar(&awp->w_scrollbars[SBAR_RIGHT], FALSE);
gui_may_update_scrollbars();
}
#endif
diff --git a/src/buffer.c b/src/buffer.c
index f99da25e8..eba5dd2d5 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -150,11 +150,15 @@ buffer_ensure_loaded(buf_T *buf)
{
aco_save_T aco;
+ // Make sure the buffer is in a window. If not then skip it.
aucmd_prepbuf(&aco, buf);
- if (swap_exists_action != SEA_READONLY)
- swap_exists_action = SEA_NONE;
- open_buffer(FALSE, NULL, 0);
- aucmd_restbuf(&aco);
+ if (curbuf == buf)
+ {
+ if (swap_exists_action != SEA_READONLY)
+ swap_exists_action = SEA_NONE;
+ open_buffer(FALSE, NULL, 0);
+ aucmd_restbuf(&aco);
+ }
}
}
#endif
@@ -361,21 +365,26 @@ open_buffer(
{
aco_save_T aco;
- // Go to the buffer that was opened.
+ // Go to the buffer that was opened, make sure it is in a window.
+ // If not then skip it.
aucmd_prepbuf(&aco, old_curbuf.br_buf);
- do_modelines(0);
- curbuf->b_flags &= ~(BF_CHECK_RO | BF_NEVERLOADED);
+ if (curbuf == old_curbuf.br_buf)
+ {
+ do_modelines(0);
+ curbuf->b_flags &= ~(BF_CHECK_RO | BF_NEVERLOADED);
- if ((flags & READ_NOWINENTER) == 0)
+ if ((flags & READ_NOWINENTER) == 0)
#ifdef FEAT_EVAL
- apply_autocmds_retval(EVENT_BUFWINENTER, NULL, NULL, FALSE,
- curbuf, &retval);
+ apply_autocmds_retval(EVENT_BUFWINENTER, NULL, NULL,
+ FALSE, curbuf, &retval);
#else
- apply_autocmds(EVENT_BUFWINENTER, NULL, NULL, FALSE, curbuf);
+ apply_autocmds(EVENT_BUFWINENTER, NULL, NULL,
+ FALSE, curbuf);
#endif
- // restore curwin/curbuf and a few other things
- aucmd_restbuf(&aco);
+ // restore curwin/curbuf and a few other things
+ aucmd_restbuf(&aco);
+ }
}
}
@@ -5942,8 +5951,14 @@ buf_contents_changed(buf_T *buf)
return TRUE;
}
- // set curwin/curbuf to buf and save a few things
+ // Set curwin/curbuf to buf and save a few things.
aucmd_prepbuf(&aco, newbuf);
+ if (curbuf != newbuf)
+ {
+ // Failed to find a window for "newbuf".
+ wipe_buffer(newbuf, FALSE);
+ return TRUE;
+ }
if (ml_open(curbuf) == OK
&& readfile(buf->b_ffname, buf->b_fname,
diff --git a/src/bufwrite.c b/src/bufwrite.c
index 18448dcde..03a83b569 100644
--- a/src/bufwrite.c
+++ b/src/bufwrite.c
@@ -802,8 +802,15 @@ buf_write(
if (fname == buf->b_sfname)
buf_fname_s = TRUE;
- // set curwin/curbuf to buf and save a few things
+ // Set curwin/curbuf to buf and save a few things.
aucmd_prepbuf(&aco, buf);
+ if (curbuf != buf)
+ {
+ // Could not find a window for "buf". Doing more might cause
+ // problems, better bail out.
+ return FAIL;
+ }
+
set_bufref(&bufref, buf);
if (append)
@@ -2592,23 +2599,26 @@ nofail:
// Apply POST autocommands.
// Careful: The autocommands may call buf_write() recursively!
+ // Only do this when a window was found for "buf".
aucmd_prepbuf(&aco, buf);
+ if (curbuf == buf)
+ {
+ if (append)
+ apply_autocmds_exarg(EVENT_FILEAPPENDPOST, fname, fname,
+ FALSE, curbuf, eap);
+ else if (filtering)
+ apply_autocmds_exarg(EVENT_FILTERWRITEPOST, NULL, fname,
+ FALSE, curbuf, eap);
+ else if (reset_changed && whole)
+ apply_autocmds_exarg(EVENT_BUFWRITEPOST, fname, fname,
+ FALSE, curbuf, eap);
+ else
+ apply_autocmds_exarg(EVENT_FILEWRITEPOST, fname, fname,
+ FALSE, curbuf, eap);
- if (append)
- apply_autocmds_exarg(EVENT_FILEAPPENDPOST, fname, fname,
- FALSE, curbuf, eap);
- else if (filtering)
- apply_autocmds_exarg(EVENT_FILTERWRITEPOST, NULL, fname,
- FALSE, curbuf, eap);
- else if (reset_changed && whole)
- apply_autocmds_exarg(EVENT_BUFWRITEPOST, fname, fname,
- FALSE, curbuf, eap);
- else
- apply_autocmds_exarg(EVENT_FILEWRITEPOST, fname, fname,
- FALSE, curbuf, eap);
-
- // restore curwin/curbuf and a few other things
- aucmd_restbuf(&aco);
+ // restore curwin/curbuf and a few other things
+ aucmd_restbuf(&aco);
+ }
#ifdef FEAT_EVAL
if (aborting()) // autocmds may abort script processing
diff --git a/src/channel.c b/src/channel.c
index 08b1ac867..4e6457546 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -2872,8 +2872,14 @@ append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel, ch_part_T part)
buffer->b_p_ma = TRUE;
- // set curbuf to be our buf, temporarily
+ // Set curbuf to "buffer", temporarily.
aucmd_prepbuf(&aco, buffer);
+ if (curbuf != buffer)
+ {
+ // Could not find a window for this buffer, the following might cause
+ // trouble, better bail out.
+ return;
+ }
u_sync(TRUE);
// ignore undo failure, undo is not very useful here
diff --git a/src/diff.c b/src/diff.c
index 80f1eb336..88e3ec453 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -2786,8 +2786,12 @@ ex_diffgetput(exarg_T *eap)
idx_to = idx_other;
// Need to make the other buffer the current buffer to be able to make
// changes in it.
- // set curwin/curbuf to buf and save a few things
+ // Set curwin/curbuf to buf and save a few things.
aucmd_prepbuf(&aco, curtab->tp_diffbuf[idx_other]);
+ if (curbuf != curtab->tp_diffbuf[idx_other])
+ // Could not find a window for this buffer, the rest is likely to
+ // fail.
+ goto theend;
}
// May give the warning for a changed buffer here, which can trigger the
diff --git a/src/eval.c b/src/eval.c
index 84a7b2620..c43158a29 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -5084,9 +5084,10 @@ garbage_collect(int testing)
FOR_ALL_TAB_WINDOWS(tp, wp)
abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID,
NULL, NULL);
- if (aucmd_win != NULL)
- abort = abort || set_ref_in_item(&aucmd_win->w_winvar.di_tv, copyID,
- NULL, NULL);
+ for (int i = 0; i < AUCMD_WIN_COUNT; ++i)
+ if (aucmd_win[i].auc_win_used)
+ abort = abort || set_ref_in_item(
+ &aucmd_win[i].auc_win->w_winvar.di_tv, copyID, NULL, NULL);
#ifdef FEAT_PROP_POPUP
FOR_ALL_POPUPWINS(wp)
abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID,
diff --git a/src/evalbuffer.c b/src/evalbuffer.c
index 82a10d675..e611c52e4 100644
--- a/src/evalbuffer.c
+++ b/src/evalbuffer.c
@@ -136,6 +136,8 @@ typedef struct {
*
* Information is saved in "cob" and MUST be restored by calling
* change_other_buffer_restore().
+ *
+ * If this fails then "curbuf" will not be equal to "buf".
*/
static void
change_other_buffer_prepare(cob_T *cob, buf_T *buf)
@@ -156,7 +158,8 @@ change_other_buffer_prepare(cob_T *cob, buf_T *buf)
// curwin->w_buffer differ from "curbuf", use the autocmd window.
curbuf = curwin->w_buffer;
aucmd_prepbuf(&cob->cob_aco, buf);
- cob->cob_using_aco = TRUE;
+ if (curbuf == buf)
+ cob->cob_using_aco = TRUE;
}
}
diff --git a/src/evalvars.c b/src/evalvars.c
index 28516c172..20223c8fe 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -4761,13 +4761,16 @@ f_setbufvar(typval_T *argvars, typval_T *rettv UNUSED)
{
aco_save_T aco;
- // set curbuf to be our buf, temporarily
+ // Set curbuf to be our buf, temporarily.
aucmd_prepbuf(&aco, buf);
+ if (curbuf == buf)
+ {
+ // Only when it worked to set "curbuf".
+ set_option_from_tv(varname + 1, varp);
- set_option_from_tv(varname + 1, varp);
-
- // reset notion of buffer
- aucmd_restbuf(&aco);
+ // reset notion of buffer
+ aucmd_restbuf(&aco);
+ }
}
else
{
diff --git a/src/evalwindow.c b/src/evalwindow.c
index 3578669ae..f8c0c7acf 100644
--- a/src/evalwindow.c
+++ b/src/evalwindow.c
@@ -1064,7 +1064,7 @@ f_win_gettype(typval_T *argvars, typval_T *rettv)
return;
}
}
- if (wp == aucmd_win)
+ if (is_aucmd_win(wp))
rettv->vval.v_string = vim_strsave((char_u *)"autocmd");
#if defined(FEAT_QUICKFIX)
else if (wp->w_p_pvw)
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index c13d354bc..9c00b80b7 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -705,9 +705,12 @@ ex_listdo(exarg_T *eap)
else
{
aucmd_prepbuf(&aco, buf);
- apply_autocmds(EVENT_SYNTAX, buf->b_p_syn,
+ if (curbuf == buf)
+ {
+ apply_autocmds(EVENT_SYNTAX, buf->b_p_syn,
buf->b_fname, TRUE, buf);
- aucmd_restbuf(&aco);
+ aucmd_restbuf(&aco);
+ }
}
// start over, in case autocommands messed things up.
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index bb4a83163..218b7edd9 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -6050,7 +6050,7 @@ ex_win_close(
buf_T *buf = win->w_buffer;
// Never close the autocommand window.
- if (win == aucmd_win)
+ if (is_aucmd_win(win))
{
emsg(_(e_cannot_close_autocmd_or_popup_window));
return;
diff --git a/src/fileio.c b/src/fileio.c
index 9916de8a6..1ee08e21e 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -4369,8 +4369,14 @@ buf_reload(buf_T *buf, int orig_mode, int reload_options)
int flags = READ_NEW;
int prepped = OK;
- // set curwin/curbuf for "buf" and save some things
+ // Set curwin/curbuf for "buf" and save some things.
aucmd_prepbuf(&aco, buf);
+ if (curbuf != buf)
+ {
+ // Failed to find a window for "buf", it is dangerous to continue,
+ // better bail out.
+ return;
+ }
// Unless reload_options is set, we only want to read the text from the
// file, not reset the syntax highlighting, clear marks, diff status, etc.
diff --git a/src/globals.h b/src/globals.h
index d9207b940..eadff43c9 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -977,8 +977,18 @@ EXTERN win_T *prevwin INIT(= NULL); // previous window
EXTERN win_T *curwin; // currently active window
-EXTERN win_T *aucmd_win; // window used in aucmd_prepbuf()
-EXTERN int aucmd_win_used INIT(= FALSE); // aucmd_win is being used
+// When executing autocommands for a buffer that is not in any window, a
+// special window is created to handle the side effects. When autocommands
+// nest we may need more than one. Allow for up to five, if more are needed
+// something crazy is happening.
+#define AUCMD_WIN_COUNT 5
+
+typedef struct {
+ win_T *auc_win; // window used in aucmd_prepbuf()
+ int auc_win_used; // this auc_win is being used
+} aucmdwin_T;
+
+EXTERN aucmdwin_T aucmd_win[AUCMD_WIN_COUNT];
#ifdef FEAT_PROP_POPUP
EXTERN win_T *first_popupwin; // first global popup window
diff --git a/src/if_perl.xs b/src/if_perl.xs
index 34315be71..c69ed9ef1 100644
--- a/src/if_perl.xs
+++ b/src/if_perl.xs
@@ -1869,18 +1869,21 @@ Set(vimbuf, ...)
{
aco_save_T aco;
- /* set curwin/curbuf for "vimbuf" and save some things */
+ /* Set curwin/curbuf for "vimbuf" and save some things. */
aucmd_prepbuf(&aco, vimbuf);
-
- if (u_savesub(lnum) == OK)
+ if (curbuf == vimbuf)
{
- ml_replace(lnum, (char_u *)line, TRUE);
- changed_bytes(lnum, 0);
- }
+ /* Only when a window was found. */
+ if (u_savesub(lnum) == OK)
+ {
+ ml_replace(lnum, (char_u *)line, TRUE);
+ changed_bytes(lnum, 0);
+ }
- /* restore curwin/curbuf and a few other things */
- aucmd_restbuf(&aco);
- /* Careful: autocommands may have made "vimbuf" invalid! */
+ /* restore curwin/curbuf and a few other things */
+ aucmd_restbuf(&aco);
+ /* Careful: autocommands may have made "vimbuf" invalid! */
+ }
}
}
}
@@ -1921,18 +1924,22 @@ Delete(vimbuf, ...)
/* set curwin/curbuf for "vimbuf" and save some things */
aucmd_prepbuf(&aco, vimbuf);
-
- if (u_savedel(lnum, 1) == OK)
+ if (curbuf == vimbuf)
{
- ml_delete(lnum);
- check_cursor();
- deleted_lines_mark(lnum, 1L);
+ /* Only when a window was found. */
+ if (u_savedel(lnum, 1) == OK)
+ {
+ ml_delete(lnum);
+ check_cursor();
+ deleted_lines_mark(lnum, 1L);
+ }
+
+ /* restore curwin/curbuf and a few other things */
+ aucmd_restbuf(&aco);
+ /* Careful: autocommands may have made "vimbuf"
+ * invalid! */
}
- /* restore curwin/curbuf and a few other things */
- aucmd_restbuf(&aco);
- /* Careful: autocommands may have made "vimbuf" invalid! */
-
update_curbuf(UPD_VALID);
}
}
@@ -1963,16 +1970,19 @@ Append(vimbuf, ...)
/* set curwin/curbuf for "vimbuf" and save some things */
aucmd_prepbuf(&aco, vimbuf);
-
- if (u_inssub(lnum + 1) == OK)
+ if (curbuf == vimbuf)
{
- ml_append(lnum, (char_u *)line, (colnr_T)0, FALSE);
- appended_lines_mark(lnum, 1L);
- }
+ /* Only when a window for "vimbuf" was found. */
+ if (u_inssub(lnum + 1) == OK)
+ {
+ ml_append(lnum, (char_u *)line, (colnr_T)0, FALSE);
+ appended_lines_mark(lnum, 1L);
+ }
- /* restore curwin/curbuf and a few other things */
- aucmd_restbuf(&aco);
- /* Careful: autocommands may have made "vimbuf" invalid! */
+ /* restore curwin/curbuf and a few other things */
+ aucmd_restbuf(&aco);
+ /* Careful: autocommands may have made "vimbuf" invalid! */
+ }
update_curbuf(UPD_VALID);
}
diff --git a/src/if_py_both.h b/src/if_py_both.h
index d6cb13b83..0cde18d05 100644
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -5283,8 +5283,11 @@ BufferSetattr(BufferObject *self, char *name, PyObject *valObject)
VimTryStart();
// Using aucmd_*: autocommands will be executed by rename_buffer
aucmd_prepbuf(&aco, self->buf);
- ren_ret = rename_buffer(val);
- aucmd_restbuf(&aco);
+ if (curbuf == self->buf)
+ {
+ ren_ret = rename_buffer(val);
+ aucmd_restbuf(&aco);
+ }
Py_XDECREF(todecref);
if (VimTryEnd())
return -1;
diff --git a/src/if_ruby.c b/src/if_ruby.c
index 51cfff13d..b157bb83d 100644
--- a/src/if_ruby.c
+++ b/src/if_ruby.c
@@ -1371,21 +1371,24 @@ set_buffer_line(buf_T *buf, linenr_T n, VALUE str)
if (n > 0 && n <= buf->b_ml.ml_line_count && line != NULL)
{
- // set curwin/curbuf for "buf" and save some things
+ // Set curwin/curbuf for "buf" and save some things.
aucmd_prepbuf(&aco, buf);
-
- if (u_savesub(n) == OK)
+ if (curbuf == buf)
{
- ml_replace(n, (char_u *)line, TRUE);
- changed();
+ // Only when it worked to set "curbuf".
+ if (u_savesub(n) == OK)
+ {
+ ml_replace(n, (char_u *)line, TRUE);
+ changed();
#ifdef SYNTAX_HL
- syn_changed(n); // recompute syntax hl. for this line
+ syn_changed(n); // recompute syntax hl. for this line
#endif
- }
+ }
- // restore curwin/curbuf and a few other things
- aucmd_restbuf(&aco);
- // Careful: autocommands may have made "buf" invalid!
+ // restore curwin/curbuf and a few other things
+ aucmd_restbuf(&aco);
+ // Careful: autocommands may have made "buf" invalid!
+ }
update_curbuf(UPD_NOT_VALID);
}
@@ -1415,23 +1418,26 @@ buffer_delete(VALUE self, VALUE num)
if (n > 0 && n <= buf->b_ml.ml_line_count)
{
- // set curwin/curbuf for "buf" and save some things
+ // Set curwin/curbuf for "buf" and save some things.
aucmd_prepbuf(&aco, buf);
-
- if (u_savedel(n, 1) == OK)
+ if (curbuf == buf)
{
- ml_delete(n);
+ // Only when it worked to set "curbuf".
+ if (u_savedel(n, 1) == OK)
+ {
+ ml_delete(n);
- // Changes to non-active buffers should properly refresh
- // SegPhault - 01/09/05
- deleted_lines_mark(n, 1L);
+ // Changes to non-active buffers should properly refresh
+ // SegPhault - 01/09/05
+ deleted_lines_mark(n, 1L);
- changed();
- }
+ changed();
+ }
- // restore curwin/curbuf and a few other things
- aucmd_restbuf(&aco);
- // Careful: autocommands may have made "buf" invalid!
+ // restore curwin/curbuf and a few other things
+ aucmd_restbuf(&aco);
+ // Careful: autocommands may have made "buf" invalid!
+ }
update_curbuf(UPD_NOT_VALID);
}
@@ -1458,21 +1464,24 @@ buffer_append(VALUE self, VALUE num, VALUE str)
{
// set curwin/curbuf for "buf" and save some things
aucmd_prepbuf(&aco, buf);
-
- if (u_inssub(n + 1) == OK)
+ if (curbuf == buf)
{
- ml_append(n, (char_u *) line, (colnr_T) 0, FALSE);
+ // Only when it worked to set "curbuf".
+ if (u_inssub(n + 1) == OK)
+ {
+ ml_append(n, (char_u *) line, (colnr_T) 0, FALSE);
- // Changes to non-active buffers should properly refresh screen
- // SegPhault - 12/20/04
- appended_lines_mark(n, 1L);
+ // Changes to non-active buffers should properly refresh screen
+ // SegPhault - 12/20/04
+ appended_lines_mark(n, 1L);
- changed();
- }
+ changed();
+ }
- // restore curwin/curbuf and a few other things
- aucmd_restbuf(&aco);
- // Careful: autocommands may have made "buf" invalid!
+ // restore curwin/curbuf and a few other things
+ aucmd_restbuf(&aco);
+ // Careful: autocommands may have made "buf" invalid!
+ }
update_curbuf(UPD_NOT_VALID);
}
diff --git a/src/main.c b/src/main.c
index ca28eca72..db81a3f3c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -123,6 +123,8 @@ main
#endif
params.window_count = -1;
+ autocmd_init();
+
#ifdef FEAT_RUBY
{
int ruby_stack_start;
diff --git a/src/os_unix.c b/src/os_unix.c
index fd6d35fed..c43d9c172 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -4490,27 +4490,30 @@ mch_call_shell_terminal(
// Find a window to make "buf" curbuf.
aucmd_prepbuf(&aco, buf);
-
- clear_oparg(&oa);
- while (term_use_loop())
+ if (curbuf == buf)
{
- if (oa.op_type == OP_NOP && oa.regname == NUL && !VIsual_active)
+ // Only when managed to find a window for "buf",
+ clear_oparg(&oa);
+ while (term_use_loop())
{
- // If terminal_loop() returns OK we got a key that is handled
- // in Normal model. We don't do redrawing anyway.
- if (terminal_loop(TRUE) == OK)
+ if (oa.op_type == OP_NOP && oa.regname == NUL && !VIsual_active)
+ {
+ // If terminal_loop() returns OK we got a key that is handled
+ // in Normal model. We don't do redrawing anyway.
+ if (terminal_loop(TRUE) == OK)
+ normal_cmd(&oa, TRUE);
+ }
+ else
normal_cmd(&oa, TRUE);
}
- else
- normal_cmd(&oa, TRUE);
- }
- retval = job->jv_exitval;
- ch_log(NULL, "system command finished");
+ retval = job->jv_exitval;
+ ch_log(NULL, "system command finished");
- job_unref(job);
+ job_unref(job);
- // restore curwin/curbuf and a few other things
- aucmd_restbuf(&aco);
+ // restore curwin/curbuf and a few other things
+ aucmd_restbuf(&aco);
+ }
// Only require pressing Enter when redrawing, to avoid that system() gets
// the hit-enter prompt even though it didn't output anything.
diff --git a/src/os_win32.c b/src/os_win32.c
index 4c97b3100..acbc4cb7d 100644
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -4878,27 +4878,30 @@ mch_call_shell_terminal(
// Find a window to make "buf" curbuf.
aucmd_prepbuf(&aco, buf);
-
- clear_oparg(&oa);
- while (term_use_loop())
+ if (curbuf == buf)
{
- if (oa.op_type == OP_NOP && oa.regname == NUL && !VIsual_active)
+ // Only do this when a window was found for "buf".
+ clear_oparg(&oa);
+ while (term_use_loop())
{
- // If terminal_loop() returns OK we got a key that is handled
- // in Normal model. We don't do redrawing anyway.
- if (terminal_loop(TRUE) == OK)
+ if (oa.op_type == OP_NOP && oa.regname == NUL && !VIsual_active)
+ {
+ // If terminal_loop() returns OK we got a key that is handled
+ // in Normal model. We don't do redrawing anyway.
+ if (terminal_loop(TRUE) == OK)
+ normal_cmd(&oa, TRUE);
+ }
+ else
normal_cmd(&oa, TRUE);
}
- else
- normal_cmd(&oa, TRUE);
- }
- retval = job->jv_exitval;
- ch_log(NULL, "system command finished");
+ retval = job->jv_exitval;
+ ch_log(NULL, "system command finished");
- job_unref(job);
+ job_unref(job);
- // restore curwin/curbuf and a few other things
- aucmd_restbuf(&aco);
+ // restore curwin/curbuf and a few other things
+ aucmd_restbuf(&aco);
+ }
wait_return(TRUE);
do_buffer(DOBUF_WIPE, DOBUF_FIRST, FORWARD, buf->b_fnum, TRUE);
diff --git a/src/proto/autocmd.pro b/src/proto/autocmd.pro
index 1f55f2d27..0b61989c0 100644
--- a/src/proto/autocmd.pro
+++ b/src/proto/autocmd.pro
@@ -2,7 +2,9 @@
void aubuflocal_remove(buf_T *buf);
int au_has_group(char_u *name);
void do_augroup(char_u *arg, int del_group);
+void autocmd_init(void);
void free_all_autocmds(void);
+int is_aucmd_win(win_T *win);
int check_ei(void);
char_u *au_event_disable(char *what);
void au_event_restore(char_u *old_ei);
diff --git a/src/quickfix.c b/src/quickfix.c
index 403c397d5..e8716d268 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -4598,21 +4598,29 @@ qf_update_buffer(qf_info_T *qi, qfline_T *old_last)
// autocommands may cause trouble
incr_quickfix_busy();
+ int do_fill = TRUE;
if (old_last == NULL)
+ {
// set curwin/curbuf to buf and save a few things
aucmd_prepbuf(&aco, buf);
+ if (curbuf != buf)
+ do_fill = FALSE; // failed to find a window for "buf"
+ }
- qf_update_win_titlevar(qi);
+ if (do_fill)
+ {
+ qf_update_win_titlevar(qi);
- qf_fill_buffer(qf_get_curlist(qi), buf, old_last, qf_winid);
- ++CHANGEDTICK(buf);
+ qf_fill_buffer(qf_get_curlist(qi), buf, old_last, qf_winid);
+ ++CHANGEDTICK(buf);
- if (old_last == NULL)
- {
- (void)qf_win_pos_update(qi, 0);
+ if (old_last == NULL)
+ {
+ (void)qf_win_pos_update(qi, 0);
- // restore curwin/curbuf and a few other things
- aucmd_restbuf(&aco);
+ // restore curwin/curbuf and a few other things
+ aucmd_restbuf(&aco);
+ }
}
// Only redraw when added lines are visible. This avoids flickering
@@ -6395,12 +6403,15 @@ vgr_process_files(
// need to be done (again). But not the window-local
// options!
aucmd_prepbuf(&aco, buf);
+ if (curbuf == buf)
+ {
#if defined(FEAT_SYN_HL)
- apply_autocmds(EVENT_FILETYPE, buf->b_p_ft,
+ apply_autocmds(EVENT_FILETYPE, buf->b_p_ft,
buf->b_fname, TRUE, buf);
#endif
- do_modelines(OPT_NOWIN);
- aucmd_restbuf(&aco);
+ do_modelines(OPT_NOWIN);
+ aucmd_restbuf(&aco);
+ }
}
}
}
@@ -6593,40 +6604,43 @@ load_dummy_buffer(
// set curwin/curbuf to buf and save a few things
aucmd_prepbuf(&aco, newbuf);
-
- // Need to set the filename for autocommands.
- (void)setfname(curbuf, fname, NULL, FALSE);
-
- // Create swap file now to avoid the ATTENTION message.
- check_need_swap(TRUE);
-
- // Remove the "dummy" flag, otherwise autocommands may not
- // work.
- curbuf->b_flags &= ~BF_DUMMY;
-
- newbuf_to_wipe.br_buf = NULL;
- readfile_result = readfile(fname, NULL,
- (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM,
- NULL, READ_NEW | READ_DUMMY);
- --newbuf->b_locked;
- if (readfile_result == OK
- && !got_int
- && !(curbuf->b_flags & BF_NEW))
+ if (curbuf == newbuf)
{
- failed = FALSE;
- if (curbuf != newbuf)
+ // Need to set the filename for autocommands.
+ (void)setfname(curbuf, fname, NULL, FALSE);
+
+ // Create swap file now to avoid the ATTENTION message.
+ check_need_swap(TRUE);
+
+ // Remove the "dummy" flag, otherwise autocommands may not
+ // work.
+ curbuf->b_flags &= ~BF_DUMMY;
+
+ newbuf_to_wipe.br_buf = NULL;
+ readfile_result = readfile(fname, NULL,
+ (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM,
+ NULL, READ_NEW | READ_DUMMY);
+ --newbuf->b_locked;
+ if (readfile_result == OK
+ && !got_int
+ && !(curbuf->b_flags & BF_NEW))
{
- // Bloody autocommands changed the buffer! Can happen when
- // using netrw and editing a remote file. Use the current
- // buffer instead, delete the dummy one after restoring the
- // window stuff.
- set_bufref(&newbuf_to_wipe, newbuf);
- newbuf = curbuf;
+ failed = FALSE;
+ if (curbuf != newbuf)
+ {
+ // Bloody autocommands changed the buffer! Can happen when
+ // using netrw and editing a remote file. Use the current
+ // buffer instead, delete the dummy one after restoring the
+ // window stuff.
+ set_bufref(&newbuf_to_wipe, newbuf);
+ newbuf = curbuf;
+ }
}
+
+ // restore curwin/curbuf and a few other things
+ aucmd_restbuf(&aco);
}
- // restore curwin/curbuf and a few other things
- aucmd_restbuf(&aco);
if (newbuf_to_wipe.br_buf != NULL && bufref_valid(&newbuf_to_wipe))
wipe_buffer(newbuf_to_wipe.br_buf, FALSE);
diff --git a/src/screen.c b/src/screen.c
index 47288118c..7c3a6d7b0 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -2369,7 +2369,6 @@ screenalloc(int doclear)
u8char_T *new_ScreenLinesUC = NULL;
u8char_T *new_ScreenLinesC[MAX_MCO];
schar_T *new_ScreenLines2 = NULL;
- int i;
sattr_T *new_ScreenAttrs;
colnr_T *new_ScreenCols;
unsigned *new_LineOffset;
@@ -2438,8 +2437,9 @@ retry:
*/
FOR_ALL_TAB_WINDOWS(tp, wp)
win_free_lsize(wp);
- if (aucmd_win != NULL)
- win_free_lsize(aucmd_win);
+ for (int i = 0; i < AUCMD_WIN_COUNT; ++i)
+ if (aucmd_win[i].auc_win_used)
+ win_free_lsize(aucmd_win[i].auc_win);
#ifdef FEAT_PROP_POPUP
// global popup windows
FOR_ALL_POPUPWINS(wp)
@@ -2455,7 +2455,7 @@ retry:
if (enc_utf8)
{
new_ScreenLinesUC = LALLOC_MULT(u8char_T, (Rows + 1) * Columns);
- for (i = 0; i < p_mco; ++i)
+ for (int i = 0; i < p_mco; ++i)
new_ScreenLinesC[i] = LALLOC_CLEAR_MULT(u8char_T,
(Rows + 1) * Columns);
}
@@ -2482,9 +2482,14 @@ retry:
goto give_up;
}
}
- if (aucmd_win != NULL && aucmd_win->w_lines == NULL
- && win_alloc_lines(aucmd_win) == FAIL)
- outofmem = TRUE;
+ for (int i = 0; i < AUCMD_WIN_COUNT; ++i)
+ if (aucmd_win[i].auc_win_used
+ && aucmd_win[i].auc_win->w_lines == NULL
+ && win_alloc_lines(aucmd_win[i].auc_win) == FAIL)
+ {
+ outofmem = TRUE;
+ break;
+ }
#ifdef FEAT_PROP_POPUP
// global popup windows
FOR_ALL_POPUPWINS(wp)
@@ -2505,11 +2510,15 @@ retry:
give_up:
- for (i = 0; i < p_mco; ++i)
+ int found_null = FALSE;
+ for (int i = 0; i < p_mco; ++i)
if (new_ScreenLinesC[i] == NULL)
+ {
+ found_null = TRUE;
break;
+ }
if (new_ScreenLines == NULL
- || (enc_utf8 && (new_ScreenLinesUC == NULL || i != p_mco))
+ || (enc_utf8 && (new_ScreenLinesUC == NULL || found_null))
|| (enc_dbcs == DBCS_JPNU && new_ScreenLines2 == NULL)
|| new_ScreenAttrs == NULL
|| new_ScreenCols == NULL
@@ -2534,7 +2543,7 @@ give_up:
}
VIM_CLEAR(new_ScreenLines);
VIM_CLEAR(new_ScreenLinesUC);
- for (i = 0; i < p_mco; ++i)
+ for (int i = 0; i < p_mco; ++i)
VIM_CLEAR(new_ScreenLinesC[i]);
VIM_CLEAR(new_ScreenLines2);
VIM_CLEAR(new_ScreenAttrs);
@@ -2571,7 +2580,7 @@ give_up:
{
(void)vim_memset(new_ScreenLinesUC + new_row * Columns,
0, (size_t)Columns * sizeof(u8char_T));
- for (i = 0; i < p_mco; ++i)
+ for (int i = 0; i < p_mco; ++i)
(void)vim_memset(new_ScreenLinesC[i]
+ new_row * Columns,
0, (size_t)Columns * sizeof(u8char_T));
@@ -2603,7 +2612,7 @@ give_up:
mch_memmove(new_ScreenLinesUC + new_LineOffset[new_row],
ScreenLinesUC + LineOffset[old_row],
(size_t)len * sizeof(u8char_T));
- for (i = 0; i < p_mco; ++i)
+ for (int i = 0; i < p_mco; ++i)
mch_memmove(new_ScreenLinesC[i]
+ new_LineOffset[new_row],
ScreenLinesC[i] + LineOffset[old_row],
@@ -2636,7 +2645,7 @@ give_up:
// NOTE: this may result in all pointers to become NULL.
ScreenLines = new_ScreenLines;
ScreenLinesUC = new_ScreenLinesUC;
- for (i = 0; i < p_mco; ++i)
+ for (int i = 0; i < p_mco; ++i)
ScreenLinesC[i] = new_ScreenLinesC[i];
Screen_mco = p_mco;
ScreenLines2 = new_ScreenLines2;
diff --git a/src/structs.h b/src/structs.h
index f57fb8561..824de4556 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -4160,7 +4160,7 @@ typedef int vimmenu_T;
typedef struct
{
buf_T *save_curbuf; // saved curbuf
- int use_aucmd_win; // using aucmd_win
+ int use_aucmd_win_idx; // index in aucmd_win[] if >= 0
int save_curwin_id; // ID of saved curwin
int new_curwin_id; // ID of new curwin
int save_prevwin_id; // ID of saved prevwin
diff --git a/src/term.c b/src/term.c
index 237a3258a..b8869f9be 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2232,10 +2232,13 @@ set_termname(char_u *term)
if (curbuf->b_ml.ml_mfp != NULL)
{
aucmd_prepbuf(&aco, buf);
- apply_autocmds(EVENT_TERMCHANGED, NULL, NULL, FALSE,
+ if (curbuf == buf)
+ {
+ apply_autocmds(EVENT_TERMCHANGED, NULL, NULL, FALSE,
curbuf);
- // restore curwin/curbuf and a few other things
- aucmd_restbuf(&aco);
+ // restore curwin/curbuf and a few other things
+ aucmd_restbuf(&aco);
+ }
}
}
}
diff --git a/src/terminal.c b/src/terminal.c
index d300c59a2..18f9c6260 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -3560,15 +3560,18 @@ term_after_channel_closed(term_T *term)
// ++close or term_finish == "close"
ch_log(NULL, "terminal job finished, closing window");
aucmd_prepbuf(&aco, term->tl_buffer);
- // Avoid closing the window if we temporarily use it.
- if (curwin == aucmd_win)
- do_set_w_closing = TRUE;
- if (do_set_w_closing)
- curwin->w_closing = TRUE;
- do_bufdel(DOBUF_WIPE, (char_u *)"", 1, fnum, fnum, FALSE);
- if (do_set_w_closing)
- curwin->w_closing = FALSE;
- aucmd_restbuf(&aco);
+ if (curbuf == term->tl_buffer)
+ {
+ // Avoid closing the window if we temporarily use it.
+ if (is_aucmd_win(curwin))
+ do_set_w_closing = TRUE;
+ if (do_set_w_closing)
+ curwin->w_closing = TRUE;
+ do_bufdel(DOBUF_WIPE, (char_u *)"", 1, fnum, fnum, FALSE);
+ if (do_set_w_closing)
+ curwin->w_closing = FALSE;
+ aucmd_restbuf(&aco);
+ }
#ifdef FEAT_PROP_POPUP
if (pwin != NULL)
popup_close_with_retval(pwin, 0);
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index a0d83ecf3..593e56819 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -4068,4 +4068,27 @@ func Test_autocmd_split_dummy()
call delete('Xerr')
endfunc
+" This was crashing because there was only one window to execute autocommands
+" in.
+func Test_autocmd_nested_setbufvar()
+ CheckFeature python3
+
+ set hidden
+ edit Xaaa
+ edit Xbbb
+ call setline(1, 'bar')
+ enew
+ au BufWriteCmd Xbbb ++nested call setbufvar('Xaaa', '&ft', 'foo') | bw! Xaaa
+ au FileType foo call py3eval('vim.current.buffer.options["cindent"]')
+ wall
+
+ au! BufWriteCmd
+ au! FileType foo
+ set nohidden
+ call delete('Xaaa')
+ call delete('Xbbb')
+ %bwipe!
+endfunc
+
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index e53ad971f..8d51ea702 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 965,
+/**/
964,
/**/
963,
diff --git a/src/window.c b/src/window.c
index 869c98535..24f25d65b 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1362,7 +1362,7 @@ win_split_ins(
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);
// Don't change the window height/width to 'winheight' / 'winwidth' if a
@@ -1962,7 +1962,7 @@ win_equal(
win_equal_rec(next_curwin == NULL ? curwin : next_curwin, current,
topframe, dir, 0, tabline_height(),
(int)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);
}
@@ -2426,7 +2426,7 @@ close_windows(
/*
* Return TRUE if the current window is the only window that exists (ignoring
- * "aucmd_win").
+ * "aucmd_win[]").
* Returns FALSE if there is a window, possibly in another tab page.
*/
static int
@@ -2436,7 +2436,7 @@ last_window(void)
}
/*
- * Return TRUE if there is only one window other than "aucmd_win" in the
+ * Return TRUE if there is only one window other than "aucmd_win[]" in the
* current tab page.
*/
int
@@ -2447,7 +2447,7 @@ one_window(void)
FOR_ALL_WINDOWS(wp)
{
- if (wp != aucmd_win)
+ if (!is_aucmd_win(wp))
{
if (seen_one)
return FALSE;
@@ -2588,7 +2588,7 @@ win_close(win_T *win, int free_buf)
emsg(_(e_cannot_close_autocmd_or_popup_window));
return FAIL;
}
- if ((firstwin == aucmd_win || lastwin == aucmd_win) && one_window())
+ if ((is_aucmd_win(firstwin) || is_aucmd_win(lastwin)) && one_window())
{
emsg(_(e_cannot_close_window_only_autocmd_window_would_remain));
return FAIL;
@@ -3292,11 +3292,12 @@ win_free_all(void)
while (first_tabpage->tp_next != NULL)
tabpage_close(TRUE);
- if (aucmd_win != NULL)
- {
- (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_used)
+ {
+ (void)win_free_mem(aucmd_win[i].auc_win, &dummy, NULL);
+ aucmd_win[i].auc_win_used = FALSE;
+ }
while (firstwin != NULL)
(void)win_free_mem(firstwin, &dummy, NULL);
@@ -5663,7 +5664,7 @@ win_free(
int
win_unlisted(win_T *wp)
{
- return wp == aucmd_win || WIN_IS_POPUP(wp);
+ return is_aucmd_win(wp) || WIN_IS_POPUP(wp);
}
#if defined(FEAT_PROP_POPUP) || defined(PROTO)
@@ -7257,7 +7258,7 @@ only_one_window(void)
# ifdef FEAT_QUICKFIX
|| wp->w_p_pvw
# endif
- ) || wp == curwin) && wp != aucmd_win)
+ ) || wp == curwin) && !is_aucmd_win(wp))
++count;
return (count <= 1);
}