vim-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.

5a49789a9b
This commit is contained in:
Grzegorz Milka 2016-10-18 02:02:47 +02:00
parent c5c8a82134
commit 9755a2ffd5
6 changed files with 37 additions and 29 deletions

View File

@ -478,17 +478,20 @@ void buf_clear_file(buf_T *buf)
buf->b_ml.ml_flags = ML_EMPTY; /* empty buffer */ buf->b_ml.ml_flags = ML_EMPTY; /* empty buffer */
} }
/* /// buf_freeall() - free all things allocated for a buffer that are related to
* buf_freeall() - free all things allocated for a buffer that are related to /// the file. Careful: get here with "curwin" NULL when exiting.
* the file. flags: ///
* BFA_DEL buffer is going to be deleted /// @param flags BFA_DEL buffer is going to be deleted
* BFA_WIPE buffer is going to be wiped out /// BFA_WIPE buffer is going to be wiped out
* BFA_KEEP_UNDO do not free undo information /// BFA_KEEP_UNDO do not free undo information
*/
void buf_freeall(buf_T *buf, int flags) void buf_freeall(buf_T *buf, int flags)
{ {
bool is_curbuf = (buf == curbuf); 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; buf->b_closing = true;
apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, FALSE, buf); apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, FALSE, buf);
if (!buf_valid(buf)) /* autocommands may delete the buffer */ if (!buf_valid(buf)) /* autocommands may delete the buffer */
@ -505,6 +508,15 @@ void buf_freeall(buf_T *buf, int flags)
return; return;
} }
buf->b_closing = false; 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 */ if (aborting()) /* autocmds may abort script processing */
return; return;

View File

@ -2253,25 +2253,23 @@ do_ecmd (
if (buf == curbuf) /* already in new buffer */ if (buf == curbuf) /* already in new buffer */
auto_buf = TRUE; auto_buf = TRUE;
else { 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) if (curbuf == old_curbuf)
buf_copy_options(buf, BCO_ENTER); 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); u_sync(FALSE);
close_buffer(oldwin, curbuf, close_buffer(oldwin, curbuf,
(flags & ECMD_HIDE) || curbuf->terminal ? 0 : DOBUF_UNLOAD, FALSE); (flags & ECMD_HIDE) || curbuf->terminal ? 0 : DOBUF_UNLOAD, FALSE);
/* Autocommands may open a new window and leave oldwin open the_curwin->w_closing = FALSE;
* 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);
}
}
if (aborting()) { /* autocmds may abort script processing */ // autocmds may abort script processing
if (aborting() && curwin->w_buffer != NULL) {
xfree(new_name); xfree(new_name);
goto theend; goto theend;
} }

View File

@ -1772,10 +1772,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
if (text_locked() && !(ea.argt & CMDWIN) if (text_locked() && !(ea.argt & CMDWIN)
&& !IS_USER_CMDIDX(ea.cmdidx)) { && !IS_USER_CMDIDX(ea.cmdidx)) {
/* Command not allowed when editing the command line. */ /* Command not allowed when editing the command line. */
if (cmdwin_type != 0) errormsg = get_text_locked_msg();
errormsg = (char_u *)_(e_cmdwin);
else
errormsg = (char_u *)_(e_secure);
goto doend; goto doend;
} }
/* Disallow editing another buffer when "curbuf_lock" is set. /* Disallow editing another buffer when "curbuf_lock" is set.

View File

@ -1688,10 +1688,14 @@ int text_locked(void) {
*/ */
void text_locked_msg(void) void text_locked_msg(void)
{ {
EMSG(_(get_text_locked_msg()));
}
char_u * get_text_locked_msg(void) {
if (cmdwin_type != 0) if (cmdwin_type != 0)
EMSG(_(e_cmdwin)); return e_cmdwin;
else else
EMSG(_(e_secure)); return e_secure;
} }
/* /*

View File

@ -129,7 +129,7 @@ static int included_patches[] = {
// 2315, // 2315,
// 2314, // 2314,
// 2313, // 2313,
// 2312, 2312,
// 2311, // 2311,
// 2310 NA // 2310 NA
2309, 2309,

View File

@ -3243,10 +3243,7 @@ void goto_tabpage(int n)
if (text_locked()) { if (text_locked()) {
/* Not allowed when editing the command line. */ /* Not allowed when editing the command line. */
if (cmdwin_type != 0) text_locked_msg();
EMSG(_(e_cmdwin));
else
EMSG(_(e_secure));
return; return;
} }