diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-01-25 18:31:31 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-01-25 18:31:31 +0000 |
commit | 9243becbedbb6a1592208051f8fa2b090dcc5e7d (patch) | |
tree | 607c2a862ec3f4399b8766383f6f8e04c4aa43b4 /src/nvim/highlight.c | |
parent | 9e40b6e9e1bc67f2d856adb837ee64dd0e25b717 (diff) | |
parent | 3c48d3c83fc21dbc0841f9210f04bdb073d73cd1 (diff) | |
download | rneovim-9243becbedbb6a1592208051f8fa2b090dcc5e7d.tar.gz rneovim-9243becbedbb6a1592208051f8fa2b090dcc5e7d.tar.bz2 rneovim-9243becbedbb6a1592208051f8fa2b090dcc5e7d.zip |
Merge remote-tracking branch 'upstream/master' into usermarksusermarks
Diffstat (limited to 'src/nvim/highlight.c')
-rw-r--r-- | src/nvim/highlight.c | 174 |
1 files changed, 92 insertions, 82 deletions
diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c index d6a18fcf8e..9dab91cc2b 100644 --- a/src/nvim/highlight.c +++ b/src/nvim/highlight.c @@ -3,18 +3,32 @@ // highlight.c: low level code for UI and syntax highlighting +#include <assert.h> +#include <inttypes.h> +#include <limits.h> +#include <string.h> + +#include "klib/kvec.h" +#include "lauxlib.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" +#include "nvim/api/ui.h" #include "nvim/decoration_provider.h" #include "nvim/drawscreen.h" +#include "nvim/gettext.h" +#include "nvim/globals.h" #include "nvim/highlight.h" #include "nvim/highlight_defs.h" #include "nvim/highlight_group.h" +#include "nvim/log.h" #include "nvim/lua/executor.h" +#include "nvim/macros.h" #include "nvim/map.h" +#include "nvim/memory.h" #include "nvim/message.h" #include "nvim/option.h" #include "nvim/popupmenu.h" +#include "nvim/types.h" #include "nvim/ui.h" #include "nvim/vim.h" @@ -115,19 +129,15 @@ static int get_attr_entry(HlEntry entry) /// When a UI connects, we need to send it the table of highlights used so far. void ui_send_all_hls(UI *ui) { - if (ui->hl_attr_define) { - for (size_t i = 1; i < kv_size(attr_entries); i++) { - Array inspect = hl_inspect((int)i); - ui->hl_attr_define(ui, (Integer)i, kv_A(attr_entries, i).attr, - kv_A(attr_entries, i).attr, inspect); - api_free_array(inspect); - } + for (size_t i = 1; i < kv_size(attr_entries); i++) { + Array inspect = hl_inspect((int)i); + remote_ui_hl_attr_define(ui, (Integer)i, kv_A(attr_entries, i).attr, + kv_A(attr_entries, i).attr, inspect); + api_free_array(inspect); } - if (ui->hl_group_set) { - for (size_t hlf = 0; hlf < HLF_COUNT; hlf++) { - ui->hl_group_set(ui, cstr_as_string((char *)hlf_names[hlf]), - highlight_attr[hlf]); - } + for (size_t hlf = 0; hlf < HLF_COUNT; hlf++) { + remote_ui_hl_group_set(ui, cstr_as_string((char *)hlf_names[hlf]), + highlight_attr[hlf]); } } @@ -141,10 +151,9 @@ int hl_get_syn_attr(int ns_id, int idx, HlAttrs at_en) || at_en.rgb_ae_attr != 0 || ns_id != 0) { return get_attr_entry((HlEntry){ .attr = at_en, .kind = kHlSyntax, .id1 = idx, .id2 = ns_id }); - } else { - // If all the fields are cleared, clear the attr field back to default value - return 0; } + // If all the fields are cleared, clear the attr field back to default value + return 0; } void ns_hl_def(NS ns_id, int hl_id, HlAttrs attrs, int link_id, Dict(highlight) *dict) @@ -223,7 +232,7 @@ int ns_get_hl(NS *ns_hl, int hl_id, bool link, bool nodefault) } } - it.attr_id = fallback ? -1 : hl_get_syn_attr((int)ns_id, hl_id, attrs); + it.attr_id = fallback ? -1 : hl_get_syn_attr(ns_id, hl_id, attrs); it.version = p->hl_valid - tmp; it.is_default = attrs.rgb_ae_attr & HL_DEFAULT; it.link_global = attrs.rgb_ae_attr & HL_GLOBAL; @@ -238,12 +247,11 @@ int ns_get_hl(NS *ns_hl, int hl_id, bool link, bool nodefault) if (link) { if (it.attr_id >= 0) { return 0; - } else { - if (it.link_global) { - *ns_hl = 0; - } - return it.link_id; } + if (it.link_global) { + *ns_hl = 0; + } + return it.link_id; } else { return it.attr_id; } @@ -406,8 +414,8 @@ void update_ns_hl(int ns_id) } int *hl_attrs = **alloc; - for (int hlf = 0; hlf < (int)HLF_COUNT; hlf++) { - int id = syn_check_group(hlf_names[hlf], STRLEN(hlf_names[hlf])); + for (int hlf = 0; hlf < HLF_COUNT; hlf++) { + int id = syn_check_group(hlf_names[hlf], strlen(hlf_names[hlf])); bool optional = (hlf == HLF_INACTIVE || hlf == HLF_NFLOAT); hl_attrs[hlf] = hl_get_ui_attr(ns_id, hlf, id, optional); } @@ -641,7 +649,7 @@ int hl_blend_attrs(int back_attr, int front_attr, bool *through) cattrs = battrs; cattrs.rgb_fg_color = rgb_blend(ratio, battrs.rgb_fg_color, fattrs.rgb_bg_color); - if (cattrs.rgb_ae_attr & (HL_ANY_UNDERLINE)) { + if (cattrs.rgb_ae_attr & (HL_UNDERLINE_MASK)) { cattrs.rgb_sp_color = rgb_blend(ratio, battrs.rgb_sp_color, fattrs.rgb_bg_color); } else { @@ -659,7 +667,7 @@ int hl_blend_attrs(int back_attr, int front_attr, bool *through) } cattrs.rgb_fg_color = rgb_blend(ratio/2, battrs.rgb_fg_color, fattrs.rgb_fg_color); - if (cattrs.rgb_ae_attr & (HL_ANY_UNDERLINE)) { + if (cattrs.rgb_ae_attr & (HL_UNDERLINE_MASK)) { cattrs.rgb_sp_color = rgb_blend(ratio/2, battrs.rgb_bg_color, fattrs.rgb_sp_color); } else { @@ -729,7 +737,7 @@ static int hl_cterm2rgb_color(int nr) 0x08, 0x12, 0x1C, 0x26, 0x30, 0x3A, 0x44, 0x4E, 0x58, 0x62, 0x6C, 0x76, 0x80, 0x8A, 0x94, 0x9E, 0xA8, 0xB2, 0xBC, 0xC6, 0xD0, 0xDA, 0xE4, 0xEE }; - static char_u ansi_table[16][4] = { + static uint8_t ansi_table[16][4] = { // R G B idx { 0, 0, 0, 1 }, // black { 224, 0, 0, 2 }, // dark red @@ -788,7 +796,7 @@ HlAttrs syn_attr2entry(int attr) } /// Gets highlight description for id `attr_id` as a map. -Dictionary hl_get_attr_by_id(Integer attr_id, Boolean rgb, Error *err) +Dictionary hl_get_attr_by_id(Integer attr_id, Boolean rgb, Arena *arena, Error *err) { Dictionary dic = ARRAY_DICT_INIT; @@ -801,66 +809,68 @@ Dictionary hl_get_attr_by_id(Integer attr_id, Boolean rgb, Error *err) "Invalid attribute id: %" PRId64, attr_id); return dic; } - - return hlattrs2dict(NULL, syn_attr2entry((int)attr_id), rgb); + Dictionary retval = arena_dict(arena, HLATTRS_DICT_SIZE); + hlattrs2dict(&retval, syn_attr2entry((int)attr_id), rgb); + return retval; } /// Converts an HlAttrs into Dictionary /// -/// @param[out] hl optional pre-allocated dictionary for return value -/// if present, must be allocated with at least 16 elements! +/// @param[in/out] hl Dictionary with pre-allocated space for HLATTRS_DICT_SIZE elements /// @param[in] aep data to convert /// @param use_rgb use 'gui*' settings if true, else resorts to 'cterm*' -Dictionary hlattrs2dict(Dictionary *hl_alloc, HlAttrs ae, bool use_rgb) +void hlattrs2dict(Dictionary *dict, HlAttrs ae, bool use_rgb) { + assert(dict->capacity >= HLATTRS_DICT_SIZE); // at most 16 items + Dictionary hl = *dict; int mask = use_rgb ? ae.rgb_ae_attr : ae.cterm_ae_attr; - Dictionary hl = ARRAY_DICT_INIT; - if (hl_alloc) { - hl = *hl_alloc; - } else { - kv_ensure_space(hl, 16); + + if (mask & HL_INVERSE) { + PUT_C(hl, "reverse", BOOLEAN_OBJ(true)); } if (mask & HL_BOLD) { PUT_C(hl, "bold", BOOLEAN_OBJ(true)); } - if (mask & HL_STANDOUT) { - PUT_C(hl, "standout", BOOLEAN_OBJ(true)); + if (mask & HL_ITALIC) { + PUT_C(hl, "italic", BOOLEAN_OBJ(true)); } - if (mask & HL_UNDERLINE) { + switch (mask & HL_UNDERLINE_MASK) { + case HL_UNDERLINE: PUT_C(hl, "underline", BOOLEAN_OBJ(true)); - } - - if (mask & HL_UNDERCURL) { - PUT_C(hl, "undercurl", BOOLEAN_OBJ(true)); - } + break; - if (mask & HL_UNDERDOUBLE) { + case HL_UNDERDOUBLE: PUT_C(hl, "underdouble", BOOLEAN_OBJ(true)); - } + break; - if (mask & HL_UNDERDOTTED) { + case HL_UNDERCURL: + PUT_C(hl, "undercurl", BOOLEAN_OBJ(true)); + break; + + case HL_UNDERDOTTED: PUT_C(hl, "underdotted", BOOLEAN_OBJ(true)); - } + break; - if (mask & HL_UNDERDASHED) { + case HL_UNDERDASHED: PUT_C(hl, "underdashed", BOOLEAN_OBJ(true)); + break; } - if (mask & HL_ITALIC) { - PUT_C(hl, "italic", BOOLEAN_OBJ(true)); - } - - if (mask & HL_INVERSE) { - PUT_C(hl, "reverse", BOOLEAN_OBJ(true)); + if (mask & HL_STANDOUT) { + PUT_C(hl, "standout", BOOLEAN_OBJ(true)); } if (mask & HL_STRIKETHROUGH) { PUT_C(hl, "strikethrough", BOOLEAN_OBJ(true)); } + if (mask & HL_ALTFONT) { + PUT_C(hl, "altfont", BOOLEAN_OBJ(true)); + } + if (mask & HL_NOCOMBINE) { PUT_C(hl, "nocombine", BOOLEAN_OBJ(true)); } @@ -899,14 +909,7 @@ Dictionary hlattrs2dict(Dictionary *hl_alloc, HlAttrs ae, bool use_rgb) PUT_C(hl, "blend", INTEGER_OBJ(ae.hl_blend)); } - if (hl_alloc) { - *hl_alloc = hl; - return hl; - } else { - Dictionary allocated = copy_dictionary(hl); - kv_destroy(hl); - return allocated; - } + *dict = hl; } HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, Error *err) @@ -923,32 +926,37 @@ HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, Error *e m = m | flag; \ } + CHECK_FLAG(dict, mask, reverse, , HL_INVERSE); CHECK_FLAG(dict, mask, bold, , HL_BOLD); - CHECK_FLAG(dict, mask, standout, , HL_STANDOUT); + CHECK_FLAG(dict, mask, italic, , HL_ITALIC); CHECK_FLAG(dict, mask, underline, , HL_UNDERLINE); - CHECK_FLAG(dict, mask, undercurl, , HL_UNDERCURL); CHECK_FLAG(dict, mask, underdouble, , HL_UNDERDOUBLE); + CHECK_FLAG(dict, mask, undercurl, , HL_UNDERCURL); CHECK_FLAG(dict, mask, underdotted, , HL_UNDERDOTTED); CHECK_FLAG(dict, mask, underdashed, , HL_UNDERDASHED); - CHECK_FLAG(dict, mask, italic, , HL_ITALIC); - CHECK_FLAG(dict, mask, reverse, , HL_INVERSE); + CHECK_FLAG(dict, mask, standout, , HL_STANDOUT); CHECK_FLAG(dict, mask, strikethrough, , HL_STRIKETHROUGH); + CHECK_FLAG(dict, mask, altfont, , HL_ALTFONT); + if (use_rgb) { + CHECK_FLAG(dict, mask, fg_indexed, , HL_FG_INDEXED); + CHECK_FLAG(dict, mask, bg_indexed, , HL_BG_INDEXED); + } CHECK_FLAG(dict, mask, nocombine, , HL_NOCOMBINE); CHECK_FLAG(dict, mask, default, _, HL_DEFAULT); if (HAS_KEY(dict->fg)) { - fg = object_to_color(dict->fg, "fg", true, err); + fg = object_to_color(dict->fg, "fg", use_rgb, err); } else if (HAS_KEY(dict->foreground)) { - fg = object_to_color(dict->foreground, "foreground", true, err); + fg = object_to_color(dict->foreground, "foreground", use_rgb, err); } if (ERROR_SET(err)) { return hlattrs; } if (HAS_KEY(dict->bg)) { - bg = object_to_color(dict->bg, "bg", true, err); + bg = object_to_color(dict->bg, "bg", use_rgb, err); } else if (HAS_KEY(dict->background)) { - bg = object_to_color(dict->background, "background", true, err); + bg = object_to_color(dict->background, "background", use_rgb, err); } if (ERROR_SET(err)) { return hlattrs; @@ -1004,13 +1012,14 @@ HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, Error *e } cterm_mask_provided = true; + CHECK_FLAG(cterm, cterm_mask, reverse, , HL_INVERSE); CHECK_FLAG(cterm, cterm_mask, bold, , HL_BOLD); - CHECK_FLAG(cterm, cterm_mask, standout, , HL_STANDOUT); + CHECK_FLAG(cterm, cterm_mask, italic, , HL_ITALIC); CHECK_FLAG(cterm, cterm_mask, underline, , HL_UNDERLINE); CHECK_FLAG(cterm, cterm_mask, undercurl, , HL_UNDERCURL); - CHECK_FLAG(cterm, cterm_mask, italic, , HL_ITALIC); - CHECK_FLAG(cterm, cterm_mask, reverse, , HL_INVERSE); + CHECK_FLAG(cterm, cterm_mask, standout, , HL_STANDOUT); CHECK_FLAG(cterm, cterm_mask, strikethrough, , HL_STRIKETHROUGH); + CHECK_FLAG(cterm, cterm_mask, altfont, , HL_ALTFONT); CHECK_FLAG(cterm, cterm_mask, nocombine, , HL_NOCOMBINE); } else if (dict->cterm.type == kObjectTypeArray && dict->cterm.data.array.size == 0) { // empty list from Lua API should clear all cterm attributes @@ -1035,11 +1044,11 @@ HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, Error *e } } - // apply gui mask as default for cterm mask - if (!cterm_mask_provided) { - cterm_mask = mask; - } if (use_rgb) { + // apply gui mask as default for cterm mask + if (!cterm_mask_provided) { + cterm_mask = mask; + } hlattrs.rgb_ae_attr = mask; hlattrs.rgb_bg_color = bg; hlattrs.rgb_fg_color = fg; @@ -1049,9 +1058,9 @@ HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, Error *e hlattrs.cterm_fg_color = ctermfg == -1 ? 0 : ctermfg + 1; hlattrs.cterm_ae_attr = cterm_mask; } else { - hlattrs.cterm_bg_color = ctermbg == -1 ? 0 : ctermbg + 1; - hlattrs.cterm_fg_color = ctermfg == -1 ? 0 : ctermfg + 1; - hlattrs.cterm_ae_attr = cterm_mask; + hlattrs.cterm_bg_color = bg == -1 ? 0 : bg + 1; + hlattrs.cterm_fg_color = fg == -1 ? 0 : fg + 1; + hlattrs.cterm_ae_attr = mask; } return hlattrs; @@ -1086,6 +1095,7 @@ int object_to_color(Object val, char *key, bool rgb, Error *err) Array hl_inspect(int attr) { + // TODO(bfredl): use arena allocation Array ret = ARRAY_DICT_INIT; if (hlstate_active) { hl_inspect_impl(&ret, attr); |