diff src/buffer.c @ 10082:7fc6103c6651 v7.4.2312

commit https://github.com/vim/vim/commit/5a49789a9b1f6447aeafbbbdd5b235dd10c471d5 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Sep 3 16:29:04 2016 +0200 patch 7.4.2312 Problem: Crash when autocommand moves to another tab. (Dominique Pelle) Solution: When navigating to another window halfway the :edit command go back to the right window.
author Christian Brabandt <cb@256bit.org>
date Sat, 03 Sep 2016 16:30:06 +0200
parents 4aead6a9b7a9
children 58e6dd1d8be3
line wrap: on
line diff
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -666,7 +666,8 @@ buf_clear_file(buf_T *buf)
 
 /*
  * buf_freeall() - free all things allocated for a buffer that are related to
- * the file.  flags:
+ * the file.  Careful: get here with "curwin" NULL when exiting.
+ * flags:
  * BFA_DEL	  buffer is going to be deleted
  * BFA_WIPE	  buffer is going to be wiped out
  * BFA_KEEP_UNDO  do not free undo information
@@ -677,7 +678,13 @@ buf_freeall(buf_T *buf, int flags)
 #ifdef FEAT_AUTOCMD
     int		is_curbuf = (buf == curbuf);
     bufref_T	bufref;
-
+# ifdef FEAT_WINDOWS
+    int		is_curwin = (curwin!= NULL && curwin->w_buffer == buf);
+    win_T	*the_curwin = curwin;
+    tabpage_T	*the_curtab = curtab;
+# endif
+
+    /* Make sure the buffer isn't closed by autocommands. */
     buf->b_closing = TRUE;
     set_bufref(&bufref, buf);
     if (buf->b_ml.ml_mfp != NULL)
@@ -705,6 +712,19 @@ buf_freeall(buf_T *buf, int flags)
 	    return;
     }
     buf->b_closing = FALSE;
+
+# ifdef FEAT_WINDOWS
+    /* If the buffer was in curwin and the window has changed, go back to that
+     * window, if it still exists.  This avoids that ":edit x" triggering a
+     * "tabnext" BufUnload autocmd leaves a window behind without a buffer. */
+    if (is_curwin && curwin != the_curwin &&  win_valid_any_tab(the_curwin))
+    {
+	block_autocmds();
+	goto_tabpage_win(the_curtab, the_curwin);
+	unblock_autocmds();
+    }
+# endif
+
 # ifdef FEAT_EVAL
     if (aborting())	    /* autocmds may abort script processing */
 	return;