feat(extmarks): support hl_mode "combine" for inline virt_text (#24099)

This commit is contained in:
zeertzjq 2023-06-22 20:39:35 +08:00 committed by GitHub
parent 134b9ec483
commit f0884f21fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 28 deletions

View File

@ -2630,9 +2630,10 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {*opts})
highlights of the text. Currently only affects virt_text highlights of the text. Currently only affects virt_text
highlights, but might affect `hl_group` in later versions. highlights, but might affect `hl_group` in later versions.
• "replace": only show the virt_text color. This is the • "replace": only show the virt_text color. This is the
default default.
• "combine": combine with background text color • "combine": combine with background text color.
• "blend": blend with background text color. • "blend": blend with background text color. Not supported
for "inline" virt_text.
• virt_lines : virtual lines to add next to this mark This • virt_lines : virtual lines to add next to this mark This
should be an array over lines, where each line in turn is should be an array over lines, where each line in turn is

View File

@ -478,7 +478,7 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e
/// shifting the underlying text. /// shifting the underlying text.
/// - "right_align": display right aligned in the window. /// - "right_align": display right aligned in the window.
/// - "inline": display at the specified column, and /// - "inline": display at the specified column, and
/// shift the buffer text to the right as needed /// shift the buffer text to the right as needed
/// - virt_text_win_col : position the virtual text at a fixed /// - virt_text_win_col : position the virtual text at a fixed
/// window column (starting from the first /// window column (starting from the first
/// text column) /// text column)
@ -490,10 +490,10 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e
/// highlights of the text. Currently only affects /// highlights of the text. Currently only affects
/// virt_text highlights, but might affect `hl_group` /// virt_text highlights, but might affect `hl_group`
/// in later versions. /// in later versions.
/// - "replace": only show the virt_text color. This is the /// - "replace": only show the virt_text color. This is the default.
/// default /// - "combine": combine with background text color.
/// - "combine": combine with background text color
/// - "blend": blend with background text color. /// - "blend": blend with background text color.
/// Not supported for "inline" virt_text.
/// ///
/// - virt_lines : virtual lines to add next to this mark /// - virt_lines : virtual lines to add next to this mark
/// This should be an array over lines, where each line in /// This should be an array over lines, where each line in
@ -730,6 +730,11 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
} else if (strequal("combine", str.data)) { } else if (strequal("combine", str.data)) {
decor.hl_mode = kHlModeCombine; decor.hl_mode = kHlModeCombine;
} else if (strequal("blend", str.data)) { } else if (strequal("blend", str.data)) {
if (decor.virt_text_pos == kVTInline) {
VALIDATE(false, "%s", "cannot use 'blend' hl_mode with inline virtual text", {
goto error;
});
}
decor.hl_mode = kHlModeBlend; decor.hl_mode = kHlModeBlend;
} else { } else {
VALIDATE_S(false, "hl_mode", str.data, { VALIDATE_S(false, "hl_mode", str.data, {

View File

@ -128,6 +128,7 @@ typedef struct {
VirtText virt_inline; VirtText virt_inline;
size_t virt_inline_i; size_t virt_inline_i;
HlMode virt_inline_hl_mode;
bool reset_extra_attr; bool reset_extra_attr;
@ -886,6 +887,7 @@ static void handle_inline_virtual_text(win_T *wp, winlinevars_T *wlv, ptrdiff_t
} }
if (item->draw_col >= -1 && item->start_col == v) { if (item->draw_col >= -1 && item->start_col == v) {
wlv->virt_inline = item->decor.virt_text; wlv->virt_inline = item->decor.virt_text;
wlv->virt_inline_hl_mode = item->decor.hl_mode;
item->draw_col = INT_MIN; item->draw_col = INT_MIN;
break; break;
} }
@ -1798,7 +1800,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
if (!has_fold) { if (!has_fold) {
handle_inline_virtual_text(wp, &wlv, v); handle_inline_virtual_text(wp, &wlv, v);
if (wlv.n_extra > 0) { if (wlv.n_extra > 0 && wlv.virt_inline_hl_mode <= kHlModeReplace) {
// restore search_attr and area_attr when n_extra is down to zero // restore search_attr and area_attr when n_extra is down to zero
// TODO(bfredl): this is ugly as fuck. look if we can do this some other way. // TODO(bfredl): this is ugly as fuck. look if we can do this some other way.
saved_search_attr = search_attr; saved_search_attr = search_attr;

View File

@ -1587,13 +1587,15 @@ describe('decorations: inline virtual text', function()
[9] = {background = Screen.colors.Plum1}; [9] = {background = Screen.colors.Plum1};
[10] = {foreground = Screen.colors.SlateBlue}; [10] = {foreground = Screen.colors.SlateBlue};
[11] = {blend = 30, background = Screen.colors.Red1}; [11] = {blend = 30, background = Screen.colors.Red1};
[12] = {background = Screen.colors.Yellow1}; [12] = {background = Screen.colors.Yellow};
[13] = {reverse = true}; [13] = {reverse = true};
[14] = {foreground = Screen.colors.SlateBlue, background = Screen.colors.LightMagenta}; [14] = {foreground = Screen.colors.SlateBlue, background = Screen.colors.LightMagenta};
[15] = {bold = true, reverse = true}; [15] = {bold = true, reverse = true};
[16] = {foreground = Screen.colors.Red}; [16] = {foreground = Screen.colors.Red};
[17] = {background = Screen.colors.LightGrey, foreground = Screen.colors.DarkBlue}; [17] = {background = Screen.colors.LightGrey, foreground = Screen.colors.DarkBlue};
[18] = {background = Screen.colors.LightGrey, foreground = Screen.colors.Red}; [18] = {background = Screen.colors.LightGrey, foreground = Screen.colors.Red};
[19] = {background = Screen.colors.Yellow, foreground = Screen.colors.SlateBlue};
[20] = {background = Screen.colors.LightGrey, foreground = Screen.colors.SlateBlue};
} }
ns = meths.create_namespace 'test' ns = meths.create_namespace 'test'
@ -2000,13 +2002,15 @@ bbbbbbb]])
end) end)
it('search highlight is correct', function() it('search highlight is correct', function()
insert('foo foo foo foo') insert('foo foo foo foo\nfoo foo foo foo')
feed('0') feed('gg0')
meths.buf_set_extmark(0, ns, 0, 8, meths.buf_set_extmark(0, ns, 0, 9, { virt_text = { { 'AAA', 'Special' } }, virt_text_pos = 'inline' })
{ virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' }) meths.buf_set_extmark(0, ns, 0, 9, { virt_text = { { 'BBB', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' })
meths.buf_set_extmark(0, ns, 1, 9, { virt_text = { { 'CCC', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' })
meths.buf_set_extmark(0, ns, 1, 9, { virt_text = { { 'DDD', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'replace' })
screen:expect { grid = [[ screen:expect { grid = [[
^foo foo {10:virtual text}foo foo | ^foo foo f{10:AAABBB}oo foo |
{1:~ }| foo foo f{10:CCCDDD}oo foo |
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
@ -2019,8 +2023,8 @@ bbbbbbb]])
feed('/foo') feed('/foo')
screen:expect { grid = [[ screen:expect { grid = [[
{12:foo} {13:foo} {10:virtual text}{12:foo} {12:foo} | {12:foo} {13:foo} {12:f}{10:AAA}{19:BBB}{12:oo} {12:foo} |
{1:~ }| {12:foo} {12:foo} {12:f}{19:CCC}{10:DDD}{12:oo} {12:foo} |
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
@ -2033,14 +2037,16 @@ bbbbbbb]])
end) end)
it('visual select highlight is correct', function() it('visual select highlight is correct', function()
insert('foo foo foo foo') insert('foo foo foo foo\nfoo foo foo foo')
feed('0') feed('gg0')
meths.buf_set_extmark(0, ns, 0, 8, meths.buf_set_extmark(0, ns, 0, 8, { virt_text = { { 'AAA', 'Special' } }, virt_text_pos = 'inline' })
{ virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' }) meths.buf_set_extmark(0, ns, 0, 8, { virt_text = { { 'BBB', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' })
meths.buf_set_extmark(0, ns, 1, 8, { virt_text = { { 'CCC', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' })
meths.buf_set_extmark(0, ns, 1, 8, { virt_text = { { 'DDD', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'replace' })
feed('8l') feed('8l')
screen:expect { grid = [[ screen:expect { grid = [[
foo foo {10:virtual text}^foo foo | foo foo {10:AAABBB}^foo foo |
{1:~ }| foo foo {10:CCCDDD}foo foo |
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
@ -2051,10 +2057,11 @@ bbbbbbb]])
| |
]]} ]]}
feed('v') feed('<C-V>')
feed('2h') feed('2hj')
screen:expect { grid = [[ screen:expect { grid = [[
foo fo^o{7: }{10:virtual text}{7:f}oo foo | foo fo{7:o }{10:AAA}{20:BBB}{7:f}oo foo |
foo fo^o{7: }{20:CCC}{10:DDD}{7:f}oo foo |
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
@ -2062,8 +2069,7 @@ bbbbbbb]])
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
{1:~ }| {8:-- VISUAL BLOCK --} |
{8:-- VISUAL --} |
]]} ]]}
end) end)