aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/buffer.c26
-rw-r--r--src/nvim/ex_cmds.c20
-rw-r--r--src/nvim/ex_docmd.c5
-rw-r--r--src/nvim/ex_getln.c8
-rw-r--r--src/nvim/version.c2
-rw-r--r--src/nvim/window.c5
6 files changed, 37 insertions, 29 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 176967ad2a..fc6e46cf64 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -478,17 +478,20 @@ void buf_clear_file(buf_T *buf)
buf->b_ml.ml_flags = ML_EMPTY; /* empty buffer */
}
-/*
- * buf_freeall() - free all things allocated for a buffer that are related to
- * the file. 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
- */
+/// buf_freeall() - free all things allocated for a buffer that are related to
+/// the file. Careful: get here with "curwin" NULL when exiting.
+///
+/// @param 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
void buf_freeall(buf_T *buf, int flags)
{
bool is_curbuf = (buf == curbuf);
+ int is_curwin = (curwin != NULL && curwin->w_buffer == buf);
+ win_T *the_curwin = curwin;
+ tabpage_T *the_curtab = curtab;
+ // Make sure the buffer isn't closed by autocommands.
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 */
@@ -505,6 +508,15 @@ void buf_freeall(buf_T *buf, int flags)
return;
}
buf->b_closing = false;
+
+ // 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();
+ }
if (aborting()) /* autocmds may abort script processing */
return;
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 6205daf0cb..79ee69bb56 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -2253,25 +2253,23 @@ do_ecmd (
if (buf == curbuf) /* already in new buffer */
auto_buf = TRUE;
else {
+ win_T *the_curwin = curwin;
+
+ // Set the w_closing flag to avoid that autocommands close the window.
+ the_curwin->w_closing = TRUE;
if (curbuf == old_curbuf)
buf_copy_options(buf, BCO_ENTER);
- /* close the link to the current buffer */
+ // Close the link to the current buffer. This will set
+ // curwin->w_buffer to NULL.
u_sync(FALSE);
close_buffer(oldwin, curbuf,
(flags & ECMD_HIDE) || curbuf->terminal ? 0 : DOBUF_UNLOAD, FALSE);
- /* Autocommands may open a new window and leave oldwin open
- * which leads to crashes since the above call sets
- * oldwin->w_buffer to NULL. */
- if (curwin != oldwin && oldwin != aucmd_win && win_valid(oldwin)) {
- assert(oldwin);
- if (oldwin->w_buffer == NULL) {
- win_close(oldwin, FALSE);
- }
- }
+ the_curwin->w_closing = FALSE;
- if (aborting()) { /* autocmds may abort script processing */
+ // autocmds may abort script processing
+ if (aborting() && curwin->w_buffer != NULL) {
xfree(new_name);
goto theend;
}
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index cbe4d19d2c..5c84b5bb4e 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -1772,10 +1772,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
if (text_locked() && !(ea.argt & CMDWIN)
&& !IS_USER_CMDIDX(ea.cmdidx)) {
/* Command not allowed when editing the command line. */
- if (cmdwin_type != 0)
- errormsg = (char_u *)_(e_cmdwin);
- else
- errormsg = (char_u *)_(e_secure);
+ errormsg = get_text_locked_msg();
goto doend;
}
/* Disallow editing another buffer when "curbuf_lock" is set.
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 7444eb8a38..a58cdd5c6b 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -1688,10 +1688,14 @@ int text_locked(void) {
*/
void text_locked_msg(void)
{
+ EMSG(_(get_text_locked_msg()));
+}
+
+char_u * get_text_locked_msg(void) {
if (cmdwin_type != 0)
- EMSG(_(e_cmdwin));
+ return e_cmdwin;
else
- EMSG(_(e_secure));
+ return e_secure;
}
/*
diff --git a/src/nvim/version.c b/src/nvim/version.c
index f0f6f6a3cb..389eefdcca 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -129,7 +129,7 @@ static int included_patches[] = {
// 2315,
// 2314,
// 2313,
- // 2312,
+ 2312,
// 2311,
// 2310 NA
2309,
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 2fb1fbede9..e7be1fb7f8 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -3243,10 +3243,7 @@ void goto_tabpage(int n)
if (text_locked()) {
/* Not allowed when editing the command line. */
- if (cmdwin_type != 0)
- EMSG(_(e_cmdwin));
- else
- EMSG(_(e_secure));
+ text_locked_msg();
return;
}