summaryrefslogtreecommitdiff
path: root/src/window.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2012-06-06 19:02:45 +0200
committerBram Moolenaar <Bram@vim.org>2012-06-06 19:02:45 +0200
commit362ce4804819f39d5a4a21923577f3ccc59c8ad5 (patch)
tree7c3d79ed0e4334faa016c4ecaa97b3a00183b608 /src/window.c
parent3b53dfb3b0743af7d6ae381a766e1bb2018fd01e (diff)
downloadvim-git-362ce4804819f39d5a4a21923577f3ccc59c8ad5.tar.gz
updated for version 7.3.545v7.3.545
Problem: When closing a window or buffer autocommands may close it too, causing problems for where the autocommand was invoked from. Solution: Add the w_closing and b_closing flags. When set disallow ":q" and ":close" to prevent recursive closing.
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c45
1 files changed, 39 insertions, 6 deletions
diff --git a/src/window.c b/src/window.c
index 9f5e39efc..ecf2aa29a 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2034,7 +2034,11 @@ close_windows(buf, keep_curwin)
for (wp = firstwin; wp != NULL && lastwin != firstwin; )
{
- if (wp->w_buffer == buf && (!keep_curwin || wp != curwin))
+ if (wp->w_buffer == buf && (!keep_curwin || wp != curwin)
+#ifdef FEAT_AUTOCMD
+ && !(wp->w_closing || wp->w_buffer->b_closing)
+#endif
+ )
{
win_close(wp, FALSE);
@@ -2051,7 +2055,11 @@ close_windows(buf, keep_curwin)
nexttp = tp->tp_next;
if (tp != curtab)
for (wp = tp->tp_firstwin; wp != NULL; wp = wp->w_next)
- if (wp->w_buffer == buf)
+ if (wp->w_buffer == buf
+#ifdef FEAT_AUTOCMD
+ && !(wp->w_closing || wp->w_buffer->b_closing)
+#endif
+ )
{
win_close_othertab(wp, FALSE, tp);
@@ -2168,6 +2176,8 @@ win_close(win, free_buf)
}
#ifdef FEAT_AUTOCMD
+ if (win->w_closing || win->w_buffer->b_closing)
+ return; /* window is already being closed */
if (win == aucmd_win)
{
EMSG(_("E813: Cannot close autocmd window"));
@@ -2203,17 +2213,26 @@ win_close(win, free_buf)
wp = frame2win(win_altframe(win, NULL));
/*
- * Be careful: If autocommands delete the window, return now.
+ * Be careful: If autocommands delete the window or cause this window
+ * to be the last one left, return now.
*/
if (wp->w_buffer != curbuf)
{
other_buffer = TRUE;
+ win->w_closing = TRUE;
apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
- if (!win_valid(win) || last_window())
+ if (!win_valid(win))
+ return;
+ win->w_closing = FALSE;
+ if (last_window())
return;
}
+ win->w_closing = TRUE;
apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf);
- if (!win_valid(win) || last_window())
+ if (!win_valid(win))
+ return;
+ win->w_closing = FALSE;
+ if (last_window())
return;
# ifdef FEAT_EVAL
/* autocmds may abort script processing */
@@ -2240,7 +2259,16 @@ win_close(win, free_buf)
* Close the link to the buffer.
*/
if (win->w_buffer != NULL)
- close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, TRUE);
+ {
+#ifdef FEAT_AUTOCMD
+ win->w_closing = TRUE;
+#endif
+ close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, FALSE);
+#ifdef FEAT_AUTOCMD
+ if (win_valid(win))
+ win->w_closing = FALSE;
+#endif
+ }
/* Autocommands may have closed the window already, or closed the only
* other window or moved to another tab page. */
@@ -2346,6 +2374,11 @@ win_close_othertab(win, free_buf, tp)
tabpage_T *ptp = NULL;
int free_tp = FALSE;
+#ifdef FEAT_AUTOCMD
+ if (win->w_closing || win->w_buffer->b_closing)
+ return; /* window is already being closed */
+#endif
+
/* Close the link to the buffer. */
close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, FALSE);