# HG changeset patch # User Bram Moolenaar # Date 1571229904 -7200 # Node ID d2228d4cf1f60ed6ca1cd311788693748f1f6614 # Parent 6c8a3a02b533e2b17d55f47954e265bf890905af patch 8.1.2153: combining text property and syntax highlight is wrong Commit: https://github.com/vim/vim/commit/3439028c8909aaa71ffe612a7191babdfe07c04c Author: Bram Moolenaar 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) diff --git a/src/drawline.c b/src/drawline.c --- 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 diff --git a/src/testdir/dumps/Test_textprop_syn_1.dump b/src/testdir/dumps/Test_textprop_syn_1.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_textprop_syn_1.dump @@ -0,0 +1,6 @@ +>(+0(ffff15|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| diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -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'}) diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -754,6 +754,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2153, +/**/ 2152, /**/ 2151,