mirror of
https://github.com/neovim/neovim.git
synced 2026-04-18 05:20:40 +00:00
feat(api): nvim_set_hl can set "font" #37668
Problem: Cannot set highlight group fonts via API, only via :highlight command. Solution: Add font parameter in nvim_set_hl().
This commit is contained in:
@@ -1575,6 +1575,8 @@ nvim_set_hl({ns_id}, {name}, {val}) *nvim_set_hl()*
|
||||
• fg: color name or "#RRGGBB", see note.
|
||||
• fg_indexed: boolean (default false) If true, fg is a
|
||||
terminal palette index (0-255).
|
||||
• font: GUI font name (string). Sets |highlight-font|. Use
|
||||
"NONE" to clear.
|
||||
• force: if true force update the highlight group when it
|
||||
exists.
|
||||
• italic: boolean
|
||||
|
||||
@@ -106,7 +106,9 @@ The following new features were added.
|
||||
|
||||
API
|
||||
|
||||
• todo
|
||||
• |vim.lsp.buf.declaration()|, |vim.lsp.buf.definition()|, |vim.lsp.buf.definition()|,
|
||||
and |vim.lsp.buf.implementation()| now follows 'switchbuf'.
|
||||
• |nvim_set_hl()| supports "font" key.
|
||||
|
||||
BUILD
|
||||
|
||||
|
||||
1
runtime/lua/vim/_meta/api.lua
generated
1
runtime/lua/vim/_meta/api.lua
generated
@@ -2240,6 +2240,7 @@ function vim.api.nvim_set_decoration_provider(ns_id, opts) end
|
||||
--- - dim: boolean
|
||||
--- - fg: color name or "#RRGGBB", see note.
|
||||
--- - fg_indexed: boolean (default false) If true, fg is a terminal palette index (0-255).
|
||||
--- - font: GUI font name (string). Sets `highlight-font`. Use "NONE" to clear.
|
||||
--- - force: if true force update the highlight group when it exists.
|
||||
--- - italic: boolean
|
||||
--- - link: Name of highlight group to link to. `:hi-link`
|
||||
|
||||
1
runtime/lua/vim/_meta/api_keysets.lua
generated
1
runtime/lua/vim/_meta/api_keysets.lua
generated
@@ -337,6 +337,7 @@ error('Cannot require a meta file')
|
||||
--- @field force? boolean
|
||||
--- @field update? boolean
|
||||
--- @field url? string
|
||||
--- @field font? string
|
||||
|
||||
--- @class vim.api.keyset.highlight_cterm
|
||||
--- @field bold? boolean
|
||||
|
||||
@@ -208,6 +208,7 @@ typedef struct {
|
||||
Boolean force;
|
||||
Boolean update;
|
||||
String url;
|
||||
String font;
|
||||
} Dict(highlight);
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -156,6 +156,7 @@ DictAs(get_hl_info) nvim_get_hl(Integer ns_id, Dict(get_highlight) *opts, Arena
|
||||
/// - dim: boolean
|
||||
/// - fg: color name or "#RRGGBB", see note.
|
||||
/// - fg_indexed: boolean (default false) If true, fg is a terminal palette index (0-255).
|
||||
/// - font: GUI font name (string). Sets |highlight-font|. Use "NONE" to clear.
|
||||
/// - force: if true force update the highlight group when it exists.
|
||||
/// - italic: boolean
|
||||
/// - link: Name of highlight group to link to. |:hi-link|
|
||||
|
||||
@@ -41,6 +41,8 @@ static Map(uint64_t, int) combine_attr_entries = MAP_INIT;
|
||||
static Map(uint64_t, int) blend_attr_entries = MAP_INIT;
|
||||
static Map(uint64_t, int) blendthrough_attr_entries = MAP_INIT;
|
||||
static Set(cstr_t) urls = SET_INIT;
|
||||
/// Interned font names, referenced by index in HlAttrs.font.
|
||||
static Set(cstr_t) fonts = SET_INIT;
|
||||
|
||||
#define attr_entry(i) attr_entries.keys[i]
|
||||
|
||||
@@ -536,6 +538,37 @@ const char *hl_get_url(uint32_t index)
|
||||
return urls.keys[index];
|
||||
}
|
||||
|
||||
// Intern a font name and return its stable index for use in HlAttrs.font.
|
||||
///
|
||||
/// @param font_name The font name to add
|
||||
/// @return Font index, or -1 if font_name is NULL or empty
|
||||
int32_t hl_add_font_idx(const char *font_name)
|
||||
{
|
||||
if (font_name == NULL || *font_name == '\0') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
MHPutStatus status;
|
||||
uint32_t k = set_put_idx(cstr_t, &fonts, font_name, &status);
|
||||
if (status != kMHExisting) {
|
||||
fonts.keys[k] = xstrdup(font_name);
|
||||
}
|
||||
|
||||
return (int32_t)k;
|
||||
}
|
||||
|
||||
/// Get a font name by its index.
|
||||
///
|
||||
/// @param index Font index
|
||||
/// @return Font name, or NULL if index is invalid
|
||||
const char *hl_get_font(int32_t index)
|
||||
{
|
||||
if (index < 0 || !fonts.keys) {
|
||||
return NULL;
|
||||
}
|
||||
return fonts.keys[index];
|
||||
}
|
||||
|
||||
/// Get attribute code for forwarded :terminal highlights.
|
||||
int hl_get_term_attr(HlAttrs *aep)
|
||||
{
|
||||
@@ -551,6 +584,11 @@ void clear_hl_tables(bool reinit)
|
||||
xfree((void *)url);
|
||||
});
|
||||
|
||||
const char *font = NULL;
|
||||
set_foreach(&fonts, font, {
|
||||
xfree((void *)font);
|
||||
});
|
||||
|
||||
if (reinit) {
|
||||
set_clear(HlEntry, &attr_entries);
|
||||
highlight_init();
|
||||
@@ -558,6 +596,7 @@ void clear_hl_tables(bool reinit)
|
||||
map_clear(uint64_t, &blend_attr_entries);
|
||||
map_clear(uint64_t, &blendthrough_attr_entries);
|
||||
set_clear(cstr_t, &urls);
|
||||
set_clear(cstr_t, &fonts);
|
||||
memset(highlight_attr_last, -1, sizeof(highlight_attr_last));
|
||||
highlight_attr_set_all();
|
||||
highlight_changed();
|
||||
@@ -569,6 +608,7 @@ void clear_hl_tables(bool reinit)
|
||||
map_destroy(uint64_t, &blendthrough_attr_entries);
|
||||
map_destroy(ColorKey, &ns_hls);
|
||||
set_destroy(cstr_t, &urls);
|
||||
set_destroy(cstr_t, &fonts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1021,6 +1061,10 @@ void hlattrs2dict(Dict *hl, Dict *hl_attrs, HlAttrs ae, bool use_rgb, bool short
|
||||
if (ae.hl_blend > -1 && (use_rgb || !short_keys)) {
|
||||
PUT_C(*hl, "blend", INTEGER_OBJ(ae.hl_blend));
|
||||
}
|
||||
const char *font = hl_get_font(ae.font);
|
||||
if (font != NULL) {
|
||||
PUT_C(*hl, "font", STRING_OBJ(cstr_as_string(font)));
|
||||
}
|
||||
}
|
||||
|
||||
HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, HlAttrs *base, Error *err)
|
||||
@@ -1195,6 +1239,13 @@ HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, HlAttrs
|
||||
hlattrs.cterm_ae_attr = mask;
|
||||
}
|
||||
|
||||
if (HAS_KEY_X(dict, font)) {
|
||||
String str = dict->font;
|
||||
if (str.size > 0 && STRICMP(str.data, "NONE") != 0) {
|
||||
hlattrs.font = hl_add_font_idx(str.data);
|
||||
}
|
||||
}
|
||||
|
||||
return hlattrs;
|
||||
#undef HAS_KEY_X
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ typedef struct {
|
||||
int16_t cterm_fg_color, cterm_bg_color;
|
||||
int32_t hl_blend;
|
||||
int32_t url;
|
||||
int32_t font;
|
||||
} HlAttrs;
|
||||
|
||||
#define HLATTRS_INIT (HlAttrs) { \
|
||||
@@ -57,6 +58,7 @@ typedef struct {
|
||||
.cterm_bg_color = 0, \
|
||||
.hl_blend = -1, \
|
||||
.url = -1, \
|
||||
.font = -1, \
|
||||
}
|
||||
|
||||
/// Values for index in highlight_attr[].
|
||||
|
||||
@@ -112,6 +112,7 @@ typedef struct {
|
||||
int sg_rgb_sp_idx; ///< RGB special color index
|
||||
|
||||
int sg_blend; ///< blend level (0-100 inclusive), -1 if unset
|
||||
char *sg_font; ///< font name, NULL if not set
|
||||
|
||||
int sg_parent; ///< parent of @nested.group
|
||||
} HlGroup;
|
||||
@@ -1339,8 +1340,16 @@ void do_highlight(const char *line, const bool forceit, const bool init)
|
||||
hl_table[idx].sg_gui = attr;
|
||||
}
|
||||
}
|
||||
} else if (strcmp(key, "FONT") == 0) {
|
||||
// in non-GUI fonts are simply ignored
|
||||
} else if (strcmp(key, "FONT") == 0 && (!init || !(hl_table[idx].sg_set & SG_GUI))) {
|
||||
if (!init) {
|
||||
hl_table[idx].sg_set |= SG_GUI;
|
||||
}
|
||||
if (hl_table[idx].sg_font != NULL) {
|
||||
XFREE_CLEAR(hl_table[idx].sg_font);
|
||||
}
|
||||
if (strcmp(arg, "NONE") != 0) {
|
||||
hl_table[idx].sg_font = xstrdup(arg);
|
||||
}
|
||||
} else if (strcmp(key, "CTERMFG") == 0 || strcmp(key, "CTERMBG") == 0) {
|
||||
if (!init || !(hl_table[idx].sg_set & SG_CTERM)) {
|
||||
if (!init) {
|
||||
@@ -1574,6 +1583,9 @@ static void highlight_clear(int idx)
|
||||
hl_table[idx].sg_rgb_bg_idx = kColorIdxNone;
|
||||
hl_table[idx].sg_rgb_sp_idx = kColorIdxNone;
|
||||
hl_table[idx].sg_blend = -1;
|
||||
if (hl_table[idx].sg_font != NULL) {
|
||||
XFREE_CLEAR(hl_table[idx].sg_font);
|
||||
}
|
||||
// Restore default link and context if they exist. Otherwise clears.
|
||||
hl_table[idx].sg_link = hl_table[idx].sg_deflink;
|
||||
// Since we set the default link, set the location to where the default
|
||||
@@ -1619,8 +1631,9 @@ static void highlight_list_one(const int id)
|
||||
didh = highlight_list_arg(id, didh, LIST_STRING, 0,
|
||||
coloridx_to_name(sgp->sg_rgb_sp_idx, sgp->sg_rgb_sp, hexbuf), "guisp");
|
||||
|
||||
didh = highlight_list_arg(id, didh, LIST_INT,
|
||||
sgp->sg_blend + 1, NULL, "blend");
|
||||
didh = highlight_list_arg(id, didh, LIST_INT, sgp->sg_blend + 1, NULL, "blend");
|
||||
|
||||
didh = highlight_list_arg(id, didh, LIST_STRING, 0, sgp->sg_font, "font");
|
||||
|
||||
if (sgp->sg_link && !got_int) {
|
||||
syn_list_header(didh, 0, id, true);
|
||||
@@ -1948,6 +1961,10 @@ static void set_hl_attr(int idx)
|
||||
at_en.rgb_bg_color = sgp->sg_rgb_bg_idx != kColorIdxNone ? sgp->sg_rgb_bg : -1;
|
||||
at_en.rgb_sp_color = sgp->sg_rgb_sp_idx != kColorIdxNone ? sgp->sg_rgb_sp : -1;
|
||||
at_en.hl_blend = sgp->sg_blend;
|
||||
// Convert font name to index
|
||||
if (sgp->sg_font != NULL) {
|
||||
at_en.font = hl_add_font_idx(sgp->sg_font);
|
||||
}
|
||||
|
||||
sgp->sg_attr = hl_get_syn_attr(0, idx + 1, at_en);
|
||||
|
||||
|
||||
@@ -334,6 +334,29 @@ describe('API: set highlight', function()
|
||||
eq(nil, hl.underdouble)
|
||||
eq(true, hl.bold)
|
||||
end)
|
||||
|
||||
it('can set font', function()
|
||||
local ns = api.nvim_create_namespace('test_font')
|
||||
api.nvim_set_hl(ns, 'TestFont', { fg = '#ff0000', font = 'Courier New 10' })
|
||||
local hl = api.nvim_get_hl(ns, { name = 'TestFont' })
|
||||
eq('Courier New 10', hl.font)
|
||||
eq(16711680, hl.fg)
|
||||
|
||||
api.nvim_set_hl(ns, 'TestFont', { font = 'Monaco' })
|
||||
hl = api.nvim_get_hl(ns, { name = 'TestFont' })
|
||||
eq('Monaco', hl.font)
|
||||
|
||||
-- Clear font with "NONE"
|
||||
api.nvim_set_hl(ns, 'TestFont', { font = 'NONE' })
|
||||
hl = api.nvim_get_hl(ns, { name = 'TestFont' })
|
||||
eq(nil, hl.font)
|
||||
|
||||
-- global namespace
|
||||
api.nvim_set_hl(0, 'TestFontGlobal', { bg = '#00ff00', font = 'JetBrains Mono' })
|
||||
hl = api.nvim_get_hl(0, { name = 'TestFontGlobal' })
|
||||
eq('JetBrains Mono', hl.font)
|
||||
eq(65280, hl.bg)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('API: get highlight', function()
|
||||
|
||||
Reference in New Issue
Block a user