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 -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/201912141518.xBEFImKm003775%40masaka.moolenaar.net.

Raspunde prin e-mail lui