Skip to content

Commit 3439028

Browse files
committed
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)
1 parent 27fc8ca commit 3439028

4 files changed

Lines changed: 110 additions & 107 deletions

File tree

src/drawline.c

Lines changed: 75 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ win_line(
307307
#endif
308308
#ifdef FEAT_SPELL
309309
int has_spell = FALSE; // this buffer has spell checking
310+
int can_spell;
310311
# define SPWORDLEN 150
311312
char_u nextline[SPWORDLEN * 2];// text with start of the next line
312313
int nextlinecol = 0; // column where nextline[] starts
@@ -747,6 +748,9 @@ win_line(
747748
win_attr = wcr_attr;
748749
area_highlighting = TRUE;
749750
}
751+
if (vi_attr != 0 && win_attr != 0)
752+
vi_attr = hl_combine_attr(win_attr, vi_attr);
753+
750754
#ifdef FEAT_TEXT_PROP
751755
if (WIN_IS_POPUP(wp))
752756
screen_line_flags |= SLF_POPUP;
@@ -1281,11 +1285,7 @@ win_line(
12811285
break;
12821286
}
12831287

1284-
if (draw_state == WL_LINE && (area_highlighting
1285-
#ifdef FEAT_SPELL
1286-
|| has_spell
1287-
#endif
1288-
))
1288+
if (draw_state == WL_LINE && (area_highlighting || extra_check))
12891289
{
12901290
// handle Visual or match highlighting in this line
12911291
if (vcol == fromcol
@@ -1397,6 +1397,70 @@ win_line(
13971397
}
13981398
#endif
13991399

1400+
if (extra_check)
1401+
{
1402+
#ifdef FEAT_TERMINAL
1403+
if (get_term_attr)
1404+
{
1405+
syntax_attr = term_get_attr(wp->w_buffer, lnum, vcol);
1406+
1407+
if (!attr_pri)
1408+
char_attr = syntax_attr;
1409+
else
1410+
char_attr = hl_combine_attr(syntax_attr, char_attr);
1411+
}
1412+
#endif
1413+
1414+
#ifdef FEAT_SYN_HL
1415+
// Get syntax attribute.
1416+
if (has_syntax)
1417+
{
1418+
// Get the syntax attribute for the character. If there
1419+
// is an error, disable syntax highlighting.
1420+
save_did_emsg = did_emsg;
1421+
did_emsg = FALSE;
1422+
1423+
v = (long)(ptr - line);
1424+
can_spell = TRUE;
1425+
syntax_attr = get_syntax_attr((colnr_T)v,
1426+
# ifdef FEAT_SPELL
1427+
has_spell ? &can_spell :
1428+
# endif
1429+
NULL, FALSE);
1430+
1431+
// combine syntax attribute with 'wincolor'
1432+
if (syntax_attr != 0 && win_attr != 0)
1433+
syntax_attr = hl_combine_attr(win_attr, syntax_attr);
1434+
1435+
if (did_emsg)
1436+
{
1437+
wp->w_s->b_syn_error = TRUE;
1438+
has_syntax = FALSE;
1439+
syntax_attr = 0;
1440+
}
1441+
else
1442+
did_emsg = save_did_emsg;
1443+
# ifdef SYN_TIME_LIMIT
1444+
if (wp->w_s->b_syn_slow)
1445+
has_syntax = FALSE;
1446+
# endif
1447+
1448+
// Need to get the line again, a multi-line regexp may
1449+
// have made it invalid.
1450+
line = ml_get_buf(wp->w_buffer, lnum, FALSE);
1451+
ptr = line + v;
1452+
# ifdef FEAT_CONCEAL
1453+
// no concealing past the end of the line, it interferes
1454+
// with line highlighting
1455+
if (*ptr == NUL)
1456+
syntax_flags = 0;
1457+
else
1458+
syntax_flags = get_syntax_info(&syntax_seqnr);
1459+
# endif
1460+
}
1461+
#endif
1462+
}
1463+
14001464
// Decide which of the highlight attributes to use.
14011465
attr_pri = TRUE;
14021466
#ifdef LINE_ATTR
@@ -1420,7 +1484,12 @@ win_line(
14201484
{
14211485
// Use line_attr when not in the Visual or 'incsearch' area
14221486
// (area_attr may be 0 when "noinvcur" is set).
1423-
char_attr = line_attr;
1487+
# ifdef FEAT_SYN_HL
1488+
if (has_syntax)
1489+
char_attr = hl_combine_attr(syntax_attr, line_attr);
1490+
else
1491+
# endif
1492+
char_attr = line_attr;
14241493
attr_pri = FALSE;
14251494
}
14261495
#else
@@ -1741,99 +1810,6 @@ win_line(
17411810

17421811
if (extra_check)
17431812
{
1744-
#ifdef FEAT_SPELL
1745-
int can_spell = TRUE;
1746-
#endif
1747-
1748-
#ifdef FEAT_TERMINAL
1749-
if (get_term_attr)
1750-
{
1751-
syntax_attr = term_get_attr(wp->w_buffer, lnum, vcol);
1752-
1753-
if (!attr_pri)
1754-
char_attr = syntax_attr;
1755-
else
1756-
char_attr = hl_combine_attr(syntax_attr, char_attr);
1757-
}
1758-
#endif
1759-
1760-
#ifdef FEAT_SYN_HL
1761-
// Get syntax attribute, unless still at the start of the line
1762-
// (double-wide char that doesn't fit).
1763-
v = (long)(ptr - line);
1764-
if (has_syntax && v > 0)
1765-
{
1766-
// Get the syntax attribute for the character. If there
1767-
// is an error, disable syntax highlighting.
1768-
save_did_emsg = did_emsg;
1769-
did_emsg = FALSE;
1770-
1771-
syntax_attr = get_syntax_attr((colnr_T)v - 1,
1772-
# ifdef FEAT_SPELL
1773-
has_spell ? &can_spell :
1774-
# endif
1775-
NULL, FALSE);
1776-
1777-
if (did_emsg)
1778-
{
1779-
wp->w_s->b_syn_error = TRUE;
1780-
has_syntax = FALSE;
1781-
syntax_attr = 0;
1782-
}
1783-
else
1784-
did_emsg = save_did_emsg;
1785-
1786-
// combine syntax attribute with 'wincolor'
1787-
if (win_attr != 0)
1788-
syntax_attr = hl_combine_attr(win_attr, syntax_attr);
1789-
1790-
# ifdef SYN_TIME_LIMIT
1791-
if (wp->w_s->b_syn_slow)
1792-
has_syntax = FALSE;
1793-
# endif
1794-
1795-
// Need to get the line again, a multi-line regexp may
1796-
// have made it invalid.
1797-
line = ml_get_buf(wp->w_buffer, lnum, FALSE);
1798-
ptr = line + v;
1799-
1800-
# ifdef FEAT_TEXT_PROP
1801-
// Text properties overrule syntax highlighting or combine.
1802-
if (text_prop_attr == 0 || text_prop_combine)
1803-
# endif
1804-
{
1805-
int comb_attr = syntax_attr;
1806-
# ifdef FEAT_TEXT_PROP
1807-
comb_attr = hl_combine_attr(text_prop_attr, comb_attr);
1808-
# endif
1809-
if (!attr_pri)
1810-
{
1811-
#ifdef FEAT_SYN_HL
1812-
if (cul_attr)
1813-
char_attr = hl_combine_attr(
1814-
comb_attr, cul_attr);
1815-
else
1816-
#endif
1817-
if (line_attr)
1818-
char_attr = hl_combine_attr(
1819-
comb_attr, line_attr);
1820-
else
1821-
char_attr = comb_attr;
1822-
}
1823-
else
1824-
char_attr = hl_combine_attr(comb_attr, char_attr);
1825-
}
1826-
# ifdef FEAT_CONCEAL
1827-
// no concealing past the end of the line, it interferes
1828-
// with line highlighting
1829-
if (c == NUL)
1830-
syntax_flags = 0;
1831-
else
1832-
syntax_flags = get_syntax_info(&syntax_seqnr);
1833-
# endif
1834-
}
1835-
#endif
1836-
18371813
#ifdef FEAT_SPELL
18381814
// Check spelling (unless at the end of the line).
18391815
// Only do this when there is no syntax highlighting, the
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
>(+0&#40ffff15|a+0#e000e06#ffffff0|b|c|)+0#0000000#40ffff15| +0&#ffffff0@69
2+
|~+0#4040ff13&| @73
3+
|~| @73
4+
|~| @73
5+
|~| @73
6+
| +0#0000000&@56|1|,|1| @10|A|l@1|

src/testdir/test_textprop.vim

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -652,9 +652,10 @@ endfunc
652652

653653
" screenshot test with textprop highlighting
654654
func Test_textprop_screenshot_various()
655+
CheckScreendump
655656
" The Vim running in the terminal needs to use utf-8.
656-
if !CanRunVimInTerminal() || g:orig_encoding != 'utf-8'
657-
throw 'Skipped: cannot make screendumps or not using utf-8'
657+
if g:orig_encoding != 'utf-8'
658+
throw 'Skipped: not using utf-8'
658659
endif
659660
call writefile([
660661
\ "call setline(1, ["
@@ -750,9 +751,7 @@ endfunc
750751

751752
" screenshot test with Visual block mode operations
752753
func Test_textprop_screenshot_visual()
753-
if !CanRunVimInTerminal()
754-
throw 'Skipped: cannot make screendumps'
755-
endif
754+
CheckScreendump
756755

757756
" Delete two columns while text props are three chars wide.
758757
call RunTestVisualBlock(2, '01')
@@ -762,9 +761,7 @@ func Test_textprop_screenshot_visual()
762761
endfunc
763762

764763
func Test_textprop_after_tab()
765-
if !CanRunVimInTerminal()
766-
throw 'Skipped: cannot make screendumps'
767-
endif
764+
CheckScreendump
768765

769766
let lines =<< trim END
770767
call setline(1, [
@@ -785,6 +782,28 @@ func Test_textprop_after_tab()
785782
call delete('XtestPropTab')
786783
endfunc
787784

785+
func Test_textprop_with_syntax()
786+
CheckScreendump
787+
788+
let lines =<< trim END
789+
call setline(1, [
790+
\ "(abc)",
791+
\ ])
792+
syn match csParens "[()]" display
793+
hi! link csParens MatchParen
794+
795+
call prop_type_add('TPTitle', #{ highlight: 'Title' })
796+
call prop_add(1, 2, #{type: 'TPTitle', end_col: 5})
797+
END
798+
call writefile(lines, 'XtestPropSyn')
799+
let buf = RunVimInTerminal('-S XtestPropSyn', {'rows': 6})
800+
call VerifyScreenDump(buf, 'Test_textprop_syn_1', {})
801+
802+
" clean up
803+
call StopVimInTerminal(buf)
804+
call delete('XtestPropSyn')
805+
endfunc
806+
788807
" Adding a text property to a new buffer should not fail
789808
func Test_textprop_empty_buffer()
790809
call prop_type_add('comment', {'highlight': 'Search'})

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,8 @@ static char *(features[]) =
753753

754754
static int included_patches[] =
755755
{ /* Add new patch number below this line */
756+
/**/
757+
2153,
756758
/**/
757759
2152,
758760
/**/

0 commit comments

Comments
 (0)