Patch 8.0.1810
Problem:    Buffer of a terminal only updated in Terminal-Normal mode.
Solution:   Copy the terminal window content to the buffer when in
            Terminal-Job mode.
Files:      src/terminal.c, src/proto/terminal.pro, src/ex_cmds2.c,
            src/proto/ex_cmds2.pro


*** ../vim-8.0.1809/src/terminal.c      2018-05-07 20:10:08.375909886 +0200
--- src/terminal.c      2018-05-10 18:05:19.925323334 +0200
***************
*** 43,50 ****
   * - Win32: Redirecting output works but includes escape sequences.
   * - Win32: Make terminal used for :!cmd in the GUI work better.  Allow for
   *   redirection.
-  * - 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
   *   better: store lines separated by line breaks, instead of screen lines,
   *   then when the window is resized redraw those lines.
--- 43,48 ----
***************
*** 131,137 ****
      /* Range of screen rows to update.  Zero based. */
      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;
--- 129,139 ----
      /* Range of screen rows to update.  Zero based. */
      int               tl_dirty_row_start; /* MAX_ROW if nothing dirty */
      int               tl_dirty_row_end;   /* row below last one to update */
!     int               tl_dirty_snapshot;  /* text updated after making 
snapshot */
! #ifdef FEAT_TIMERS
!     int               tl_timer_set;
!     proftime_T        tl_timer_due;
! #endif
      int               tl_postponed_scroll;    /* to be scrolled up */
  
      garray_T  tl_scrollback;
***************
*** 1442,1447 ****
--- 1444,1472 ----
  }
  
  /*
+  * Remove the terminal contents from the scrollback and the buffer.
+  * Used before adding a new scrollback line or updating the buffer for lines
+  * displayed in the terminal.
+  */
+     static void
+ cleanup_scrollback(term_T *term)
+ {
+     sb_line_T *line;
+     garray_T  *gap;
+ 
+     gap = &term->tl_scrollback;
+     while (curbuf->b_ml.ml_line_count > term->tl_scrollback_scrolled
+                                                           && gap->ga_len > 0)
+     {
+       ml_delete(curbuf->b_ml.ml_line_count, FALSE);
+       line = (sb_line_T *)gap->ga_data + gap->ga_len - 1;
+       vim_free(line->sb_cells);
+       --gap->ga_len;
+     }
+     check_cursor();
+ }
+ 
+ /*
   * Add the current lines of the terminal to scrollback and to the buffer.
   * Called after the job has ended and when switching to Terminal-Normal mode.
   */
***************
*** 1459,1467 ****
  
      if (term->tl_vterm == NULL)
        return;
      screen = vterm_obtain_screen(term->tl_vterm);
      fill_attr = new_fill_attr = term->tl_default_color;
- 
      for (pos.row = 0; pos.row < term->tl_rows; ++pos.row)
      {
        len = 0;
--- 1484,1505 ----
  
      if (term->tl_vterm == NULL)
        return;
+ 
+     /* Nothing to do if the buffer already has the lines and nothing was
+      * changed. */
+     if (!term->tl_dirty_snapshot
+                 && curbuf->b_ml.ml_line_count > term->tl_scrollback_scrolled)
+       return;
+ 
+     ch_log(term->tl_job == NULL ? NULL : term->tl_job->jv_channel,
+                                 "Adding terminal window snapshot to buffer");
+ 
+     /* First remove the lines that were appended before, they might be
+      * outdated. */
+     cleanup_scrollback(term);
+ 
      screen = vterm_obtain_screen(term->tl_vterm);
      fill_attr = new_fill_attr = term->tl_default_color;
      for (pos.row = 0; pos.row < term->tl_rows; ++pos.row)
      {
        len = 0;
***************
*** 1548,1553 ****
--- 1586,1596 ----
        }
      }
  
+     term->tl_dirty_snapshot = FALSE;
+ #ifdef FEAT_TIMERS
+     term->tl_timer_set = FALSE;
+ #endif
+ 
      /* Obtain the current background color. */
      vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm),
                       &term->tl_default_color.fg, &term->tl_default_color.bg);
***************
*** 1571,1576 ****
--- 1614,1651 ----
      }
  }
  
+ #if defined(FEAT_TIMERS) || defined(PROTO)
+ /*
+  * Check if any terminal timer expired.  If so, copy text from the terminal to
+  * the buffer.
+  * Return the time until the next timer will expire.
+  */
+     int
+ term_check_timers(int next_due_arg, proftime_T *now)
+ {
+     term_T  *term;
+     int           next_due = next_due_arg;
+ 
+     for (term = first_term; term != NULL; term = term->tl_next)
+     {
+       if (term->tl_timer_set && !term->tl_normal_mode)
+       {
+           long    this_due = proftime_time_left(&term->tl_timer_due, now);
+ 
+           if (this_due <= 1)
+           {
+               term->tl_timer_set = FALSE;
+               move_terminal_to_buffer(term);
+           }
+           else if (next_due == -1 || next_due > this_due)
+               next_due = this_due;
+       }
+     }
+ 
+     return next_due;
+ }
+ #endif
+ 
      static void
  set_terminal_mode(term_T *term, int normal_mode)
  {
***************
*** 1638,1657 ****
  term_enter_job_mode()
  {
      term_T    *term = curbuf->b_term;
-     sb_line_T *line;
-     garray_T  *gap;
- 
-     /* Remove the terminal contents from the scrollback and the buffer. */
-     gap = &term->tl_scrollback;
-     while (curbuf->b_ml.ml_line_count > term->tl_scrollback_scrolled
-                                                           && gap->ga_len > 0)
-     {
-       ml_delete(curbuf->b_ml.ml_line_count, FALSE);
-       line = (sb_line_T *)gap->ga_data + gap->ga_len - 1;
-       vim_free(line->sb_cells);
-       --gap->ga_len;
-     }
-     check_cursor();
  
      set_terminal_mode(term, FALSE);
  
--- 1713,1718 ----
***************
*** 2174,2179 ****
--- 2235,2246 ----
      in_terminal_loop = NULL;
      if (restore_cursor)
        prepare_restore_cursor_props();
+ 
+     /* Move a snapshot of the screen contents to the buffer, so that 
completion
+      * works in other buffers. */
+     if (curbuf->b_term != NULL)
+       move_terminal_to_buffer(curbuf->b_term);
+ 
      return ret;
  }
  
***************
*** 2390,2395 ****
--- 2457,2476 ----
      return 0;
  }
  
+     static void
+ set_dirty_snapshot(term_T *term)
+ {
+     term->tl_dirty_snapshot = TRUE;
+ #ifdef FEAT_TIMERS
+     if (!term->tl_normal_mode)
+     {
+       /* Update the snapshot after 100 msec of not getting updates. */
+       profile_setlimit(100L, &term->tl_timer_due);
+       term->tl_timer_set = TRUE;
+     }
+ #endif
+ }
+ 
      static int
  handle_damage(VTermRect rect, void *user)
  {
***************
*** 2397,2402 ****
--- 2478,2484 ----
  
      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);
+     set_dirty_snapshot(term);
      redraw_buf_later(term->tl_buffer, SOME_VALID);
      return 1;
  }
***************
*** 2443,2448 ****
--- 2525,2531 ----
  
      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);
+     set_dirty_snapshot(term);
  
      /* Note sure if the scrolling will work correctly, let's do a complete
       * redraw later. */
***************
*** 2594,2599 ****
--- 2677,2686 ----
  {
      term_T    *term = (term_T *)user;
  
+     /* First remove the lines that were appended before, the pushed line goes
+      * above it. */
+     cleanup_scrollback(term);
+ 
      /* If the number of lines that are stored goes over 'termscrollback' then
       * delete the first 10%. */
      if (term->tl_scrollback.ga_len >= term->tl_buffer->b_p_twsl)
*** ../vim-8.0.1809/src/proto/terminal.pro      2018-05-06 16:40:12.239619606 
+0200
--- src/proto/terminal.pro      2018-05-10 17:41:50.027043157 +0200
***************
*** 9,14 ****
--- 9,15 ----
  int term_job_running(term_T *term);
  int term_none_open(term_T *term);
  int term_try_stop_job(buf_T *buf);
+ int term_check_timers(int next_due_arg, proftime_T *now);
  int term_in_normal_mode(void);
  void term_enter_job_mode(void);
  int send_keys_to_term(term_T *term, int c, int typed);
*** ../vim-8.0.1809/src/ex_cmds2.c      2018-04-29 12:22:49.163522596 +0200
--- src/ex_cmds2.c      2018-05-10 17:43:02.902550999 +0200
***************
*** 1206,1212 ****
  static timer_T        *first_timer = NULL;
  static long   last_timer_id = 0;
  
!     static long
  proftime_time_left(proftime_T *due, proftime_T *now)
  {
  #  ifdef WIN3264
--- 1206,1212 ----
  static timer_T        *first_timer = NULL;
  static long   last_timer_id = 0;
  
!     long
  proftime_time_left(proftime_T *due, proftime_T *now)
  {
  #  ifdef WIN3264
***************
*** 1424,1429 ****
--- 1424,1433 ----
            next_due = this_due;
      }
  #endif
+ #ifdef FEAT_TERMINAL
+     /* Some terminal windows may need their buffer updated. */
+     next_due = term_check_timers(next_due, &now);
+ #endif
  
      return current_id != last_timer_id ? 1 : next_due;
  }
*** ../vim-8.0.1809/src/proto/ex_cmds2.pro      2018-03-29 15:55:30.874510195 
+0200
--- src/proto/ex_cmds2.pro      2018-05-10 17:43:32.950348530 +0200
***************
*** 1,5 ****
  /* ex_cmds2.c */
! int has_watchexpr (void);
  void do_debug(char_u *cmd);
  void ex_debug(exarg_T *eap);
  void dbg_check_breakpoint(exarg_T *eap);
--- 1,5 ----
  /* ex_cmds2.c */
! int has_watchexpr(void);
  void do_debug(char_u *cmd);
  void ex_debug(exarg_T *eap);
  void dbg_check_breakpoint(exarg_T *eap);
***************
*** 19,24 ****
--- 19,25 ----
  void profile_setlimit(long msec, proftime_T *tm);
  int profile_passed_limit(proftime_T *tm);
  void profile_zero(proftime_T *tm);
+ long proftime_time_left(proftime_T *due, proftime_T *now);
  timer_T *create_timer(long msec, int repeat);
  long check_due_timer(void);
  timer_T *find_timer(long id);
*** ../vim-8.0.1809/src/version.c       2018-05-10 15:09:45.893646659 +0200
--- src/version.c       2018-05-10 18:01:04.163352696 +0200
***************
*** 763,764 ****
--- 763,766 ----
  {   /* Add new patch number below this line */
+ /**/
+     1810,
  /**/

-- 
When I look deep into your eyes, I see JPEG artifacts.
I can tell by the pixels that we're wrong for each other.  (xkcd)

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