Merge pull request #25114 from bfredl/nohl

refactor(highlight): merge redundant attr_entries and attr_entry_ids
This commit is contained in:
bfredl 2023-09-13 22:18:51 +02:00 committed by GitHub
commit 77df96f3fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 37 deletions

View File

@ -40,13 +40,13 @@
static bool hlstate_active = false; static bool hlstate_active = false;
static kvec_t(HlEntry) attr_entries = KV_INITIAL_VALUE; static Set(HlEntry) attr_entries = SET_INIT;
static Map(HlEntry, int) attr_entry_ids = MAP_INIT;
static Map(int, int) combine_attr_entries = MAP_INIT; static Map(int, int) combine_attr_entries = MAP_INIT;
static Map(int, int) blend_attr_entries = MAP_INIT; static Map(int, int) blend_attr_entries = MAP_INIT;
static Map(int, int) blendthrough_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 /// highlight entries private to a namespace
static Map(ColorKey, ColorItem) ns_hls; static Map(ColorKey, ColorItem) ns_hls;
typedef int NSHlAttr[HLF_COUNT + 1]; typedef int NSHlAttr[HLF_COUNT + 1];
@ -55,8 +55,8 @@ static PMap(int) ns_hl_attr;
void highlight_init(void) void highlight_init(void)
{ {
// index 0 is no attribute, add dummy entry: // index 0 is no attribute, add dummy entry:
kv_push(attr_entries, ((HlEntry){ .attr = HLATTRS_INIT, .kind = kHlUnknown, set_put(HlEntry, &attr_entries, ((HlEntry){ .attr = HLATTRS_INIT, .kind = kHlInvalid,
.id1 = 0, .id2 = 0 })); .id1 = 0, .id2 = 0 }));
} }
/// @return true if hl table was reset /// @return true if hl table was reset
@ -77,6 +77,7 @@ bool highlight_use_hlstate(void)
/// @return 0 for error. /// @return 0 for error.
static int get_attr_entry(HlEntry entry) static int get_attr_entry(HlEntry entry)
{ {
bool retried = false;
if (!hlstate_active) { if (!hlstate_active) {
// This information will not be used, erase it and reduce the table size. // This information will not be used, erase it and reduce the table size.
entry.kind = kHlUnknown; entry.kind = kHlUnknown;
@ -84,17 +85,19 @@ static int get_attr_entry(HlEntry entry)
entry.id2 = 0; entry.id2 = 0;
} }
int id = map_get(HlEntry, int)(&attr_entry_ids, entry); retry: {}
if (id > 0) { MhPutStatus status;
return id; uint32_t k = set_put_idx(HlEntry, &attr_entries, entry, &status);
if (status == kMHExisting) {
return (int)k;
} }
static bool recursive = false; 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 // Running out of attribute entries! remove all attributes, and
// compute new ones for all groups. // compute new ones for all groups.
// When called recursively, we are really out of numbers. // When called recursively, we are really out of numbers.
if (recursive) { if (recursive || retried) {
emsg(_("E424: Too many different highlighting attributes in use")); emsg(_("E424: Too many different highlighting attributes in use"));
return 0; return 0;
} }
@ -107,17 +110,12 @@ static int get_attr_entry(HlEntry entry)
// This entry is now invalid, don't put it // This entry is now invalid, don't put it
return 0; return 0;
} }
retried = true;
goto retry;
} }
size_t next_id = kv_size(attr_entries); // new attr id, send event to remote ui:s
if (next_id > INT_MAX) { int id = (int)k;
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);
Array inspect = hl_inspect(id); 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. /// When a UI connects, we need to send it the table of highlights used so far.
void ui_send_all_hls(UI *ui) 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); Array inspect = hl_inspect((int)i);
remote_ui_hl_attr_define(ui, (Integer)i, kv_A(attr_entries, i).attr, HlAttrs attr = attr_entry(i).attr;
kv_A(attr_entries, i).attr, inspect); remote_ui_hl_attr_define(ui, (Integer)i, attr, attr, inspect);
api_free_array(inspect); api_free_array(inspect);
} }
for (size_t hlf = 0; hlf < HLF_COUNT; hlf++) { 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 blend= attribute is not set, 'winblend' value overrides it.
if (wp->w_floating && wp->w_p_winbl > 0) { 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) { if (entry.attr.hl_blend == -1) {
entry.attr.hl_blend = (int)wp->w_p_winbl; entry.attr.hl_blend = (int)wp->w_p_winbl;
wp->w_hl_attr_normal = get_attr_entry(entry); 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 blend= attribute is not set, 'winblend' value overrides it.
if (wp->w_floating && wp->w_p_winbl > 0) { 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) { if (entry.attr.hl_blend == -1) {
entry.attr.hl_blend = (int)wp->w_p_winbl; entry.attr.hl_blend = (int)wp->w_p_winbl;
wp->w_hl_attr_normalnc = get_attr_entry(entry); 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) void clear_hl_tables(bool reinit)
{ {
if (reinit) { if (reinit) {
kv_size(attr_entries) = 1; set_clear(HlEntry, &attr_entries);
map_clear(HlEntry, &attr_entry_ids); highlight_init();
map_clear(int, &combine_attr_entries); map_clear(int, &combine_attr_entries);
map_clear(int, &blend_attr_entries); map_clear(int, &blend_attr_entries);
map_clear(int, &blendthrough_attr_entries); map_clear(int, &blendthrough_attr_entries);
@ -500,8 +498,7 @@ void clear_hl_tables(bool reinit)
highlight_changed(); highlight_changed();
screen_invalidate_highlights(); screen_invalidate_highlights();
} else { } else {
kv_destroy(attr_entries); set_destroy(HlEntry, &attr_entries);
map_destroy(HlEntry, &attr_entry_ids);
map_destroy(int, &combine_attr_entries); map_destroy(int, &combine_attr_entries);
map_destroy(int, &blend_attr_entries); map_destroy(int, &blend_attr_entries);
map_destroy(int, &blendthrough_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 /// Get highlight attributes for a attribute code
HlAttrs syn_attr2entry(int attr) 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 // invalid attribute code, or the tables were cleared
return HLATTRS_INIT; 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. /// 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; 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, api_set_error(err, kErrorTypeException,
"Invalid attribute id: %" PRId64, attr_id); "Invalid attribute id: %" PRId64, attr_id);
return dic; return dic;
@ -1132,11 +1129,11 @@ Array hl_inspect(int attr)
static void hl_inspect_impl(Array *arr, int attr) static void hl_inspect_impl(Array *arr, int attr)
{ {
Dictionary item = ARRAY_DICT_INIT; Dictionary item = ARRAY_DICT_INIT;
if (attr <= 0 || attr >= (int)kv_size(attr_entries)) { if (attr <= 0 || attr >= (int)set_size(&attr_entries)) {
return; return;
} }
HlEntry e = kv_A(attr_entries, attr); HlEntry e = attr_entry(attr);
switch (e.kind) { switch (e.kind) {
case kHlSyntax: case kHlSyntax:
PUT(item, "kind", CSTR_TO_OBJ("syntax")); PUT(item, "kind", CSTR_TO_OBJ("syntax"));
@ -1165,6 +1162,7 @@ static void hl_inspect_impl(Array *arr, int attr)
return; return;
case kHlUnknown: case kHlUnknown:
case kHlInvalid:
return; return;
} }
PUT(item, "id", INTEGER_OBJ(attr)); PUT(item, "id", INTEGER_OBJ(attr));

View File

@ -219,6 +219,7 @@ typedef enum {
kHlCombine, kHlCombine,
kHlBlend, kHlBlend,
kHlBlendThrough, kHlBlendThrough,
kHlInvalid,
} HlKind; } HlKind;
typedef struct { typedef struct {

View File

@ -196,9 +196,6 @@ void mh_clear(MapHash *h)
#define KEY_NAME(x) x##HlEntry #define KEY_NAME(x) x##HlEntry
#include "nvim/map_key_impl.c.h" #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 #undef KEY_NAME
#define KEY_NAME(x) x##ColorKey #define KEY_NAME(x) x##ColorKey

View File

@ -142,7 +142,6 @@ MAP_DECLS(uint64_t, uint64_t)
MAP_DECLS(int64_t, int64_t) MAP_DECLS(int64_t, int64_t)
MAP_DECLS(int64_t, ptr_t) MAP_DECLS(int64_t, ptr_t)
MAP_DECLS(uint32_t, uint32_t) MAP_DECLS(uint32_t, uint32_t)
MAP_DECLS(HlEntry, int)
MAP_DECLS(String, int) MAP_DECLS(String, int)
MAP_DECLS(int, String) MAP_DECLS(int, String)
MAP_DECLS(ColorKey, ColorItem) 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_has(T, set, key) set_has_##T(set, key)
#define set_put(T, set, key) set_put_##T(set, key, NULL) #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_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_del(T, set, key) set_del_##T(set, key)
#define set_destroy(T, set) (xfree((set)->keys), xfree((set)->h.hash)) #define set_destroy(T, set) (xfree((set)->keys), xfree((set)->h.hash))
#define set_clear(T, set) mh_clear(&(set)->h) #define set_clear(T, set) mh_clear(&(set)->h)