summaryrefslogtreecommitdiff
path: root/src/buffer.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/buffer.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/buffer.c')
-rw-r--r--src/buffer.c36
1 files changed, 26 insertions, 10 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 7ff949c02..00d1f3535 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -377,28 +377,35 @@ close_buffer(win, buf, action, abort_if_last)
/* When the buffer is no longer in a window, trigger BufWinLeave */
if (buf->b_nwindows == 1)
{
+ buf->b_closing = TRUE;
apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
FALSE, buf);
- /* Return if autocommands deleted the buffer or made it the only one. */
- if (!buf_valid(buf) || (abort_if_last && one_window()))
+ if (!buf_valid(buf))
{
+ /* Autocommands deleted the buffer. */
+aucmd_abort:
EMSG(_(e_auabort));
return;
}
+ buf->b_closing = FALSE;
+ if (abort_if_last && one_window())
+ /* Autocommands made this the only window. */
+ goto aucmd_abort;
/* When the buffer becomes hidden, but is not unloaded, trigger
* BufHidden */
if (!unload_buf)
{
+ buf->b_closing = TRUE;
apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname,
FALSE, buf);
- /* Return if autocommands deleted the buffer or made it the only
- * one. */
- if (!buf_valid(buf) || (abort_if_last && one_window()))
- {
- EMSG(_(e_auabort));
- return;
- }
+ if (!buf_valid(buf))
+ /* Autocommands deleted the buffer. */
+ goto aucmd_abort;
+ buf->b_closing = FALSE;
+ if (abort_if_last && one_window())
+ /* Autocommands made this the only window. */
+ goto aucmd_abort;
}
# ifdef FEAT_EVAL
if (aborting()) /* autocmds may abort script processing */
@@ -552,6 +559,7 @@ buf_freeall(buf, flags)
#ifdef FEAT_AUTOCMD
int is_curbuf = (buf == curbuf);
+ buf->b_closing = TRUE;
apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, FALSE, buf);
if (!buf_valid(buf)) /* autocommands may delete the buffer */
return;
@@ -568,6 +576,7 @@ buf_freeall(buf, flags)
if (!buf_valid(buf)) /* autocommands may delete the buffer */
return;
}
+ buf->b_closing = FALSE;
# ifdef FEAT_EVAL
if (aborting()) /* autocmds may abort script processing */
return;
@@ -1150,6 +1159,9 @@ do_buffer(action, start, dir, count, forceit)
* a window with this buffer.
*/
while (buf == curbuf
+# ifdef FEAT_AUTOCMD
+ && !(curwin->w_closing || curwin->w_buffer->b_closing)
+# endif
&& (firstwin != lastwin || first_tabpage->tp_next != NULL))
win_close(curwin, FALSE);
#endif
@@ -4750,7 +4762,11 @@ ex_buffer_all(eap)
#ifdef FEAT_WINDOWS
|| (had_tab > 0 && wp != firstwin)
#endif
- ) && firstwin != lastwin)
+ ) && firstwin != lastwin
+#ifdef FEAT_AUTOCMD
+ && !(wp->w_closing || wp->w_buffer->b_closing)
+#endif
+ )
{
win_close(wp, FALSE);
#ifdef FEAT_AUTOCMD