diff options
author | bfredl <bjorn.linse@gmail.com> | 2022-02-01 17:16:14 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-01 17:16:14 +0100 |
commit | 5be2cdd913ce94bf3b88ce70042fbf7a92066459 (patch) | |
tree | 960442a3778992bc3d33e7a55a7de66c4196f555 /src | |
parent | f4300985d3212887ef27d703ba8cb4230813e095 (diff) | |
parent | 4aa0cdd3aa117e032325edeb755107acd4ecbf84 (diff) | |
download | rneovim-5be2cdd913ce94bf3b88ce70042fbf7a92066459.tar.gz rneovim-5be2cdd913ce94bf3b88ce70042fbf7a92066459.tar.bz2 rneovim-5be2cdd913ce94bf3b88ce70042fbf7a92066459.zip |
Merge pull request #17187 from lewis6991/master
feat(highlight): ns=0 to set :highlight namespace
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/vim.c | 18 | ||||
-rw-r--r-- | src/nvim/highlight.c | 32 | ||||
-rw-r--r-- | src/nvim/highlight_defs.h | 12 | ||||
-rw-r--r-- | src/nvim/syntax.c | 84 |
4 files changed, 130 insertions, 16 deletions
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index f7ea6bc4d3..e9182fde7f 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -32,6 +32,7 @@ #include "nvim/fileio.h" #include "nvim/getchar.h" #include "nvim/highlight.h" +#include "nvim/highlight_defs.h" #include "nvim/lua/executor.h" #include "nvim/mark.h" #include "nvim/memline.h" @@ -122,7 +123,9 @@ Dictionary nvim__get_hl_defs(Integer ns_id, Error *err) /// Set a highlight group. /// -/// @param ns_id number of namespace for this highlight +/// @param ns_id number of namespace for this highlight. Use value 0 +/// to set a highlight group in the global (`:highlight`) +/// namespace. /// @param name highlight group name, like ErrorMsg /// @param val highlight definition map, like |nvim_get_hl_by_name|. /// in addition the following keys are also recognized: @@ -136,18 +139,23 @@ Dictionary nvim__get_hl_defs(Integer ns_id, Error *err) /// same as attributes of gui color /// @param[out] err Error details, if any /// -/// TODO: ns_id = 0, should modify :highlight namespace -/// TODO val should take update vs reset flag +// TODO(bfredl): val should take update vs reset flag void nvim_set_hl(Integer ns_id, String name, Dictionary val, Error *err) FUNC_API_SINCE(7) { int hl_id = syn_check_group(name.data, (int)name.size); int link_id = -1; - HlAttrs attrs = dict2hlattrs(val, true, &link_id, err); + HlAttrNames *names = NULL; // Only used when setting global namespace + if (ns_id == 0) { + names = xmalloc(sizeof(*names)); + *names = HLATTRNAMES_INIT; + } + HlAttrs attrs = dict2hlattrs(val, true, &link_id, names, err); if (!ERROR_SET(err)) { - ns_hl_def((NS)ns_id, hl_id, attrs, link_id); + ns_hl_def((NS)ns_id, hl_id, attrs, link_id, names); } + xfree(names); } /// Set active namespace for highlights. diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c index 3050ca02de..83a6ccf38f 100644 --- a/src/nvim/highlight.c +++ b/src/nvim/highlight.c @@ -144,13 +144,19 @@ int hl_get_syn_attr(int ns_id, int idx, HlAttrs at_en) } } -void ns_hl_def(NS ns_id, int hl_id, HlAttrs attrs, int link_id) +void ns_hl_def(NS ns_id, int hl_id, HlAttrs attrs, int link_id, HlAttrNames *names) { - DecorProvider *p = get_decor_provider(ns_id, true); if ((attrs.rgb_ae_attr & HL_DEFAULT) && map_has(ColorKey, ColorItem)(&ns_hl, ColorKey(ns_id, hl_id))) { return; } + if (ns_id == 0) { + assert(names); + // set in global (':highlight') namespace + set_hl_group(hl_id, attrs, names, link_id); + return; + } + DecorProvider *p = get_decor_provider(ns_id, true); int attr_id = link_id > 0 ? -1 : hl_get_syn_attr(ns_id, hl_id, attrs); ColorItem it = { .attr_id = attr_id, .link_id = link_id, @@ -194,7 +200,7 @@ int ns_get_hl(NS ns_id, int hl_id, bool link, bool nodefault) if (ret.type == kObjectTypeDictionary) { Dictionary dict = ret.data.dictionary; fallback = false; - attrs = dict2hlattrs(dict, true, &it.link_id, &err); + attrs = dict2hlattrs(dict, true, &it.link_id, NULL, &err); for (size_t i = 0; i < dict.size; i++) { char *key = dict.items[i].key.data; Object val = dict.items[i].value; @@ -796,7 +802,7 @@ Dictionary hlattrs2dict(HlAttrs ae, bool use_rgb) return hl; } -HlAttrs dict2hlattrs(Dictionary dict, bool use_rgb, int *link_id, Error *err) +HlAttrs dict2hlattrs(Dictionary dict, bool use_rgb, int *link_id, HlAttrNames *names, Error *err) { HlAttrs hlattrs = HLATTRS_INIT; @@ -820,7 +826,7 @@ HlAttrs dict2hlattrs(Dictionary dict, bool use_rgb, int *link_id, Error *err) { "italic", HL_ITALIC }, { "reverse", HL_INVERSE }, { "default", HL_DEFAULT }, - { "global", HL_GLOBAL }, + // { "global", HL_GLOBAL }, { NULL, 0 }, }; @@ -857,13 +863,14 @@ HlAttrs dict2hlattrs(Dictionary dict, bool use_rgb, int *link_id, Error *err) const char *name; const char *shortname; int *dest; + char **dest_name; } colors[] = { - { "foreground", "fg", &fg }, - { "background", "bg", &bg }, - { "ctermfg", NULL, &ctermfg }, - { "ctermbg", NULL, &ctermbg }, - { "special", "sp", &sp }, - { NULL, NULL, NULL }, + { "foreground", "fg", &fg, names ? &names->fg_name : NULL }, + { "background", "bg", &bg, names ? &names->bg_name : NULL }, + { "ctermfg", NULL, &ctermfg, NULL }, + { "ctermbg", NULL, &ctermbg, NULL }, + { "special", "sp", &sp, names ? &names->sp_name : NULL }, + { NULL, NULL, NULL, NULL }, }; int k; @@ -876,6 +883,9 @@ HlAttrs dict2hlattrs(Dictionary dict, bool use_rgb, int *link_id, Error *err) // TODO(bfredl): be more fancy with "bg", "fg" etc if (str.size) { *colors[k].dest = name_to_color(str.data); + if (colors[k].dest_name) { + *colors[k].dest_name = str.data; + } } } else { api_set_error(err, kErrorTypeValidation, diff --git a/src/nvim/highlight_defs.h b/src/nvim/highlight_defs.h index 50a03e0c02..65374782b6 100644 --- a/src/nvim/highlight_defs.h +++ b/src/nvim/highlight_defs.h @@ -46,6 +46,18 @@ typedef struct attr_entry { .hl_blend = -1, \ } +typedef struct { + char *bg_name; + char *fg_name; + char *sp_name; +} HlAttrNames; + +#define HLATTRNAMES_INIT (HlAttrNames) { \ + .bg_name = NULL, \ + .fg_name = NULL, \ + .sp_name = NULL, \ +} + /// Values for index in highlight_attr[]. /// When making changes, also update hlf_names below! typedef enum { diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index a9447165c2..b383b290ba 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -6714,6 +6714,90 @@ int lookup_color(const int idx, const bool foreground, TriState *const boldp) return color; } +void set_hl_group(int id, HlAttrs attrs, HlAttrNames *names, int link_id) +{ + int idx = id - 1; // Index is ID minus one. + + bool is_default = attrs.rgb_ae_attr & HL_DEFAULT; + + // Return if "default" was used and the group already has settings + if (is_default && hl_has_settings(idx, true)) { + return; + } + + HlGroup *g = &HL_TABLE()[idx]; + + 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; + g->sg_set |= SG_LINK; + if (is_default) { + g->sg_deflink = link_id; + g->sg_deflink_sctx = current_sctx; + g->sg_deflink_sctx.sc_lnum += sourcing_lnum; + } + return; + } + + g->sg_cleared = false; + g->sg_link = 0; + g->sg_gui = attrs.rgb_ae_attr; + + g->sg_rgb_fg = attrs.rgb_fg_color; + g->sg_rgb_bg = attrs.rgb_bg_color; + g->sg_rgb_sp = attrs.rgb_sp_color; + + struct { + char **dest; RgbValue val; char *name; + } cattrs[] = { + { &g->sg_rgb_fg_name, g->sg_rgb_fg, names->fg_name }, + { &g->sg_rgb_bg_name, g->sg_rgb_bg, names->bg_name }, + { &g->sg_rgb_sp_name, g->sg_rgb_sp, names->sp_name }, + { NULL, -1, NULL }, + }; + + for (int j = 0; cattrs[j].dest; j++) { + if (cattrs[j].val != -1) { + xfree(*cattrs[j].dest); + if (cattrs[j].name) { + *cattrs[j].dest = xstrdup(cattrs[j].name); + } else { + char hex_name[8]; + snprintf(hex_name, sizeof(hex_name), "#%06x", cattrs[j].val); + *cattrs[j].dest = xstrdup(hex_name); + } + } + } + + g->sg_cterm = attrs.cterm_ae_attr; + g->sg_cterm_bg = attrs.cterm_bg_color; + g->sg_cterm_fg = attrs.cterm_fg_color; + g->sg_cterm_bold = g->sg_cterm & HL_BOLD; + g->sg_blend = attrs.hl_blend; + + g->sg_script_ctx = current_sctx; + g->sg_script_ctx.sc_lnum += sourcing_lnum; + + // 'Normal' is special + if (STRCMP(g->sg_name_u, "NORMAL") == 0) { + cterm_normal_fg_color = g->sg_cterm_fg; + cterm_normal_bg_color = g->sg_cterm_bg; + normal_fg = g->sg_rgb_fg; + normal_bg = g->sg_rgb_bg; + normal_sp = g->sg_rgb_sp; + ui_default_colors_set(); + } else { + g->sg_attr = hl_get_syn_attr(0, id, attrs); + + // a cursor style uses this syn_id, make sure its attribute is updated. + if (cursor_mode_uses_syn_id(id)) { + ui_mode_info_set(); + } + } +} + /// Handle ":highlight" command /// |