mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 03:18:16 +00:00
Merge pull request #21234 from zeertzjq/vim-9.0.0965
vim-patch:9.0.{0965,0966,0967}: using one window for executing autocommands is insufficient
This commit is contained in:
@@ -633,6 +633,11 @@ void do_augroup(char *arg, int del_group)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void autocmd_init(void)
|
||||||
|
{
|
||||||
|
CLEAR_FIELD(aucmd_win);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(EXITFREE)
|
#if defined(EXITFREE)
|
||||||
void free_all_autocmds(void)
|
void free_all_autocmds(void)
|
||||||
{
|
{
|
||||||
@@ -659,9 +664,22 @@ void free_all_autocmds(void)
|
|||||||
api_free_string(name);
|
api_free_string(name);
|
||||||
})
|
})
|
||||||
map_destroy(int, String)(&map_augroup_id_to_name);
|
map_destroy(int, String)(&map_augroup_id_to_name);
|
||||||
|
|
||||||
|
// aucmd_win[] is freed in win_free_all()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// Return true if "win" is an active entry in aucmd_win[].
|
||||||
|
bool 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 the event number for event name "start".
|
||||||
// Return NUM_EVENTS if the event name was not found.
|
// Return NUM_EVENTS if the event name was not found.
|
||||||
// Return a pointer to the next event name in "end".
|
// Return a pointer to the next event name in "end".
|
||||||
@@ -1310,6 +1328,13 @@ void ex_doautoall(exarg_T *eap)
|
|||||||
|
|
||||||
// Find a window for this buffer and save some values.
|
// Find a window for this buffer and save some values.
|
||||||
aucmd_prepbuf(&aco, buf);
|
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);
|
set_bufref(&bufref, buf);
|
||||||
|
|
||||||
// execute the autocommands for this buffer
|
// execute the autocommands for this buffer
|
||||||
@@ -1319,7 +1344,7 @@ void ex_doautoall(exarg_T *eap)
|
|||||||
// Execute the modeline settings, but don't set window-local
|
// Execute the modeline settings, but don't set window-local
|
||||||
// options if we are using the current window for another
|
// options if we are using the current window for another
|
||||||
// buffer.
|
// buffer.
|
||||||
do_modelines(curwin == aucmd_win ? OPT_NOWIN : 0);
|
do_modelines(is_aucmd_win(curwin) ? OPT_NOWIN : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore the current window
|
// restore the current window
|
||||||
@@ -1358,8 +1383,9 @@ bool check_nomodeline(char **argp)
|
|||||||
|
|
||||||
/// Prepare for executing autocommands for (hidden) buffer `buf`.
|
/// Prepare for executing autocommands for (hidden) buffer `buf`.
|
||||||
/// If the current buffer is not in any visible window, put it in a temporary
|
/// If the current buffer is not in any visible window, put it in a temporary
|
||||||
/// floating window `aucmd_win`.
|
/// floating window using an entry in `aucmd_win[]`.
|
||||||
/// Set `curbuf` and `curwin` to match `buf`.
|
/// Set `curbuf` and `curwin` to match `buf`.
|
||||||
|
/// When this fails `curbuf` is not equal `buf`.
|
||||||
///
|
///
|
||||||
/// @param aco structure to save values in
|
/// @param aco structure to save values in
|
||||||
/// @param buf new curbuf
|
/// @param buf new curbuf
|
||||||
@@ -1381,15 +1407,28 @@ void aucmd_prepbuf(aco_save_T *aco, buf_T *buf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate the `aucmd_win` dummy floating window.
|
// Allocate a window when needed.
|
||||||
if (win == NULL && aucmd_win == NULL) {
|
win_T *auc_win = NULL;
|
||||||
win_alloc_aucmd_win();
|
int auc_idx = AUCMD_WIN_COUNT;
|
||||||
need_append = false;
|
if (win == NULL) {
|
||||||
}
|
for (auc_idx = 0; auc_idx < AUCMD_WIN_COUNT; auc_idx++) {
|
||||||
if (win == NULL && aucmd_win_used) {
|
if (!aucmd_win[auc_idx].auc_win_used) {
|
||||||
// Strange recursive autocommand, fall back to using the current
|
if (aucmd_win[auc_idx].auc_win == NULL) {
|
||||||
// window. Expect a few side effects...
|
win_alloc_aucmd_win(auc_idx);
|
||||||
win = curwin;
|
need_append = false;
|
||||||
|
}
|
||||||
|
auc_win = aucmd_win[auc_idx].auc_win;
|
||||||
|
aucmd_win[auc_idx].auc_win_used = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this fails (using all AUCMD_WIN_COUNT entries)
|
||||||
|
// then we can't reliably execute the autocmd,
|
||||||
|
// return with "curbuf" unequal "buf".
|
||||||
|
if (auc_win == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aco->save_curwin_handle = curwin->handle;
|
aco->save_curwin_handle = curwin->handle;
|
||||||
@@ -1399,42 +1438,41 @@ void aucmd_prepbuf(aco_save_T *aco, buf_T *buf)
|
|||||||
// There is a window for "buf" in the current tab page, make it the
|
// 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
|
// curwin. This is preferred, it has the least side effects (esp. if
|
||||||
// "buf" is curbuf).
|
// "buf" is curbuf).
|
||||||
aco->use_aucmd_win = false;
|
aco->use_aucmd_win_idx = -1;
|
||||||
curwin = win;
|
curwin = win;
|
||||||
} else {
|
} 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.
|
// effects, insert it in the current tab page.
|
||||||
// Anything related to a window (e.g., setting folds) may have
|
// Anything related to a window (e.g., setting folds) may have
|
||||||
// unexpected results.
|
// unexpected results.
|
||||||
aco->use_aucmd_win = true;
|
aco->use_aucmd_win_idx = auc_idx;
|
||||||
aucmd_win_used = true;
|
auc_win->w_buffer = buf;
|
||||||
aucmd_win->w_buffer = buf;
|
auc_win->w_s = &buf->b_s;
|
||||||
aucmd_win->w_s = &buf->b_s;
|
|
||||||
buf->b_nwindows++;
|
buf->b_nwindows++;
|
||||||
win_init_empty(aucmd_win); // set cursor and topline to safe values
|
win_init_empty(auc_win); // set cursor and topline to safe values
|
||||||
|
|
||||||
// Make sure w_localdir and globaldir are NULL to avoid a chdir() in
|
// Make sure w_localdir and globaldir are NULL to avoid a chdir() in
|
||||||
// win_enter_ext().
|
// win_enter_ext().
|
||||||
XFREE_CLEAR(aucmd_win->w_localdir);
|
XFREE_CLEAR(auc_win->w_localdir);
|
||||||
aco->globaldir = globaldir;
|
aco->globaldir = globaldir;
|
||||||
globaldir = NULL;
|
globaldir = NULL;
|
||||||
|
|
||||||
block_autocmds(); // We don't want BufEnter/WinEnter autocommands.
|
block_autocmds(); // We don't want BufEnter/WinEnter autocommands.
|
||||||
if (need_append) {
|
if (need_append) {
|
||||||
win_append(lastwin, aucmd_win);
|
win_append(lastwin, auc_win);
|
||||||
pmap_put(handle_T)(&window_handles, aucmd_win->handle, aucmd_win);
|
pmap_put(handle_T)(&window_handles, auc_win->handle, auc_win);
|
||||||
win_config_float(aucmd_win, aucmd_win->w_float_config);
|
win_config_float(auc_win, auc_win->w_float_config);
|
||||||
}
|
}
|
||||||
// Prevent chdir() call in win_enter_ext(), through do_autochdir()
|
// Prevent chdir() call in win_enter_ext(), through do_autochdir()
|
||||||
int save_acd = p_acd;
|
int save_acd = p_acd;
|
||||||
p_acd = false;
|
p_acd = false;
|
||||||
// no redrawing and don't set the window title
|
// no redrawing and don't set the window title
|
||||||
RedrawingDisabled++;
|
RedrawingDisabled++;
|
||||||
win_enter(aucmd_win, false);
|
win_enter(auc_win, false);
|
||||||
RedrawingDisabled--;
|
RedrawingDisabled--;
|
||||||
p_acd = save_acd;
|
p_acd = save_acd;
|
||||||
unblock_autocmds();
|
unblock_autocmds();
|
||||||
curwin = aucmd_win;
|
curwin = auc_win;
|
||||||
}
|
}
|
||||||
curbuf = buf;
|
curbuf = buf;
|
||||||
aco->new_curwin_handle = curwin->handle;
|
aco->new_curwin_handle = curwin->handle;
|
||||||
@@ -1451,18 +1489,20 @@ void aucmd_prepbuf(aco_save_T *aco, buf_T *buf)
|
|||||||
/// @param aco structure holding saved values
|
/// @param aco structure holding saved values
|
||||||
void aucmd_restbuf(aco_save_T *aco)
|
void aucmd_restbuf(aco_save_T *aco)
|
||||||
{
|
{
|
||||||
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--;
|
curbuf->b_nwindows--;
|
||||||
// Find "aucmd_win", it can't be closed, but it may be in another tab page.
|
// Find "awp", it can't be closed, but it may be in another tab page.
|
||||||
// Do not trigger autocommands here.
|
// Do not trigger autocommands here.
|
||||||
block_autocmds();
|
block_autocmds();
|
||||||
if (curwin != aucmd_win) {
|
if (curwin != awp) {
|
||||||
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
||||||
if (wp == aucmd_win) {
|
if (wp == awp) {
|
||||||
if (tp != curtab) {
|
if (tp != curtab) {
|
||||||
goto_tabpage_tp(tp, true, true);
|
goto_tabpage_tp(tp, true, true);
|
||||||
}
|
}
|
||||||
win_goto(aucmd_win);
|
win_goto(awp);
|
||||||
goto win_found;
|
goto win_found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1477,7 +1517,9 @@ win_found:
|
|||||||
grid_free(&curwin->w_grid_alloc);
|
grid_free(&curwin->w_grid_alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
aucmd_win_used = false;
|
// The window is marked as not used, but it is not freed, it can be
|
||||||
|
// used again.
|
||||||
|
aucmd_win[aco->use_aucmd_win_idx].auc_win_used = false;
|
||||||
|
|
||||||
if (!valid_tabpage_win(curtab)) {
|
if (!valid_tabpage_win(curtab)) {
|
||||||
// no valid window in current tabpage
|
// no valid window in current tabpage
|
||||||
@@ -1498,8 +1540,8 @@ win_found:
|
|||||||
entering_window(curwin);
|
entering_window(curwin);
|
||||||
|
|
||||||
prevwin = win_find_by_handle(aco->save_prevwin_handle);
|
prevwin = win_find_by_handle(aco->save_prevwin_handle);
|
||||||
vars_clear(&aucmd_win->w_vars->dv_hashtab); // free all w: variables
|
vars_clear(&awp->w_vars->dv_hashtab); // free all w: variables
|
||||||
hash_init(&aucmd_win->w_vars->dv_hashtab); // re-use the hashtab
|
hash_init(&awp->w_vars->dv_hashtab); // re-use the hashtab
|
||||||
|
|
||||||
xfree(globaldir);
|
xfree(globaldir);
|
||||||
globaldir = aco->globaldir;
|
globaldir = aco->globaldir;
|
||||||
|
@@ -25,7 +25,7 @@ struct AutoPat_S;
|
|||||||
// not the current buffer.
|
// not the current buffer.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
buf_T *save_curbuf; ///< saved curbuf
|
buf_T *save_curbuf; ///< saved curbuf
|
||||||
bool use_aucmd_win; ///< using aucmd_win
|
int use_aucmd_win_idx; ///< index in aucmd_win[] if >= 0
|
||||||
handle_T save_curwin_handle; ///< ID of saved curwin
|
handle_T save_curwin_handle; ///< ID of saved curwin
|
||||||
handle_T new_curwin_handle; ///< ID of new curwin
|
handle_T new_curwin_handle; ///< ID of new curwin
|
||||||
handle_T save_prevwin_handle; ///< ID of saved prevwin
|
handle_T save_prevwin_handle; ///< ID of saved prevwin
|
||||||
|
@@ -175,6 +175,22 @@ static int read_buffer(int read_stdin, exarg_T *eap, int flags)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ensure buffer "buf" is loaded. Does not trigger the swap-exists action.
|
||||||
|
void buffer_ensure_loaded(buf_T *buf)
|
||||||
|
{
|
||||||
|
if (buf->b_ml.ml_mfp == NULL) {
|
||||||
|
aco_save_T aco;
|
||||||
|
|
||||||
|
// Make sure the buffer is in a window. If not then skip it.
|
||||||
|
aucmd_prepbuf(&aco, buf);
|
||||||
|
if (curbuf == buf) {
|
||||||
|
swap_exists_action = SEA_NONE;
|
||||||
|
open_buffer(false, NULL, 0);
|
||||||
|
aucmd_restbuf(&aco);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Open current buffer, that is: open the memfile and read the file into
|
/// Open current buffer, that is: open the memfile and read the file into
|
||||||
/// memory.
|
/// memory.
|
||||||
///
|
///
|
||||||
@@ -352,18 +368,21 @@ int open_buffer(int read_stdin, exarg_T *eap, int flags_arg)
|
|||||||
if (bufref_valid(&old_curbuf) && old_curbuf.br_buf->b_ml.ml_mfp != NULL) {
|
if (bufref_valid(&old_curbuf) && old_curbuf.br_buf->b_ml.ml_mfp != NULL) {
|
||||||
aco_save_T aco;
|
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);
|
aucmd_prepbuf(&aco, old_curbuf.br_buf);
|
||||||
do_modelines(0);
|
if (curbuf == old_curbuf.br_buf) {
|
||||||
curbuf->b_flags &= ~(BF_CHECK_RO | BF_NEVERLOADED);
|
do_modelines(0);
|
||||||
|
curbuf->b_flags &= ~(BF_CHECK_RO | BF_NEVERLOADED);
|
||||||
|
|
||||||
if ((flags & READ_NOWINENTER) == 0) {
|
if ((flags & READ_NOWINENTER) == 0) {
|
||||||
apply_autocmds_retval(EVENT_BUFWINENTER, NULL, NULL, false, curbuf,
|
apply_autocmds_retval(EVENT_BUFWINENTER, NULL, NULL, false, curbuf,
|
||||||
&retval);
|
&retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore curwin/curbuf and a few other things
|
||||||
|
aucmd_restbuf(&aco);
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore curwin/curbuf and a few other things
|
|
||||||
aucmd_restbuf(&aco);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
@@ -1316,7 +1335,7 @@ int do_buffer(int action, int start, int dir, int count, int forceit)
|
|||||||
// Repeat this so long as we end up in a window with this buffer.
|
// Repeat this so long as we end up in a window with this buffer.
|
||||||
while (buf == curbuf
|
while (buf == curbuf
|
||||||
&& !(curwin->w_closing || curwin->w_buffer->b_locked > 0)
|
&& !(curwin->w_closing || curwin->w_buffer->b_locked > 0)
|
||||||
&& (lastwin == aucmd_win || !last_window(curwin))) {
|
&& (is_aucmd_win(lastwin) || !last_window(curwin))) {
|
||||||
if (win_close(curwin, false, false) == FAIL) {
|
if (win_close(curwin, false, false) == FAIL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -4155,9 +4174,14 @@ bool buf_contents_changed(buf_T *buf)
|
|||||||
exarg_T ea;
|
exarg_T ea;
|
||||||
prep_exarg(&ea, buf);
|
prep_exarg(&ea, buf);
|
||||||
|
|
||||||
// set curwin/curbuf to buf and save a few things
|
// Set curwin/curbuf to buf and save a few things.
|
||||||
aco_save_T aco;
|
aco_save_T aco;
|
||||||
aucmd_prepbuf(&aco, newbuf);
|
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
|
if (ml_open(curbuf) == OK
|
||||||
&& readfile(buf->b_ffname, buf->b_fname,
|
&& readfile(buf->b_ffname, buf->b_fname,
|
||||||
|
@@ -2943,8 +2943,13 @@ void ex_diffgetput(exarg_T *eap)
|
|||||||
// Need to make the other buffer the current buffer to be able to make
|
// Need to make the other buffer the current buffer to be able to make
|
||||||
// changes in it.
|
// 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]);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int idx_from = eap->cmdidx == CMD_diffget ? idx_other : idx_cur;
|
const int idx_from = eap->cmdidx == CMD_diffget ? idx_other : idx_cur;
|
||||||
|
@@ -4174,8 +4174,11 @@ bool garbage_collect(bool testing)
|
|||||||
ABORTING(set_ref_in_fmark)(wp->w_jumplist[i].fmark, copyID);
|
ABORTING(set_ref_in_fmark)(wp->w_jumplist[i].fmark, copyID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (aucmd_win != NULL) {
|
// window-local variables in autocmd windows
|
||||||
ABORTING(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 != NULL) {
|
||||||
|
ABORTING(set_ref_in_item)(&aucmd_win[i].auc_win->w_winvar.di_tv, copyID, NULL, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// registers (ShaDa additional data)
|
// registers (ShaDa additional data)
|
||||||
|
@@ -86,6 +86,8 @@ static void find_win_for_curbuf(void)
|
|||||||
///
|
///
|
||||||
/// Information is saved in "cob" and MUST be restored by calling
|
/// Information is saved in "cob" and MUST be restored by calling
|
||||||
/// change_other_buffer_restore().
|
/// 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)
|
static void change_other_buffer_prepare(cob_T *cob, buf_T *buf)
|
||||||
{
|
{
|
||||||
CLEAR_POINTER(cob);
|
CLEAR_POINTER(cob);
|
||||||
@@ -103,7 +105,9 @@ static void change_other_buffer_prepare(cob_T *cob, buf_T *buf)
|
|||||||
// curwin->w_buffer differ from "curbuf", use the autocmd window.
|
// curwin->w_buffer differ from "curbuf", use the autocmd window.
|
||||||
curbuf = curwin->w_buffer;
|
curbuf = curwin->w_buffer;
|
||||||
aucmd_prepbuf(&cob->cob_aco, buf);
|
aucmd_prepbuf(&cob->cob_aco, buf);
|
||||||
cob->cob_using_aco = true;
|
if (curbuf == buf) {
|
||||||
|
cob->cob_using_aco = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,13 +306,8 @@ void f_bufload(typval_T *argvars, typval_T *unused, EvalFuncData fptr)
|
|||||||
{
|
{
|
||||||
buf_T *buf = get_buf_arg(&argvars[0]);
|
buf_T *buf = get_buf_arg(&argvars[0]);
|
||||||
|
|
||||||
if (buf != NULL && buf->b_ml.ml_mfp == NULL) {
|
if (buf != NULL) {
|
||||||
aco_save_T aco;
|
buffer_ensure_loaded(buf);
|
||||||
|
|
||||||
aucmd_prepbuf(&aco, buf);
|
|
||||||
swap_exists_action = SEA_NONE;
|
|
||||||
open_buffer(false, NULL, 0);
|
|
||||||
aucmd_restbuf(&aco);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1800,13 +1800,15 @@ void f_setbufvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
if (*varname == '&') {
|
if (*varname == '&') {
|
||||||
aco_save_T aco;
|
aco_save_T aco;
|
||||||
|
|
||||||
// set curbuf to be our buf, temporarily
|
// Set curbuf to be our buf, temporarily.
|
||||||
aucmd_prepbuf(&aco, buf);
|
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 {
|
} else {
|
||||||
const size_t varname_len = strlen(varname);
|
const size_t varname_len = strlen(varname);
|
||||||
char *const bufvarname = xmalloc(varname_len + 3);
|
char *const bufvarname = xmalloc(varname_len + 3);
|
||||||
|
@@ -590,7 +590,7 @@ static void win_move_into_split(win_T *wp, win_T *targetwin, int size, int flags
|
|||||||
int height = wp->w_height;
|
int height = wp->w_height;
|
||||||
win_T *oldwin = curwin;
|
win_T *oldwin = curwin;
|
||||||
|
|
||||||
if (wp == targetwin || wp == aucmd_win) {
|
if (wp == targetwin || is_aucmd_win(wp)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -674,7 +674,7 @@ void f_win_gettype(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (wp == aucmd_win) {
|
if (is_aucmd_win(wp)) {
|
||||||
rettv->vval.v_string = xstrdup("autocmd");
|
rettv->vval.v_string = xstrdup("autocmd");
|
||||||
} else if (wp->w_p_pvw) {
|
} else if (wp->w_p_pvw) {
|
||||||
rettv->vval.v_string = xstrdup("preview");
|
rettv->vval.v_string = xstrdup("preview");
|
||||||
|
@@ -683,8 +683,10 @@ void ex_listdo(exarg_T *eap)
|
|||||||
curbuf);
|
curbuf);
|
||||||
} else {
|
} else {
|
||||||
aucmd_prepbuf(&aco, buf);
|
aucmd_prepbuf(&aco, buf);
|
||||||
apply_autocmds(EVENT_SYNTAX, buf->b_p_syn, buf->b_fname, true, buf);
|
if (curbuf == buf) {
|
||||||
aucmd_restbuf(&aco);
|
apply_autocmds(EVENT_SYNTAX, buf->b_p_syn, buf->b_fname, true, buf);
|
||||||
|
aucmd_restbuf(&aco);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// start over, in case autocommands messed things up.
|
// start over, in case autocommands messed things up.
|
||||||
|
@@ -4621,7 +4621,7 @@ static void ex_pclose(exarg_T *eap)
|
|||||||
void ex_win_close(int forceit, win_T *win, tabpage_T *tp)
|
void ex_win_close(int forceit, win_T *win, tabpage_T *tp)
|
||||||
{
|
{
|
||||||
// Never close the autocommand window.
|
// Never close the autocommand window.
|
||||||
if (win == aucmd_win) {
|
if (is_aucmd_win(win)) {
|
||||||
emsg(_(e_autocmd_close));
|
emsg(_(e_autocmd_close));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -2310,6 +2310,12 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
|
|||||||
|
|
||||||
// Set curwin/curbuf to buf and save a few things.
|
// Set curwin/curbuf to buf and save a few things.
|
||||||
aucmd_prepbuf(&aco, buf);
|
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);
|
set_bufref(&bufref, buf);
|
||||||
|
|
||||||
if (append) {
|
if (append) {
|
||||||
@@ -3612,25 +3618,27 @@ nofail:
|
|||||||
|
|
||||||
// Apply POST autocommands.
|
// Apply POST autocommands.
|
||||||
// Careful: The autocommands may call buf_write() recursively!
|
// Careful: The autocommands may call buf_write() recursively!
|
||||||
|
// Only do this when a window was found for "buf".
|
||||||
aucmd_prepbuf(&aco, 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) {
|
// restore curwin/curbuf and a few other things
|
||||||
apply_autocmds_exarg(EVENT_FILEAPPENDPOST, fname, fname,
|
aucmd_restbuf(&aco);
|
||||||
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);
|
|
||||||
|
|
||||||
if (aborting()) { // autocmds may abort script processing
|
if (aborting()) { // autocmds may abort script processing
|
||||||
retval = false;
|
retval = false;
|
||||||
}
|
}
|
||||||
@@ -5003,8 +5011,13 @@ void buf_reload(buf_T *buf, int orig_mode, bool reload_options)
|
|||||||
aco_save_T aco;
|
aco_save_T aco;
|
||||||
int flags = READ_NEW;
|
int flags = READ_NEW;
|
||||||
|
|
||||||
// set curwin/curbuf for "buf" and save some things
|
// Set curwin/curbuf for "buf" and save some things.
|
||||||
aucmd_prepbuf(&aco, buf);
|
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
|
// 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.
|
// file, not reset the syntax highlighting, clear marks, diff status, etc.
|
||||||
|
@@ -422,8 +422,19 @@ EXTERN win_T *prevwin INIT(= NULL); // previous window
|
|||||||
|
|
||||||
EXTERN win_T *curwin; // currently active window
|
EXTERN win_T *curwin; // currently active window
|
||||||
|
|
||||||
EXTERN win_T *aucmd_win; // window used in aucmd_prepbuf()
|
/// When executing autocommands for a buffer that is not in any window, a
|
||||||
EXTERN int aucmd_win_used INIT(= false); // aucmd_win is being used
|
/// 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.
|
||||||
|
enum { AUCMD_WIN_COUNT = 5, };
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
win_T *auc_win; ///< Window used in aucmd_prepbuf(). When not NULL the
|
||||||
|
///< window has been allocated.
|
||||||
|
bool auc_win_used; ///< This auc_win is being used.
|
||||||
|
} aucmdwin_T;
|
||||||
|
|
||||||
|
EXTERN aucmdwin_T aucmd_win[AUCMD_WIN_COUNT];
|
||||||
|
|
||||||
// The window layout is kept in a tree of frames. topframe points to the top
|
// The window layout is kept in a tree of frames. topframe points to the top
|
||||||
// of the tree.
|
// of the tree.
|
||||||
|
@@ -251,6 +251,8 @@ int main(int argc, char **argv)
|
|||||||
// `argc` and `argv` are also copied, so that they can be changed.
|
// `argc` and `argv` are also copied, so that they can be changed.
|
||||||
init_params(¶ms, argc, argv);
|
init_params(¶ms, argc, argv);
|
||||||
|
|
||||||
|
autocmd_init();
|
||||||
|
|
||||||
// Since os_open is called during the init_startuptime, we need to call
|
// Since os_open is called during the init_startuptime, we need to call
|
||||||
// fs_init before it.
|
// fs_init before it.
|
||||||
fs_init();
|
fs_init();
|
||||||
|
@@ -3902,21 +3902,27 @@ static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last)
|
|||||||
|
|
||||||
aco_save_T aco;
|
aco_save_T aco;
|
||||||
|
|
||||||
|
bool do_fill = true;
|
||||||
if (old_last == NULL) {
|
if (old_last == NULL) {
|
||||||
// set curwin/curbuf to buf and save a few things
|
// set curwin/curbuf to buf and save a few things
|
||||||
aucmd_prepbuf(&aco, buf);
|
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);
|
qf_fill_buffer(qf_get_curlist(qi), buf, old_last, qf_winid);
|
||||||
buf_inc_changedtick(buf);
|
buf_inc_changedtick(buf);
|
||||||
|
|
||||||
if (old_last == NULL) {
|
if (old_last == NULL) {
|
||||||
(void)qf_win_pos_update(qi, 0);
|
(void)qf_win_pos_update(qi, 0);
|
||||||
|
|
||||||
// restore curwin/curbuf and a few other things
|
// restore curwin/curbuf and a few other things
|
||||||
aucmd_restbuf(&aco);
|
aucmd_restbuf(&aco);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only redraw when added lines are visible. This avoids flickering when
|
// Only redraw when added lines are visible. This avoids flickering when
|
||||||
@@ -5463,9 +5469,11 @@ static int vgr_process_files(win_T *wp, qf_info_T *qi, vgr_args_T *cmd_args, boo
|
|||||||
// options!
|
// options!
|
||||||
aco_save_T aco;
|
aco_save_T aco;
|
||||||
aucmd_prepbuf(&aco, buf);
|
aucmd_prepbuf(&aco, buf);
|
||||||
apply_autocmds(EVENT_FILETYPE, buf->b_p_ft, buf->b_fname, true, buf);
|
if (curbuf == buf) {
|
||||||
do_modelines(OPT_NOWIN);
|
apply_autocmds(EVENT_FILETYPE, buf->b_p_ft, buf->b_fname, true, buf);
|
||||||
aucmd_restbuf(&aco);
|
do_modelines(OPT_NOWIN);
|
||||||
|
aucmd_restbuf(&aco);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5623,41 +5631,43 @@ static buf_T *load_dummy_buffer(char *fname, char *dirname_start, char *resultin
|
|||||||
// set curwin/curbuf to buf and save a few things
|
// set curwin/curbuf to buf and save a few things
|
||||||
aco_save_T aco;
|
aco_save_T aco;
|
||||||
aucmd_prepbuf(&aco, newbuf);
|
aucmd_prepbuf(&aco, newbuf);
|
||||||
|
if (curbuf == newbuf) {
|
||||||
|
// Need to set the filename for autocommands.
|
||||||
|
(void)setfname(curbuf, fname, NULL, false);
|
||||||
|
|
||||||
// Need to set the filename for autocommands.
|
// Create swap file now to avoid the ATTENTION message.
|
||||||
(void)setfname(curbuf, fname, NULL, false);
|
check_need_swap(true);
|
||||||
|
|
||||||
// Create swap file now to avoid the ATTENTION message.
|
// Remove the "dummy" flag, otherwise autocommands may not
|
||||||
check_need_swap(true);
|
// work.
|
||||||
|
curbuf->b_flags &= ~BF_DUMMY;
|
||||||
|
|
||||||
// Remove the "dummy" flag, otherwise autocommands may not
|
bufref_T newbuf_to_wipe;
|
||||||
// work.
|
newbuf_to_wipe.br_buf = NULL;
|
||||||
curbuf->b_flags &= ~BF_DUMMY;
|
int readfile_result = readfile(fname, NULL, (linenr_T)0, (linenr_T)0,
|
||||||
|
(linenr_T)MAXLNUM, NULL,
|
||||||
bufref_T newbuf_to_wipe;
|
READ_NEW | READ_DUMMY, false);
|
||||||
newbuf_to_wipe.br_buf = NULL;
|
newbuf->b_locked--;
|
||||||
int readfile_result = readfile(fname, NULL, (linenr_T)0, (linenr_T)0,
|
if (readfile_result == OK
|
||||||
(linenr_T)MAXLNUM, NULL,
|
&& !got_int
|
||||||
READ_NEW | READ_DUMMY, false);
|
&& !(curbuf->b_flags & BF_NEW)) {
|
||||||
newbuf->b_locked--;
|
failed = false;
|
||||||
if (readfile_result == OK
|
if (curbuf != newbuf) {
|
||||||
&& !got_int
|
// Bloody autocommands changed the buffer! Can happen when
|
||||||
&& !(curbuf->b_flags & BF_NEW)) {
|
// using netrw and editing a remote file. Use the current
|
||||||
failed = false;
|
// buffer instead, delete the dummy one after restoring the
|
||||||
if (curbuf != newbuf) {
|
// window stuff.
|
||||||
// Bloody autocommands changed the buffer! Can happen when
|
set_bufref(&newbuf_to_wipe, newbuf);
|
||||||
// using netrw and editing a remote file. Use the current
|
newbuf = curbuf;
|
||||||
// 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.
|
// Restore curwin/curbuf and a few other things.
|
||||||
aucmd_restbuf(&aco);
|
aucmd_restbuf(&aco);
|
||||||
if (newbuf_to_wipe.br_buf != NULL && bufref_valid(&newbuf_to_wipe)) {
|
|
||||||
wipe_buffer(newbuf_to_wipe.br_buf, false);
|
if (newbuf_to_wipe.br_buf != NULL && bufref_valid(&newbuf_to_wipe)) {
|
||||||
|
wipe_buffer(newbuf_to_wipe.br_buf, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add back the "dummy" flag, otherwise buflist_findname_file_id()
|
// Add back the "dummy" flag, otherwise buflist_findname_file_id()
|
||||||
|
@@ -387,7 +387,7 @@ void terminal_check_size(Terminal *term)
|
|||||||
// Check if there is a window that displays the terminal and find the maximum width and height.
|
// Check if there is a window that displays the terminal and find the maximum width and height.
|
||||||
// Skip the autocommand window which isn't actually displayed.
|
// Skip the autocommand window which isn't actually displayed.
|
||||||
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
||||||
if (wp == aucmd_win) {
|
if (is_aucmd_win(wp)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (wp->w_buffer && wp->w_buffer->terminal == term) {
|
if (wp->w_buffer && wp->w_buffer->terminal == term) {
|
||||||
|
@@ -3483,4 +3483,27 @@ func Test_autocmd_split_dummy()
|
|||||||
call delete('Xerr')
|
call delete('Xerr')
|
||||||
endfunc
|
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
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@@ -1046,8 +1046,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
|||||||
{
|
{
|
||||||
win_T *wp = new_wp;
|
win_T *wp = new_wp;
|
||||||
|
|
||||||
// aucmd_win should always remain floating
|
// aucmd_win[] should always remain floating
|
||||||
if (new_wp != NULL && new_wp == aucmd_win) {
|
if (new_wp != NULL && is_aucmd_win(new_wp)) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1505,7 +1505,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
|||||||
// equalize the window sizes.
|
// equalize the window sizes.
|
||||||
if (do_equal || dir != 0) {
|
if (do_equal || dir != 0) {
|
||||||
win_equal(wp, true, (flags & WSP_VERT) ? (dir == 'v' ? 'b' : 'h') : (dir == 'h' ? 'b' : 'v'));
|
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);
|
win_fix_scroll(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1940,7 +1940,7 @@ static void win_totop(int size, int flags)
|
|||||||
beep_flush();
|
beep_flush();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (curwin == aucmd_win) {
|
if (is_aucmd_win(curwin)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (check_split_disallowed() == FAIL) {
|
if (check_split_disallowed() == FAIL) {
|
||||||
@@ -2086,7 +2086,7 @@ void win_equal(win_T *next_curwin, bool current, int dir)
|
|||||||
win_equal_rec(next_curwin == NULL ? curwin : next_curwin, current,
|
win_equal_rec(next_curwin == NULL ? curwin : next_curwin, current,
|
||||||
topframe, dir, 0, tabline_height(),
|
topframe, dir, 0, tabline_height(),
|
||||||
Columns, topframe->fr_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);
|
win_fix_scroll(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2459,7 +2459,7 @@ void close_windows(buf_T *buf, bool keep_curwin)
|
|||||||
|
|
||||||
// Start from lastwin to close floating windows with the same buffer first.
|
// 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.
|
// 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)
|
if (wp->w_buffer == buf && (!keep_curwin || wp != curwin)
|
||||||
&& !(wp->w_closing || wp->w_buffer->b_locked > 0)) {
|
&& !(wp->w_closing || wp->w_buffer->b_locked > 0)) {
|
||||||
if (win_close(wp, false, false) == FAIL) {
|
if (win_close(wp, false, false) == FAIL) {
|
||||||
@@ -2508,14 +2508,14 @@ bool last_window(win_T *win) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
|||||||
return one_window(win) && first_tabpage->tp_next == NULL;
|
return one_window(win) && first_tabpage->tp_next == NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check that current tab page contains no more then one window other than `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`
|
/// @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 one_window(win_T *counted_float) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
bool seen_one = false;
|
bool seen_one = false;
|
||||||
|
|
||||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
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) {
|
if (seen_one) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2545,7 +2545,7 @@ bool last_nonfloat(win_T *wp) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
|||||||
/// @return true if all floating windows can be closed
|
/// @return true if all floating windows can be closed
|
||||||
static bool can_close_floating_windows(void)
|
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) {
|
for (win_T *wp = lastwin; wp->w_floating; wp = wp->w_prev) {
|
||||||
buf_T *buf = wp->w_buffer;
|
buf_T *buf = wp->w_buffer;
|
||||||
int need_hide = (bufIsChanged(buf) && buf->b_nwindows <= 1);
|
int need_hide = (bufIsChanged(buf) && buf->b_nwindows <= 1);
|
||||||
@@ -2663,12 +2663,12 @@ int win_close(win_T *win, bool free_buf, bool force)
|
|||||||
|| (win->w_buffer != NULL && win->w_buffer->b_locked > 0)) {
|
|| (win->w_buffer != NULL && win->w_buffer->b_locked > 0)) {
|
||||||
return FAIL; // window is already being closed
|
return FAIL; // window is already being closed
|
||||||
}
|
}
|
||||||
if (win == aucmd_win) {
|
if (is_aucmd_win(win)) {
|
||||||
emsg(_(e_autocmd_close));
|
emsg(_(e_autocmd_close));
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
if (lastwin->w_floating && one_window(win)) {
|
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"));
|
emsg(_("E814: Cannot close window, only autocmd window would remain"));
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
@@ -3092,15 +3092,19 @@ void win_free_all(void)
|
|||||||
win_remove(lastwin, NULL);
|
win_remove(lastwin, NULL);
|
||||||
int dummy;
|
int dummy;
|
||||||
(void)win_free_mem(wp, &dummy, NULL);
|
(void)win_free_mem(wp, &dummy, NULL);
|
||||||
if (wp == aucmd_win) {
|
for (int i = 0; i < AUCMD_WIN_COUNT; i++) {
|
||||||
aucmd_win = NULL;
|
if (aucmd_win[i].auc_win == wp) {
|
||||||
|
aucmd_win[i].auc_win = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aucmd_win != NULL) {
|
for (int i = 0; i < AUCMD_WIN_COUNT; i++) {
|
||||||
int dummy;
|
if (aucmd_win[i].auc_win != NULL) {
|
||||||
(void)win_free_mem(aucmd_win, &dummy, NULL);
|
int dummy;
|
||||||
aucmd_win = NULL;
|
(void)win_free_mem(aucmd_win[i].auc_win, &dummy, NULL);
|
||||||
|
aucmd_win[i].auc_win = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (firstwin != NULL) {
|
while (firstwin != NULL) {
|
||||||
@@ -3904,18 +3908,18 @@ void win_alloc_first(void)
|
|||||||
unuse_tabpage(first_tabpage);
|
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().
|
// 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;
|
Error err = ERROR_INIT;
|
||||||
FloatConfig fconfig = FLOAT_CONFIG_INIT;
|
FloatConfig fconfig = FLOAT_CONFIG_INIT;
|
||||||
fconfig.width = Columns;
|
fconfig.width = Columns;
|
||||||
fconfig.height = 5;
|
fconfig.height = 5;
|
||||||
fconfig.focusable = false;
|
fconfig.focusable = false;
|
||||||
aucmd_win = win_new_float(NULL, true, fconfig, &err);
|
aucmd_win[idx].auc_win = win_new_float(NULL, true, fconfig, &err);
|
||||||
aucmd_win->w_buffer->b_nwindows--;
|
aucmd_win[idx].auc_win->w_buffer->b_nwindows--;
|
||||||
RESET_BINDING(aucmd_win);
|
RESET_BINDING(aucmd_win[idx].auc_win);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate the first window or the first window in a new tab page.
|
// Allocate the first window or the first window in a new tab page.
|
||||||
@@ -5108,7 +5112,7 @@ static void win_free(win_T *wp, tabpage_T *tp)
|
|||||||
|
|
||||||
win_free_grid(wp, false);
|
win_free_grid(wp, false);
|
||||||
|
|
||||||
if (wp != aucmd_win) {
|
if (win_valid_any_tab(wp)) {
|
||||||
win_remove(wp, tp);
|
win_remove(wp, tp);
|
||||||
}
|
}
|
||||||
if (autocmd_busy) {
|
if (autocmd_busy) {
|
||||||
@@ -7059,7 +7063,7 @@ bool only_one_window(void) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
|||||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||||
if (wp->w_buffer != NULL
|
if (wp->w_buffer != NULL
|
||||||
&& (!((bt_help(wp->w_buffer) && !bt_help(curbuf)) || wp->w_floating
|
&& (!((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++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user