changeset 2226:36a9ac99e1ca vim73

Don't execute some autocommands when v:dying is 2 or more.
author Bram Moolenaar <bram@vim.org>
date Fri, 28 May 2010 21:07:08 +0200
parents dd5c1983e355
children 9c510840e896
files runtime/doc/autocmd.txt runtime/doc/eval.txt runtime/doc/todo.txt runtime/doc/version7.txt src/main.c
diffstat 5 files changed, 46 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -401,6 +401,8 @@ BufUnload			Before unloading a buffer.  
 				buffer being unloaded "<afile>".
 				Don't change to another buffer, it will cause
 				problems.
+				When exiting and v:dying is 2 or more this
+				event is not triggered.
 							*BufWinEnter*
 BufWinEnter			After a buffer is displayed in a window.  This
 				can be when the buffer is loaded (after
@@ -422,6 +424,8 @@ BufWinLeave			Before a buffer is removed
 				NOTE: When this autocommand is executed, the
 				current buffer "%" may be different from the
 				buffer being unloaded "<afile>".
+				When exiting and v:dying is 2 or more this
+				event is not triggered.
 							*BufWipeout*
 BufWipeout			Before completely deleting a buffer.  The
 				BufUnload and BufDelete events may be called
@@ -799,6 +803,8 @@ VimLeave			Before exiting Vim, just afte
 				.viminfo file.  Executed only once, like
 				VimLeavePre.
 				To detect an abnormal exit use |v:dying|.
+				When v:dying is 2 or more this event is not
+				triggered.
 							*VimLeavePre*
 VimLeavePre			Before exiting Vim, just before writing the
 				.viminfo file.  This is executed only once,
@@ -807,6 +813,8 @@ VimLeavePre			Before exiting Vim, just b
 				Mostly useful with a "*" pattern. >
 	:autocmd VimLeavePre * call CleanupStuff()
 <				To detect an abnormal exit use |v:dying|.
+				When v:dying is 2 or more this event is not
+				triggered.
 							*VimResized*
 VimResized			After the Vim window was resized, thus 'lines'
 				and/or 'columns' changed.  Not when starting
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1348,7 +1348,9 @@ v:dying		Normally zero.	When a deadly si
 		terminate normally. {only works on Unix}
 		Example: >
 	:au VimLeave * if v:dying | echo "\nAAAAaaaarrrggghhhh!!!\n" | endif
-<
+<		Note: if another deadly signal is caught when v:dying is one,
+		VimLeave autocommands will not be executed.
+
 					*v:errmsg* *errmsg-variable*
 v:errmsg	Last given error message.  It's allowed to set this variable.
 		Example: >
--- a/runtime/doc/todo.txt
+++ b/runtime/doc/todo.txt
@@ -30,9 +30,6 @@ be worked on, but only if you sponsor Vi
 							*known-bugs*
 -------------------- Known bugs and current work -----------------------
 
-When Vim crashes it may run out of stack while executing autocommands.  Patch
-to not run autocommands when leaving Vim? (James Vega, 2010 May 23)
-
 Patch for invalid mem access in completion. (Dominique Pelle, 2010 May 26)
 
 Invalid memory access when deleting funcref variable.  Patch by Lech Lorens,
--- a/runtime/doc/version7.txt
+++ b/runtime/doc/version7.txt
@@ -7166,6 +7166,10 @@ don't save what you see.  This could res
 after recovery is compared to the original file contents.  When they differ
 the buffer is marked as modified.
 
+When Vim is exiting because of a deadly signal, when v:dying is 2 or more,
+VimLeavePre, VimLeave, BufWinLeave and BufUnload autocommands are not
+executed.
+
 
 Added							*added-7.3*
 -----
--- a/src/main.c
+++ b/src/main.c
@@ -1276,40 +1276,44 @@ getout(exitval)
 #endif
 
 #ifdef FEAT_AUTOCMD
-    /* Trigger BufWinLeave for all windows, but only once per buffer. */
-# if defined FEAT_WINDOWS
-    for (tp = first_tabpage; tp != NULL; tp = next_tp)
+    if (get_vim_var_nr(VV_DYING) <= 1)
     {
-	next_tp = tp->tp_next;
-	for (wp = (tp == curtab)
-		    ? firstwin : tp->tp_firstwin; wp != NULL; wp = wp->w_next)
+	/* Trigger BufWinLeave for all windows, but only once per buffer. */
+# if defined FEAT_WINDOWS
+	for (tp = first_tabpage; tp != NULL; tp = next_tp)
 	{
-	    buf = wp->w_buffer;
-	    if (buf->b_changedtick != -1)
+	    next_tp = tp->tp_next;
+	    for (wp = (tp == curtab)
+		    ? firstwin : tp->tp_firstwin; wp != NULL; wp = wp->w_next)
 	    {
-		apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
-								  FALSE, buf);
-		buf->b_changedtick = -1;    /* note that we did it already */
-		/* start all over, autocommands may mess up the lists */
-		next_tp = first_tabpage;
-		break;
+		buf = wp->w_buffer;
+		if (buf->b_changedtick != -1)
+		{
+		    apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname,
+						    buf->b_fname, FALSE, buf);
+		    buf->b_changedtick = -1;    /* note that we did it already */
+		    /* start all over, autocommands may mess up the lists */
+		    next_tp = first_tabpage;
+		    break;
+		}
 	    }
 	}
-    }
 # else
-    apply_autocmds(EVENT_BUFWINLEAVE, curbuf, curbuf->b_fname, FALSE, curbuf);
+	apply_autocmds(EVENT_BUFWINLEAVE, curbuf, curbuf->b_fname,
+							       FALSE, curbuf);
 # endif
 
-    /* Trigger BufUnload for buffers that are loaded */
-    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
-	if (buf->b_ml.ml_mfp != NULL)
-	{
-	    apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname,
+	/* Trigger BufUnload for buffers that are loaded */
+	for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+	    if (buf->b_ml.ml_mfp != NULL)
+	    {
+		apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname,
 								  FALSE, buf);
-	    if (!buf_valid(buf))	/* autocmd may delete the buffer */
-		break;
-	}
-    apply_autocmds(EVENT_VIMLEAVEPRE, NULL, NULL, FALSE, curbuf);
+		if (!buf_valid(buf))	/* autocmd may delete the buffer */
+		    break;
+	    }
+	apply_autocmds(EVENT_VIMLEAVEPRE, NULL, NULL, FALSE, curbuf);
+    }
 #endif
 
 #ifdef FEAT_VIMINFO
@@ -1319,7 +1323,8 @@ getout(exitval)
 #endif
 
 #ifdef FEAT_AUTOCMD
-    apply_autocmds(EVENT_VIMLEAVE, NULL, NULL, FALSE, curbuf);
+    if (get_vim_var_nr(VV_DYING) <= 1)
+	apply_autocmds(EVENT_VIMLEAVE, NULL, NULL, FALSE, curbuf);
 #endif
 
 #ifdef FEAT_PROFILE