fix(ui): fix visual and search highlighting interfering with virtual text

vim-patch:9.0.0193: search and match highlgith interfere with virtual text

Problem:    Search and match highlgith interfere with virtual text highlight.
            (Ben Jackson)
Solution:   Check for match highlight after text properties.  Reset and
            restore search highlight when showing virtual text.
            (closes vim/vim#10892)

e38fc86180

vim-patch:9.0.0452: Visual highlighting extends into virtual text prop

Problem:    Visual highlighting extends into virtual text prop.
Solution:   Do not highlight what isn't actually selected.  Fix ordering of
            stored text props.

6eda17d881

Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
Ibby 2023-03-27 01:25:37 +11:00 committed by bfredl
parent e12b5882af
commit c5bf838f8a
2 changed files with 146 additions and 38 deletions

View File

@ -978,7 +978,10 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
bool area_highlighting = false; // Visual or incsearch highlighting in this line
int vi_attr = 0; // attributes for Visual and incsearch highlighting
int area_attr = 0; // attributes desired by highlighting
int saved_area_attr = 0; // idem for area_attr
int search_attr = 0; // attributes desired by 'hlsearch'
int saved_search_attr = 0; // search_attr to be used when n_extra
// goes to zero
int vcol_save_attr = 0; // saved attr for 'cursorcolumn'
int syntax_attr = 0; // attributes desired by syntax
bool has_syntax = false; // this buffer has syntax highl.
@ -1729,6 +1732,50 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
area_active = false;
}
if (has_decor && v >= 0) {
bool selected = (area_active || (area_highlighting && noinvcur
&& wlv.vcol == wp->w_virtcol));
extmark_attr = decor_redraw_col(wp, (colnr_T)v, wlv.off,
selected, &decor_state);
// we could already be inside an existing virt_line with multiple chunks
if (!(virt_inline_i < kv_size(virt_inline))) {
DecorState *state = &decor_state;
for (size_t i = 0; i < kv_size(state->active); i++) {
DecorRange *item = &kv_A(state->active, i);
if (!(item->start_row == state->row
&& kv_size(item->decor.virt_text)
&& item->decor.virt_text_pos == kVTInline)) {
continue;
}
if (item->win_col >= -1 && item->start_col <= v) {
virt_inline = item->decor.virt_text;
virt_inline_i = 0;
item->win_col = -2;
break;
}
}
}
if (wlv.n_extra <= 0 && virt_inline_i < kv_size(virt_inline)) {
VirtTextChunk vtc = kv_A(virt_inline, virt_inline_i);
wlv.p_extra = vtc.text;
wlv.n_extra = (int)strlen(wlv.p_extra);
wlv.c_extra = NUL;
wlv.c_final = NUL;
wlv.extra_attr = vtc.hl_id ? syn_id2attr(vtc.hl_id) : 0;
n_attr = mb_charlen(vtc.text);
// restore search_attr and area_attr when n_extra
// is down to zero
saved_search_attr = search_attr;
saved_area_attr = area_attr;
search_attr = 0;
area_attr = 0;
extmark_attr = 0;
virt_inline_i++;
}
}
if (!wlv.n_extra) {
// Check for start/end of 'hlsearch' and other matches.
// After end, check for start/end of next match.
@ -1792,43 +1839,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
wlv.char_attr = 0;
}
}
if (has_decor && v >= 0) {
bool selected = (area_active || (area_highlighting && noinvcur
&& wlv.vcol == wp->w_virtcol));
extmark_attr = decor_redraw_col(wp, (colnr_T)v, wlv.off, selected, &decor_state);
// we could already be inside an existing virt_line with multiple chunks
if (!(virt_inline_i < kv_size(virt_inline))) {
DecorState *state = &decor_state;
for (size_t i = 0; i < kv_size(state->active); i++) {
DecorRange *item = &kv_A(state->active, i);
if (!(item->start_row == state->row
&& kv_size(item->decor.virt_text)
&& item->decor.virt_text_pos == kVTInline)) {
continue;
}
if (item->win_col >= -1 && item->start_col <= v) {
virt_inline = item->decor.virt_text;
virt_inline_i = 0;
item->win_col = -2;
break;
}
}
}
if (wlv.n_extra <= 0 && virt_inline_i < kv_size(virt_inline)) {
VirtTextChunk vtc = kv_A(virt_inline, virt_inline_i);
wlv.p_extra = vtc.text;
wlv.n_extra = (int)strlen(wlv.p_extra);
wlv.c_extra = NUL;
wlv.c_final = NUL;
wlv.extra_attr = vtc.hl_id ? syn_id2attr(vtc.hl_id) : 0;
n_attr = mb_charlen(vtc.text);
extmark_attr = 0;
virt_inline_i++;
}
}
}
// Get the next character to put on the screen.
@ -1890,6 +1900,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
wlv.p_extra++;
}
wlv.n_extra--;
if (wlv.n_extra <= 0) {
if (search_attr == 0) {
search_attr = saved_search_attr;
}
if (area_attr == 0 && *ptr != NUL) {
area_attr = saved_area_attr;
}
}
} else if (foldinfo.fi_lines > 0) {
// skip writing the buffer line itself
c = NUL;

View File

@ -646,6 +646,8 @@ describe('extmark decorations', function()
[26] = {background=Screen.colors.DarkGrey, foreground=Screen.colors.LightGrey};
[27] = {background = Screen.colors.Plum1};
[28] = {foreground = Screen.colors.SlateBlue};
[29] = {background = Screen.colors.Yellow1};
[30] = {reverse = true};
}
ns = meths.create_namespace 'test'
@ -1582,7 +1584,7 @@ bbbbbbb]])
]]}
end)
it('has correct cursor position with virtual text on an empty line', function()
it('cursor position is correct with virtual text on an empty line', function()
command('set linebreak')
insert('one twoword')
feed('0')
@ -1606,6 +1608,94 @@ bbbbbbb]])
|
]]}
end)
it('search highlight is correct with virtual text attatched to', function()
insert('foo foo foo foo')
feed('0')
meths.buf_set_extmark(0, ns, 0, 8,
{ virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' })
screen:expect { grid = [[
^foo foo {28:virtual text}foo foo |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
|
]]}
feed('/foo')
screen:expect { grid = [[
{29:foo} {30:foo} {28:virtual text}{29:foo} {29:foo} |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
/foo^ |
]]}
end)
it('visual select highlight is correct with virtual text attatched to', function()
insert('foo foo foo foo')
feed('0')
meths.buf_set_extmark(0, ns, 0, 8,
{ virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' })
feed('8l')
screen:expect { grid = [[
foo foo {28:virtual text}^foo foo |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
|
]]}
feed('v')
feed('2h')
screen:expect { grid = [[
foo fo^o{18: }{28:virtual text}{18:f}oo foo |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{24:-- VISUAL --} |
]]}
end)
end)
describe('decorations: virtual lines', function()