]> granicus.if.org Git - vim/commitdiff
patch 8.0.0798: no highlighting in a terminal window with a finished job v8.0.0798
authorBram Moolenaar <Bram@vim.org>
Fri, 28 Jul 2017 20:29:35 +0000 (22:29 +0200)
committerBram Moolenaar <Bram@vim.org>
Fri, 28 Jul 2017 20:29:35 +0000 (22:29 +0200)
Problem:    No highlighting in a terminal window with a finished job.
Solution:   Highlight the text.

src/proto/terminal.pro
src/screen.c
src/terminal.c
src/undo.c
src/version.c

index 70e619a5dc12e137a75b1e25c9cec857b4cf9fa2..fbc0d1e8102ca3279ebca9ccc7687515c444f2df 100644 (file)
@@ -5,6 +5,9 @@ void write_to_term(buf_T *buffer, char_u *msg, channel_T *channel);
 int terminal_loop(void);
 void term_channel_closed(channel_T *ch);
 int term_update_window(win_T *wp);
+int term_is_finished(buf_T *buf);
+void term_change_in_curbuf(void);
+int term_get_attr(buf_T *buf, linenr_T lnum, int col);
 char_u *term_get_status_text(term_T *term);
 int set_ref_in_term(int copyID);
 /* vim: set ft=c : */
index 7d62042cb763f428a11e32201843a31b1e7eb041..40f83c0b6fdcaa836f43a21222696102752308b0 100644 (file)
@@ -3130,6 +3130,9 @@ win_line(
 #if defined(LINE_ATTR)
     int                did_line_attr = 0;
 #endif
+#ifdef FEAT_TERMINAL
+    int                get_term_attr = FALSE;
+#endif
 
     /* draw_state: items that are drawn in sequence: */
 #define WL_START       0               /* nothing done yet */
@@ -3241,6 +3244,14 @@ win_line(
        draw_color_col = advance_color_col(VCOL_HLC, &color_cols);
 #endif
 
+#ifdef FEAT_TERMINAL
+    if (term_is_finished(wp->w_buffer))
+    {
+       extra_check = TRUE;
+       get_term_attr = TRUE;
+    }
+#endif
+
 #ifdef FEAT_SPELL
     if (wp->w_p_spell
            && *wp->w_s->b_p_spl != NUL
@@ -4527,6 +4538,18 @@ win_line(
                int     can_spell = TRUE;
 #endif
 
+#ifdef FEAT_TERMINAL
+               if (get_term_attr)
+               {
+                   syntax_attr = term_get_attr(wp->w_buffer, lnum, col);
+
+                   if (!attr_pri)
+                       char_attr = syntax_attr;
+                   else
+                       char_attr = hl_combine_attr(syntax_attr, char_attr);
+               }
+#endif
+
 #ifdef FEAT_SYN_HL
                /* Get syntax attribute, unless still at the start of the line
                 * (double-wide char that doesn't fit). */
index 9e1a5e23e8662c858bce917301cebb4bd1723a07..aba3d45690d03cde78d5dbfb1d1bf2caa9083848 100644 (file)
@@ -19,7 +19,7 @@
  *    Uses pseudo-tty's (pty's).
  *
  * For each terminal one VTerm is constructed.  This uses libvterm.  A copy of
- * that library is in the libvterm directory.
+ * this library is in the libvterm directory.
  *
  * When a terminal window is opened, a job is started that will be connected to
  * the terminal emulator.
  * line range is stored in tl_dirty_row_start and tl_dirty_row_end.  Once in a
  * while, if the terminal window is visible, the screen contents is drawn.
  *
+ * When the job ends the text is put in a buffer.  Redrawing then happens from
+ * that buffer, attributes come from the scrollback buffer tl_scrollback.
+ *
  * TODO:
+ * - Patch for functions: Yasuhiro Matsumoto, #1871
  * - For the scrollback buffer store lines in the buffer, only attributes in
  *   tl_scrollback.
  * - When the job ends:
- *   - Display the scrollback buffer (but with attributes).
- *     Make the buffer not modifiable, drop attributes when making changes.
  *   - Need an option or argument to drop the window+buffer right away, to be
  *     used for a shell or Vim.
  * - To set BS correctly, check get_stty(); Pass the fd of the pty.
- * - Patch for functions: Yasuhiro Matsumoto, #1871
  * - do not store terminal buffer in viminfo.  Or prefix term:// ?
  * - add a character in :ls output
  * - when closing window and job has not ended, make terminal hidden?
@@ -253,6 +254,19 @@ ex_terminal(exarg_T *eap)
     /* TODO: Setup pty, see mch_call_shell(). */
 }
 
+/*
+ * Free the scrollback buffer for "term".
+ */
+    static void
+free_scrollback(term_T *term)
+{
+    int i;
+
+    for (i = 0; i < term->tl_scrollback.ga_len; ++i)
+       vim_free(((sb_line_T *)term->tl_scrollback.ga_data + i)->sb_cells);
+    ga_clear(&term->tl_scrollback);
+}
+
 /*
  * Free a terminal and everything it refers to.
  * Kills the job if there is one.
@@ -263,7 +277,6 @@ free_terminal(buf_T *buf)
 {
     term_T     *term = buf->b_term;
     term_T     *tp;
-    int                i;
 
     if (term == NULL)
        return;
@@ -285,9 +298,7 @@ free_terminal(buf_T *buf)
        job_unref(term->tl_job);
     }
 
-    for (i = 0; i < term->tl_scrollback.ga_len; ++i)
-       vim_free(((sb_line_T *)term->tl_scrollback.ga_data + i) ->sb_cells);
-    ga_clear(&term->tl_scrollback);
+    free_scrollback(term);
 
     term_free_vterm(term);
     vim_free(term->tl_title);
@@ -1217,6 +1228,48 @@ term_update_window(win_T *wp)
     return OK;
 }
 
+/*
+ * Return TRUE if "wp" is a terminal window where the job has finished.
+ */
+    int
+term_is_finished(buf_T *buf)
+{
+    return buf->b_term != NULL && buf->b_term->tl_vterm == NULL;
+}
+
+/*
+ * The current buffer is going to be changed.  If there is terminal
+ * highlighting remove it now.
+ */
+    void
+term_change_in_curbuf(void)
+{
+    term_T *term = curbuf->b_term;
+
+    if (term_is_finished(curbuf) && term->tl_scrollback.ga_len > 0)
+    {
+       free_scrollback(term);
+       redraw_buf_later(term->tl_buffer, NOT_VALID);
+    }
+}
+
+/*
+ * Get the screen attribute for a position in the buffer.
+ */
+    int
+term_get_attr(buf_T *buf, linenr_T lnum, int col)
+{
+    term_T *term = buf->b_term;
+    sb_line_T *line;
+
+    if (lnum >= term->tl_scrollback.ga_len)
+       return 0;
+    line = (sb_line_T *)term->tl_scrollback.ga_data + lnum - 1;
+    if (col >= line->sb_cols)
+       return 0;
+    return cell2attr(line->sb_cells + col);
+}
+
 /*
  * Set job options common for Unix and MS-Windows.
  */
index aeca25f009509beb0fa968b03878402dae22b2b0..6ab8572aa03f9856772fcdc5673bfd82af2bd3b5 100644 (file)
@@ -419,6 +419,10 @@ u_savecommon(
            }
        }
 #endif
+#ifdef FEAT_TERMINAL
+       /* A change in a terminal buffer removes the highlighting. */
+       term_change_in_curbuf();
+#endif
 
 #ifdef FEAT_AUTOCMD
        /*
index 119de2c9179b4bc23d214ce1ac2ca2124854aa61..db316da653e633e3673a3236371c10ec46802986 100644 (file)
@@ -769,6 +769,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    798,
 /**/
     797,
 /**/