mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
feat(extmark): stack multiple highlight groups in hl_group
This has been possible in the "backend" for a while but API was missing. Followup: we will need a `details2=true` mode for `nvim_get_hl_id_by_name` to return information in a way forward compatible with even further enhancements.
This commit is contained in:
parent
5dd60e01ac
commit
4cced601c8
@ -2660,6 +2660,8 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {opts})
|
||||
and below highlight groups can be supplied either as a
|
||||
string or as an integer, the latter of which can be
|
||||
obtained using |nvim_get_hl_id_by_name()|.
|
||||
Multiple highlight groups can be stacked by passing an
|
||||
array (highest priority last).
|
||||
• hl_eol : when true, for a multiline highlight covering the
|
||||
EOL of a line, continue the highlight for the rest of the
|
||||
screen line (just like for diff and cursorline highlight).
|
||||
|
@ -188,6 +188,7 @@ API
|
||||
• |nvim_echo()| `err` field to print error messages and `chunks` accepts
|
||||
highlight group IDs.
|
||||
• |nvim_open_win()| `relative` field can be set to "laststatus" and "tabline".
|
||||
• |nvim_buf_set_extmark()| `hl_group` field can be an array of layered groups
|
||||
|
||||
DEFAULTS
|
||||
|
||||
|
3
runtime/lua/vim/_meta/api.lua
generated
3
runtime/lua/vim/_meta/api.lua
generated
@ -595,6 +595,9 @@ function vim.api.nvim_buf_line_count(buffer) end
|
||||
--- - hl_group : highlight group used for the text range. This and below
|
||||
--- highlight groups can be supplied either as a string or as an integer,
|
||||
--- the latter of which can be obtained using `nvim_get_hl_id_by_name()`.
|
||||
---
|
||||
--- Multiple highlight groups can be stacked by passing an array (highest
|
||||
--- priority last).
|
||||
--- - hl_eol : when true, for a multiline highlight covering the
|
||||
--- EOL of a line, continue the highlight for the rest
|
||||
--- of the screen line (just like for diff and
|
||||
|
2
runtime/lua/vim/_meta/api_keysets.lua
generated
2
runtime/lua/vim/_meta/api_keysets.lua
generated
@ -241,7 +241,7 @@ error('Cannot require a meta file')
|
||||
--- @field end_line? integer
|
||||
--- @field end_row? integer
|
||||
--- @field end_col? integer
|
||||
--- @field hl_group? integer|string
|
||||
--- @field hl_group? any
|
||||
--- @field virt_text? any[]
|
||||
--- @field virt_text_pos? string
|
||||
--- @field virt_text_win_col? integer
|
||||
|
@ -385,6 +385,9 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e
|
||||
/// - hl_group : highlight group used for the text range. This and below
|
||||
/// highlight groups can be supplied either as a string or as an integer,
|
||||
/// the latter of which can be obtained using |nvim_get_hl_id_by_name()|.
|
||||
///
|
||||
/// Multiple highlight groups can be stacked by passing an array (highest
|
||||
/// priority last).
|
||||
/// - hl_eol : when true, for a multiline highlight covering the
|
||||
/// EOL of a line, continue the highlight for the rest
|
||||
/// of the screen line (just like for diff and
|
||||
@ -499,6 +502,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
|
||||
DecorVirtText virt_lines = DECOR_VIRT_LINES_INIT;
|
||||
char *url = NULL;
|
||||
bool has_hl = false;
|
||||
bool has_hl_multiple = false;
|
||||
|
||||
buf_T *buf = find_buffer_by_handle(buffer, err);
|
||||
if (!buf) {
|
||||
@ -551,8 +555,33 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
|
||||
col2 = (int)val;
|
||||
}
|
||||
|
||||
hl.hl_id = (int)opts->hl_group;
|
||||
has_hl = hl.hl_id > 0;
|
||||
if (HAS_KEY(opts, set_extmark, hl_group)) {
|
||||
if (opts->hl_group.type == kObjectTypeArray) {
|
||||
Array arr = opts->hl_group.data.array;
|
||||
if (arr.size >= 1) {
|
||||
hl.hl_id = object_to_hl_id(arr.items[0], "hl_group item", err);
|
||||
if (ERROR_SET(err)) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
for (size_t i = 1; i < arr.size; i++) {
|
||||
int hl_id = object_to_hl_id(arr.items[i], "hl_group item", err);
|
||||
if (ERROR_SET(err)) {
|
||||
goto error;
|
||||
}
|
||||
if (hl_id) {
|
||||
has_hl_multiple = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
hl.hl_id = object_to_hl_id(opts->hl_group, "hl_group", err);
|
||||
if (ERROR_SET(err)) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
has_hl = hl.hl_id > 0;
|
||||
}
|
||||
|
||||
sign.hl_id = (int)opts->sign_hl_group;
|
||||
sign.cursorline_hl_id = (int)opts->cursorline_hl_group;
|
||||
sign.number_hl_id = (int)opts->number_hl_group;
|
||||
@ -794,6 +823,21 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
|
||||
}
|
||||
}
|
||||
|
||||
if (has_hl_multiple) {
|
||||
Array arr = opts->hl_group.data.array;
|
||||
for (size_t i = arr.size - 1; i > 0; i--) { // skip hl_group[0], handled as hl.hl_id below
|
||||
int hl_id = object_to_hl_id(arr.items[i], "hl_group item", err);
|
||||
if (hl_id > 0) {
|
||||
DecorSignHighlight sh = DECOR_SIGN_HIGHLIGHT_INIT;
|
||||
sh.hl_id = hl_id;
|
||||
sh.flags = opts->hl_eol ? kSHHlEol : 0;
|
||||
sh.next = decor_indexed;
|
||||
decor_indexed = decor_put_sh(sh);
|
||||
decor_flags |= MT_FLAG_DECOR_HL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DecorInline decor = DECOR_INLINE_INIT;
|
||||
if (decor_alloc || decor_indexed != DECOR_ID_INVALID || url != NULL
|
||||
|| schar_high(hl.conceal_char)) {
|
||||
|
@ -29,7 +29,7 @@ typedef struct {
|
||||
Integer end_line;
|
||||
Integer end_row;
|
||||
Integer end_col;
|
||||
HLGroupID hl_group;
|
||||
Object hl_group;
|
||||
Array virt_text;
|
||||
String virt_text_pos;
|
||||
Integer virt_text_win_col;
|
||||
|
@ -834,6 +834,9 @@ describe('extmark decorations', function()
|
||||
[42] = {undercurl = true, special = Screen.colors.Red};
|
||||
[43] = {background = Screen.colors.Yellow, undercurl = true, special = Screen.colors.Red};
|
||||
[44] = {background = Screen.colors.LightMagenta};
|
||||
[45] = { background = Screen.colors.Red, special = Screen.colors.Red, foreground = Screen.colors.Red };
|
||||
[46] = { background = Screen.colors.Blue, foreground = Screen.colors.Blue, special = Screen.colors.Red };
|
||||
[47] = { background = Screen.colors.Green, foreground = Screen.colors.Blue, special = Screen.colors.Red };
|
||||
}
|
||||
|
||||
ns = api.nvim_create_namespace 'test'
|
||||
@ -1924,6 +1927,46 @@ describe('extmark decorations', function()
|
||||
]]}
|
||||
end)
|
||||
|
||||
it('highlight can combine multiple groups', function()
|
||||
screen:try_resize(50, 3)
|
||||
command('hi Group1 guibg=Red guifg=Red guisp=Red')
|
||||
command('hi Group2 guibg=Blue guifg=Blue')
|
||||
command('hi Group3 guibg=Green')
|
||||
insert([[example text]])
|
||||
api.nvim_buf_set_extmark(0, ns, 0, 0, { end_row=1, hl_group = {} })
|
||||
screen:expect([[
|
||||
example tex^t |
|
||||
{1:~ }|
|
||||
|
|
||||
]])
|
||||
|
||||
api.nvim_buf_clear_namespace(0, ns, 0, -1)
|
||||
api.nvim_buf_set_extmark(0, ns, 0, 0, { end_row=1, hl_group = {'Group1'} })
|
||||
screen:expect([[
|
||||
{45:example tex^t} |
|
||||
{1:~ }|
|
||||
|
|
||||
]])
|
||||
api.nvim_buf_clear_namespace(0, ns, 0, -1)
|
||||
api.nvim_buf_set_extmark(0, ns, 0, 0, { end_row = 1, hl_group = {'Group1', 'Group2'} })
|
||||
screen:expect([[
|
||||
{46:example tex^t} |
|
||||
{1:~ }|
|
||||
|
|
||||
]])
|
||||
api.nvim_buf_clear_namespace(0, ns, 0, -1)
|
||||
api.nvim_buf_set_extmark(0, ns, 0, 0, { end_row = 1, hl_group = {'Group1', 'Group2', 'Group3'}, hl_eol=true })
|
||||
screen:expect([[
|
||||
{47:example tex^t }|
|
||||
{1:~ }|
|
||||
|
|
||||
]])
|
||||
|
||||
eq('Invalid hl_group: hl_group item',
|
||||
pcall_err(api.nvim_buf_set_extmark, 0, ns, 0, 0, { end_row = 1, hl_group = {'Group1', 'Group2', {'fail'}}, hl_eol=true }))
|
||||
end)
|
||||
|
||||
|
||||
it('highlight works after TAB with sidescroll #14201', function()
|
||||
screen:try_resize(50, 3)
|
||||
command('set nowrap')
|
||||
|
Loading…
Reference in New Issue
Block a user