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.c158
1 files changed, 78 insertions, 80 deletions
diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c
index 404835c4a9..3d91335f55 100644
--- a/src/nvim/highlight_group.c
+++ b/src/nvim/highlight_group.c
@@ -67,32 +67,32 @@ Map(cstr_t, int) highlight_unames = MAP_INIT;
static char *(hl_name_table[]) =
{ "bold", "standout", "underline",
"undercurl", "underdouble", "underdotted", "underdashed",
- "italic", "reverse", "inverse", "strikethrough", "nocombine", "NONE" };
+ "italic", "reverse", "inverse", "strikethrough", "altfont",
+ "nocombine", "NONE" };
static int hl_attr_table[] =
{ HL_BOLD, HL_STANDOUT, HL_UNDERLINE,
HL_UNDERCURL, HL_UNDERDOUBLE, HL_UNDERDOTTED, HL_UNDERDASHED,
- HL_ITALIC, HL_INVERSE, HL_INVERSE, HL_STRIKETHROUGH, HL_NOCOMBINE, 0 };
+ HL_ITALIC, HL_INVERSE, HL_INVERSE, HL_STRIKETHROUGH, HL_ALTFONT,
+ HL_NOCOMBINE, 0 };
/// Structure that stores information about a highlight group.
/// The ID of a highlight group is also called group ID. It is the index in
/// the highlight_ga array PLUS ONE.
typedef struct {
- char_u *sg_name; ///< highlight group name
- char *sg_name_u; ///< uppercase of sg_name
+ char *sg_name; ///< highlight group name
+ char *sg_name_u; ///< uppercase of sg_name
bool sg_cleared; ///< "hi clear" was used
int sg_attr; ///< Screen attr @see ATTR_ENTRY
int sg_link; ///< link to this highlight group ID
int sg_deflink; ///< default link; restored in highlight_clear()
int sg_set; ///< combination of flags in \ref SG_SET
sctx_T sg_deflink_sctx; ///< script where the default link was set
- sctx_T sg_script_ctx; ///< script in which the group was last set
- // for terminal UIs
+ sctx_T sg_script_ctx; ///< script in which the group was last set for terminal UIs
int sg_cterm; ///< "cterm=" highlighting attr
///< (combination of \ref HlAttrFlags)
int sg_cterm_fg; ///< terminal fg color number + 1
int sg_cterm_bg; ///< terminal bg color number + 1
- bool sg_cterm_bold; ///< bold attr was set for light color
- // for RGB UIs
+ bool sg_cterm_bold; ///< bold attr was set for light color for RGB UIs
int sg_gui; ///< "gui=" highlighting attributes
///< (combination of \ref HlAttrFlags)
RgbValue sg_rgb_fg; ///< RGB foreground color
@@ -571,7 +571,7 @@ int highlight_num_groups(void)
}
/// Returns the name of a highlight group.
-char_u *highlight_group_name(int id)
+char *highlight_group_name(int id)
{
return hl_table[id].sg_name;
}
@@ -658,8 +658,6 @@ void init_highlight(bool both, bool reset)
/// @return OK for success, FAIL for failure.
int load_colors(char *name)
{
- char_u *buf;
- int retval = FAIL;
static bool recursive = false;
// When being called recursively, this is probably because setting
@@ -671,13 +669,13 @@ int load_colors(char *name)
recursive = true;
size_t buflen = strlen(name) + 12;
- buf = xmalloc(buflen);
+ char *buf = xmalloc(buflen);
apply_autocmds(EVENT_COLORSCHEMEPRE, name, curbuf->b_fname, false, curbuf);
- snprintf((char *)buf, buflen, "colors/%s.vim", name);
- retval = source_runtime((char *)buf, DIP_START + DIP_OPT);
+ snprintf(buf, buflen, "colors/%s.vim", name);
+ int retval = source_runtime(buf, DIP_START + DIP_OPT);
if (retval == FAIL) {
- snprintf((char *)buf, buflen, "colors/%s.lua", name);
- retval = source_runtime((char *)buf, DIP_START + DIP_OPT);
+ snprintf(buf, buflen, "colors/%s.lua", name);
+ retval = source_runtime(buf, DIP_START + DIP_OPT);
}
xfree(buf);
if (retval == OK) {
@@ -873,25 +871,6 @@ update:
void do_highlight(const char *line, const bool forceit, const bool init)
FUNC_ATTR_NONNULL_ALL
{
- const char *name_end;
- const char *linep;
- const char *key_start;
- const char *arg_start;
- int off;
- int len;
- int attr;
- int id;
- int idx;
- HlGroup item_before;
- bool did_change = false;
- bool dodefault = false;
- bool doclear = false;
- bool dolink = false;
- bool error = false;
- int color;
- bool is_normal_group = false; // "Normal" group
- bool did_highlight_changed = false;
-
// If no argument, list current highlighting.
if (!init && ends_excmd((uint8_t)(*line))) {
for (int i = 1; i <= highlight_ga.ga_len && !got_int; i++) {
@@ -901,9 +880,11 @@ void do_highlight(const char *line, const bool forceit, const bool init)
return;
}
+ bool dodefault = false;
+
// Isolate the name.
- name_end = (const char *)skiptowhite(line);
- linep = (const char *)skipwhite(name_end);
+ const char *name_end = (const char *)skiptowhite(line);
+ const char *linep = (const char *)skipwhite(name_end);
// Check for "default" argument.
if (strncmp(line, "default", (size_t)(name_end - line)) == 0) {
@@ -913,6 +894,9 @@ void do_highlight(const char *line, const bool forceit, const bool init)
linep = (const char *)skipwhite(name_end);
}
+ bool doclear = false;
+ bool dolink = false;
+
// Check for "clear" or "link" argument.
if (strncmp(line, "clear", (size_t)(name_end - line)) == 0) {
doclear = true;
@@ -922,7 +906,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
// ":highlight {group-name}": list highlighting for one group.
if (!doclear && !dolink && ends_excmd((uint8_t)(*linep))) {
- id = syn_name2id_len(line, (size_t)(name_end - line));
+ int id = syn_name2id_len(line, (size_t)(name_end - line));
if (id == 0) {
semsg(_("E411: highlight group not found: %s"), line);
} else {
@@ -1024,11 +1008,11 @@ void do_highlight(const char *line, const bool forceit, const bool init)
}
// Find the group name in the table. If it does not exist yet, add it.
- id = syn_check_group(line, (size_t)(name_end - line));
+ int id = syn_check_group(line, (size_t)(name_end - line));
if (id == 0) { // Failed (out of memory).
return;
}
- idx = id - 1; // Index is ID minus one.
+ int idx = id - 1; // Index is ID minus one.
// Return if "default" was used and the group already has settings
if (dodefault && hl_has_settings(idx, true)) {
@@ -1036,8 +1020,8 @@ void do_highlight(const char *line, const bool forceit, const bool init)
}
// Make a copy so we can check if any attribute actually changed
- item_before = hl_table[idx];
- is_normal_group = (strcmp(hl_table[idx].sg_name_u, "NORMAL") == 0);
+ HlGroup item_before = hl_table[idx];
+ bool is_normal_group = (strcmp(hl_table[idx].sg_name_u, "NORMAL") == 0);
// Clear the highlighting for ":hi clear {group}" and ":hi clear".
if (doclear || (forceit && init)) {
@@ -1047,11 +1031,16 @@ void do_highlight(const char *line, const bool forceit, const bool init)
}
}
+ bool did_change = false;
+ bool error = false;
+
char key[64];
char arg[512];
if (!doclear) {
+ const char *arg_start;
+
while (!ends_excmd((uint8_t)(*linep))) {
- key_start = linep;
+ const char *key_start = linep;
if (*linep == '=') {
semsg(_("E415: unexpected equal sign: %s"), key_start);
error = true;
@@ -1071,7 +1060,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((char_u *)key);
+ vim_strup(key);
linep = (const char *)skipwhite(linep);
if (strcmp(key, "NONE") == 0) {
@@ -1128,12 +1117,12 @@ void do_highlight(const char *line, const bool forceit, const bool init)
if (strcmp(key, "TERM") == 0
|| strcmp(key, "CTERM") == 0
|| strcmp(key, "GUI") == 0) {
- attr = 0;
- off = 0;
+ int attr = 0;
+ int off = 0;
int i;
while (arg[off] != NUL) {
for (i = ARRAY_SIZE(hl_attr_table); --i >= 0;) {
- len = (int)strlen(hl_name_table[i]);
+ int len = (int)strlen(hl_name_table[i]);
if (STRNICMP(arg + off, hl_name_table[i], len) == 0) {
attr |= hl_attr_table[i];
off += len;
@@ -1183,6 +1172,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
hl_table[idx].sg_cterm_bold = false;
}
+ int color;
if (ascii_isdigit(*arg)) {
color = atoi(arg);
} else if (STRICMP(arg, "fg") == 0) {
@@ -1203,7 +1193,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
}
} else {
// Reduce calls to STRICMP a bit, it can be slow.
- off = TOUPPER_ASC(*arg);
+ int off = TOUPPER_ASC(*arg);
int i;
for (i = ARRAY_SIZE(color_names); --i >= 0;) {
if (off == color_names[i][0]
@@ -1360,6 +1350,8 @@ void do_highlight(const char *line, const bool forceit, const bool init)
}
}
+ bool did_highlight_changed = false;
+
if (!error && is_normal_group) {
// Need to update all groups, because they might be using "bg" and/or
// "fg", which have been changed now.
@@ -1471,7 +1463,7 @@ static void highlight_list_one(const int id)
const HlGroup *sgp = &hl_table[id - 1]; // index is ID minus one
bool didh = false;
- if (message_filtered((char *)sgp->sg_name)) {
+ if (message_filtered(sgp->sg_name)) {
return;
}
@@ -1505,7 +1497,7 @@ static void highlight_list_one(const int id)
didh = true;
msg_puts_attr("links to", HL_ATTR(HLF_D));
msg_putchar(' ');
- msg_outtrans((char *)hl_table[hl_table[id - 1].sg_link - 1].sg_name);
+ msg_outtrans(hl_table[hl_table[id - 1].sg_link - 1].sg_name);
}
if (!didh) {
@@ -1527,7 +1519,7 @@ Dictionary get_global_hl_defs(Arena *arena)
hlattrs2dict(&attrs, syn_attr2entry(h->sg_attr), true);
} else if (h->sg_link > 0) {
attrs = arena_dict(arena, 1);
- char *link = (char *)hl_table[h->sg_link - 1].sg_name;
+ char *link = hl_table[h->sg_link - 1].sg_name;
PUT_C(attrs, "link", STRING_OBJ(cstr_as_string(link)));
}
PUT_C(rv, (char *)h->sg_name, DICTIONARY_OBJ(attrs));
@@ -1544,8 +1536,6 @@ Dictionary get_global_hl_defs(Arena *arena)
static bool highlight_list_arg(const int id, bool didh, const int type, int iarg, const char *sarg,
const char *const name)
{
- char buf[100];
-
if (got_int) {
return false;
}
@@ -1554,6 +1544,7 @@ static bool highlight_list_arg(const int id, bool didh, const int type, int iarg
return didh;
}
+ char buf[100];
const char *ts = buf;
if (type == LIST_INT) {
snprintf((char *)buf, sizeof(buf), "%d", iarg - 1);
@@ -1562,12 +1553,17 @@ static bool highlight_list_arg(const int id, bool didh, const int type, int iarg
} else { // type == LIST_ATTR
buf[0] = NUL;
for (int i = 0; hl_attr_table[i] != 0; i++) {
- if (iarg & hl_attr_table[i]) {
+ if (((hl_attr_table[i] & HL_UNDERLINE_MASK)
+ && ((iarg & HL_UNDERLINE_MASK) == hl_attr_table[i]))
+ || (!(hl_attr_table[i] & HL_UNDERLINE_MASK)
+ && (iarg & hl_attr_table[i]))) {
if (buf[0] != NUL) {
xstrlcat(buf, ",", 100);
}
xstrlcat(buf, hl_name_table[i], 100);
- iarg &= ~hl_attr_table[i]; // don't want "inverse"
+ if (!(hl_attr_table[i] & HL_UNDERLINE_MASK)) {
+ iarg &= ~hl_attr_table[i]; // don't want "inverse"
+ }
}
}
}
@@ -1594,19 +1590,24 @@ static bool highlight_list_arg(const int id, bool didh, const int type, int iarg
const char *highlight_has_attr(const int id, const int flag, const int modec)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
{
- int attr;
-
if (id <= 0 || id > highlight_ga.ga_len) {
return NULL;
}
+ int attr;
+
if (modec == 'g') {
attr = hl_table[id - 1].sg_gui;
} else {
attr = hl_table[id - 1].sg_cterm;
}
- return (attr & flag) ? "1" : NULL;
+ if (flag & HL_UNDERLINE_MASK) {
+ int ul = attr & HL_UNDERLINE_MASK;
+ return ul == flag ? "1" : NULL;
+ } else {
+ return (attr & flag) ? "1" : NULL;
+ }
}
/// Return color name of the given highlight group
@@ -1622,7 +1623,6 @@ const char *highlight_color(const int id, const char *const what, const int mode
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
static char name[20];
- int n;
bool fg = false;
bool sp = false;
bool font = false;
@@ -1641,6 +1641,9 @@ const char *highlight_color(const int id, const char *const what, const int mode
} else if (!(TOLOWER_ASC(what[0]) == 'b' && TOLOWER_ASC(what[1]) == 'g')) {
return NULL;
}
+
+ int n;
+
if (modec == 'g') {
if (what[2] == '#' && ui_rgb_attached()) {
if (fg) {
@@ -1702,7 +1705,7 @@ bool syn_list_header(const bool did_header, const int outlen, const int id, bool
if (got_int) {
return true;
}
- msg_outtrans((char *)hl_table[id - 1].sg_name);
+ msg_outtrans(hl_table[id - 1].sg_name);
name_col = msg_col;
endcol = 15;
} else if ((ui_has(kUIMessages) || msg_silent) && !force_newline) {
@@ -1795,7 +1798,7 @@ int syn_name2id_len(const char *name, size_t len)
// Avoid alloc()/free(), these are slow too.
memcpy(name_u, name, len);
name_u[len] = '\0';
- vim_strup((char_u *)name_u);
+ vim_strup(name_u);
// map_get(..., int) returns 0 when no key is present, which is
// the expected value for missing highlight group.
@@ -1804,10 +1807,10 @@ int syn_name2id_len(const char *name, size_t len)
/// Lookup a highlight group name and return its attributes.
/// Return zero if not found.
-int syn_name2attr(const char_u *name)
+int syn_name2attr(const char *name)
FUNC_ATTR_NONNULL_ALL
{
- int id = syn_name2id((char *)name);
+ int id = syn_name2id(name);
if (id != 0) {
return syn_id2attr(id);
@@ -1823,10 +1826,10 @@ int highlight_exists(const char *name)
/// Return the name of highlight group "id".
/// When not a valid ID return an empty string.
-char_u *syn_id2name(int id)
+char *syn_id2name(int id)
{
if (id <= 0 || id > highlight_ga.ga_len) {
- return (char_u *)"";
+ return "";
}
return hl_table[id - 1].sg_name;
}
@@ -1896,7 +1899,7 @@ static int syn_add_group(const char *name, size_t len)
// Append another syntax_highlight entry.
HlGroup *hlgp = GA_APPEND_VIA_PTR(HlGroup, &highlight_ga);
CLEAR_POINTER(hlgp);
- hlgp->sg_name = (char_u *)arena_memdupz(&highlight_arena, name, len);
+ hlgp->sg_name = arena_memdupz(&highlight_arena, name, len);
hlgp->sg_rgb_bg = -1;
hlgp->sg_rgb_fg = -1;
hlgp->sg_rgb_sp = -1;
@@ -1908,7 +1911,7 @@ static int syn_add_group(const char *name, size_t len)
hlgp->sg_parent = scoped_parent;
// will get set to false by caller if settings are added
hlgp->sg_cleared = true;
- vim_strup((char_u *)hlgp->sg_name_u);
+ vim_strup(hlgp->sg_name_u);
int id = highlight_ga.ga_len; // ID is index plus one
@@ -2048,17 +2051,15 @@ static void combine_stl_hlt(int id, int id_S, int id_alt, int hlcnt, int i, int
/// screen redraw after any :highlight command.
void highlight_changed(void)
{
- int id;
char userhl[30]; // use 30 to avoid compiler warning
int id_S = -1;
int id_SNC = 0;
- int hlcnt;
need_highlight_changed = false;
/// Translate builtin highlight groups into attributes for quick lookup.
for (int hlf = 0; hlf < HLF_COUNT; hlf++) {
- id = syn_check_group(hlf_names[hlf], strlen(hlf_names[hlf]));
+ int id = syn_check_group(hlf_names[hlf], strlen(hlf_names[hlf]));
if (id == 0) {
abort();
}
@@ -2097,7 +2098,7 @@ void highlight_changed(void)
// Must to be in there simultaneously in case of table overflows in
// get_attr_entry()
ga_grow(&highlight_ga, 10);
- hlcnt = highlight_ga.ga_len;
+ int hlcnt = highlight_ga.ga_len;
if (id_S == -1) {
// Make sure id_S is always valid to simplify code below. Use the last entry
CLEAR_POINTER(&hl_table[hlcnt + 9]);
@@ -2105,7 +2106,7 @@ void highlight_changed(void)
}
for (int i = 0; i < 9; i++) {
snprintf(userhl, sizeof(userhl), "User%d", i + 1);
- id = syn_name2id(userhl);
+ int id = syn_name2id(userhl);
if (id == 0) {
highlight_user[i] = 0;
highlight_stlnc[i] = 0;
@@ -2171,12 +2172,10 @@ void set_context_in_highlight_cmd(expand_T *xp, const char *arg)
/// List highlighting matches in a nice way.
static void highlight_list(void)
{
- int i;
-
- for (i = 10; --i >= 0;) {
+ for (int i = 10; --i >= 0;) {
highlight_list_two(i, HL_ATTR(HLF_D));
}
- for (i = 40; --i >= 0;) {
+ for (int i = 40; --i >= 0;) {
highlight_list_two(99, 0);
}
}
@@ -2921,9 +2920,9 @@ color_name_table_T color_name_table[] = {
/// return the hex value or -1 if could not find a correct value
RgbValue name_to_color(const char *name, int *idx)
{
- if (name[0] == '#' && isxdigit(name[1]) && isxdigit(name[2])
- && isxdigit(name[3]) && isxdigit(name[4]) && isxdigit(name[5])
- && isxdigit(name[6]) && name[7] == NUL) {
+ if (name[0] == '#' && isxdigit((uint8_t)name[1]) && isxdigit((uint8_t)name[2])
+ && isxdigit((uint8_t)name[3]) && isxdigit((uint8_t)name[4]) && isxdigit((uint8_t)name[5])
+ && isxdigit((uint8_t)name[6]) && name[7] == NUL) {
// rgb hex string
*idx = kColorIdxHex;
return (RgbValue)strtol((char *)(name + 1), NULL, 16);
@@ -2947,7 +2946,6 @@ RgbValue name_to_color(const char *name, int *idx)
} else { // found match
*idx = m;
return color_name_table[m].color;
- break;
}
}