aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2023-09-12 11:54:36 +0200
committerbfredl <bjorn.linse@gmail.com>2023-09-13 10:37:48 +0200
commita6d745865a7f8b17f016b1879ed28376fed7b6b2 (patch)
tree94c5da3018d35b4a4fce1a29b725567190859cf5
parent1c4a93b591828bc6970edad6282c004eb46f0b2d (diff)
downloadrneovim-a6d745865a7f8b17f016b1879ed28376fed7b6b2.tar.gz
rneovim-a6d745865a7f8b17f016b1879ed28376fed7b6b2.tar.bz2
rneovim-a6d745865a7f8b17f016b1879ed28376fed7b6b2.zip
refactor(highlight): merge redundant attr_entries and attr_entry_ids structs
An insert-only set now defines a monotonically increasing ordering by itself. It can be used to both lookup the key from index, and vice versa.
-rw-r--r--src/nvim/highlight.c64
-rw-r--r--src/nvim/highlight_defs.h1
-rw-r--r--src/nvim/map.c3
-rw-r--r--src/nvim/map.h2
4 files changed, 33 insertions, 37 deletions
diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c
index 29e5db7a96..df4bffdac3 100644
--- a/src/nvim/highlight.c
+++ b/src/nvim/highlight.c
@@ -40,13 +40,13 @@
static bool hlstate_active = false;
-static kvec_t(HlEntry) attr_entries = KV_INITIAL_VALUE;
-
-static Map(HlEntry, int) attr_entry_ids = MAP_INIT;
+static Set(HlEntry) attr_entries = SET_INIT;
static Map(int, int) combine_attr_entries = MAP_INIT;
static Map(int, int) blend_attr_entries = MAP_INIT;
static Map(int, int) blendthrough_attr_entries = MAP_INIT;
+#define attr_entry(i) attr_entries.keys[i]
+
/// highlight entries private to a namespace
static Map(ColorKey, ColorItem) ns_hls;
typedef int NSHlAttr[HLF_COUNT + 1];
@@ -55,8 +55,8 @@ static PMap(int) ns_hl_attr;
void highlight_init(void)
{
// index 0 is no attribute, add dummy entry:
- kv_push(attr_entries, ((HlEntry){ .attr = HLATTRS_INIT, .kind = kHlUnknown,
- .id1 = 0, .id2 = 0 }));
+ set_put(HlEntry, &attr_entries, ((HlEntry){ .attr = HLATTRS_INIT, .kind = kHlInvalid,
+ .id1 = 0, .id2 = 0 }));
}
/// @return true if hl table was reset
@@ -77,6 +77,7 @@ bool highlight_use_hlstate(void)
/// @return 0 for error.
static int get_attr_entry(HlEntry entry)
{
+ bool retried = false;
if (!hlstate_active) {
// This information will not be used, erase it and reduce the table size.
entry.kind = kHlUnknown;
@@ -84,17 +85,19 @@ static int get_attr_entry(HlEntry entry)
entry.id2 = 0;
}
- int id = map_get(HlEntry, int)(&attr_entry_ids, entry);
- if (id > 0) {
- return id;
+retry: {}
+ MhPutStatus status;
+ uint32_t k = set_put_idx(HlEntry, &attr_entries, entry, &status);
+ if (status == kMHExisting) {
+ return (int)k;
}
static bool recursive = false;
- if (kv_size(attr_entries) > MAX_TYPENR) {
+ if (set_size(&attr_entries) > MAX_TYPENR) {
// Running out of attribute entries! remove all attributes, and
// compute new ones for all groups.
// When called recursively, we are really out of numbers.
- if (recursive) {
+ if (recursive || retried) {
emsg(_("E424: Too many different highlighting attributes in use"));
return 0;
}
@@ -107,17 +110,12 @@ static int get_attr_entry(HlEntry entry)
// This entry is now invalid, don't put it
return 0;
}
+ retried = true;
+ goto retry;
}
- size_t next_id = kv_size(attr_entries);
- if (next_id > INT_MAX) {
- ELOG("The index on attr_entries has overflowed");
- return 0;
- }
- id = (int)next_id;
- kv_push(attr_entries, entry);
-
- map_put(HlEntry, int)(&attr_entry_ids, entry, id);
+ // new attr id, send event to remote ui:s
+ int id = (int)k;
Array inspect = hl_inspect(id);
@@ -131,10 +129,10 @@ 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)
{
- for (size_t i = 1; i < kv_size(attr_entries); i++) {
+ for (size_t i = 1; i < set_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);
+ HlAttrs attr = attr_entry(i).attr;
+ remote_ui_hl_attr_define(ui, (Integer)i, attr, attr, inspect);
api_free_array(inspect);
}
for (size_t hlf = 0; hlf < HLF_COUNT; hlf++) {
@@ -364,7 +362,7 @@ void update_window_hl(win_T *wp, bool invalid)
// if blend= attribute is not set, 'winblend' value overrides it.
if (wp->w_floating && wp->w_p_winbl > 0) {
- HlEntry entry = kv_A(attr_entries, wp->w_hl_attr_normal);
+ HlEntry entry = attr_entry(wp->w_hl_attr_normal);
if (entry.attr.hl_blend == -1) {
entry.attr.hl_blend = (int)wp->w_p_winbl;
wp->w_hl_attr_normal = get_attr_entry(entry);
@@ -401,7 +399,7 @@ void update_window_hl(win_T *wp, bool invalid)
// if blend= attribute is not set, 'winblend' value overrides it.
if (wp->w_floating && wp->w_p_winbl > 0) {
- HlEntry entry = kv_A(attr_entries, wp->w_hl_attr_normalnc);
+ HlEntry entry = attr_entry(wp->w_hl_attr_normalnc);
if (entry.attr.hl_blend == -1) {
entry.attr.hl_blend = (int)wp->w_p_winbl;
wp->w_hl_attr_normalnc = get_attr_entry(entry);
@@ -490,8 +488,8 @@ int hl_get_term_attr(HlAttrs *aep)
void clear_hl_tables(bool reinit)
{
if (reinit) {
- kv_size(attr_entries) = 1;
- map_clear(HlEntry, &attr_entry_ids);
+ set_clear(HlEntry, &attr_entries);
+ highlight_init();
map_clear(int, &combine_attr_entries);
map_clear(int, &blend_attr_entries);
map_clear(int, &blendthrough_attr_entries);
@@ -500,8 +498,7 @@ void clear_hl_tables(bool reinit)
highlight_changed();
screen_invalidate_highlights();
} else {
- kv_destroy(attr_entries);
- map_destroy(HlEntry, &attr_entry_ids);
+ set_destroy(HlEntry, &attr_entries);
map_destroy(int, &combine_attr_entries);
map_destroy(int, &blend_attr_entries);
map_destroy(int, &blendthrough_attr_entries);
@@ -809,11 +806,11 @@ static int hl_cterm2rgb_color(int nr)
/// Get highlight attributes for a attribute code
HlAttrs syn_attr2entry(int attr)
{
- if (attr <= 0 || attr >= (int)kv_size(attr_entries)) {
+ if (attr <= 0 || attr >= (int)set_size(&attr_entries)) {
// invalid attribute code, or the tables were cleared
return HLATTRS_INIT;
}
- return kv_A(attr_entries, attr).attr;
+ return attr_entry(attr).attr;
}
/// Gets highlight description for id `attr_id` as a map.
@@ -825,7 +822,7 @@ Dictionary hl_get_attr_by_id(Integer attr_id, Boolean rgb, Arena *arena, Error *
return dic;
}
- if (attr_id <= 0 || attr_id >= (int)kv_size(attr_entries)) {
+ if (attr_id <= 0 || attr_id >= (int)set_size(&attr_entries)) {
api_set_error(err, kErrorTypeException,
"Invalid attribute id: %" PRId64, attr_id);
return dic;
@@ -1132,11 +1129,11 @@ Array hl_inspect(int attr)
static void hl_inspect_impl(Array *arr, int attr)
{
Dictionary item = ARRAY_DICT_INIT;
- if (attr <= 0 || attr >= (int)kv_size(attr_entries)) {
+ if (attr <= 0 || attr >= (int)set_size(&attr_entries)) {
return;
}
- HlEntry e = kv_A(attr_entries, attr);
+ HlEntry e = attr_entry(attr);
switch (e.kind) {
case kHlSyntax:
PUT(item, "kind", CSTR_TO_OBJ("syntax"));
@@ -1165,6 +1162,7 @@ static void hl_inspect_impl(Array *arr, int attr)
return;
case kHlUnknown:
+ case kHlInvalid:
return;
}
PUT(item, "id", INTEGER_OBJ(attr));
diff --git a/src/nvim/highlight_defs.h b/src/nvim/highlight_defs.h
index f690b57148..ae58ff8696 100644
--- a/src/nvim/highlight_defs.h
+++ b/src/nvim/highlight_defs.h
@@ -219,6 +219,7 @@ typedef enum {
kHlCombine,
kHlBlend,
kHlBlendThrough,
+ kHlInvalid,
} HlKind;
typedef struct {
diff --git a/src/nvim/map.c b/src/nvim/map.c
index 33a7759a1b..e1d0646083 100644
--- a/src/nvim/map.c
+++ b/src/nvim/map.c
@@ -196,9 +196,6 @@ void mh_clear(MapHash *h)
#define KEY_NAME(x) x##HlEntry
#include "nvim/map_key_impl.c.h"
-#define VAL_NAME(x) quasiquote(x, int)
-#include "nvim/map_value_impl.c.h"
-#undef VAL_NAME
#undef KEY_NAME
#define KEY_NAME(x) x##ColorKey
diff --git a/src/nvim/map.h b/src/nvim/map.h
index bfba014736..23a5ea36a3 100644
--- a/src/nvim/map.h
+++ b/src/nvim/map.h
@@ -142,7 +142,6 @@ MAP_DECLS(uint64_t, uint64_t)
MAP_DECLS(int64_t, int64_t)
MAP_DECLS(int64_t, ptr_t)
MAP_DECLS(uint32_t, uint32_t)
-MAP_DECLS(HlEntry, int)
MAP_DECLS(String, int)
MAP_DECLS(int, String)
MAP_DECLS(ColorKey, ColorItem)
@@ -150,6 +149,7 @@ MAP_DECLS(ColorKey, ColorItem)
#define set_has(T, set, key) set_has_##T(set, key)
#define set_put(T, set, key) set_put_##T(set, key, NULL)
#define set_put_ref(T, set, key, key_alloc) set_put_##T(set, key, key_alloc)
+#define set_put_idx(T, set, key, status) mh_put_##T(set, key, status)
#define set_del(T, set, key) set_del_##T(set, key)
#define set_destroy(T, set) (xfree((set)->keys), xfree((set)->h.hash))
#define set_clear(T, set) mh_clear(&(set)->h)