diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/buffer.c | 26 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 20 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 5 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 8 | ||||
-rw-r--r-- | src/nvim/version.c | 2 | ||||
-rw-r--r-- | src/nvim/window.c | 5 |
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; } |