forked from aniani/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.
This commit is contained in:
22
src/buffer.c
22
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
|
* 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_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
|
||||||
@@ -677,7 +678,13 @@ buf_freeall(buf_T *buf, int flags)
|
|||||||
#ifdef FEAT_AUTOCMD
|
#ifdef FEAT_AUTOCMD
|
||||||
int is_curbuf = (buf == curbuf);
|
int is_curbuf = (buf == curbuf);
|
||||||
bufref_T bufref;
|
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;
|
buf->b_closing = TRUE;
|
||||||
set_bufref(&bufref, buf);
|
set_bufref(&bufref, buf);
|
||||||
if (buf->b_ml.ml_mfp != NULL)
|
if (buf->b_ml.ml_mfp != NULL)
|
||||||
@@ -705,6 +712,19 @@ buf_freeall(buf_T *buf, int flags)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
buf->b_closing = FALSE;
|
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
|
# ifdef FEAT_EVAL
|
||||||
if (aborting()) /* autocmds may abort script processing */
|
if (aborting()) /* autocmds may abort script processing */
|
||||||
return;
|
return;
|
||||||
|
@@ -3935,25 +3935,28 @@ do_ecmd(
|
|||||||
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.br_buf)
|
if (curbuf == old_curbuf.br_buf)
|
||||||
#endif
|
#endif
|
||||||
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) ? 0 : DOBUF_UNLOAD, FALSE);
|
(flags & ECMD_HIDE) ? 0 : DOBUF_UNLOAD, FALSE);
|
||||||
|
|
||||||
#ifdef FEAT_AUTOCMD
|
#ifdef FEAT_AUTOCMD
|
||||||
/* 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) && oldwin->w_buffer == NULL)
|
|
||||||
win_close(oldwin, FALSE);
|
|
||||||
|
|
||||||
# ifdef FEAT_EVAL
|
# ifdef FEAT_EVAL
|
||||||
if (aborting()) /* autocmds may abort script processing */
|
/* autocmds may abort script processing */
|
||||||
|
if (aborting() && curwin->w_buffer != NULL)
|
||||||
{
|
{
|
||||||
vim_free(new_name);
|
vim_free(new_name);
|
||||||
goto theend;
|
goto theend;
|
||||||
|
@@ -2475,12 +2475,7 @@ do_one_cmd(
|
|||||||
&& !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. */
|
||||||
#ifdef FEAT_CMDWIN
|
errormsg = get_text_locked_msg();
|
||||||
if (cmdwin_type != 0)
|
|
||||||
errormsg = (char_u *)_(e_cmdwin);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
errormsg = (char_u *)_(e_secure);
|
|
||||||
goto doend;
|
goto doend;
|
||||||
}
|
}
|
||||||
#ifdef FEAT_AUTOCMD
|
#ifdef FEAT_AUTOCMD
|
||||||
|
@@ -2132,13 +2132,18 @@ text_locked(void)
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
text_locked_msg(void)
|
text_locked_msg(void)
|
||||||
|
{
|
||||||
|
EMSG(_(get_text_locked_msg()));
|
||||||
|
}
|
||||||
|
|
||||||
|
char_u *
|
||||||
|
get_text_locked_msg(void)
|
||||||
{
|
{
|
||||||
#ifdef FEAT_CMDWIN
|
#ifdef FEAT_CMDWIN
|
||||||
if (cmdwin_type != 0)
|
if (cmdwin_type != 0)
|
||||||
EMSG(_(e_cmdwin));
|
return e_cmdwin;
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
EMSG(_(e_secure));
|
return e_secure;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(FEAT_AUTOCMD) || defined(PROTO)
|
#if defined(FEAT_AUTOCMD) || defined(PROTO)
|
||||||
|
@@ -3,6 +3,7 @@ char_u *getcmdline(int firstc, long count, int indent);
|
|||||||
char_u *getcmdline_prompt(int firstc, char_u *prompt, int attr, int xp_context, char_u *xp_arg);
|
char_u *getcmdline_prompt(int firstc, char_u *prompt, int attr, int xp_context, char_u *xp_arg);
|
||||||
int text_locked(void);
|
int text_locked(void);
|
||||||
void text_locked_msg(void);
|
void text_locked_msg(void);
|
||||||
|
char_u *get_text_locked_msg(void);
|
||||||
int curbuf_locked(void);
|
int curbuf_locked(void);
|
||||||
int allbuf_locked(void);
|
int allbuf_locked(void);
|
||||||
char_u *getexline(int c, void *cookie, int indent);
|
char_u *getexline(int c, void *cookie, int indent);
|
||||||
|
@@ -218,7 +218,7 @@ function Test_tabpage_with_tab_modifier()
|
|||||||
bw!
|
bw!
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
func Test_tabnext_on_buf_unload()
|
func Test_tabnext_on_buf_unload1()
|
||||||
" This once caused a crash
|
" This once caused a crash
|
||||||
new
|
new
|
||||||
tabedit
|
tabedit
|
||||||
@@ -227,7 +227,19 @@ func Test_tabnext_on_buf_unload()
|
|||||||
q
|
q
|
||||||
|
|
||||||
while tabpagenr('$') > 1
|
while tabpagenr('$') > 1
|
||||||
quit
|
bwipe!
|
||||||
|
endwhile
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_tabnext_on_buf_unload2()
|
||||||
|
" This once caused a crash
|
||||||
|
tabedit
|
||||||
|
autocmd BufUnload <buffer> tabnext
|
||||||
|
file x
|
||||||
|
edit y
|
||||||
|
|
||||||
|
while tabpagenr('$') > 1
|
||||||
|
bwipe!
|
||||||
endwhile
|
endwhile
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
@@ -763,6 +763,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
2312,
|
||||||
/**/
|
/**/
|
||||||
2311,
|
2311,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -3912,12 +3912,7 @@ goto_tabpage(int n)
|
|||||||
if (text_locked())
|
if (text_locked())
|
||||||
{
|
{
|
||||||
/* Not allowed when editing the command line. */
|
/* Not allowed when editing the command line. */
|
||||||
#ifdef FEAT_CMDWIN
|
text_locked_msg();
|
||||||
if (cmdwin_type != 0)
|
|
||||||
EMSG(_(e_cmdwin));
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
EMSG(_(e_secure));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user