diff src/screen.c @ 15314:c4d62945d96f v8.1.0665

patch 8.1.0665: text property display wrong when 'spell' is set commit https://github.com/vim/vim/commit/c6d86dccc4edff8627e309fb23dc8f810ef36b28 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Dec 31 13:57:36 2018 +0100 patch 8.1.0665: text property display wrong when 'spell' is set Problem: Text property display wrong when 'spell' is set. (Dominique Pelle) Solution: Remove unnecessary assignment to char_attr. Combine attributes if needed. Add a screenshot test.
author Bram Moolenaar <Bram@vim.org>
date Mon, 31 Dec 2018 14:00:06 +0100
parents 34a04c9a3575
children 0eed23d9733a
line wrap: on
line diff
--- a/src/screen.c
+++ b/src/screen.c
@@ -3051,6 +3051,38 @@ fill_foldcolumn(
 }
 #endif /* FEAT_FOLDING */
 
+#ifdef FEAT_TEXT_PROP
+static textprop_T	*current_text_props = NULL;
+static buf_T		*current_buf = NULL;
+
+    static int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+text_prop_compare(const void *s1, const void *s2)
+{
+    int  idx1, idx2;
+    proptype_T  *pt1, *pt2;
+    colnr_T col1, col2;
+
+    idx1 = *(int *)s1;
+    idx2 = *(int *)s2;
+    pt1 = text_prop_type_by_id(current_buf, current_text_props[idx1].tp_type);
+    pt2 = text_prop_type_by_id(current_buf, current_text_props[idx2].tp_type);
+    if (pt1 == pt2)
+	return 0;
+    if (pt1 == NULL)
+	return -1;
+    if (pt2 == NULL)
+	return 1;
+    if (pt1->pt_priority != pt2->pt_priority)
+	return pt1->pt_priority > pt2->pt_priority ? 1 : -1;
+    col1 = current_text_props[idx1].tp_col;
+    col2 = current_text_props[idx2].tp_col;
+    return col1 == col2 ? 0 : col1 > col2 ? 1 : -1;
+}
+#endif
+
 /*
  * Display line "lnum" of window 'wp' on the screen.
  * Start at row "startrow", stop when "endrow" is reached.
@@ -4322,34 +4354,32 @@ win_line(
 			   && vcol >= text_props[text_prop_next].tp_col - 1)
 		    text_prop_idxs[text_props_active++] = text_prop_next++;
 
-		text_prop_type = NULL;
+		text_prop_attr = 0;
 		if (text_props_active > 0)
 		{
-		    int max_priority = INT_MIN;
-		    int max_col = 0;
-
-		    // Get the property type with the highest priority
-		    // and/or starting last.
+		    // Sort the properties on priority and/or starting last.
+		    // Then combine the attributes, highest priority last.
+		    current_text_props = text_props;
+		    current_buf = wp->w_buffer;
+		    qsort((void *)text_prop_idxs, (size_t)text_props_active,
+					       sizeof(int), text_prop_compare);
+
 		    for (pi = 0; pi < text_props_active; ++pi)
 		    {
-			int		tpi = text_prop_idxs[pi];
-			proptype_T  *pt;
-
-			pt = text_prop_type_by_id(
-				curwin->w_buffer, text_props[tpi].tp_type);
-			if (pt != NULL
-				&& (pt->pt_priority > max_priority
-				    || (pt->pt_priority == max_priority
-				    && text_props[tpi].tp_col >= max_col)))
+			int	    tpi = text_prop_idxs[pi];
+			proptype_T  *pt = text_prop_type_by_id(wp->w_buffer, text_props[tpi].tp_type);
+
+			if (pt != NULL)
 			{
+			    int pt_attr = syn_id2attr(pt->pt_hl_id);
+
 			    text_prop_type = pt;
-			    max_priority = pt->pt_priority;
-			    max_col = text_props[tpi].tp_col;
+			    if (text_prop_attr == 0)
+				text_prop_attr = pt_attr;
+			    else
+				text_prop_attr = hl_combine_attr(text_prop_attr, pt_attr);
 			}
 		    }
-		    if (text_prop_type != NULL)
-			text_prop_attr =
-				     syn_id2attr(text_prop_type->pt_hl_id);
 		}
 	    }
 #endif
@@ -4775,10 +4805,6 @@ win_line(
 		if (has_spell && v >= word_end && v > cur_checked_col)
 		{
 		    spell_attr = 0;
-# ifdef FEAT_SYN_HL
-		    if (!attr_pri)
-			char_attr = syntax_attr;
-# endif
 		    if (c != 0 && (
 # ifdef FEAT_SYN_HL
 				!has_syntax ||