fix(api): return both link and attributes with nvim_get_hl (#22824)

Problem: No way to get the actual highlight attributes for a linked
group through |nvim_get_hl()| (not the attributes from the link target).
Solution: Return the actual attributes as well as the link target name.
This commit is contained in:
Sindre T. Strøm
2023-03-31 12:52:53 +02:00
committed by GitHub
parent ed10e4ef60
commit b34097fe6d
4 changed files with 39 additions and 14 deletions

View File

@@ -941,6 +941,10 @@ nvim_get_hl({ns_id}, {*opts}) *nvim_get_hl()*
map as in |nvim_set_hl()|, or only a single highlight definition map map as in |nvim_set_hl()|, or only a single highlight definition map
if requested by name or id. if requested by name or id.
Note:
When the `link` attribute is defined in the highlight definition map,
other attributes will not be taking effect (see |:hi-link|).
nvim_get_hl_id_by_name({name}) *nvim_get_hl_id_by_name()* nvim_get_hl_id_by_name({name}) *nvim_get_hl_id_by_name()*
Gets a highlight group by name Gets a highlight group by name
@@ -1388,6 +1392,10 @@ nvim_set_hl({ns_id}, {name}, {*val}) *nvim_set_hl()*
values of the Normal group. If the Normal group has not been defined, values of the Normal group. If the Normal group has not been defined,
using these values results in an error. using these values results in an error.
Note:
If `link` is used in combination with other attributes; only the
`link` will take effect (see |:hi-link|).
Parameters: ~ Parameters: ~
• {ns_id} Namespace id for this highlight |nvim_create_namespace()|. • {ns_id} Namespace id for this highlight |nvim_create_namespace()|.
Use 0 to set a highlight group globally |:highlight|. Use 0 to set a highlight group globally |:highlight|.

View File

@@ -95,6 +95,9 @@ Integer nvim_get_hl_id_by_name(String name)
/// @param[out] err Error details, if any. /// @param[out] err Error details, if any.
/// @return Highlight groups as a map from group name to a highlight definition map as in |nvim_set_hl()|, /// @return Highlight groups as a map from group name to a highlight definition map as in |nvim_set_hl()|,
/// or only a single highlight definition map if requested by name or id. /// or only a single highlight definition map if requested by name or id.
///
/// @note When the `link` attribute is defined in the highlight definition
/// map, other attributes will not be taking effect (see |:hi-link|).
Dictionary nvim_get_hl(Integer ns_id, Dict(get_highlight) *opts, Arena *arena, Error *err) Dictionary nvim_get_hl(Integer ns_id, Dict(get_highlight) *opts, Arena *arena, Error *err)
FUNC_API_SINCE(11) FUNC_API_SINCE(11)
{ {
@@ -113,6 +116,10 @@ Dictionary nvim_get_hl(Integer ns_id, Dict(get_highlight) *opts, Arena *arena, E
/// values of the Normal group. If the Normal group has not been defined, /// values of the Normal group. If the Normal group has not been defined,
/// using these values results in an error. /// using these values results in an error.
/// ///
///
/// @note If `link` is used in combination with other attributes; only the
/// `link` will take effect (see |:hi-link|).
///
/// @param ns_id Namespace id for this highlight |nvim_create_namespace()|. /// @param ns_id Namespace id for this highlight |nvim_create_namespace()|.
/// Use 0 to set a highlight group globally |:highlight|. /// Use 0 to set a highlight group globally |:highlight|.
/// Highlights from non-global namespaces are not active by default, use /// Highlights from non-global namespaces are not active by default, use

View File

@@ -797,9 +797,9 @@ void set_hl_group(int id, HlAttrs attrs, Dict(highlight) *dict, int link_id)
} }
HlGroup *g = &hl_table[idx]; HlGroup *g = &hl_table[idx];
g->sg_cleared = false;
if (link_id > 0) { if (link_id > 0) {
g->sg_cleared = false;
g->sg_link = link_id; g->sg_link = link_id;
g->sg_script_ctx = current_sctx; g->sg_script_ctx = current_sctx;
g->sg_script_ctx.sc_lnum += SOURCING_LNUM; g->sg_script_ctx.sc_lnum += SOURCING_LNUM;
@@ -809,11 +809,10 @@ void set_hl_group(int id, HlAttrs attrs, Dict(highlight) *dict, int link_id)
g->sg_deflink_sctx = current_sctx; g->sg_deflink_sctx = current_sctx;
g->sg_deflink_sctx.sc_lnum += SOURCING_LNUM; g->sg_deflink_sctx.sc_lnum += SOURCING_LNUM;
} }
goto update; } else {
g->sg_link = 0;
} }
g->sg_cleared = false;
g->sg_link = 0;
g->sg_gui = attrs.rgb_ae_attr; g->sg_gui = attrs.rgb_ae_attr;
g->sg_rgb_fg = attrs.rgb_fg_color; g->sg_rgb_fg = attrs.rgb_fg_color;
@@ -865,7 +864,6 @@ void set_hl_group(int id, HlAttrs attrs, Dict(highlight) *dict, int link_id)
} }
} }
update:
if (!updating_screen) { if (!updating_screen) {
redraw_all_later(UPD_NOT_VALID); redraw_all_later(UPD_NOT_VALID);
} }
@@ -1533,18 +1531,16 @@ static bool hlgroup2dict(Dictionary *hl, NS ns_id, int hl_id, Arena *arena)
} }
HlAttrs attr = HlAttrs attr =
syn_attr2entry(ns_id == 0 ? sgp->sg_attr : ns_get_hl(&ns_id, hl_id, false, sgp->sg_set)); syn_attr2entry(ns_id == 0 ? sgp->sg_attr : ns_get_hl(&ns_id, hl_id, false, sgp->sg_set));
*hl = arena_dict(arena, HLATTRS_DICT_SIZE + 1);
if (link > 0) { if (link > 0) {
*hl = arena_dict(arena, 1);
PUT_C(*hl, "link", STRING_OBJ(cstr_as_string(hl_table[link - 1].sg_name))); PUT_C(*hl, "link", STRING_OBJ(cstr_as_string(hl_table[link - 1].sg_name)));
} else { }
*hl = arena_dict(arena, HLATTRS_DICT_SIZE);
Dictionary hl_cterm = arena_dict(arena, HLATTRS_DICT_SIZE); Dictionary hl_cterm = arena_dict(arena, HLATTRS_DICT_SIZE);
hlattrs2dict(hl, NULL, attr, true, true); hlattrs2dict(hl, NULL, attr, true, true);
hlattrs2dict(hl, &hl_cterm, attr, false, true); hlattrs2dict(hl, &hl_cterm, attr, false, true);
if (kv_size(hl_cterm)) { if (kv_size(hl_cterm)) {
PUT_C(*hl, "cterm", DICTIONARY_OBJ(hl_cterm)); PUT_C(*hl, "cterm", DICTIONARY_OBJ(hl_cterm));
} }
}
return true; return true;
} }

View File

@@ -561,4 +561,18 @@ describe('API: get highlight', function()
eq({ link = 'String' }, meths.get_hl(0, { name = '@string' })) eq({ link = 'String' }, meths.get_hl(0, { name = '@string' }))
eq({ fg = 10937249 }, meths.get_hl(0, { name = '@string.cpp', link = false })) eq({ fg = 10937249 }, meths.get_hl(0, { name = '@string.cpp', link = false }))
end) end)
it('can get all attributes for a linked group', function()
command('hi Bar guifg=red')
command('hi Foo guifg=#00ff00 gui=bold,underline')
command('hi! link Foo Bar')
eq({ link = 'Bar', fg = tonumber('00ff00', 16), bold = true, underline = true }, meths.get_hl(0, { name = 'Foo', link = true }))
end)
it('can set link as well as other attributes', function()
command('hi Bar guifg=red')
local hl = { link = 'Bar', fg = tonumber('00ff00', 16), bold = true, cterm = { bold = true } }
meths.set_hl(0, 'Foo', hl)
eq(hl, meths.get_hl(0, { name = 'Foo', link = true }))
end)
end) end)