mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 01:34:25 +00:00 
			
		
		
		
	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:
		@@ -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
 | 
			
		||||
        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()*
 | 
			
		||||
    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,
 | 
			
		||||
        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: ~
 | 
			
		||||
      • {ns_id}  Namespace id for this highlight |nvim_create_namespace()|.
 | 
			
		||||
                 Use 0 to set a highlight group globally |:highlight|.
 | 
			
		||||
 
 | 
			
		||||
@@ -95,6 +95,9 @@ Integer nvim_get_hl_id_by_name(String name)
 | 
			
		||||
/// @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()|,
 | 
			
		||||
///                   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)
 | 
			
		||||
  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,
 | 
			
		||||
///       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()|.
 | 
			
		||||
///              Use 0 to set a highlight group globally |:highlight|.
 | 
			
		||||
///              Highlights from non-global namespaces are not active by default, use
 | 
			
		||||
 
 | 
			
		||||
@@ -797,9 +797,9 @@ void set_hl_group(int id, HlAttrs attrs, Dict(highlight) *dict, int link_id)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  HlGroup *g = &hl_table[idx];
 | 
			
		||||
  g->sg_cleared = false;
 | 
			
		||||
 | 
			
		||||
  if (link_id > 0) {
 | 
			
		||||
    g->sg_cleared = false;
 | 
			
		||||
    g->sg_link = link_id;
 | 
			
		||||
    g->sg_script_ctx = current_sctx;
 | 
			
		||||
    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.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_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) {
 | 
			
		||||
    redraw_all_later(UPD_NOT_VALID);
 | 
			
		||||
  }
 | 
			
		||||
@@ -1533,17 +1531,15 @@ static bool hlgroup2dict(Dictionary *hl, NS ns_id, int hl_id, Arena *arena)
 | 
			
		||||
  }
 | 
			
		||||
  HlAttrs attr =
 | 
			
		||||
    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) {
 | 
			
		||||
    *hl = arena_dict(arena, 1);
 | 
			
		||||
    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);
 | 
			
		||||
    hlattrs2dict(hl, NULL, attr, true, true);
 | 
			
		||||
    hlattrs2dict(hl, &hl_cterm, attr, false, true);
 | 
			
		||||
    if (kv_size(hl_cterm)) {
 | 
			
		||||
      PUT_C(*hl, "cterm", DICTIONARY_OBJ(hl_cterm));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  Dictionary hl_cterm = arena_dict(arena, HLATTRS_DICT_SIZE);
 | 
			
		||||
  hlattrs2dict(hl, NULL, attr, true, true);
 | 
			
		||||
  hlattrs2dict(hl, &hl_cterm, attr, false, true);
 | 
			
		||||
  if (kv_size(hl_cterm)) {
 | 
			
		||||
    PUT_C(*hl, "cterm", DICTIONARY_OBJ(hl_cterm));
 | 
			
		||||
  }
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -561,4 +561,18 @@ describe('API: get highlight', function()
 | 
			
		||||
    eq({ link = 'String' }, meths.get_hl(0, { name = '@string' }))
 | 
			
		||||
    eq({ fg = 10937249 }, meths.get_hl(0, { name = '@string.cpp', link = false }))
 | 
			
		||||
  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)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user