Patch 8.0.1815 (after 8.0.1814)
Problem:    Still a crash with terminal window and with 'lazyredraw' set.
            (Antoine)
Solution:   Do not wipe out the buffer when updating the screen.
Files:      src/terminal.c, src/proto/terminal.pro, src/screen.c,
            src/proto/screen.pro, src/ui.c


*** ../vim-8.0.1814/src/terminal.c      2018-05-11 20:48:24.803810853 +0200
--- src/terminal.c      2018-05-11 21:49:00.634487103 +0200
***************
*** 103,108 ****
--- 103,110 ----
  
      int               tl_normal_mode; /* TRUE: Terminal-Normal mode */
      int               tl_channel_closed;
+     int               tl_channel_recently_closed; // still need to handle 
tl_finish
+ 
      int               tl_finish;
  #define TL_FINISH_UNSET           NUL
  #define TL_FINISH_CLOSE           'c' /* ++close or :terminal without 
argument */
***************
*** 2780,2785 ****
--- 2782,2834 ----
  };
  
  /*
+  * Do the work after the channel of a terminal was closed.
+  * Must be called only when updating_screen is FALSE.
+  * Returns TRUE when a buffer was closed (list of terminals may have changed).
+  */
+     static int
+ term_after_channel_closed(term_T *term)
+ {
+     /* Unless in Terminal-Normal mode: clear the vterm. */
+     if (!term->tl_normal_mode)
+     {
+       int     fnum = term->tl_buffer->b_fnum;
+ 
+       cleanup_vterm(term);
+ 
+       if (term->tl_finish == TL_FINISH_CLOSE)
+       {
+           aco_save_T  aco;
+ 
+           /* ++close or term_finish == "close" */
+           ch_log(NULL, "terminal job finished, closing window");
+           aucmd_prepbuf(&aco, term->tl_buffer);
+           do_bufdel(DOBUF_WIPE, (char_u *)"", 1, fnum, fnum, FALSE);
+           aucmd_restbuf(&aco);
+           return TRUE;
+       }
+       if (term->tl_finish == TL_FINISH_OPEN
+                                  && term->tl_buffer->b_nwindows == 0)
+       {
+           char buf[50];
+ 
+           /* TODO: use term_opencmd */
+           ch_log(NULL, "terminal job finished, opening window");
+           vim_snprintf(buf, sizeof(buf),
+                   term->tl_opencmd == NULL
+                           ? "botright sbuf %d"
+                           : (char *)term->tl_opencmd, fnum);
+           do_cmdline_cmd((char_u *)buf);
+       }
+       else
+           ch_log(NULL, "terminal job finished");
+     }
+ 
+     redraw_buf_and_status_later(term->tl_buffer, NOT_VALID);
+     return FALSE;
+ }
+ 
+ /*
   * Called when a channel has been closed.
   * If this was a channel for a terminal window then finish it up.
   */
***************
*** 2787,2795 ****
  term_channel_closed(channel_T *ch)
  {
      term_T *term;
      int           did_one = FALSE;
  
!     for (term = first_term; term != NULL; term = term->tl_next)
        if (term->tl_job == ch->ch_job)
        {
            term->tl_channel_closed = TRUE;
--- 2836,2847 ----
  term_channel_closed(channel_T *ch)
  {
      term_T *term;
+     term_T *next_term;
      int           did_one = FALSE;
  
!     for (term = first_term; term != NULL; term = next_term)
!     {
!       next_term = term->tl_next;
        if (term->tl_job == ch->ch_job)
        {
            term->tl_channel_closed = TRUE;
***************
*** 2805,2847 ****
            }
  #endif
  
!           /* Unless in Terminal-Normal mode: clear the vterm. */
!           if (!term->tl_normal_mode)
            {
!               int     fnum = term->tl_buffer->b_fnum;
! 
!               cleanup_vterm(term);
! 
!               if (term->tl_finish == TL_FINISH_CLOSE)
!               {
!                   aco_save_T  aco;
! 
!                   /* ++close or term_finish == "close" */
!                   ch_log(NULL, "terminal job finished, closing window");
!                   aucmd_prepbuf(&aco, term->tl_buffer);
!                   do_bufdel(DOBUF_WIPE, (char_u *)"", 1, fnum, fnum, FALSE);
!                   aucmd_restbuf(&aco);
!                   break;
!               }
!               if (term->tl_finish == TL_FINISH_OPEN
!                                          && term->tl_buffer->b_nwindows == 0)
!               {
!                   char buf[50];
! 
!                   /* TODO: use term_opencmd */
!                   ch_log(NULL, "terminal job finished, opening window");
!                   vim_snprintf(buf, sizeof(buf),
!                           term->tl_opencmd == NULL
!                                   ? "botright sbuf %d"
!                                   : (char *)term->tl_opencmd, fnum);
!                   do_cmdline_cmd((char_u *)buf);
!               }
!               else
!                   ch_log(NULL, "terminal job finished");
            }
  
!           redraw_buf_and_status_later(term->tl_buffer, NOT_VALID);
        }
      if (did_one)
      {
        redraw_statuslines();
--- 2857,2875 ----
            }
  #endif
  
!           if (updating_screen)
            {
!               /* Cannot open or close windows now.  Can happen when
!                * 'lazyredraw' is set. */
!               term->tl_channel_recently_closed = TRUE;
!               continue;
            }
  
!           if (term_after_channel_closed(term))
!               next_term = first_term;
        }
+     }
+ 
      if (did_one)
      {
        redraw_statuslines();
***************
*** 2859,2864 ****
--- 2887,2915 ----
        }
      }
  }
+ 
+ /*
+  * To be called after resetting updating_screen: handle any terminal where the
+  * channel was closed.
+  */
+     void
+ term_check_channel_closed_recently()
+ {
+     term_T *term;
+     term_T *next_term;
+ 
+     for (term = first_term; term != NULL; term = next_term)
+     {
+       next_term = term->tl_next;
+       if (term->tl_channel_recently_closed)
+       {
+           term->tl_channel_recently_closed = FALSE;
+           if (term_after_channel_closed(term))
+               // start over, the list may have changed
+               next_term = first_term;
+       }
+     }
+ }
  
  /*
   * Fill one screen line from a line of the terminal.
*** ../vim-8.0.1814/src/proto/terminal.pro      2018-05-10 18:05:52.541048471 
+0200
--- src/proto/terminal.pro      2018-05-11 21:49:05.006461139 +0200
***************
*** 20,25 ****
--- 20,26 ----
  int terminal_loop(int blocking);
  void term_job_ended(job_T *job);
  void term_channel_closed(channel_T *ch);
+ void term_check_channel_closed_recently(void);
  int term_do_update_window(win_T *wp);
  void term_update_window(win_T *wp);
  int term_is_finished(buf_T *buf);
*** ../vim-8.0.1814/src/screen.c        2018-05-10 15:09:45.893646659 +0200
--- src/screen.c        2018-05-11 21:59:36.538421642 +0200
***************
*** 514,519 ****
--- 514,532 ----
  #endif
  }
  
+     void
+ reset_updating_screen(int may_resize_shell UNUSED)
+ {
+     updating_screen = FALSE;
+ #ifdef FEAT_GUI
+     if (may_resize_shell)
+       gui_may_resize_shell();
+ #endif
+ #ifdef FEAT_TERMINAL
+     term_check_channel_closed_recently();
+ #endif
+ }
+ 
  /*
   * Update all windows that are editing the current buffer.
   */
***************
*** 778,787 ****
      FOR_ALL_WINDOWS(wp)
        wp->w_buffer->b_mod_set = FALSE;
  
!     updating_screen = FALSE;
! #ifdef FEAT_GUI
!     gui_may_resize_shell();
! #endif
  
      /* Clear or redraw the command line.  Done last, because scrolling may
       * mess up the command line. */
--- 791,797 ----
      FOR_ALL_WINDOWS(wp)
        wp->w_buffer->b_mod_set = FALSE;
  
!     reset_updating_screen(TRUE);
  
      /* Clear or redraw the command line.  Done last, because scrolling may
       * mess up the command line. */
***************
*** 861,871 ****
      end_search_hl();
  # endif
  
!     updating_screen = FALSE;
  
  # ifdef FEAT_GUI
-     gui_may_resize_shell();
- 
      /* Redraw the cursor and update the scrollbars when all screen updating is
       * done. */
      if (gui.in_use)
--- 871,879 ----
      end_search_hl();
  # endif
  
!     reset_updating_screen(TRUE);
  
  # ifdef FEAT_GUI
      /* Redraw the cursor and update the scrollbars when all screen updating is
       * done. */
      if (gui.in_use)
*** ../vim-8.0.1814/src/proto/screen.pro        2018-05-10 15:09:45.893646659 
+0200
--- src/proto/screen.pro        2018-05-11 21:59:39.766397331 +0200
***************
*** 9,14 ****
--- 9,15 ----
  int redraw_asap(int type);
  void redraw_after_callback(int call_update_screen);
  void redrawWinline(linenr_T lnum, int invalid);
+ void reset_updating_screen(int may_resize_shell);
  void update_curbuf(int type);
  int update_screen(int type_arg);
  int conceal_cursor_line(win_T *wp);
*** ../vim-8.0.1814/src/ui.c    2018-05-10 15:09:45.893646659 +0200
--- src/ui.c    2018-05-11 21:58:49.282780697 +0200
***************
*** 415,421 ****
  #endif
        mch_breakcheck(force);
  
!     updating_screen = save_us;
  }
  
  /*****************************************************************************
--- 415,424 ----
  #endif
        mch_breakcheck(force);
  
!     if (save_us)
!       updating_screen = save_us;
!     else
!       reset_updating_screen(FALSE);
  }
  
  /*****************************************************************************
*** ../vim-8.0.1814/src/version.c       2018-05-11 20:48:24.803810853 +0200
--- src/version.c       2018-05-11 22:00:25.210057829 +0200
***************
*** 763,764 ****
--- 763,766 ----
  {   /* Add new patch number below this line */
+ /**/
+     1815,
  /**/

-- 
TIM: But follow only if you are men of valour.  For the entrance to this cave
     is guarded by a monster, a creature so foul and cruel that no man yet has
     fought with it and lived.  Bones of full fifty men lie strewn about its
     lair ...
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// 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].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui