forked from aniani/vim
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)
This commit is contained in:
parent
27fc8cab22
commit
3439028c89
174
src/drawline.c
174
src/drawline.c
@ -307,6 +307,7 @@ win_line(
|
|||||||
#endif
|
#endif
|
||||||
#ifdef FEAT_SPELL
|
#ifdef FEAT_SPELL
|
||||||
int has_spell = FALSE; // this buffer has spell checking
|
int has_spell = FALSE; // this buffer has spell checking
|
||||||
|
int can_spell;
|
||||||
# define SPWORDLEN 150
|
# define SPWORDLEN 150
|
||||||
char_u nextline[SPWORDLEN * 2];// text with start of the next line
|
char_u nextline[SPWORDLEN * 2];// text with start of the next line
|
||||||
int nextlinecol = 0; // column where nextline[] starts
|
int nextlinecol = 0; // column where nextline[] starts
|
||||||
@ -747,6 +748,9 @@ win_line(
|
|||||||
win_attr = wcr_attr;
|
win_attr = wcr_attr;
|
||||||
area_highlighting = TRUE;
|
area_highlighting = TRUE;
|
||||||
}
|
}
|
||||||
|
if (vi_attr != 0 && win_attr != 0)
|
||||||
|
vi_attr = hl_combine_attr(win_attr, vi_attr);
|
||||||
|
|
||||||
#ifdef FEAT_TEXT_PROP
|
#ifdef FEAT_TEXT_PROP
|
||||||
if (WIN_IS_POPUP(wp))
|
if (WIN_IS_POPUP(wp))
|
||||||
screen_line_flags |= SLF_POPUP;
|
screen_line_flags |= SLF_POPUP;
|
||||||
@ -1281,11 +1285,7 @@ win_line(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (draw_state == WL_LINE && (area_highlighting
|
if (draw_state == WL_LINE && (area_highlighting || extra_check))
|
||||||
#ifdef FEAT_SPELL
|
|
||||||
|| has_spell
|
|
||||||
#endif
|
|
||||||
))
|
|
||||||
{
|
{
|
||||||
// handle Visual or match highlighting in this line
|
// handle Visual or match highlighting in this line
|
||||||
if (vcol == fromcol
|
if (vcol == fromcol
|
||||||
@ -1397,6 +1397,70 @@ win_line(
|
|||||||
}
|
}
|
||||||
#endif
|
#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.
|
// Decide which of the highlight attributes to use.
|
||||||
attr_pri = TRUE;
|
attr_pri = TRUE;
|
||||||
#ifdef LINE_ATTR
|
#ifdef LINE_ATTR
|
||||||
@ -1420,7 +1484,12 @@ win_line(
|
|||||||
{
|
{
|
||||||
// Use line_attr when not in the Visual or 'incsearch' area
|
// Use line_attr when not in the Visual or 'incsearch' area
|
||||||
// (area_attr may be 0 when "noinvcur" is set).
|
// (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;
|
attr_pri = FALSE;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -1741,99 +1810,6 @@ win_line(
|
|||||||
|
|
||||||
if (extra_check)
|
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
|
#ifdef FEAT_SPELL
|
||||||
// Check spelling (unless at the end of the line).
|
// Check spelling (unless at the end of the line).
|
||||||
// Only do this when there is no syntax highlighting, the
|
// Only do this when there is no syntax highlighting, the
|
||||||
|
6
src/testdir/dumps/Test_textprop_syn_1.dump
Normal file
6
src/testdir/dumps/Test_textprop_syn_1.dump
Normal file
@ -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|
|
@ -652,9 +652,10 @@ endfunc
|
|||||||
|
|
||||||
" screenshot test with textprop highlighting
|
" screenshot test with textprop highlighting
|
||||||
func Test_textprop_screenshot_various()
|
func Test_textprop_screenshot_various()
|
||||||
|
CheckScreendump
|
||||||
" The Vim running in the terminal needs to use utf-8.
|
" The Vim running in the terminal needs to use utf-8.
|
||||||
if !CanRunVimInTerminal() || g:orig_encoding != 'utf-8'
|
if g:orig_encoding != 'utf-8'
|
||||||
throw 'Skipped: cannot make screendumps or not using utf-8'
|
throw 'Skipped: not using utf-8'
|
||||||
endif
|
endif
|
||||||
call writefile([
|
call writefile([
|
||||||
\ "call setline(1, ["
|
\ "call setline(1, ["
|
||||||
@ -750,9 +751,7 @@ endfunc
|
|||||||
|
|
||||||
" screenshot test with Visual block mode operations
|
" screenshot test with Visual block mode operations
|
||||||
func Test_textprop_screenshot_visual()
|
func Test_textprop_screenshot_visual()
|
||||||
if !CanRunVimInTerminal()
|
CheckScreendump
|
||||||
throw 'Skipped: cannot make screendumps'
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Delete two columns while text props are three chars wide.
|
" Delete two columns while text props are three chars wide.
|
||||||
call RunTestVisualBlock(2, '01')
|
call RunTestVisualBlock(2, '01')
|
||||||
@ -762,9 +761,7 @@ func Test_textprop_screenshot_visual()
|
|||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_textprop_after_tab()
|
func Test_textprop_after_tab()
|
||||||
if !CanRunVimInTerminal()
|
CheckScreendump
|
||||||
throw 'Skipped: cannot make screendumps'
|
|
||||||
endif
|
|
||||||
|
|
||||||
let lines =<< trim END
|
let lines =<< trim END
|
||||||
call setline(1, [
|
call setline(1, [
|
||||||
@ -785,6 +782,28 @@ func Test_textprop_after_tab()
|
|||||||
call delete('XtestPropTab')
|
call delete('XtestPropTab')
|
||||||
endfunc
|
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
|
" Adding a text property to a new buffer should not fail
|
||||||
func Test_textprop_empty_buffer()
|
func Test_textprop_empty_buffer()
|
||||||
call prop_type_add('comment', {'highlight': 'Search'})
|
call prop_type_add('comment', {'highlight': 'Search'})
|
||||||
|
@ -753,6 +753,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
2153,
|
||||||
/**/
|
/**/
|
||||||
2152,
|
2152,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user