summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-07-28 22:29:35 +0200
committerBram Moolenaar <Bram@vim.org>2017-07-28 22:29:35 +0200
commit63ecddab6d918214371ccaaeb10c118ae7c39d02 (patch)
tree7c5f8f89a456a607c850e0f83db2d57135b1f0b6
parentd85f271bf8516dbd90be4d18f905f0abbfcd6db6 (diff)
patch 8.0.0798: no highlighting in a terminal window with a finished jobv8.0.0798
Problem: No highlighting in a terminal window with a finished job. Solution: Highlight the text.
-rw-r--r--src/proto/terminal.pro3
-rw-r--r--src/screen.c23
-rw-r--r--src/terminal.c69
-rw-r--r--src/undo.c4
-rw-r--r--src/version.c2
5 files changed, 93 insertions, 8 deletions
diff --git a/src/proto/terminal.pro b/src/proto/terminal.pro
index 70e619a5dc..fbc0d1e810 100644
--- a/src/proto/terminal.pro
+++ b/src/proto/terminal.pro
@@ -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 : */
diff --git a/src/screen.c b/src/screen.c
index 7d62042cb7..40f83c0b6f 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -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). */
diff --git a/src/terminal.c b/src/terminal.c
index 9e1a5e23e8..aba3d45690 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -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.
@@ -32,16 +32,17 @@
* 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?
@@ -254,6 +255,19 @@ ex_terminal(exarg_T *eap)
}
/*
+ * 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.
* Called when wiping out a buffer.
@@ -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);
@@ -1218,6 +1229,48 @@ term_update_window(win_T *wp)
}
/*
+ * 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.
*/
static void
diff --git a/src/undo.c b/src/undo.c
index aeca25f009..6ab8572aa0 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -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
/*
diff --git a/src/version.c b/src/version.c
index 119de2c917..db316da653 100644
--- a/src/version.c
+++ b/src/version.c
@@ -770,6 +770,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 798,
+/**/
797,
/**/
796,