]> granicus.if.org Git - vim/commitdiff
patch 8.1.2153: combining text property and syntax highlight is wrong v8.1.2153
authorBram Moolenaar <Bram@vim.org>
Wed, 16 Oct 2019 12:38:26 +0000 (14:38 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 16 Oct 2019 12:38:26 +0000 (14:38 +0200)
Problem:    Combining text property and syntax highlight is wrong. (Nick
            Jensen)
Solution:   Compute the syntax highlight attribute much earlier.
            (closes #5057)

src/drawline.c
src/testdir/dumps/Test_textprop_syn_1.dump [new file with mode: 0644]
src/testdir/test_textprop.vim
src/version.c

index ea7764ea6275448dacb0dfef235e802aef501c99..4477b3f0c40bb7f32276ca9d445cfe9c514e8dbe 100644 (file)
@@ -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
@@ -1741,99 +1810,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
diff --git a/src/testdir/dumps/Test_textprop_syn_1.dump b/src/testdir/dumps/Test_textprop_syn_1.dump
new file mode 100644 (file)
index 0000000..6f5aff5
--- /dev/null
@@ -0,0 +1,6 @@
+>(+0&#40ffff15|a+0#e000e06#ffffff0|b|c|)+0#0000000#40ffff15| +0&#ffffff0@69
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|1|,|1| @10|A|l@1| 
index aede59b2d619fb702684bc14136a2532b7b29c4d..54cf5f3c7dede82c6048f919500b60bd14565e28 100644 (file)
@@ -652,9 +652,10 @@ endfunc
 
 " screenshot test with textprop highlighting
 func Test_textprop_screenshot_various()
+  CheckScreendump
   " The Vim running in the terminal needs to use utf-8.
-  if !CanRunVimInTerminal() || g:orig_encoding != 'utf-8'
-    throw 'Skipped: cannot make screendumps or not using utf-8'
+  if g:orig_encoding != 'utf-8'
+    throw 'Skipped: not using utf-8'
   endif
   call writefile([
        \ "call setline(1, ["
@@ -750,9 +751,7 @@ endfunc
 
 " screenshot test with Visual block mode operations
 func Test_textprop_screenshot_visual()
-  if !CanRunVimInTerminal()
-    throw 'Skipped: cannot make screendumps'
-  endif
+  CheckScreendump
 
   " Delete two columns while text props are three chars wide.
   call RunTestVisualBlock(2, '01')
@@ -762,9 +761,7 @@ func Test_textprop_screenshot_visual()
 endfunc
 
 func Test_textprop_after_tab()
-  if !CanRunVimInTerminal()
-    throw 'Skipped: cannot make screendumps'
-  endif
+  CheckScreendump
 
   let lines =<< trim END
        call setline(1, [
@@ -785,6 +782,28 @@ func Test_textprop_after_tab()
   call delete('XtestPropTab')
 endfunc
 
+func Test_textprop_with_syntax()
+  CheckScreendump
+
+  let lines =<< trim END
+       call setline(1, [
+             \ "(abc)",
+             \ ])
+       syn match csParens "[()]" display
+       hi! link csParens MatchParen
+
+       call prop_type_add('TPTitle', #{ highlight: 'Title' })
+       call prop_add(1, 2, #{type: 'TPTitle', end_col: 5})
+  END
+  call writefile(lines, 'XtestPropSyn')
+  let buf = RunVimInTerminal('-S XtestPropSyn', {'rows': 6})
+  call VerifyScreenDump(buf, 'Test_textprop_syn_1', {})
+
+  " clean up
+  call StopVimInTerminal(buf)
+  call delete('XtestPropSyn')
+endfunc
+
 " Adding a text property to a new buffer should not fail
 func Test_textprop_empty_buffer()
   call prop_type_add('comment', {'highlight': 'Search'})
index e21f5c468bc7f7f480cfddafb78127dc68feb93c..33929149dc477a48c0ec3bca3f868a772686a1ca 100644 (file)
@@ -753,6 +753,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2153,
 /**/
     2152,
 /**/