Mercurial > vim
changeset 10082:7fc6103c6651 v7.4.2312
commit https://github.com/vim/vim/commit/5a49789a9b1f6447aeafbbbdd5b235dd10c471d5
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Sep 3 16:29:04 2016 +0200
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.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sat, 03 Sep 2016 16:30:06 +0200 |
parents | a7e347d09237 |
children | 00694b6618b0 |
files | src/buffer.c src/ex_cmds.c src/ex_docmd.c src/ex_getln.c src/proto/ex_getln.pro src/testdir/test_tabpage.vim src/version.c src/window.c |
diffstat | 8 files changed, 61 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/src/buffer.c +++ b/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 - * the file. flags: + * the file. Careful: get here with "curwin" NULL when exiting. + * 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 @@ -677,7 +678,13 @@ buf_freeall(buf_T *buf, int flags) #ifdef FEAT_AUTOCMD int is_curbuf = (buf == curbuf); 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; set_bufref(&bufref, buf); if (buf->b_ml.ml_mfp != NULL) @@ -705,6 +712,19 @@ buf_freeall(buf_T *buf, int flags) return; } 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 if (aborting()) /* autocmds may abort script processing */ return;
--- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -3935,25 +3935,28 @@ do_ecmd( 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.br_buf) #endif 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) ? 0 : DOBUF_UNLOAD, FALSE); #ifdef FEAT_AUTOCMD - /* 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) && oldwin->w_buffer == NULL) - win_close(oldwin, FALSE); + the_curwin->w_closing = FALSE; # 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); goto theend;
--- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -2475,12 +2475,7 @@ do_one_cmd( && !IS_USER_CMDIDX(ea.cmdidx)) { /* Command not allowed when editing the command line. */ -#ifdef FEAT_CMDWIN - if (cmdwin_type != 0) - errormsg = (char_u *)_(e_cmdwin); - else -#endif - errormsg = (char_u *)_(e_secure); + errormsg = get_text_locked_msg(); goto doend; } #ifdef FEAT_AUTOCMD
--- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -2133,12 +2133,17 @@ text_locked(void) void text_locked_msg(void) { + EMSG(_(get_text_locked_msg())); +} + + char_u * +get_text_locked_msg(void) +{ #ifdef FEAT_CMDWIN if (cmdwin_type != 0) - EMSG(_(e_cmdwin)); - else -#endif - EMSG(_(e_secure)); + return e_cmdwin; +#endif + return e_secure; } #if defined(FEAT_AUTOCMD) || defined(PROTO)
--- a/src/proto/ex_getln.pro +++ b/src/proto/ex_getln.pro @@ -3,6 +3,7 @@ char_u *getcmdline(int firstc, long coun char_u *getcmdline_prompt(int firstc, char_u *prompt, int attr, int xp_context, char_u *xp_arg); int text_locked(void); void text_locked_msg(void); +char_u *get_text_locked_msg(void); int curbuf_locked(void); int allbuf_locked(void); char_u *getexline(int c, void *cookie, int indent);
--- a/src/testdir/test_tabpage.vim +++ b/src/testdir/test_tabpage.vim @@ -218,7 +218,7 @@ function Test_tabpage_with_tab_modifier( bw! endfunction -func Test_tabnext_on_buf_unload() +func Test_tabnext_on_buf_unload1() " This once caused a crash new tabedit @@ -227,7 +227,19 @@ func Test_tabnext_on_buf_unload() q 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 endfunc