diff src/drawline.c @ 18317:d2228d4cf1f6 v8.1.2153

patch 8.1.2153: combining text property and syntax highlight is wrong Commit: https://github.com/vim/vim/commit/3439028c8909aaa71ffe612a7191babdfe07c04c Author: Bram Moolenaar <Bram@vim.org> Date: Wed Oct 16 14:38:26 2019 +0200 patch 8.1.2153: combining text property and syntax highlight is wrong Problem: Combining text property and syntax highlight is wrong. (Nick Jensen) Solution: Compute the syntax highlight attribute much earlier. (closes #5057)
author Bram Moolenaar <Bram@vim.org>
date Wed, 16 Oct 2019 14:45:04 +0200
parents 1f5571e7f012
children 2ffe3309958c
line wrap: on
line diff
--- a/src/drawline.c
+++ b/src/drawline.c
@@ -307,6 +307,7 @@ win_line(
 #endif
 #ifdef FEAT_SPELL
     int		has_spell = FALSE;	// this buffer has spell checking
+    int		can_spell;
 # define SPWORDLEN 150
     char_u	nextline[SPWORDLEN * 2];// text with start of the next line
     int		nextlinecol = 0;	// column where nextline[] starts
@@ -747,6 +748,9 @@ win_line(
 	win_attr = wcr_attr;
 	area_highlighting = TRUE;
     }
+    if (vi_attr != 0 && win_attr != 0)
+	vi_attr = hl_combine_attr(win_attr, vi_attr);
+
 #ifdef FEAT_TEXT_PROP
     if (WIN_IS_POPUP(wp))
 	screen_line_flags |= SLF_POPUP;
@@ -1281,11 +1285,7 @@ win_line(
 	    break;
 	}
 
-	if (draw_state == WL_LINE && (area_highlighting
-#ifdef FEAT_SPELL
-		|| has_spell
-#endif
-	   ))
+	if (draw_state == WL_LINE && (area_highlighting || extra_check))
 	{
 	    // handle Visual or match highlighting in this line
 	    if (vcol == fromcol
@@ -1397,6 +1397,70 @@ win_line(
 	    }
 #endif
 
+	    if (extra_check)
+	    {
+#ifdef FEAT_TERMINAL
+		if (get_term_attr)
+		{
+		    syntax_attr = term_get_attr(wp->w_buffer, lnum, vcol);
+
+		    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.
+		if (has_syntax)
+		{
+		    // Get the syntax attribute for the character.  If there
+		    // is an error, disable syntax highlighting.
+		    save_did_emsg = did_emsg;
+		    did_emsg = FALSE;
+
+		    v = (long)(ptr - line);
+		    can_spell = TRUE;
+		    syntax_attr = get_syntax_attr((colnr_T)v,
+# ifdef FEAT_SPELL
+						has_spell ? &can_spell :
+# endif
+						NULL, FALSE);
+
+		    // combine syntax attribute with 'wincolor'
+		    if (syntax_attr != 0 && win_attr != 0)
+			syntax_attr = hl_combine_attr(win_attr, syntax_attr);
+
+		    if (did_emsg)
+		    {
+			wp->w_s->b_syn_error = TRUE;
+			has_syntax = FALSE;
+			syntax_attr = 0;
+		    }
+		    else
+			did_emsg = save_did_emsg;
+# ifdef SYN_TIME_LIMIT
+		    if (wp->w_s->b_syn_slow)
+			has_syntax = FALSE;
+# endif
+
+		    // Need to get the line again, a multi-line regexp may
+		    // have made it invalid.
+		    line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+		    ptr = line + v;
+# ifdef FEAT_CONCEAL
+		    // no concealing past the end of the line, it interferes
+		    // with line highlighting
+		    if (*ptr == NUL)
+			syntax_flags = 0;
+		    else
+			syntax_flags = get_syntax_info(&syntax_seqnr);
+# endif
+		}
+#endif
+	    }
+
 	    // Decide which of the highlight attributes to use.
 	    attr_pri = TRUE;
 #ifdef LINE_ATTR
@@ -1420,7 +1484,12 @@ win_line(
 	    {
 		// Use line_attr when not in the Visual or 'incsearch' area
 		// (area_attr may be 0 when "noinvcur" is set).
-		char_attr = line_attr;
+# ifdef FEAT_SYN_HL
+		if (has_syntax)
+		    char_attr = hl_combine_attr(syntax_attr, line_attr);
+		else
+# endif
+		    char_attr = line_attr;
 		attr_pri = FALSE;
 	    }
 #else
@@ -1742,99 +1811,6 @@ win_line(
 	    if (extra_check)
 	    {
 #ifdef FEAT_SPELL
-		int	can_spell = TRUE;
-#endif
-
-#ifdef FEAT_TERMINAL
-		if (get_term_attr)
-		{
-		    syntax_attr = term_get_attr(wp->w_buffer, lnum, vcol);
-
-		    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).
-		v = (long)(ptr - line);
-		if (has_syntax && v > 0)
-		{
-		    // Get the syntax attribute for the character.  If there
-		    // is an error, disable syntax highlighting.
-		    save_did_emsg = did_emsg;
-		    did_emsg = FALSE;
-
-		    syntax_attr = get_syntax_attr((colnr_T)v - 1,
-# ifdef FEAT_SPELL
-						has_spell ? &can_spell :
-# endif
-						NULL, FALSE);
-
-		    if (did_emsg)
-		    {
-			wp->w_s->b_syn_error = TRUE;
-			has_syntax = FALSE;
-			syntax_attr = 0;
-		    }
-		    else
-			did_emsg = save_did_emsg;
-
-		    // combine syntax attribute with 'wincolor'
-		    if (win_attr != 0)
-			syntax_attr = hl_combine_attr(win_attr, syntax_attr);
-
-# ifdef SYN_TIME_LIMIT
-		    if (wp->w_s->b_syn_slow)
-			has_syntax = FALSE;
-# endif
-
-		    // Need to get the line again, a multi-line regexp may
-		    // have made it invalid.
-		    line = ml_get_buf(wp->w_buffer, lnum, FALSE);
-		    ptr = line + v;
-
-# ifdef FEAT_TEXT_PROP
-		    // Text properties overrule syntax highlighting or combine.
-		    if (text_prop_attr == 0 || text_prop_combine)
-# endif
-		    {
-			int comb_attr = syntax_attr;
-# ifdef FEAT_TEXT_PROP
-			comb_attr = hl_combine_attr(text_prop_attr, comb_attr);
-# endif
-			if (!attr_pri)
-			{
-#ifdef FEAT_SYN_HL
-			    if (cul_attr)
-				char_attr = hl_combine_attr(
-							  comb_attr, cul_attr);
-			    else
-#endif
-				if (line_attr)
-				char_attr = hl_combine_attr(
-							 comb_attr, line_attr);
-			    else
-				char_attr = comb_attr;
-			}
-			else
-			    char_attr = hl_combine_attr(comb_attr, char_attr);
-		    }
-# ifdef FEAT_CONCEAL
-		    // no concealing past the end of the line, it interferes
-		    // with line highlighting
-		    if (c == NUL)
-			syntax_flags = 0;
-		    else
-			syntax_flags = get_syntax_info(&syntax_seqnr);
-# endif
-		}
-#endif
-
-#ifdef FEAT_SPELL
 		// Check spelling (unless at the end of the line).
 		// Only do this when there is no syntax highlighting, the
 		// @Spell cluster is not used or the current syntax item