Patch 8.0.1797
Problem:    Terminal window is redrawn too often and scrolling is repeated.
Solution:   Don't scroll immediately but only when redrawing.  Avoid redrawing
            the whole terminal window on every change.
Files:      src/terminal.c, src/screen.c, src/proto/terminal.pro


*** ../vim-8.0.1796/src/terminal.c      2018-05-06 13:53:46.374938177 +0200
--- src/terminal.c      2018-05-06 16:38:36.516316098 +0200
***************
*** 42,50 ****
   *   redirection.  Probably in call to channel_set_pipes().
   * - Win32: Redirecting output does not work, Test_terminal_redir_file()
   *   is disabled.
-  * - handle_moverect() scrolls one line at a time.  Postpone scrolling, count
-  *   the number of lines, until a redraw happens.  Then if scrolling many 
lines
-  *   a redraw is faster.
   * - Copy text in the vterm to the Vim buffer once in a while, so that
   *   completion works.
   * - When the job only outputs lines, we could handle resizing the terminal
--- 42,47 ----
***************
*** 137,142 ****
--- 134,141 ----
      int               tl_dirty_row_start; /* MAX_ROW if nothing dirty */
      int               tl_dirty_row_end;   /* row below last one to update */
  
+     int               tl_postponed_scroll;    /* to be scrolled up */
+ 
      garray_T  tl_scrollback;
      int               tl_scrollback_scrolled;
      cellattr_T        tl_default_color;
***************
*** 2373,2416 ****
  
      term->tl_dirty_row_start = MIN(term->tl_dirty_row_start, rect.start_row);
      term->tl_dirty_row_end = MAX(term->tl_dirty_row_end, rect.end_row);
!     redraw_buf_later(term->tl_buffer, NOT_VALID);
      return 1;
  }
  
      static int
  handle_moverect(VTermRect dest, VTermRect src, void *user)
  {
      term_T    *term = (term_T *)user;
  
      /* Scrolling up is done much more efficiently by deleting lines instead of
!      * redrawing the text. */
      if (dest.start_col == src.start_col
            && dest.end_col == src.end_col
            && dest.start_row < src.start_row)
      {
!       win_T       *wp;
!       VTermColor  fg, bg;
!       VTermScreenCellAttrs attr;
!       int         clear_attr;
! 
!       /* Set the color to clear lines with. */
!       vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm),
!                                                                    &fg, &bg);
!       vim_memset(&attr, 0, sizeof(attr));
!       clear_attr = cell2attr(attr, fg, bg);
! 
!       FOR_ALL_WINDOWS(wp)
!       {
!           if (wp->w_buffer == term->tl_buffer)
!               win_del_lines(wp, dest.start_row,
!                                src.start_row - dest.start_row, FALSE, FALSE,
!                                clear_attr);
!       }
      }
  
      term->tl_dirty_row_start = MIN(term->tl_dirty_row_start, dest.start_row);
      term->tl_dirty_row_end = MIN(term->tl_dirty_row_end, dest.end_row);
  
      redraw_buf_later(term->tl_buffer, NOT_VALID);
      return 1;
  }
--- 2372,2426 ----
  
      term->tl_dirty_row_start = MIN(term->tl_dirty_row_start, rect.start_row);
      term->tl_dirty_row_end = MAX(term->tl_dirty_row_end, rect.end_row);
!     redraw_buf_later(term->tl_buffer, SOME_VALID);
      return 1;
  }
  
+     static void
+ term_scroll_up(term_T *term, int start_row, int count)
+ {
+     win_T              *wp;
+     VTermColor                 fg, bg;
+     VTermScreenCellAttrs attr;
+     int                        clear_attr;
+ 
+     /* Set the color to clear lines with. */
+     vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm),
+                                                                    &fg, &bg);
+     vim_memset(&attr, 0, sizeof(attr));
+     clear_attr = cell2attr(attr, fg, bg);
+ 
+     FOR_ALL_WINDOWS(wp)
+     {
+       if (wp->w_buffer == term->tl_buffer)
+           win_del_lines(wp, start_row, count, FALSE, FALSE, clear_attr);
+     }
+ }
+ 
      static int
  handle_moverect(VTermRect dest, VTermRect src, void *user)
  {
      term_T    *term = (term_T *)user;
+     int               count = src.start_row - dest.start_row;
  
      /* Scrolling up is done much more efficiently by deleting lines instead of
!      * redrawing the text. But avoid doing this multiple times, postpone until
!      * the redraw happens. */
      if (dest.start_col == src.start_col
            && dest.end_col == src.end_col
            && dest.start_row < src.start_row)
      {
!       if (dest.start_row == 0)
!           term->tl_postponed_scroll += count;
!       else
!           term_scroll_up(term, dest.start_row, count);
      }
  
      term->tl_dirty_row_start = MIN(term->tl_dirty_row_start, dest.start_row);
      term->tl_dirty_row_end = MIN(term->tl_dirty_row_end, dest.end_row);
  
+     /* Note sure if the scrolling will work correctly, let's do a complete
+      * redraw later. */
      redraw_buf_later(term->tl_buffer, NOT_VALID);
      return 1;
  }
***************
*** 2857,2867 ****
  #endif
  
  /*
!  * Called to update a window that contains an active terminal.
!  * Returns FAIL when there is no terminal running in this window or in
   * Terminal-Normal mode.
   */
      int
  term_update_window(win_T *wp)
  {
      term_T    *term = wp->w_buffer->b_term;
--- 2867,2888 ----
  #endif
  
  /*
!  * Return TRUE if window "wp" is to be redrawn with term_update_window().
!  * Returns FALSE when there is no terminal running in this window or it is in
   * Terminal-Normal mode.
   */
      int
+ term_do_update_window(win_T *wp)
+ {
+     term_T    *term = wp->w_buffer->b_term;
+ 
+     return term != NULL && term->tl_vterm != NULL && !term->tl_normal_mode;
+ }
+ 
+ /*
+  * Called to update a window that contains an active terminal.
+  */
+     void
  term_update_window(win_T *wp)
  {
      term_T    *term = wp->w_buffer->b_term;
***************
*** 2874,2890 ****
      int               minsize;
      win_T     *twp;
  
-     if (term == NULL || term->tl_vterm == NULL || term->tl_normal_mode)
-       return FAIL;
- 
      vterm = term->tl_vterm;
      screen = vterm_obtain_screen(vterm);
      state = vterm_obtain_state(vterm);
  
!     if (wp->w_redr_type >= SOME_VALID)
      {
        term->tl_dirty_row_start = 0;
        term->tl_dirty_row_end = MAX_ROW;
      }
  
      /*
--- 2895,2917 ----
      int               minsize;
      win_T     *twp;
  
      vterm = term->tl_vterm;
      screen = vterm_obtain_screen(vterm);
      state = vterm_obtain_state(vterm);
  
!     /* We use NOT_VALID on a resize or scroll, redraw everything then.  With
!      * SOME_VALID only redraw what was marked dirty. */
!     if (wp->w_redr_type > SOME_VALID)
      {
        term->tl_dirty_row_start = 0;
        term->tl_dirty_row_end = MAX_ROW;
+ 
+       if (term->tl_postponed_scroll > 0
+                             && term->tl_postponed_scroll < term->tl_rows / 3)
+           /* Scrolling is usually faster than redrawing, when there are only
+            * a few lines to scroll. */
+           term_scroll_up(term, 0, term->tl_postponed_scroll);
+       term->tl_postponed_scroll = 0;
      }
  
      /*
***************
*** 2943,2950 ****
      }
      term->tl_dirty_row_start = MAX_ROW;
      term->tl_dirty_row_end = 0;
- 
-     return OK;
  }
  
  /*
--- 2970,2975 ----
*** ../vim-8.0.1796/src/screen.c        2018-04-27 22:53:03.930590711 +0200
--- src/screen.c        2018-05-06 16:30:59.487900163 +0200
***************
*** 567,574 ****
        must_redraw = 0;
      }
  
!     /* Need to update w_lines[]. */
!     if (curwin->w_lines_valid == 0 && type < NOT_VALID)
        type = NOT_VALID;
  
      /* Postpone the redrawing when it's not needed and when being called
--- 567,578 ----
        must_redraw = 0;
      }
  
!     /* May need to update w_lines[]. */
!     if (curwin->w_lines_valid == 0 && type < NOT_VALID
! #ifdef FEAT_TERMINAL
!           && !term_do_update_window(curwin)
! #endif
!               )
        type = NOT_VALID;
  
      /* Postpone the redrawing when it's not needed and when being called
***************
*** 1172,1181 ****
      }
  
  #ifdef FEAT_TERMINAL
!     /* If this window contains a terminal, redraw works completely 
differently.
!      */
!     if (term_update_window(wp) == OK)
      {
  # ifdef FEAT_MENU
        /* Draw the window toolbar, if there is one. */
        if (winbar_height(wp) > 0)
--- 1176,1185 ----
      }
  
  #ifdef FEAT_TERMINAL
!     // If this window contains a terminal, redraw works completely 
differently.
!     if (term_do_update_window(wp))
      {
+       term_update_window(wp);
  # ifdef FEAT_MENU
        /* Draw the window toolbar, if there is one. */
        if (winbar_height(wp) > 0)
*** ../vim-8.0.1796/src/proto/terminal.pro      2018-04-14 17:05:29.787581114 
+0200
--- src/proto/terminal.pro      2018-05-06 16:30:55.115937396 +0200
***************
*** 14,25 ****
  int send_keys_to_term(term_T *term, int c, int typed);
  int terminal_is_active(void);
  cursorentry_T *term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg);
- void term_win_entered(void);
  int term_use_loop(void);
  int terminal_loop(int blocking);
  void term_job_ended(job_T *job);
  void term_channel_closed(channel_T *ch);
! int term_update_window(win_T *wp);
  int term_is_finished(buf_T *buf);
  int term_show_buffer(buf_T *buf);
  void term_change_in_curbuf(void);
--- 14,26 ----
  int send_keys_to_term(term_T *term, int c, int typed);
  int terminal_is_active(void);
  cursorentry_T *term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg);
  int term_use_loop(void);
+ void term_win_entered(void);
  int terminal_loop(int blocking);
  void term_job_ended(job_T *job);
  void term_channel_closed(channel_T *ch);
! int term_do_update_window(win_T *wp);
! void term_update_window(win_T *wp);
  int term_is_finished(buf_T *buf);
  int term_show_buffer(buf_T *buf);
  void term_change_in_curbuf(void);
*** ../vim-8.0.1796/src/version.c       2018-05-06 13:53:46.378938152 +0200
--- src/version.c       2018-05-06 16:39:05.092106787 +0200
***************
*** 763,764 ****
--- 763,766 ----
  {   /* Add new patch number below this line */
+ /**/
+     1797,
  /**/

-- 
I'm sure that I asked CBuilder to do a "full" install.  Looks like I got
a "fool" install, instead.              Charles E Campbell, Jr, PhD


 /// 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