updated for version 7.2-132
diff --git a/src/ex_getln.c b/src/ex_getln.c
index ecaeb3f..5cda65a 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -2000,8 +2000,8 @@
#if defined(FEAT_AUTOCMD) || defined(PROTO)
/*
- * Check if "curbuf_lock" is set and return TRUE when it is and give an error
- * message.
+ * Check if "curbuf_lock" or "allbuf_lock" is set and return TRUE when it is
+ * and give an error message.
*/
int
curbuf_locked()
@@ -2011,6 +2011,21 @@
EMSG(_("E788: Not allowed to edit another buffer now"));
return TRUE;
}
+ return allbuf_locked();
+}
+
+/*
+ * Check if "allbuf_lock" is set and return TRUE when it is and give an error
+ * message.
+ */
+ int
+allbuf_locked()
+{
+ if (allbuf_lock > 0)
+ {
+ EMSG(_("E811: Not allowed to change buffer information now"));
+ return TRUE;
+ }
return FALSE;
}
#endif
diff --git a/src/fileio.c b/src/fileio.c
index 76d4b85..342cf59 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -69,7 +69,7 @@
static int au_find_group __ARGS((char_u *name));
# define AUGROUP_DEFAULT -1 /* default autocmd group */
-# define AUGROUP_ERROR -2 /* errornouse autocmd group */
+# define AUGROUP_ERROR -2 /* erroneous autocmd group */
# define AUGROUP_ALL -3 /* all autocmd groups */
#endif
@@ -144,7 +144,9 @@
# endif
#endif
static int move_lines __ARGS((buf_T *frombuf, buf_T *tobuf));
-
+#ifdef FEAT_AUTOCMD
+static char *e_auchangedbuf = N_("E812: Autocommands changed buffer or buffer name");
+#endif
void
filemess(buf, name, s, attr)
@@ -295,6 +297,19 @@
int conv_restlen = 0; /* nr of bytes in conv_rest[] */
#endif
+#ifdef FEAT_AUTOCMD
+ /* Remember the initial values of curbuf, curbuf->b_ffname and
+ * curbuf->b_fname to detect whether they are altered as a result of
+ * executing nasty autocommands. Also check if "fname" and "sfname"
+ * point to one of these values. */
+ buf_T *old_curbuf = curbuf;
+ char_u *old_b_ffname = curbuf->b_ffname;
+ char_u *old_b_fname = curbuf->b_fname;
+ int using_b_ffname = (fname == curbuf->b_ffname)
+ || (sfname == curbuf->b_ffname);
+ int using_b_fname = (fname == curbuf->b_fname)
+ || (sfname == curbuf->b_fname);
+#endif
write_no_eol_lnum = 0; /* in case it was set by the previous read */
/*
@@ -589,7 +604,21 @@
#ifdef FEAT_QUICKFIX
if (!bt_dontwrite(curbuf))
#endif
+ {
check_need_swap(newfile);
+#ifdef FEAT_AUTOCMD
+ /* SwapExists autocommand may mess things up */
+ if (curbuf != old_curbuf
+ || (using_b_ffname
+ && (old_b_ffname != curbuf->b_ffname))
+ || (using_b_fname
+ && (old_b_fname != curbuf->b_fname)))
+ {
+ EMSG(_(e_auchangedbuf));
+ return FAIL;
+ }
+#endif
+ }
if (dir_of_file_exists(fname))
filemess(curbuf, sfname, (char_u *)_("[New File]"), 0);
else
@@ -668,6 +697,17 @@
#endif
{
check_need_swap(newfile);
+#ifdef FEAT_AUTOCMD
+ if (!read_stdin && (curbuf != old_curbuf
+ || (using_b_ffname && (old_b_ffname != curbuf->b_ffname))
+ || (using_b_fname && (old_b_fname != curbuf->b_fname))))
+ {
+ EMSG(_(e_auchangedbuf));
+ if (!read_buffer)
+ close(fd);
+ return FAIL;
+ }
+#endif
#ifdef UNIX
/* Set swap file protection bits after creating it. */
if (swap_mode > 0 && curbuf->b_ml.ml_mfp->mf_fname != NULL)
@@ -698,7 +738,6 @@
{
int m = msg_scroll;
int n = msg_scrolled;
- buf_T *old_curbuf = curbuf;
/*
* The file must be closed again, the autocommands may want to change
@@ -740,8 +779,13 @@
/*
* Don't allow the autocommands to change the current buffer.
* Try to re-open the file.
+ *
+ * Don't allow the autocommands to change the buffer name either
+ * (cd for example) if it invalidates fname or sfname.
*/
if (!read_stdin && (curbuf != old_curbuf
+ || (using_b_ffname && (old_b_ffname != curbuf->b_ffname))
+ || (using_b_fname && (old_b_fname != curbuf->b_fname))
|| (fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) < 0))
{
--no_wait_return;
@@ -6320,7 +6364,7 @@
if (!stuff_empty() || global_busy || !typebuf_typed()
#ifdef FEAT_AUTOCMD
- || autocmd_busy || curbuf_lock > 0
+ || autocmd_busy || curbuf_lock > 0 || allbuf_lock > 0
#endif
)
need_check_timestamps = TRUE; /* check later */
@@ -6522,8 +6566,10 @@
set_vim_var_string(VV_FCS_REASON, (char_u *)reason, -1);
set_vim_var_string(VV_FCS_CHOICE, (char_u *)"", -1);
# endif
+ ++allbuf_lock;
n = apply_autocmds(EVENT_FILECHANGEDSHELL,
buf->b_fname, buf->b_fname, FALSE, buf);
+ --allbuf_lock;
busy = FALSE;
if (n)
{
diff --git a/src/globals.h b/src/globals.h
index 3236a1e..548927a 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -619,6 +619,11 @@
EXTERN int curbuf_lock INIT(= 0);
/* non-zero when the current buffer can't be
* changed. Used for FileChangedRO. */
+EXTERN int allbuf_lock INIT(= 0);
+ /* non-zero when no buffer name can be
+ * changed, no buffer can be deleted and
+ * current directory can't be changed.
+ * Used for SwapExists et al. */
#endif
#ifdef FEAT_EVAL
# define HAVE_SANDBOX
diff --git a/src/proto/ex_getln.pro b/src/proto/ex_getln.pro
index afbf664..2750542 100644
--- a/src/proto/ex_getln.pro
+++ b/src/proto/ex_getln.pro
@@ -4,6 +4,7 @@
int text_locked __ARGS((void));
void text_locked_msg __ARGS((void));
int curbuf_locked __ARGS((void));
+int allbuf_locked __ARGS((void));
char_u *getexline __ARGS((int c, void *dummy, int indent));
char_u *getexmodeline __ARGS((int promptc, void *dummy, int indent));
int cmdline_overstrike __ARGS((void));
diff --git a/src/version.c b/src/version.c
index a8783b9..4388cd2 100644
--- a/src/version.c
+++ b/src/version.c
@@ -677,6 +677,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 132,
+/**/
131,
/**/
130,