changeset 12152:69af108df70e v8.0.0956

patch 8.0.0956: scrolling in a terminal window has flicker commit https://github.com/vim/vim/commit/cfce71710b6a2e1fb7f7f27d2a359e4b926f3af9 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Aug 17 20:31:48 2017 +0200 patch 8.0.0956: scrolling in a terminal window has flicker Problem: Scrolling in a terminal hwindow as flicker when the Normal background differs from the terminal window background. Solution: Set the attribute to clear with.
author Christian Brabandt <cb@256bit.org>
date Thu, 17 Aug 2017 20:45:04 +0200
parents dcab6d218e96
children 7264e03147e1
files src/message.c src/move.c src/proto/screen.pro src/screen.c src/terminal.c src/version.c
diffstat 6 files changed, 228 insertions(+), 199 deletions(-) [+]
line wrap: on
line diff
--- a/src/message.c
+++ b/src/message.c
@@ -2313,7 +2313,7 @@ msg_scroll_up(void)
 	gui_undraw_cursor();
 #endif
     /* scrolling up always works */
-    screen_del_lines(0, 0, 1, (int)Rows, TRUE, NULL);
+    screen_del_lines(0, 0, 1, (int)Rows, TRUE, 0, NULL);
 
     if (!can_clear((char_u *)" "))
     {
@@ -2905,7 +2905,7 @@ do_more_prompt(int typed_char)
 		    }
 
 		    if (toscroll == -1 && screen_ins_lines(0, 0, 1,
-						       (int)Rows, NULL) == OK)
+						     (int)Rows, 0, NULL) == OK)
 		    {
 			/* display line at top */
 			(void)disp_sb_line(0, mp);
--- a/src/move.c
+++ b/src/move.c
@@ -1163,7 +1163,7 @@ curs_columns(
 	if (extra > 0)
 	    win_ins_lines(curwin, 0, extra, FALSE, FALSE);
 	else if (extra < 0)
-	    win_del_lines(curwin, 0, -extra, FALSE, FALSE);
+	    win_del_lines(curwin, 0, -extra, FALSE, FALSE, 0);
     }
     else
 	curwin->w_skipcol = 0;
--- a/src/proto/screen.pro
+++ b/src/proto/screen.pro
@@ -45,9 +45,9 @@ void screen_start(void);
 void windgoto(int row, int col);
 void setcursor(void);
 int win_ins_lines(win_T *wp, int row, int line_count, int invalid, int mayclear);
-int win_del_lines(win_T *wp, int row, int line_count, int invalid, int mayclear);
-int screen_ins_lines(int off, int row, int line_count, int end, win_T *wp);
-int screen_del_lines(int off, int row, int line_count, int end, int force, win_T *wp);
+int win_del_lines(win_T *wp, int row, int line_count, int invalid, int mayclear, int clear_attr);
+int screen_ins_lines(int off, int row, int line_count, int end, int clear_attr, win_T *wp);
+int screen_del_lines(int off, int row, int line_count, int end, int force, int attr, win_T *wp);
 int showmode(void);
 void unshowmode(int force);
 void clearmode(void);
--- a/src/screen.c
+++ b/src/screen.c
@@ -151,13 +151,13 @@ static void screen_char(unsigned off, in
 static void screen_char_2(unsigned off, int row, int col);
 #endif
 static void screenclear2(void);
-static void lineclear(unsigned off, int width);
+static void lineclear(unsigned off, int width, int attr);
 static void lineinvalid(unsigned off, int width);
 #ifdef FEAT_WINDOWS
 static void linecopy(int to, int from, win_T *wp);
 static void redraw_block(int row, int end, win_T *wp);
 #endif
-static int win_do_lines(win_T *wp, int row, int line_count, int mayclear, int del);
+static int win_do_lines(win_T *wp, int row, int line_count, int mayclear, int del, int clear_attr);
 static void win_rest_invalid(win_T *wp);
 static void msg_pos_mode(void);
 static void recording_mode(int attr);
@@ -609,7 +609,8 @@ update_screen(int type_arg)
 	else if (type != CLEAR)
 	{
 	    check_for_delay(FALSE);
-	    if (screen_ins_lines(0, 0, msg_scrolled, (int)Rows, NULL) == FAIL)
+	    if (screen_ins_lines(0, 0, msg_scrolled, (int)Rows, 0, NULL)
+								       == FAIL)
 		type = CLEAR;
 	    FOR_ALL_WINDOWS(wp)
 	    {
@@ -1537,7 +1538,8 @@ win_update(win_T *wp)
 		if (row > 0)
 		{
 		    check_for_delay(FALSE);
-		    if (win_del_lines(wp, 0, row, FALSE, wp == firstwin) == OK)
+		    if (win_del_lines(wp, 0, row, FALSE, wp == firstwin, 0)
+									 == OK)
 			bot_start = wp->w_height - row;
 		    else
 			mid_start = 0;		/* redraw all lines */
@@ -2003,7 +2005,7 @@ win_update(win_T *wp)
 			{
 			    check_for_delay(FALSE);
 			    if (win_del_lines(wp, row,
-					    -xtra_rows, FALSE, FALSE) == FAIL)
+					  -xtra_rows, FALSE, FALSE, 0) == FAIL)
 				mod_bot = MAXLNUM;
 			    else
 				bot_start = wp->w_height + xtra_rows;
@@ -6773,7 +6775,7 @@ win_redr_status_matches(
 		 * no room, scroll the screen one line up. */
 		if (cmdline_row == Rows - 1)
 		{
-		    screen_del_lines(0, 0, 1, (int)Rows, TRUE, NULL);
+		    screen_del_lines(0, 0, 1, (int)Rows, TRUE, 0, NULL);
 		    ++msg_scrolled;
 		}
 		else
@@ -9074,7 +9076,7 @@ screenclear2(void)
     /* blank out ScreenLines */
     for (i = 0; i < Rows; ++i)
     {
-	lineclear(LineOffset[i], (int)Columns);
+	lineclear(LineOffset[i], (int)Columns, 0);
 	LineWraps[i] = FALSE;
     }
 
@@ -9114,7 +9116,7 @@ screenclear2(void)
  * Clear one line in ScreenLines.
  */
     static void
-lineclear(unsigned off, int width)
+lineclear(unsigned off, int width, int attr)
 {
     (void)vim_memset(ScreenLines + off, ' ', (size_t)width * sizeof(schar_T));
 #ifdef FEAT_MBYTE
@@ -9122,7 +9124,7 @@ lineclear(unsigned off, int width)
 	(void)vim_memset(ScreenLinesUC + off, 0,
 					  (size_t)width * sizeof(u8char_T));
 #endif
-    (void)vim_memset(ScreenAttrs + off, 0, (size_t)width * sizeof(sattr_T));
+    (void)vim_memset(ScreenAttrs + off, attr, (size_t)width * sizeof(sattr_T));
 }
 
 /*
@@ -9508,7 +9510,7 @@ win_ins_lines(
     if (line_count > wp->w_height - row)
 	line_count = wp->w_height - row;
 
-    retval = win_do_lines(wp, row, line_count, mayclear, FALSE);
+    retval = win_do_lines(wp, row, line_count, mayclear, FALSE, 0);
     if (retval != MAYBE)
 	return retval;
 
@@ -9523,7 +9525,7 @@ win_ins_lines(
     if (wp->w_next != NULL || wp->w_status_height)
     {
 	if (screen_del_lines(0, W_WINROW(wp) + wp->w_height - line_count,
-				    line_count, (int)Rows, FALSE, NULL) == OK)
+				  line_count, (int)Rows, FALSE, 0, NULL) == OK)
 	    did_delete = TRUE;
 	else if (wp->w_next)
 	    return FAIL;
@@ -9547,7 +9549,7 @@ win_ins_lines(
 		  ' ', ' ', 0);
     }
 
-    if (screen_ins_lines(0, W_WINROW(wp) + row, line_count, (int)Rows, NULL)
+    if (screen_ins_lines(0, W_WINROW(wp) + row, line_count, (int)Rows, 0, NULL)
 								      == FAIL)
     {
 	    /* deletion will have messed up other windows */
@@ -9577,7 +9579,8 @@ win_del_lines(
     int		row,
     int		line_count,
     int		invalid,
-    int		mayclear)
+    int		mayclear,
+    int		clear_attr)	    /* for clearing lines */
 {
     int		retval;
 
@@ -9587,12 +9590,12 @@ win_del_lines(
     if (line_count > wp->w_height - row)
 	line_count = wp->w_height - row;
 
-    retval = win_do_lines(wp, row, line_count, mayclear, TRUE);
+    retval = win_do_lines(wp, row, line_count, mayclear, TRUE, clear_attr);
     if (retval != MAYBE)
 	return retval;
 
     if (screen_del_lines(0, W_WINROW(wp) + row, line_count,
-					      (int)Rows, FALSE, NULL) == FAIL)
+				   (int)Rows, FALSE, clear_attr, NULL) == FAIL)
 	return FAIL;
 
 #ifdef FEAT_WINDOWS
@@ -9603,7 +9606,7 @@ win_del_lines(
     if (wp->w_next || wp->w_status_height || cmdline_row < Rows - 1)
     {
 	if (screen_ins_lines(0, W_WINROW(wp) + wp->w_height - line_count,
-					 line_count, (int)Rows, NULL) == FAIL)
+			      line_count, (int)Rows, clear_attr, NULL) == FAIL)
 	{
 	    wp->w_redr_status = TRUE;
 	    win_rest_invalid(wp->w_next);
@@ -9630,7 +9633,8 @@ win_do_lines(
     int		row,
     int		line_count,
     int		mayclear,
-    int		del)
+    int		del,
+    int		clear_attr)
 {
     int		retval;
 
@@ -9694,10 +9698,10 @@ win_do_lines(
 	    scroll_region_set(wp, row);
 	if (del)
 	    retval = screen_del_lines(W_WINROW(wp) + row, 0, line_count,
-					       wp->w_height - row, FALSE, wp);
+				    wp->w_height - row, FALSE, clear_attr, wp);
 	else
 	    retval = screen_ins_lines(W_WINROW(wp) + row, 0, line_count,
-						      wp->w_height - row, wp);
+					   wp->w_height - row, clear_attr, wp);
 #ifdef FEAT_WINDOWS
 	if (scroll_region && (wp->w_width == Columns || *T_CSV != NUL))
 #endif
@@ -9771,6 +9775,7 @@ screen_ins_lines(
     int		row,
     int		line_count,
     int		end,
+    int		clear_attr,
     win_T	*wp)	    /* NULL or window to use width from */
 {
     int		i;
@@ -9851,7 +9856,7 @@ screen_ins_lines(
      */
     if (type == USE_T_CD || type == USE_T_CDL ||
 					 type == USE_T_CE || type == USE_T_DL)
-	return screen_del_lines(off, row, line_count, end, FALSE, wp);
+	return screen_del_lines(off, row, line_count, end, FALSE, 0, wp);
 
     /*
      * If text is retained below the screen, first clear or delete as many
@@ -9859,7 +9864,7 @@ screen_ins_lines(
      * the deleted lines won't later surface during a screen_del_lines.
      */
     if (*T_DB)
-	screen_del_lines(off, end - line_count, line_count, end, FALSE, wp);
+	screen_del_lines(off, end - line_count, line_count, end, FALSE, 0, wp);
 
 #ifdef FEAT_CLIPBOARD
     /* Remove a modeless selection when inserting lines halfway the screen
@@ -9902,7 +9907,8 @@ screen_ins_lines(
 		linecopy(j + line_count, j, wp);
 	    j += line_count;
 	    if (can_clear((char_u *)" "))
-		lineclear(LineOffset[j] + wp->w_wincol, wp->w_width);
+		lineclear(LineOffset[j] + wp->w_wincol, wp->w_width,
+								   clear_attr);
 	    else
 		lineinvalid(LineOffset[j] + wp->w_wincol, wp->w_width);
 	    LineWraps[j] = FALSE;
@@ -9920,7 +9926,7 @@ screen_ins_lines(
 	    LineOffset[j + line_count] = temp;
 	    LineWraps[j + line_count] = FALSE;
 	    if (can_clear((char_u *)" "))
-		lineclear(temp, (int)Columns);
+		lineclear(temp, (int)Columns, clear_attr);
 	    else
 		lineinvalid(temp, (int)Columns);
 	}
@@ -9928,6 +9934,8 @@ screen_ins_lines(
 
     screen_stop_highlight();
     windgoto(cursor_row, 0);
+    if (clear_attr != 0)
+	screen_start_highlight(clear_attr);
 
 #ifdef FEAT_WINDOWS
     /* redraw the characters */
@@ -9993,6 +10001,7 @@ screen_del_lines(
     int		line_count,
     int		end,
     int		force,		/* even when line_count > p_ttyscroll */
+    int		clear_attr,	/* used for clearing lines */
     win_T	*wp UNUSED)	/* NULL or window to use width from */
 {
     int		j;
@@ -10136,7 +10145,8 @@ screen_del_lines(
 		linecopy(j - line_count, j, wp);
 	    j -= line_count;
 	    if (can_clear((char_u *)" "))
-		lineclear(LineOffset[j] + wp->w_wincol, wp->w_width);
+		lineclear(LineOffset[j] + wp->w_wincol, wp->w_width,
+								   clear_attr);
 	    else
 		lineinvalid(LineOffset[j] + wp->w_wincol, wp->w_width);
 	    LineWraps[j] = FALSE;
@@ -10155,13 +10165,16 @@ screen_del_lines(
 	    LineOffset[j - line_count] = temp;
 	    LineWraps[j - line_count] = FALSE;
 	    if (can_clear((char_u *)" "))
-		lineclear(temp, (int)Columns);
+		lineclear(temp, (int)Columns, clear_attr);
 	    else
 		lineinvalid(temp, (int)Columns);
 	}
     }
 
-    screen_stop_highlight();
+    if (screen_attr != clear_attr)
+	screen_stop_highlight();
+    if (clear_attr != 0)
+	screen_start_highlight(clear_attr);
 
 #ifdef FEAT_WINDOWS
     /* redraw the characters */
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -1483,6 +1483,169 @@ may_toggle_cursor(term_T *term)
     }
 }
 
+/*
+ * Reverse engineer the RGB value into a cterm color index.
+ * First color is 1.  Return 0 if no match found.
+ */
+    static int
+color2index(VTermColor *color, int fg, int *boldp)
+{
+    int red = color->red;
+    int blue = color->blue;
+    int green = color->green;
+
+    /* The argument for lookup_color() is for the color_names[] table. */
+    if (red == 0)
+    {
+	if (green == 0)
+	{
+	    if (blue == 0)
+		return lookup_color(0, fg, boldp) + 1; /* black */
+	    if (blue == 224)
+		return lookup_color(1, fg, boldp) + 1; /* dark blue */
+	}
+	else if (green == 224)
+	{
+	    if (blue == 0)
+		return lookup_color(2, fg, boldp) + 1; /* dark green */
+	    if (blue == 224)
+		return lookup_color(3, fg, boldp) + 1; /* dark cyan */
+	}
+    }
+    else if (red == 224)
+    {
+	if (green == 0)
+	{
+	    if (blue == 0)
+		return lookup_color(4, fg, boldp) + 1; /* dark red */
+	    if (blue == 224)
+		return lookup_color(5, fg, boldp) + 1; /* dark magenta */
+	}
+	else if (green == 224)
+	{
+	    if (blue == 0)
+		return lookup_color(6, fg, boldp) + 1; /* dark yellow / brown */
+	    if (blue == 224)
+		return lookup_color(8, fg, boldp) + 1; /* white / light grey */
+	}
+    }
+    else if (red == 128)
+    {
+	if (green == 128 && blue == 128)
+	    return lookup_color(12, fg, boldp) + 1; /* high intensity black / dark grey */
+    }
+    else if (red == 255)
+    {
+	if (green == 64)
+	{
+	    if (blue == 64)
+		return lookup_color(20, fg, boldp) + 1;  /* light red */
+	    if (blue == 255)
+		return lookup_color(22, fg, boldp) + 1;  /* light magenta */
+	}
+	else if (green == 255)
+	{
+	    if (blue == 64)
+		return lookup_color(24, fg, boldp) + 1;  /* yellow */
+	    if (blue == 255)
+		return lookup_color(26, fg, boldp) + 1;  /* white */
+	}
+    }
+    else if (red == 64)
+    {
+	if (green == 64)
+	{
+	    if (blue == 255)
+		return lookup_color(14, fg, boldp) + 1;  /* light blue */
+	}
+	else if (green == 255)
+	{
+	    if (blue == 64)
+		return lookup_color(16, fg, boldp) + 1;  /* light green */
+	    if (blue == 255)
+		return lookup_color(18, fg, boldp) + 1;  /* light cyan */
+	}
+    }
+    if (t_colors >= 256)
+    {
+	if (red == blue && red == green)
+	{
+	    /* 24-color greyscale */
+	    static int cutoff[23] = {
+		0x05, 0x10, 0x1B, 0x26, 0x31, 0x3C, 0x47, 0x52,
+		0x5D, 0x68, 0x73, 0x7F, 0x8A, 0x95, 0xA0, 0xAB,
+		0xB6, 0xC1, 0xCC, 0xD7, 0xE2, 0xED, 0xF9};
+	    int i;
+
+	    for (i = 0; i < 23; ++i)
+		if (red < cutoff[i])
+		    return i + 233;
+	    return 256;
+	}
+
+	/* 216-color cube */
+	return 17 + ((red + 25) / 0x33) * 36
+	          + ((green + 25) / 0x33) * 6
+		  + (blue + 25) / 0x33;
+    }
+    return 0;
+}
+
+/*
+ * Convert the attributes of a vterm cell into an attribute index.
+ */
+    static int
+cell2attr(VTermScreenCellAttrs cellattrs, VTermColor cellfg, VTermColor cellbg)
+{
+    int attr = 0;
+
+    if (cellattrs.bold)
+	attr |= HL_BOLD;
+    if (cellattrs.underline)
+	attr |= HL_UNDERLINE;
+    if (cellattrs.italic)
+	attr |= HL_ITALIC;
+    if (cellattrs.strike)
+	attr |= HL_STANDOUT;
+    if (cellattrs.reverse)
+	attr |= HL_INVERSE;
+
+#ifdef FEAT_GUI
+    if (gui.in_use)
+    {
+	guicolor_T fg, bg;
+
+	fg = gui_mch_get_rgb_color(cellfg.red, cellfg.green, cellfg.blue);
+	bg = gui_mch_get_rgb_color(cellbg.red, cellbg.green, cellbg.blue);
+	return get_gui_attr_idx(attr, fg, bg);
+    }
+    else
+#endif
+#ifdef FEAT_TERMGUICOLORS
+    if (p_tgc)
+    {
+	guicolor_T fg, bg;
+
+	fg = gui_get_rgb_color_cmn(cellfg.red, cellfg.green, cellfg.blue);
+	bg = gui_get_rgb_color_cmn(cellbg.red, cellbg.green, cellbg.blue);
+
+	return get_tgc_attr_idx(attr, fg, bg);
+    }
+    else
+#endif
+    {
+	int bold = MAYBE;
+	int fg = color2index(&cellfg, TRUE, &bold);
+	int bg = color2index(&cellbg, FALSE, &bold);
+
+	/* with 8 colors set the bold attribute to get a bright foreground */
+	if (bold == TRUE)
+	    attr |= HL_BOLD;
+	return get_cterm_attr_idx(attr, fg, bg);
+    }
+    return 0;
+}
+
     static int
 handle_damage(VTermRect rect, void *user)
 {
@@ -1498,18 +1661,32 @@ handle_damage(VTermRect rect, void *user
 handle_moverect(VTermRect dest, VTermRect src, void *user)
 {
     term_T	*term = (term_T *)user;
-    win_T	*wp;
-
+
+    /* 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)
-		/* scrolling up is much more efficient when deleting lines */
 		win_del_lines(wp, dest.start_row,
-				 src.start_row - dest.start_row, FALSE, FALSE);
+				 src.start_row - dest.start_row, FALSE, FALSE,
+				 clear_attr);
 	}
+    }
     redraw_buf_later(term->tl_buffer, NOT_VALID);
     return 1;
 }
@@ -1774,169 +1951,6 @@ term_channel_closed(channel_T *ch)
 }
 
 /*
- * Reverse engineer the RGB value into a cterm color index.
- * First color is 1.  Return 0 if no match found.
- */
-    static int
-color2index(VTermColor *color, int fg, int *boldp)
-{
-    int red = color->red;
-    int blue = color->blue;
-    int green = color->green;
-
-    /* The argument for lookup_color() is for the color_names[] table. */
-    if (red == 0)
-    {
-	if (green == 0)
-	{
-	    if (blue == 0)
-		return lookup_color(0, fg, boldp) + 1; /* black */
-	    if (blue == 224)
-		return lookup_color(1, fg, boldp) + 1; /* dark blue */
-	}
-	else if (green == 224)
-	{
-	    if (blue == 0)
-		return lookup_color(2, fg, boldp) + 1; /* dark green */
-	    if (blue == 224)
-		return lookup_color(3, fg, boldp) + 1; /* dark cyan */
-	}
-    }
-    else if (red == 224)
-    {
-	if (green == 0)
-	{
-	    if (blue == 0)
-		return lookup_color(4, fg, boldp) + 1; /* dark red */
-	    if (blue == 224)
-		return lookup_color(5, fg, boldp) + 1; /* dark magenta */
-	}
-	else if (green == 224)
-	{
-	    if (blue == 0)
-		return lookup_color(6, fg, boldp) + 1; /* dark yellow / brown */
-	    if (blue == 224)
-		return lookup_color(8, fg, boldp) + 1; /* white / light grey */
-	}
-    }
-    else if (red == 128)
-    {
-	if (green == 128 && blue == 128)
-	    return lookup_color(12, fg, boldp) + 1; /* high intensity black / dark grey */
-    }
-    else if (red == 255)
-    {
-	if (green == 64)
-	{
-	    if (blue == 64)
-		return lookup_color(20, fg, boldp) + 1;  /* light red */
-	    if (blue == 255)
-		return lookup_color(22, fg, boldp) + 1;  /* light magenta */
-	}
-	else if (green == 255)
-	{
-	    if (blue == 64)
-		return lookup_color(24, fg, boldp) + 1;  /* yellow */
-	    if (blue == 255)
-		return lookup_color(26, fg, boldp) + 1;  /* white */
-	}
-    }
-    else if (red == 64)
-    {
-	if (green == 64)
-	{
-	    if (blue == 255)
-		return lookup_color(14, fg, boldp) + 1;  /* light blue */
-	}
-	else if (green == 255)
-	{
-	    if (blue == 64)
-		return lookup_color(16, fg, boldp) + 1;  /* light green */
-	    if (blue == 255)
-		return lookup_color(18, fg, boldp) + 1;  /* light cyan */
-	}
-    }
-    if (t_colors >= 256)
-    {
-	if (red == blue && red == green)
-	{
-	    /* 24-color greyscale */
-	    static int cutoff[23] = {
-		0x05, 0x10, 0x1B, 0x26, 0x31, 0x3C, 0x47, 0x52,
-		0x5D, 0x68, 0x73, 0x7F, 0x8A, 0x95, 0xA0, 0xAB,
-		0xB6, 0xC1, 0xCC, 0xD7, 0xE2, 0xED, 0xF9};
-	    int i;
-
-	    for (i = 0; i < 23; ++i)
-		if (red < cutoff[i])
-		    return i + 233;
-	    return 256;
-	}
-
-	/* 216-color cube */
-	return 17 + ((red + 25) / 0x33) * 36
-	          + ((green + 25) / 0x33) * 6
-		  + (blue + 25) / 0x33;
-    }
-    return 0;
-}
-
-/*
- * Convert the attributes of a vterm cell into an attribute index.
- */
-    static int
-cell2attr(VTermScreenCellAttrs cellattrs, VTermColor cellfg, VTermColor cellbg)
-{
-    int attr = 0;
-
-    if (cellattrs.bold)
-	attr |= HL_BOLD;
-    if (cellattrs.underline)
-	attr |= HL_UNDERLINE;
-    if (cellattrs.italic)
-	attr |= HL_ITALIC;
-    if (cellattrs.strike)
-	attr |= HL_STANDOUT;
-    if (cellattrs.reverse)
-	attr |= HL_INVERSE;
-
-#ifdef FEAT_GUI
-    if (gui.in_use)
-    {
-	guicolor_T fg, bg;
-
-	fg = gui_mch_get_rgb_color(cellfg.red, cellfg.green, cellfg.blue);
-	bg = gui_mch_get_rgb_color(cellbg.red, cellbg.green, cellbg.blue);
-	return get_gui_attr_idx(attr, fg, bg);
-    }
-    else
-#endif
-#ifdef FEAT_TERMGUICOLORS
-    if (p_tgc)
-    {
-	guicolor_T fg, bg;
-
-	fg = gui_get_rgb_color_cmn(cellfg.red, cellfg.green, cellfg.blue);
-	bg = gui_get_rgb_color_cmn(cellbg.red, cellbg.green, cellbg.blue);
-
-	return get_tgc_attr_idx(attr, fg, bg);
-    }
-    else
-#endif
-    {
-	int bold = MAYBE;
-	int fg = color2index(&cellfg, TRUE, &bold);
-	int bg = color2index(&cellbg, FALSE, &bold);
-
-	/* with 8 colors set the bold attribute to get a bright foreground */
-	if (bold == TRUE)
-	    attr |= HL_BOLD;
-	return get_cterm_attr_idx(attr, fg, bg);
-    }
-    return 0;
-}
-
-/*
  * 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.
--- 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 */
 /**/
+    956,
+/**/
     955,
 /**/
     954,