To: vim_dev@googlegroups.com Subject: Patch 8.2.0004 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0004 Problem: Get E685 and E931 if buffer reload is interrupted. Solution: Do not abort deleting a dummy buffer. (closes #5361) Files: src/buffer.c, src/proto/buffer.pro, src/testdir/test_trycatch.vim, src/ex_cmds.c, src/ex_getln.c, src/misc2.c, src/quickfix.c, src/window.c, src/vim.h *** ../vim-8.2.0003/src/buffer.c 2019-12-10 23:33:04.000000000 +0100 --- src/buffer.c 2019-12-14 16:06:23.745309167 +0100 *************** *** 184,190 **** * There MUST be a memfile, otherwise we can't do anything * If we can't create one for the current buffer, take another buffer */ ! close_buffer(NULL, curbuf, 0, FALSE); FOR_ALL_BUFFERS(curbuf) if (curbuf->b_ml.ml_mfp != NULL) break; --- 184,190 ---- * There MUST be a memfile, otherwise we can't do anything * If we can't create one for the current buffer, take another buffer */ ! close_buffer(NULL, curbuf, 0, FALSE, FALSE); FOR_ALL_BUFFERS(curbuf) if (curbuf->b_ml.ml_mfp != NULL) break; *************** *** 487,499 **** * When "abort_if_last" is TRUE then do not close the buffer if autocommands * cause there to be only one window with this buffer. e.g. when ":quit" is * supposed to close the window but autocommands close all other windows. */ void close_buffer( win_T *win, // if not NULL, set b_last_cursor buf_T *buf, int action, ! int abort_if_last) { int is_curbuf; int nwindows; --- 487,502 ---- * When "abort_if_last" is TRUE then do not close the buffer if autocommands * cause there to be only one window with this buffer. e.g. when ":quit" is * supposed to close the window but autocommands close all other windows. + * + * When "ignore_abort" is TRUE don't abort even when aborting() returns TRUE. */ void close_buffer( win_T *win, // if not NULL, set b_last_cursor buf_T *buf, int action, ! int abort_if_last, ! int ignore_abort) { int is_curbuf; int nwindows; *************** *** 609,615 **** goto aucmd_abort; } #ifdef FEAT_EVAL ! if (aborting()) // autocmds may abort script processing return; #endif } --- 612,619 ---- goto aucmd_abort; } #ifdef FEAT_EVAL ! // autocmds may abort script processing ! if (!ignore_abort && aborting()) return; #endif } *************** *** 662,674 **** is_curbuf = (buf == curbuf); buf->b_nwindows = nwindows; ! buf_freeall(buf, (del_buf ? BFA_DEL : 0) + (wipe_buf ? BFA_WIPE : 0)); // Autocommands may have deleted the buffer. if (!bufref_valid(&bufref)) return; #ifdef FEAT_EVAL ! if (aborting()) // autocmds may abort script processing return; #endif --- 666,681 ---- is_curbuf = (buf == curbuf); buf->b_nwindows = nwindows; ! buf_freeall(buf, (del_buf ? BFA_DEL : 0) ! + (wipe_buf ? BFA_WIPE : 0) ! + (ignore_abort ? BFA_IGNORE_ABORT : 0)); // Autocommands may have deleted the buffer. if (!bufref_valid(&bufref)) return; #ifdef FEAT_EVAL ! // autocmds may abort script processing ! if (!ignore_abort && aborting()) return; #endif *************** *** 762,770 **** * 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 */ void buf_freeall(buf_T *buf, int flags) --- 769,778 ---- * 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 ! * BFA_IGNORE_ABORT don't abort even when aborting() returns TRUE */ void buf_freeall(buf_T *buf, int flags) *************** *** 815,821 **** } #ifdef FEAT_EVAL ! if (aborting()) // autocmds may abort script processing return; #endif --- 823,830 ---- } #ifdef FEAT_EVAL ! // autocmds may abort script processing ! if ((flags & BFA_IGNORE_ABORT) == 0 && aborting()) return; #endif *************** *** 1077,1083 **** // open a new, empty buffer. swap_exists_action = SEA_NONE; // don't want it again swap_exists_did_quit = TRUE; ! close_buffer(curwin, curbuf, DOBUF_UNLOAD, FALSE); if (old_curbuf == NULL || !bufref_valid(old_curbuf) || old_curbuf->br_buf == curbuf) buf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED); --- 1086,1092 ---- // open a new, empty buffer. swap_exists_action = SEA_NONE; // don't want it again swap_exists_did_quit = TRUE; ! close_buffer(curwin, curbuf, DOBUF_UNLOAD, FALSE, FALSE); if (old_curbuf == NULL || !bufref_valid(old_curbuf) || old_curbuf->br_buf == curbuf) buf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED); *************** *** 1281,1287 **** * if the buffer still exists. */ if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows == 0) ! close_buffer(NULL, buf, action, FALSE); if (!close_others) need_fileinfo = FALSE; return retval; --- 1290,1296 ---- * if the buffer still exists. */ if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows == 0) ! close_buffer(NULL, buf, action, FALSE, FALSE); if (!close_others) need_fileinfo = FALSE; return retval; *************** *** 1478,1484 **** { close_windows(buf, FALSE); if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows <= 0) ! close_buffer(NULL, buf, action, FALSE); return OK; } --- 1487,1493 ---- { close_windows(buf, FALSE); if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows <= 0) ! close_buffer(NULL, buf, action, FALSE, FALSE); return OK; } *************** *** 1708,1714 **** close_buffer(prevbuf == curwin->w_buffer ? curwin : NULL, prevbuf, unload ? action : (action == DOBUF_GOTO && !buf_hide(prevbuf) ! && !bufIsChanged(prevbuf)) ? DOBUF_UNLOAD : 0, FALSE); if (curwin != previouswin && win_valid(previouswin)) // autocommands changed curwin, Grr! curwin = previouswin; --- 1717,1724 ---- close_buffer(prevbuf == curwin->w_buffer ? curwin : NULL, prevbuf, unload ? action : (action == DOBUF_GOTO && !buf_hide(prevbuf) ! && !bufIsChanged(prevbuf)) ? DOBUF_UNLOAD : 0, ! FALSE, FALSE); if (curwin != previouswin && win_valid(previouswin)) // autocommands changed curwin, Grr! curwin = previouswin; *************** *** 3296,3302 **** return FAIL; } // delete from the list ! close_buffer(NULL, obuf, DOBUF_WIPE, FALSE); } sfname = vim_strsave(sfname); if (ffname == NULL || sfname == NULL) --- 3306,3312 ---- return FAIL; } // delete from the list ! close_buffer(NULL, obuf, DOBUF_WIPE, FALSE, FALSE); } sfname = vim_strsave(sfname); if (ffname == NULL || sfname == NULL) *************** *** 5633,5639 **** void wipe_buffer( buf_T *buf, ! int aucmd UNUSED) // When TRUE trigger autocommands. { if (buf->b_fnum == top_file_num - 1) --top_file_num; --- 5643,5649 ---- void wipe_buffer( buf_T *buf, ! int aucmd) // When TRUE trigger autocommands. { if (buf->b_fnum == top_file_num - 1) --top_file_num; *************** *** 5641,5647 **** if (!aucmd) // Don't trigger BufDelete autocommands here. block_autocmds(); ! close_buffer(NULL, buf, DOBUF_WIPE, FALSE); if (!aucmd) unblock_autocmds(); --- 5651,5657 ---- if (!aucmd) // Don't trigger BufDelete autocommands here. block_autocmds(); ! close_buffer(NULL, buf, DOBUF_WIPE, FALSE, TRUE); if (!aucmd) unblock_autocmds(); *** ../vim-8.2.0003/src/proto/buffer.pro 2019-12-12 12:55:15.000000000 +0100 --- src/proto/buffer.pro 2019-12-14 15:59:07.071090992 +0100 *************** *** 5,11 **** void set_bufref(bufref_T *bufref, buf_T *buf); int bufref_valid(bufref_T *bufref); int buf_valid(buf_T *buf); ! void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last); void buf_clear_file(buf_T *buf); void buf_freeall(buf_T *buf, int flags); void goto_buffer(exarg_T *eap, int start, int dir, int count); --- 5,11 ---- void set_bufref(bufref_T *bufref, buf_T *buf); int bufref_valid(bufref_T *bufref); int buf_valid(buf_T *buf); ! void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last, int ignore_abort); void buf_clear_file(buf_T *buf); void buf_freeall(buf_T *buf, int flags); void goto_buffer(exarg_T *eap, int start, int dir, int count); *** ../vim-8.2.0003/src/testdir/test_trycatch.vim 2019-11-03 16:09:05.000000000 +0100 --- src/testdir/test_trycatch.vim 2019-12-14 15:38:34.940230649 +0100 *************** *** 1972,1977 **** call assert_equal('jlmnpqrtueghivyzACD', g:Xpath) endfunc ! " Modelines {{{1 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker - "------------------------------------------------------------------------------- --- 1972,2000 ---- call assert_equal('jlmnpqrtueghivyzACD', g:Xpath) endfunc ! func Test_reload_in_try_catch() ! call writefile(['x'], 'Xreload') ! set autoread ! edit Xreload ! tabnew ! call writefile(['xx'], 'Xreload') ! augroup ReLoad ! au FileReadPost Xreload let x = doesnotexist ! au BufReadPost Xreload let x = doesnotexist ! augroup END ! try ! edit Xreload ! catch ! endtry ! tabnew ! ! tabclose ! tabclose ! autocmd! ReLoad ! set noautoread ! bwipe! Xreload ! call delete('Xreload') ! endfunc ! ! " Modeline {{{1 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker *** ../vim-8.2.0003/src/ex_cmds.c 2019-12-01 21:23:08.000000000 +0100 --- src/ex_cmds.c 2019-12-14 15:46:24.246352059 +0100 *************** *** 2742,2748 **** // oldwin->w_buffer to NULL. u_sync(FALSE); close_buffer(oldwin, curbuf, ! (flags & ECMD_HIDE) ? 0 : DOBUF_UNLOAD, FALSE); the_curwin->w_closing = FALSE; --buf->b_locked; --- 2742,2748 ---- // oldwin->w_buffer to NULL. u_sync(FALSE); close_buffer(oldwin, curbuf, ! (flags & ECMD_HIDE) ? 0 : DOBUF_UNLOAD, FALSE, FALSE); the_curwin->w_closing = FALSE; --buf->b_locked; *** ../vim-8.2.0003/src/ex_getln.c 2019-12-04 15:10:39.000000000 +0100 --- src/ex_getln.c 2019-12-14 15:46:30.946321728 +0100 *************** *** 4372,4378 **** // win_close() may have already wiped the buffer when 'bh' is // set to 'wipe' if (bufref_valid(&bufref)) ! close_buffer(NULL, bufref.br_buf, DOBUF_WIPE, FALSE); // Restore window sizes. win_size_restore(&winsizes); --- 4372,4378 ---- // win_close() may have already wiped the buffer when 'bh' is // set to 'wipe' if (bufref_valid(&bufref)) ! close_buffer(NULL, bufref.br_buf, DOBUF_WIPE, FALSE, FALSE); // Restore window sizes. win_size_restore(&winsizes); *** ../vim-8.2.0003/src/misc2.c 2019-11-30 22:40:44.000000000 +0100 --- src/misc2.c 2019-12-14 15:46:36.098298446 +0100 *************** *** 1185,1191 **** set_bufref(&bufref, buf); nextbuf = buf->b_next; ! close_buffer(NULL, buf, DOBUF_WIPE, FALSE); if (bufref_valid(&bufref)) buf = nextbuf; /* didn't work, try next one */ else --- 1185,1191 ---- set_bufref(&bufref, buf); nextbuf = buf->b_next; ! close_buffer(NULL, buf, DOBUF_WIPE, FALSE, FALSE); if (bufref_valid(&bufref)) buf = nextbuf; /* didn't work, try next one */ else *** ../vim-8.2.0003/src/quickfix.c 2019-12-06 21:10:07.000000000 +0100 --- src/quickfix.c 2019-12-14 15:46:57.574201640 +0100 *************** *** 1925,1931 **** { // If the quickfix buffer is not loaded in any window, then // wipe the buffer. ! close_buffer(NULL, qfbuf, DOBUF_WIPE, FALSE); qi->qf_bufnr = INVALID_QFBUFNR; } } --- 1925,1931 ---- { // If the quickfix buffer is not loaded in any window, then // wipe the buffer. ! close_buffer(NULL, qfbuf, DOBUF_WIPE, FALSE, FALSE); qi->qf_bufnr = INVALID_QFBUFNR; } } *************** *** 6311,6317 **** { if (curbuf != buf) // safety check { ! close_buffer(NULL, buf, DOBUF_UNLOAD, FALSE); // When autocommands/'autochdir' option changed directory: go back. restore_start_dir(dirname_start); --- 6311,6317 ---- { if (curbuf != buf) // safety check { ! close_buffer(NULL, buf, DOBUF_UNLOAD, FALSE, TRUE); // When autocommands/'autochdir' option changed directory: go back. restore_start_dir(dirname_start); *** ../vim-8.2.0003/src/window.c 2019-12-05 21:46:52.000000000 +0100 --- src/window.c 2019-12-14 15:47:23.734084308 +0100 *************** *** 2410,2416 **** set_bufref(&bufref, curbuf); win->w_closing = TRUE; ! close_buffer(win, win->w_buffer, action, abort_if_last); if (win_valid_any_tab(win)) win->w_closing = FALSE; // Make sure curbuf is valid. It can become invalid if 'bufhidden' is --- 2410,2416 ---- set_bufref(&bufref, curbuf); win->w_closing = TRUE; ! close_buffer(win, win->w_buffer, action, abort_if_last, FALSE); if (win_valid_any_tab(win)) win->w_closing = FALSE; // Make sure curbuf is valid. It can become invalid if 'bufhidden' is *************** *** 2677,2683 **** if (win->w_buffer != NULL) // Close the link to the buffer. ! close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, FALSE); // Careful: Autocommands may have closed the tab page or made it the // current tab page. --- 2677,2684 ---- if (win->w_buffer != NULL) // Close the link to the buffer. ! close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, ! FALSE, FALSE); // Careful: Autocommands may have closed the tab page or made it the // current tab page. *************** *** 5001,5007 **** if (bt_popup(win->w_buffer)) win_close_buffer(win, DOBUF_WIPE_REUSE, FALSE); else ! close_buffer(win, win->w_buffer, 0, FALSE); # if defined(FEAT_TIMERS) if (win->w_popup_timer != NULL) stop_timer(win->w_popup_timer); --- 5002,5008 ---- if (bt_popup(win->w_buffer)) win_close_buffer(win, DOBUF_WIPE_REUSE, FALSE); else ! close_buffer(win, win->w_buffer, 0, FALSE, FALSE); # if defined(FEAT_TIMERS) if (win->w_popup_timer != NULL) stop_timer(win->w_popup_timer); *** ../vim-8.2.0003/src/vim.h 2019-12-05 23:05:26.000000000 +0100 --- src/vim.h 2019-12-14 15:51:55.128899689 +0100 *************** *** 2458,2466 **** #define VIF_GET_OLDFILES 8 // load v:oldfiles // flags for buf_freeall() ! #define BFA_DEL 1 // buffer is going to be deleted ! #define BFA_WIPE 2 // buffer is going to be wiped out ! #define BFA_KEEP_UNDO 4 // do not free undo information // direction for nv_mousescroll() and ins_mousescroll() #define MSCR_DOWN 0 // DOWN must be FALSE --- 2458,2467 ---- #define VIF_GET_OLDFILES 8 // load v:oldfiles // flags for buf_freeall() ! #define BFA_DEL 1 // buffer is going to be deleted ! #define BFA_WIPE 2 // buffer is going to be wiped out ! #define BFA_KEEP_UNDO 4 // do not free undo information ! #define BFA_IGNORE_ABORT 8 // do not abort for aborting() // direction for nv_mousescroll() and ins_mousescroll() #define MSCR_DOWN 0 // DOWN must be FALSE *** ../vim-8.2.0003/src/version.c 2019-12-14 13:09:13.662894297 +0100 --- src/version.c 2019-12-14 16:16:30.418864436 +0100 *************** *** 744,745 **** --- 744,747 ---- { /* Add new patch number below this line */ + /**/ + 4, /**/ -- Women are probably the main cause of free software starvation. /// 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 ///