mirror of
https://github.com/neovim/neovim.git
synced 2025-09-26 04:58:33 +00:00
feat(api): autocmd group
can be either name or id (#17559)
* feat(api): `group` can be either string or int This affects the following API functions: - `vim.api.nvim_create_autocmd` - `vim.api.nvim_get_autocmds` - `vim.api.nvim_do_autocmd` closes #17552 * refactor: add two maps for fast lookups * fix: delete augroup info from id->name map When in "stupid_legacy_mode", the value in name->id map would be updated to `AUGROUP_DELETED`, but the entry would still remain in id->name. This would create a problem in `augroup_name` function which would return the name of the augroup instead of `--DELETED--`. The id->name map is only used for fast loopup in `augroup_name` function so there's no point in keeping the entry of deleted augroup in it. Co-authored-by: TJ DeVries <devries.timothyj@gmail.com>
This commit is contained in:
@@ -105,15 +105,24 @@ static char_u *old_termresponse = NULL;
|
||||
#define FOR_ALL_AUPATS_IN_EVENT(event, ap) \
|
||||
for (AutoPat *ap = first_autopat[event]; ap != NULL; ap = ap->next) // NOLINT
|
||||
|
||||
// Map of autocmd group names.
|
||||
// Map of autocmd group names and ids.
|
||||
// name -> ID
|
||||
static Map(String, int) augroup_map = MAP_INIT;
|
||||
// ID -> name
|
||||
static Map(String, int) map_augroup_name_to_id = MAP_INIT;
|
||||
static Map(int, String) map_augroup_id_to_name = MAP_INIT;
|
||||
|
||||
static void augroup_map_del(char *name)
|
||||
static void augroup_map_del(int id, char *name)
|
||||
{
|
||||
String key = map_key(String, int)(&augroup_map, cstr_as_string(name));
|
||||
map_del(String, int)(&augroup_map, key);
|
||||
api_free_string(key);
|
||||
if (name != NULL) {
|
||||
String key = map_key(String, int)(&map_augroup_name_to_id, cstr_as_string(name));
|
||||
map_del(String, int)(&map_augroup_name_to_id, key);
|
||||
api_free_string(key);
|
||||
}
|
||||
if (id > 0) {
|
||||
String mapped = map_get(int, String)(&map_augroup_id_to_name, id);
|
||||
api_free_string(mapped);
|
||||
map_del(int, String)(&map_augroup_id_to_name, id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -382,12 +391,14 @@ int augroup_add(char *name)
|
||||
}
|
||||
|
||||
if (existing_id == AUGROUP_DELETED) {
|
||||
augroup_map_del(name);
|
||||
augroup_map_del(existing_id, name);
|
||||
}
|
||||
|
||||
int next_id = next_augroup_id++;
|
||||
String name_copy = cstr_to_string(name);
|
||||
map_put(String, int)(&augroup_map, name_copy, next_id);
|
||||
String name_key = cstr_to_string(name);
|
||||
String name_val = cstr_to_string(name);
|
||||
map_put(String, int)(&map_augroup_name_to_id, name_key, next_id);
|
||||
map_put(int, String)(&map_augroup_id_to_name, next_id, name_val);
|
||||
|
||||
return next_id;
|
||||
}
|
||||
@@ -416,7 +427,8 @@ void augroup_del(char *name, bool stupid_legacy_mode)
|
||||
FOR_ALL_AUPATS_IN_EVENT(event, ap) {
|
||||
if (ap->group == i && ap->pat != NULL) {
|
||||
give_warning((char_u *)_("W19: Deleting augroup that is still in use"), true);
|
||||
map_put(String, int)(&augroup_map, cstr_as_string(name), AUGROUP_DELETED);
|
||||
map_put(String, int)(&map_augroup_name_to_id, cstr_as_string(name), AUGROUP_DELETED);
|
||||
augroup_map_del(ap->group, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -432,7 +444,7 @@ void augroup_del(char *name, bool stupid_legacy_mode)
|
||||
}
|
||||
|
||||
// Remove the group because it's not currently in use.
|
||||
augroup_map_del(name);
|
||||
augroup_map_del(i, name);
|
||||
au_cleanup();
|
||||
}
|
||||
}
|
||||
@@ -445,7 +457,7 @@ void augroup_del(char *name, bool stupid_legacy_mode)
|
||||
int augroup_find(const char *name)
|
||||
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
int existing_id = map_get(String, int)(&augroup_map, cstr_as_string((char *)name));
|
||||
int existing_id = map_get(String, int)(&map_augroup_name_to_id, cstr_as_string((char *)name));
|
||||
if (existing_id == AUGROUP_DELETED) {
|
||||
return existing_id;
|
||||
}
|
||||
@@ -487,13 +499,10 @@ char *augroup_name(int group)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
String key;
|
||||
int value;
|
||||
map_foreach(&augroup_map, key, value, {
|
||||
if (value == group) {
|
||||
return key.data;
|
||||
}
|
||||
});
|
||||
String key = map_get(int, String)(&map_augroup_id_to_name, group);
|
||||
if (key.data != NULL) {
|
||||
return key.data;
|
||||
}
|
||||
|
||||
// If it's not in the map anymore, then it must have been deleted.
|
||||
return (char *)get_deleted_augroup();
|
||||
@@ -526,7 +535,7 @@ void do_augroup(char_u *arg, int del_group)
|
||||
|
||||
String name;
|
||||
int value;
|
||||
map_foreach(&augroup_map, name, value, {
|
||||
map_foreach(&map_augroup_name_to_id, name, value, {
|
||||
if (value > 0) {
|
||||
msg_puts(name.data);
|
||||
} else {
|
||||
@@ -556,11 +565,17 @@ void free_all_autocmds(void)
|
||||
// Delete the augroup_map, including free the data
|
||||
String name;
|
||||
int id;
|
||||
map_foreach(&augroup_map, name, id, {
|
||||
map_foreach(&map_augroup_name_to_id, name, id, {
|
||||
(void)id;
|
||||
api_free_string(name);
|
||||
})
|
||||
map_destroy(String, int)(&augroup_map);
|
||||
map_destroy(String, int)(&map_augroup_name_to_id);
|
||||
|
||||
map_foreach(&map_augroup_id_to_name, id, name, {
|
||||
(void)id;
|
||||
api_free_string(name);
|
||||
})
|
||||
map_destroy(int, String)(&map_augroup_id_to_name);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user