aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/highlight_group.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/highlight_group.c')
-rw-r--r--src/nvim/highlight_group.c304
1 files changed, 203 insertions, 101 deletions
diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c
index 3d91335f55..3f1758894e 100644
--- a/src/nvim/highlight_group.c
+++ b/src/nvim/highlight_group.c
@@ -1,6 +1,3 @@
-// This is an open source non-commercial project. Dear PVS-Studio, please check
-// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-
// highlight_group.c: code for managing highlight groups
#include <ctype.h>
@@ -10,38 +7,42 @@
#include <stdlib.h>
#include <string.h>
+#include "klib/kvec.h"
+#include "nvim/api/keysets_defs.h"
#include "nvim/api/private/defs.h"
+#include "nvim/api/private/dispatch.h"
#include "nvim/api/private/helpers.h"
-#include "nvim/ascii.h"
+#include "nvim/api/private/validate.h"
+#include "nvim/ascii_defs.h"
#include "nvim/autocmd.h"
-#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/cursor_shape.h"
#include "nvim/decoration_provider.h"
#include "nvim/drawscreen.h"
#include "nvim/eval.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/eval/vars.h"
-#include "nvim/ex_cmds_defs.h"
#include "nvim/ex_docmd.h"
+#include "nvim/func_attr.h"
#include "nvim/garray.h"
#include "nvim/gettext.h"
#include "nvim/globals.h"
-#include "nvim/grid_defs.h"
#include "nvim/highlight.h"
#include "nvim/highlight_group.h"
#include "nvim/lua/executor.h"
-#include "nvim/macros.h"
-#include "nvim/map.h"
+#include "nvim/macros_defs.h"
+#include "nvim/map_defs.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/option.h"
+#include "nvim/option_vars.h"
#include "nvim/os/time.h"
#include "nvim/runtime.h"
#include "nvim/strings.h"
-#include "nvim/types.h"
+#include "nvim/types_defs.h"
#include "nvim/ui.h"
-#include "nvim/vim.h"
+#include "nvim/vim_defs.h"
/// \addtogroup SG_SET
/// @{
@@ -118,6 +119,17 @@ enum {
# include "highlight_group.c.generated.h"
#endif
+static const char e_highlight_group_name_not_found_str[]
+ = N_("E411: Highlight group not found: %s");
+static const char e_group_has_settings_highlight_link_ignored[]
+ = N_("E414: Group has settings, highlight link ignored");
+static const char e_unexpected_equal_sign_str[]
+ = N_("E415: Unexpected equal sign: %s");
+static const char e_missing_equal_sign_str_2[]
+ = N_("E416: Missing equal sign: %s");
+static const char e_missing_argument_str[]
+ = N_("E417: Missing argument: %s");
+
#define hl_table ((HlGroup *)((highlight_ga.ga_data)))
// The default highlight groups. These are compiled-in for fast startup and
@@ -150,12 +162,18 @@ static const char *highlight_init_both[] = {
"default link QuickFixLine Search",
"default link CursorLineSign SignColumn",
"default link CursorLineFold FoldColumn",
+ "default link CurSearch Search",
+ "default link PmenuKind Pmenu",
+ "default link PmenuKindSel PmenuSel",
+ "default link PmenuExtra Pmenu",
+ "default link PmenuExtraSel PmenuSel",
"default link Substitute Search",
"default link Whitespace NonText",
"default link MsgSeparator StatusLine",
"default link NormalFloat Pmenu",
"default link FloatBorder WinSeparator",
"default link FloatTitle Title",
+ "default link FloatFooter Title",
"default FloatShadow blend=80 guibg=Black",
"default FloatShadowThrough blend=100 guibg=Black",
"RedrawDebugNormal cterm=reverse gui=reverse",
@@ -213,6 +231,10 @@ static const char *highlight_init_both[] = {
"default link DiagnosticSignInfo DiagnosticInfo",
"default link DiagnosticSignHint DiagnosticHint",
"default link DiagnosticSignOk DiagnosticOk",
+ "default DiagnosticDeprecated cterm=strikethrough gui=strikethrough guisp=Red",
+ "default link DiagnosticUnnecessary Comment",
+ "default link LspInlayHint NonText",
+ "default link SnippetTabstop Visual",
// Text
"default link @text.literal Comment",
@@ -270,16 +292,23 @@ static const char *highlight_init_both[] = {
"default link @tag Tag",
// LSP semantic tokens
- "default link @class Structure",
- "default link @struct Structure",
- "default link @enum Type",
- "default link @enumMember Constant",
- "default link @event Identifier",
- "default link @interface Identifier",
- "default link @modifier Identifier",
- "default link @regexp SpecialChar",
- "default link @typeParameter Type",
- "default link @decorator Identifier",
+ "default link @lsp.type.class Structure",
+ "default link @lsp.type.comment Comment",
+ "default link @lsp.type.decorator Function",
+ "default link @lsp.type.enum Structure",
+ "default link @lsp.type.enumMember Constant",
+ "default link @lsp.type.function Function",
+ "default link @lsp.type.interface Structure",
+ "default link @lsp.type.macro Macro",
+ "default link @lsp.type.method Function",
+ "default link @lsp.type.namespace Structure",
+ "default link @lsp.type.parameter Identifier",
+ "default link @lsp.type.property Identifier",
+ "default link @lsp.type.struct Structure",
+ "default link @lsp.type.type Type",
+ "default link @lsp.type.typeParameter TypeDef",
+ "default link @lsp.type.variable Identifier",
+
NULL
};
@@ -671,12 +700,8 @@ int load_colors(char *name)
size_t buflen = strlen(name) + 12;
char *buf = xmalloc(buflen);
apply_autocmds(EVENT_COLORSCHEMEPRE, name, curbuf->b_fname, false, curbuf);
- snprintf(buf, buflen, "colors/%s.vim", name);
- int retval = source_runtime(buf, DIP_START + DIP_OPT);
- if (retval == FAIL) {
- snprintf(buf, buflen, "colors/%s.lua", name);
- retval = source_runtime(buf, DIP_START + DIP_OPT);
- }
+ snprintf(buf, buflen, "colors/%s.*", name);
+ int retval = source_runtime_vim_lua(buf, DIP_START + DIP_OPT);
xfree(buf);
if (retval == OK) {
apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, false, curbuf);
@@ -775,18 +800,17 @@ int lookup_color(const int idx, const bool foreground, TriState *const boldp)
void set_hl_group(int id, HlAttrs attrs, Dict(highlight) *dict, 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)) {
+ if (is_default && hl_has_settings(idx, true) && !dict->force) {
return;
}
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;
@@ -796,12 +820,11 @@ 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_gui = attrs.rgb_ae_attr &~HL_DEFAULT;
g->sg_rgb_fg = attrs.rgb_fg_color;
g->sg_rgb_bg = attrs.rgb_bg_color;
@@ -810,9 +833,11 @@ void set_hl_group(int id, HlAttrs attrs, Dict(highlight) *dict, int link_id)
struct {
int *dest; RgbValue val; Object name;
} cattrs[] = {
- { &g->sg_rgb_fg_idx, g->sg_rgb_fg, HAS_KEY(dict->fg) ? dict->fg : dict->foreground },
- { &g->sg_rgb_bg_idx, g->sg_rgb_bg, HAS_KEY(dict->bg) ? dict->bg : dict->background },
- { &g->sg_rgb_sp_idx, g->sg_rgb_sp, HAS_KEY(dict->sp) ? dict->sp : dict->special },
+ { &g->sg_rgb_fg_idx, g->sg_rgb_fg,
+ HAS_KEY(dict, highlight, fg) ? dict->fg : dict->foreground },
+ { &g->sg_rgb_bg_idx, g->sg_rgb_bg,
+ HAS_KEY(dict, highlight, bg) ? dict->bg : dict->background },
+ { &g->sg_rgb_sp_idx, g->sg_rgb_sp, HAS_KEY(dict, highlight, sp) ? dict->sp : dict->special },
{ NULL, -1, NIL },
};
@@ -826,7 +851,7 @@ void set_hl_group(int id, HlAttrs attrs, Dict(highlight) *dict, int link_id)
}
}
- g->sg_cterm = attrs.cterm_ae_attr;
+ g->sg_cterm = attrs.cterm_ae_attr &~HL_DEFAULT;
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;
@@ -841,9 +866,17 @@ void set_hl_group(int id, HlAttrs attrs, Dict(highlight) *dict, int link_id)
if (strcmp(g->sg_name_u, "NORMAL") == 0) {
cterm_normal_fg_color = g->sg_cterm_fg;
cterm_normal_bg_color = g->sg_cterm_bg;
+ bool did_changed = false;
+ if (normal_bg != g->sg_rgb_bg || normal_fg != g->sg_rgb_fg || normal_sp != g->sg_rgb_sp) {
+ did_changed = true;
+ }
normal_fg = g->sg_rgb_fg;
normal_bg = g->sg_rgb_bg;
normal_sp = g->sg_rgb_sp;
+
+ if (did_changed) {
+ highlight_attr_set_all();
+ }
ui_default_colors_set();
} else {
// a cursor style uses this syn_id, make sure its attribute is updated.
@@ -852,7 +885,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);
}
@@ -883,15 +915,15 @@ void do_highlight(const char *line, const bool forceit, const bool init)
bool dodefault = false;
// Isolate the name.
- const char *name_end = (const char *)skiptowhite(line);
- const char *linep = (const char *)skipwhite(name_end);
+ const char *name_end = skiptowhite(line);
+ const char *linep = skipwhite(name_end);
// Check for "default" argument.
if (strncmp(line, "default", (size_t)(name_end - line)) == 0) {
dodefault = true;
line = linep;
- name_end = (const char *)skiptowhite(line);
- linep = (const char *)skipwhite(name_end);
+ name_end = skiptowhite(line);
+ linep = skipwhite(name_end);
}
bool doclear = false;
@@ -908,7 +940,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
if (!doclear && !dolink && ends_excmd((uint8_t)(*linep))) {
int id = syn_name2id_len(line, (size_t)(name_end - line));
if (id == 0) {
- semsg(_("E411: highlight group not found: %s"), line);
+ semsg(_(e_highlight_group_name_not_found_str), line);
} else {
highlight_list_one(id);
}
@@ -925,9 +957,9 @@ void do_highlight(const char *line, const bool forceit, const bool init)
int to_id;
HlGroup *hlgroup = NULL;
- from_end = (const char *)skiptowhite(from_start);
- to_start = (const char *)skipwhite(from_end);
- to_end = (const char *)skiptowhite(to_start);
+ from_end = skiptowhite(from_start);
+ to_start = skipwhite(from_end);
+ to_end = skiptowhite(to_start);
if (ends_excmd((uint8_t)(*from_start))
|| ends_excmd((uint8_t)(*to_start))) {
@@ -964,7 +996,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
if (to_id > 0 && !forceit && !init
&& hl_has_settings(from_id - 1, dodefault)) {
if (SOURCING_NAME == NULL && !dodefault) {
- emsg(_("E414: group has settings, highlight link ignored"));
+ emsg(_(e_group_has_settings_highlight_link_ignored));
}
} else if (hlgroup->sg_link != to_id
|| hlgroup->sg_script_ctx.sc_sid != current_sctx.sc_sid
@@ -991,7 +1023,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
// ":highlight clear [group]" command.
line = linep;
if (ends_excmd((uint8_t)(*line))) {
- do_unlet(S_LEN("colors_name"), true);
+ do_unlet(S_LEN("g:colors_name"), true);
restore_cterm_colors();
// Clear all default highlight groups and load the defaults.
@@ -1003,8 +1035,8 @@ void do_highlight(const char *line, const bool forceit, const bool init)
redraw_all_later(UPD_NOT_VALID);
return;
}
- name_end = (const char *)skiptowhite(line);
- linep = (const char *)skipwhite(name_end);
+ name_end = skiptowhite(line);
+ linep = skipwhite(name_end);
}
// Find the group name in the table. If it does not exist yet, add it.
@@ -1042,7 +1074,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
while (!ends_excmd((uint8_t)(*linep))) {
const char *key_start = linep;
if (*linep == '=') {
- semsg(_("E415: unexpected equal sign: %s"), key_start);
+ semsg(_(e_unexpected_equal_sign_str), key_start);
error = true;
break;
}
@@ -1061,7 +1093,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
memcpy(key, key_start, key_len);
key[key_len] = NUL;
vim_strup(key);
- linep = (const char *)skipwhite(linep);
+ linep = skipwhite(linep);
if (strcmp(key, "NONE") == 0) {
if (!init || hl_table[idx].sg_set == 0) {
@@ -1075,14 +1107,14 @@ void do_highlight(const char *line, const bool forceit, const bool init)
// Check for the equal sign.
if (*linep != '=') {
- semsg(_("E416: missing equal sign: %s"), key_start);
+ semsg(_(e_missing_equal_sign_str_2), key_start);
error = true;
break;
}
linep++;
// Isolate the argument.
- linep = (const char *)skipwhite(linep);
+ linep = skipwhite(linep);
if (*linep == '\'') { // guifg='color name'
arg_start = ++linep;
linep = strchr(linep, '\'');
@@ -1093,10 +1125,10 @@ void do_highlight(const char *line, const bool forceit, const bool init)
}
} else {
arg_start = linep;
- linep = (const char *)skiptowhite(linep);
+ linep = skiptowhite(linep);
}
if (linep == arg_start) {
- semsg(_("E417: missing argument: %s"), key_start);
+ semsg(_(e_missing_argument_str), key_start);
error = true;
break;
}
@@ -1124,6 +1156,9 @@ void do_highlight(const char *line, const bool forceit, const bool init)
for (i = ARRAY_SIZE(hl_attr_table); --i >= 0;) {
int len = (int)strlen(hl_name_table[i]);
if (STRNICMP(arg + off, hl_name_table[i], len) == 0) {
+ if (hl_attr_table[i] & HL_UNDERLINE_MASK) {
+ attr &= ~HL_UNDERLINE_MASK;
+ }
attr |= hl_attr_table[i];
off += len;
break;
@@ -1246,7 +1281,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
if (dark != -1
&& dark != (*p_bg == 'd')
&& !option_was_set("bg")) {
- set_option_value_give_err("bg", 0L, (dark ? "dark" : "light"), 0);
+ set_option_value_give_err("bg", CSTR_AS_OPTVAL(dark ? "dark" : "light"), 0);
reset_option_was_set("bg");
}
}
@@ -1346,7 +1381,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
}
// Continue with next argument.
- linep = (const char *)skipwhite(linep);
+ linep = skipwhite(linep);
}
}
@@ -1394,7 +1429,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
void free_highlight(void)
{
ga_clear(&highlight_ga);
- map_destroy(cstr_t, int)(&highlight_unames);
+ map_destroy(cstr_t, &highlight_unames);
arena_mem_free(arena_finish(&highlight_arena));
}
@@ -1414,7 +1449,7 @@ void restore_cterm_colors(void)
/// @param check_link if true also check for an existing link.
///
/// @return true if highlight group "idx" has any settings.
-static int hl_has_settings(int idx, bool check_link)
+static bool hl_has_settings(int idx, bool check_link)
{
return hl_table[idx].sg_cleared == 0
&& (hl_table[idx].sg_attr != 0
@@ -1497,7 +1532,7 @@ static void highlight_list_one(const int id)
didh = true;
msg_puts_attr("links to", HL_ATTR(HLF_D));
msg_putchar(' ');
- msg_outtrans(hl_table[hl_table[id - 1].sg_link - 1].sg_name);
+ msg_outtrans(hl_table[hl_table[id - 1].sg_link - 1].sg_name, 0);
}
if (!didh) {
@@ -1508,24 +1543,79 @@ static void highlight_list_one(const int id)
}
}
-Dictionary get_global_hl_defs(Arena *arena)
+static bool hlgroup2dict(Dictionary *hl, NS ns_id, int hl_id, Arena *arena)
{
+ HlGroup *sgp = &hl_table[hl_id - 1];
+ int link = ns_id == 0 ? sgp->sg_link : ns_get_hl(&ns_id, hl_id, true, sgp->sg_set);
+ if (link == -1) {
+ return false;
+ }
+ if (ns_id == 0 && sgp->sg_cleared && sgp->sg_set == 0) {
+ // table entry was created but not ever set
+ return false;
+ }
+ 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 (attr.rgb_ae_attr & HL_DEFAULT) {
+ PUT_C(*hl, "default", BOOLEAN_OBJ(true));
+ }
+ if (link > 0) {
+ PUT_C(*hl, "link", CSTR_AS_OBJ(hl_table[link - 1].sg_name));
+ }
+ 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;
+}
+
+Dictionary ns_get_hl_defs(NS ns_id, Dict(get_highlight) *opts, Arena *arena, Error *err)
+{
+ Boolean link = GET_BOOL_OR_TRUE(opts, get_highlight, link);
+ int id = -1;
+ if (HAS_KEY(opts, get_highlight, name)) {
+ Boolean create = GET_BOOL_OR_TRUE(opts, get_highlight, create);
+ id = create ? syn_check_group(opts->name.data, opts->name.size)
+ : syn_name2id_len(opts->name.data, opts->name.size);
+ if (id == 0 && !create) {
+ Dictionary attrs = ARRAY_DICT_INIT;
+ return attrs;
+ }
+ } else if (HAS_KEY(opts, get_highlight, id)) {
+ id = (int)opts->id;
+ }
+
+ if (id != -1) {
+ VALIDATE(1 <= id && id <= highlight_ga.ga_len, "%s", "Highlight id out of bounds", {
+ goto cleanup;
+ });
+ Dictionary attrs = ARRAY_DICT_INIT;
+ hlgroup2dict(&attrs, ns_id, link ? id : syn_get_final_id(id), arena);
+ return attrs;
+ }
+ if (ERROR_SET(err)) {
+ goto cleanup;
+ }
+
Dictionary rv = arena_dict(arena, (size_t)highlight_ga.ga_len);
for (int i = 1; i <= highlight_ga.ga_len; i++) {
Dictionary attrs = ARRAY_DICT_INIT;
- HlGroup *h = &hl_table[i - 1];
- if (h->sg_attr > 0) {
- attrs = arena_dict(arena, HLATTRS_DICT_SIZE);
- hlattrs2dict(&attrs, syn_attr2entry(h->sg_attr), true);
- } else if (h->sg_link > 0) {
- attrs = arena_dict(arena, 1);
- char *link = hl_table[h->sg_link - 1].sg_name;
- PUT_C(attrs, "link", STRING_OBJ(cstr_as_string(link)));
+ if (!hlgroup2dict(&attrs, ns_id, i, arena)) {
+ continue;
}
- PUT_C(rv, (char *)h->sg_name, DICTIONARY_OBJ(attrs));
+ PUT_C(rv, hl_table[(link ? i : syn_get_final_id(i)) - 1].sg_name, DICTIONARY_OBJ(attrs));
}
return rv;
+
+cleanup:
+ api_free_integer(id);
+ api_free_boolean(link);
+ Dictionary empty = ARRAY_DICT_INIT;
+ return empty;
}
/// Outputs a highlight when doing ":hi MyHighlight"
@@ -1547,7 +1637,7 @@ static bool highlight_list_arg(const int id, bool didh, const int type, int iarg
char buf[100];
const char *ts = buf;
if (type == LIST_INT) {
- snprintf((char *)buf, sizeof(buf), "%d", iarg - 1);
+ snprintf(buf, sizeof(buf), "%d", iarg - 1);
} else if (type == LIST_STRING) {
ts = sarg;
} else { // type == LIST_ATTR
@@ -1568,14 +1658,14 @@ static bool highlight_list_arg(const int id, bool didh, const int type, int iarg
}
}
- (void)syn_list_header(didh, vim_strsize((char *)ts) + (int)strlen(name) + 1, id, false);
+ (void)syn_list_header(didh, vim_strsize(ts) + (int)strlen(name) + 1, id, false);
didh = true;
if (!got_int) {
if (*name != NUL) {
msg_puts_attr(name, HL_ATTR(HLF_D));
msg_puts_attr("=", HL_ATTR(HLF_D));
}
- msg_outtrans((char *)ts);
+ msg_outtrans(ts, 0);
}
return didh;
}
@@ -1705,7 +1795,7 @@ bool syn_list_header(const bool did_header, const int outlen, const int id, bool
if (got_int) {
return true;
}
- msg_outtrans(hl_table[id - 1].sg_name);
+ msg_outtrans(hl_table[id - 1].sg_name, 0);
name_col = msg_col;
endcol = 15;
} else if ((ui_has(kUIMessages) || msg_silent) && !force_newline) {
@@ -1861,13 +1951,13 @@ int syn_check_group(const char *name, size_t len)
/// @see syn_check_group
static int syn_add_group(const char *name, size_t len)
{
- // Check that the name is ASCII letters, digits and underscore.
+ // Check that the name is valid (ASCII letters, digits, '_', '.', '@', '-').
for (size_t i = 0; i < len; i++) {
int c = (uint8_t)name[i];
if (!vim_isprintc(c)) {
emsg(_("E669: Unprintable character in group name"));
return 0;
- } else if (!ASCII_ISALNUM(c) && c != '_' && c != '.' && c != '@') {
+ } else if (!ASCII_ISALNUM(c) && c != '_' && c != '.' && c != '@' && c != '-') {
// '.' and '@' are allowed characters for use with treesitter capture names.
msg_source(HL_ATTR(HLF_W));
emsg(_(e_highlight_group_name_invalid_char));
@@ -1924,18 +2014,23 @@ static int syn_add_group(const char *name, size_t len)
/// @see syn_attr2entry
int syn_id2attr(int hl_id)
{
- return syn_ns_id2attr(-1, hl_id, false);
+ bool optional = false;
+ return syn_ns_id2attr(-1, hl_id, &optional);
}
-int syn_ns_id2attr(int ns_id, int hl_id, bool optional)
+int syn_ns_id2attr(int ns_id, int hl_id, bool *optional)
+ FUNC_ATTR_NONNULL_ALL
{
- hl_id = syn_ns_get_final_id(&ns_id, hl_id);
+ if (syn_ns_get_final_id(&ns_id, &hl_id)) {
+ // If the namespace explicitly defines a group to be empty, it is not optional
+ *optional = false;
+ }
HlGroup *sgp = &hl_table[hl_id - 1]; // index is ID minus one
int attr = ns_get_hl(&ns_id, hl_id, false, sgp->sg_set);
// if a highlight group is optional, don't use the global value
- if (attr >= 0 || (optional && ns_id > 0)) {
+ if (attr >= 0 || (*optional && ns_id > 0)) {
return attr;
}
return sgp->sg_attr;
@@ -1944,16 +2039,20 @@ int syn_ns_id2attr(int ns_id, int hl_id, bool optional)
/// Translate a group ID to the final group ID (following links).
int syn_get_final_id(int hl_id)
{
- int id = curwin->w_ns_hl_active;
- return syn_ns_get_final_id(&id, hl_id);
+ int ns_id = curwin->w_ns_hl_active;
+ syn_ns_get_final_id(&ns_id, &hl_id);
+ return hl_id;
}
-int syn_ns_get_final_id(int *ns_id, int hl_id)
+bool syn_ns_get_final_id(int *ns_id, int *hl_idp)
{
int count;
+ int hl_id = *hl_idp;
+ bool used = false;
if (hl_id > highlight_ga.ga_len || hl_id < 1) {
- return 0; // Can be called from eval!!
+ *hl_idp = 0;
+ return false; // Can be called from eval!!
}
// Follow links until there is no more.
@@ -1966,8 +2065,10 @@ int syn_ns_get_final_id(int *ns_id, int hl_id)
// syn_id2attr time
int check = ns_get_hl(ns_id, hl_id, true, sgp->sg_set);
if (check == 0) {
- return hl_id; // how dare! it broke the link!
+ *hl_idp = hl_id;
+ return true; // how dare! it broke the link!
} else if (check > 0) {
+ used = true;
hl_id = check;
continue;
}
@@ -1981,7 +2082,8 @@ int syn_ns_get_final_id(int *ns_id, int hl_id)
}
}
- return hl_id;
+ *hl_idp = hl_id;
+ return used;
}
/// Refresh the color attributes of all highlight groups.
@@ -2064,15 +2166,15 @@ void highlight_changed(void)
abort();
}
int ns_id = -1;
- int final_id = syn_ns_get_final_id(&ns_id, id);
+ int final_id = id;
+ syn_ns_get_final_id(&ns_id, &final_id);
if (hlf == HLF_SNC) {
id_SNC = final_id;
} else if (hlf == HLF_S) {
id_S = final_id;
}
- highlight_attr[hlf] = hl_get_ui_attr(ns_id, hlf, final_id,
- (hlf == HLF_INACTIVE || hlf == HLF_LC));
+ highlight_attr[hlf] = hl_get_ui_attr(ns_id, hlf, final_id, hlf == HLF_INACTIVE);
if (highlight_attr[hlf] != highlight_attr_last[hlf]) {
if (hlf == HLF_MSG) {
@@ -2134,7 +2236,7 @@ void set_context_in_highlight_cmd(expand_T *xp, const char *arg)
}
// (part of) subcommand already typed
- const char *p = (const char *)skiptowhite(arg);
+ const char *p = skiptowhite(arg);
if (*p == NUL) {
return;
}
@@ -2142,9 +2244,9 @@ void set_context_in_highlight_cmd(expand_T *xp, const char *arg)
// past "default" or group name
include_default = 0;
if (strncmp("default", arg, (unsigned)(p - arg)) == 0) {
- arg = (const char *)skipwhite(p);
+ arg = skipwhite(p);
xp->xp_pattern = (char *)arg;
- p = (const char *)skiptowhite(arg);
+ p = skiptowhite(arg);
}
if (*p == NUL) {
return;
@@ -2158,10 +2260,10 @@ void set_context_in_highlight_cmd(expand_T *xp, const char *arg)
if (strncmp("link", arg, (unsigned)(p - arg)) == 0
|| strncmp("clear", arg, (unsigned)(p - arg)) == 0) {
xp->xp_pattern = skipwhite(p);
- p = (const char *)skiptowhite(xp->xp_pattern);
+ p = skiptowhite(xp->xp_pattern);
if (*p != NUL) { // past first group name
xp->xp_pattern = skipwhite(p);
- p = (const char *)skiptowhite(xp->xp_pattern);
+ p = skiptowhite(xp->xp_pattern);
}
}
if (*p != NUL) { // past group name(s)
@@ -2185,14 +2287,14 @@ static void highlight_list_two(int cnt, int attr)
msg_puts_attr(&("N \bI \b! \b"[cnt / 11]), attr);
msg_clr_eos();
ui_flush();
- os_delay(cnt == 99 ? 40L : (uint64_t)cnt * 50L, false);
+ os_delay(cnt == 99 ? 40 : (uint64_t)cnt * 50, false);
}
/// Function given to ExpandGeneric() to obtain the list of group names.
-const char *get_highlight_name(expand_T *const xp, int idx)
+char *get_highlight_name(expand_T *const xp, int idx)
FUNC_ATTR_WARN_UNUSED_RESULT
{
- return get_highlight_name_ext(xp, idx, true);
+ return (char *)get_highlight_name_ext(xp, idx, true);
}
/// Obtain a highlight group name.
@@ -2224,7 +2326,7 @@ const char *get_highlight_name_ext(expand_T *xp, int idx, bool skip_cleared)
} else if (idx >= highlight_ga.ga_len) {
return NULL;
}
- return (const char *)hl_table[idx].sg_name;
+ return hl_table[idx].sg_name;
}
color_name_table_T color_name_table[] = {
@@ -2925,7 +3027,7 @@ RgbValue name_to_color(const char *name, int *idx)
&& isxdigit((uint8_t)name[6]) && name[7] == NUL) {
// rgb hex string
*idx = kColorIdxHex;
- return (RgbValue)strtol((char *)(name + 1), NULL, 16);
+ return (RgbValue)strtol(name + 1, NULL, 16);
} else if (!STRICMP(name, "bg") || !STRICMP(name, "background")) {
*idx = kColorIdxBg;
return normal_bg;