To: vim_dev@googlegroups.com Subject: Patch 7.4.2312 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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. Files: src/buffer.c, src/ex_cmds.c, src/ex_getln.c, src/ex_docmd.c, src/window.c, src/proto/ex_getln.pro, src/testdir/test_tabpage.vim *** ../vim-7.4.2311/src/buffer.c 2016-08-29 22:48:12.113106491 +0200 --- src/buffer.c 2016-09-03 16:13:06.983259261 +0200 *************** *** 666,672 **** /* * 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 --- 666,673 ---- /* * buf_freeall() - free all things allocated for a buffer that are related to ! * 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,683 **** --- 678,690 ---- #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,710 **** --- 712,730 ---- 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; *** ../vim-7.4.2311/src/ex_cmds.c 2016-08-29 22:48:12.125106388 +0200 --- src/ex_cmds.c 2016-09-03 16:07:59.253987148 +0200 *************** *** 3935,3959 **** auto_buf = TRUE; else { if (curbuf == old_curbuf.br_buf) #endif buf_copy_options(buf, BCO_ENTER); ! /* close the link to the current buffer */ 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); # ifdef FEAT_EVAL ! if (aborting()) /* autocmds may abort script processing */ { vim_free(new_name); goto theend; --- 3935,3962 ---- 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. 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 ! the_curwin->w_closing = FALSE; # ifdef FEAT_EVAL ! /* autocmds may abort script processing */ ! if (aborting() && curwin->w_buffer != NULL) { vim_free(new_name); goto theend; *** ../vim-7.4.2311/src/ex_getln.c 2016-08-29 22:48:12.129106353 +0200 --- src/ex_getln.c 2016-09-03 15:22:18.849581001 +0200 *************** *** 2133,2144 **** void text_locked_msg(void) { #ifdef FEAT_CMDWIN if (cmdwin_type != 0) ! EMSG(_(e_cmdwin)); ! else #endif ! EMSG(_(e_secure)); } #if defined(FEAT_AUTOCMD) || defined(PROTO) --- 2133,2149 ---- void text_locked_msg(void) { + EMSG(_(get_text_locked_msg())); + } + + char_u * + get_text_locked_msg(void) + { #ifdef FEAT_CMDWIN if (cmdwin_type != 0) ! return e_cmdwin; #endif ! return e_secure; } #if defined(FEAT_AUTOCMD) || defined(PROTO) *** ../vim-7.4.2311/src/ex_docmd.c 2016-08-29 22:48:12.129106353 +0200 --- src/ex_docmd.c 2016-09-03 15:21:25.638040678 +0200 *************** *** 2475,2486 **** && !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); goto doend; } #ifdef FEAT_AUTOCMD --- 2475,2481 ---- && !IS_USER_CMDIDX(ea.cmdidx)) { /* Command not allowed when editing the command line. */ ! errormsg = get_text_locked_msg(); goto doend; } #ifdef FEAT_AUTOCMD *** ../vim-7.4.2311/src/window.c 2016-09-02 21:48:28.565811651 +0200 --- src/window.c 2016-09-03 15:11:54.063013594 +0200 *************** *** 3912,3923 **** if (text_locked()) { /* Not allowed when editing the command line. */ ! #ifdef FEAT_CMDWIN ! if (cmdwin_type != 0) ! EMSG(_(e_cmdwin)); ! else ! #endif ! EMSG(_(e_secure)); return; } --- 3912,3918 ---- if (text_locked()) { /* Not allowed when editing the command line. */ ! text_locked_msg(); return; } *** ../vim-7.4.2311/src/proto/ex_getln.pro 2016-06-11 21:04:34.927761279 +0200 --- src/proto/ex_getln.pro 2016-09-03 15:24:04.896665491 +0200 *************** *** 3,8 **** --- 3,9 ---- 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); *** ../vim-7.4.2311/src/testdir/test_tabpage.vim 2016-09-02 21:48:28.565811651 +0200 --- src/testdir/test_tabpage.vim 2016-09-03 16:24:24.765275570 +0200 *************** *** 218,224 **** bw! endfunction ! func Test_tabnext_on_buf_unload() " This once caused a crash new tabedit --- 218,224 ---- bw! endfunction ! func Test_tabnext_on_buf_unload1() " This once caused a crash new tabedit *************** *** 227,233 **** q while tabpagenr('$') > 1 ! quit endwhile endfunc --- 227,245 ---- q while tabpagenr('$') > 1 ! bwipe! ! endwhile ! endfunc ! ! func Test_tabnext_on_buf_unload2() ! " This once caused a crash ! tabedit ! autocmd BufUnload tabnext ! file x ! edit y ! ! while tabpagenr('$') > 1 ! bwipe! endwhile endfunc *** ../vim-7.4.2311/src/version.c 2016-09-02 22:26:00.758395809 +0200 --- src/version.c 2016-09-03 15:01:05.876848844 +0200 *************** *** 765,766 **** --- 765,768 ---- { /* Add new patch number below this line */ + /**/ + 2312, /**/ -- Fingers not found - Pound head on keyboard to continue. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///