aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/autocmd.c112
-rw-r--r--src/nvim/autocmd.c59
-rw-r--r--src/nvim/map.c1
-rw-r--r--src/nvim/map.h1
4 files changed, 106 insertions, 67 deletions
diff --git a/src/nvim/api/autocmd.c b/src/nvim/api/autocmd.c
index 685667ac64..5ede0e5265 100644
--- a/src/nvim/api/autocmd.c
+++ b/src/nvim/api/autocmd.c
@@ -40,7 +40,7 @@ static int64_t next_autocmd_id = 1;
///
/// @param opts Optional Parameters:
/// - event : Name or list of name of events to match against
-/// - group (string): Name of group to match against
+/// - group (string|int): Name or id of group to match against
/// - pattern: Pattern or list of patterns to match against. Cannot be used with {buffer}
/// - buffer: Buffer number or list of buffer numbers for buffer local autocommands
/// |autocmd-buflocal|. Cannot be used with {pattern}
@@ -62,19 +62,27 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Error *err)
int group = 0;
- if (opts->group.type != kObjectTypeNil) {
- Object v = opts->group;
- if (v.type != kObjectTypeString) {
- api_set_error(err, kErrorTypeValidation, "group must be a string.");
- goto cleanup;
- }
-
- group = augroup_find(v.data.string.data);
-
- if (group < 0) {
- api_set_error(err, kErrorTypeValidation, "invalid augroup passed.");
+ switch (opts->group.type) {
+ case kObjectTypeNil:
+ break;
+ case kObjectTypeString:
+ group = augroup_find(opts->group.data.string.data);
+ if (group < 0) {
+ api_set_error(err, kErrorTypeValidation, "invalid augroup passed.");
+ goto cleanup;
+ }
+ break;
+ case kObjectTypeInteger:
+ group = (int)opts->group.data.integer;
+ char *name = augroup_name(group);
+ if (!augroup_exists(name)) {
+ api_set_error(err, kErrorTypeValidation, "invalid augroup passed.");
+ goto cleanup;
+ }
+ break;
+ default:
+ api_set_error(err, kErrorTypeValidation, "group must be a string or an integer.");
goto cleanup;
- }
}
if (opts->event.type != kObjectTypeNil) {
@@ -321,7 +329,7 @@ cleanup:
/// - buffer: (bufnr)
/// - create a |autocmd-buflocal| autocmd.
/// - NOTE: Cannot be used with {pattern}
-/// - group: (string) The augroup name
+/// - group: (string|int) The augroup name or id
/// - once: (boolean) - See |autocmd-once|
/// - nested: (boolean) - See |autocmd-nested|
/// - desc: (string) - Description of the autocmd
@@ -406,23 +414,29 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc
bool is_once = api_object_to_bool(opts->once, "once", false, err);
bool is_nested = api_object_to_bool(opts->nested, "nested", false, err);
- // TODO(tjdevries): accept number for namespace instead
- if (opts->group.type != kObjectTypeNil) {
- Object *v = &opts->group;
- if (v->type != kObjectTypeString) {
- api_set_error(err, kErrorTypeValidation, "'group' must be a string");
- goto cleanup;
- }
-
- au_group = augroup_find(v->data.string.data);
-
- if (au_group == AUGROUP_ERROR) {
- api_set_error(err,
- kErrorTypeException,
- "invalid augroup: %s", v->data.string.data);
-
+ switch (opts->group.type) {
+ case kObjectTypeNil:
+ break;
+ case kObjectTypeString:
+ au_group = augroup_find(opts->group.data.string.data);
+ if (au_group == AUGROUP_ERROR) {
+ api_set_error(err,
+ kErrorTypeValidation,
+ "invalid augroup: %s", opts->group.data.string.data);
+ goto cleanup;
+ }
+ break;
+ case kObjectTypeInteger:
+ au_group = (int)opts->group.data.integer;
+ char *name = augroup_name(au_group);
+ if (!augroup_exists(name)) {
+ api_set_error(err, kErrorTypeValidation, "invalid augroup: %d", au_group);
+ goto cleanup;
+ }
+ break;
+ default:
+ api_set_error(err, kErrorTypeValidation, "'group' must be a string or an integer.");
goto cleanup;
- }
}
if (opts->pattern.type != kObjectTypeNil && opts->buffer.type != kObjectTypeNil) {
@@ -624,7 +638,7 @@ void nvim_del_augroup_by_name(String name)
/// - NOTE: Cannot be used with {pattern}
/// - pattern (string|table) - optional, defaults to "*".
/// - NOTE: Cannot be used with {buffer}
-/// - group (string) - autocmd group name
+/// - group (string|int) - autocmd group name or id
/// - modeline (boolean) - Default true, see |<nomodeline>|
void nvim_do_autocmd(Object event, Dict(do_autocmd) *opts, Error *err)
FUNC_API_SINCE(9)
@@ -644,21 +658,29 @@ void nvim_do_autocmd(Object event, Dict(do_autocmd) *opts, Error *err)
goto cleanup;
}
- if (opts->group.type != kObjectTypeNil) {
- if (opts->group.type != kObjectTypeString) {
- api_set_error(err, kErrorTypeValidation, "'group' must be a string");
- goto cleanup;
- }
-
- au_group = augroup_find(opts->group.data.string.data);
-
- if (au_group == AUGROUP_ERROR) {
- api_set_error(err,
- kErrorTypeException,
- "invalid augroup: %s", opts->group.data.string.data);
-
+ switch (opts->group.type) {
+ case kObjectTypeNil:
+ break;
+ case kObjectTypeString:
+ au_group = augroup_find(opts->group.data.string.data);
+ if (au_group == AUGROUP_ERROR) {
+ api_set_error(err,
+ kErrorTypeValidation,
+ "invalid augroup: %s", opts->group.data.string.data);
+ goto cleanup;
+ }
+ break;
+ case kObjectTypeInteger:
+ au_group = (int)opts->group.data.integer;
+ char *name = augroup_name(au_group);
+ if (!augroup_exists(name)) {
+ api_set_error(err, kErrorTypeValidation, "invalid augroup: %d", au_group);
+ goto cleanup;
+ }
+ break;
+ default:
+ api_set_error(err, kErrorTypeValidation, "'group' must be a string or an integer.");
goto cleanup;
- }
}
if (opts->buffer.type != kObjectTypeNil) {
diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c
index 7cb493f57d..a850e5c1a0 100644
--- a/src/nvim/autocmd.c
+++ b/src/nvim/autocmd.c
@@ -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)(&map_augroup_name_to_id);
+
+ map_foreach(&map_augroup_id_to_name, id, name, {
(void)id;
api_free_string(name);
})
- map_destroy(String, int)(&augroup_map);
+ map_destroy(int, String)(&map_augroup_id_to_name);
}
#endif
diff --git a/src/nvim/map.c b/src/nvim/map.c
index 091d653046..4e39eb8c07 100644
--- a/src/nvim/map.c
+++ b/src/nvim/map.c
@@ -178,6 +178,7 @@ MAP_IMPL(String, MsgpackRpcRequestHandler, MSGPACK_HANDLER_INITIALIZER)
MAP_IMPL(HlEntry, int, DEFAULT_INITIALIZER)
MAP_IMPL(String, handle_T, 0)
MAP_IMPL(String, int, DEFAULT_INITIALIZER)
+MAP_IMPL(int, String, DEFAULT_INITIALIZER)
MAP_IMPL(ColorKey, ColorItem, COLOR_ITEM_INITIALIZER)
diff --git a/src/nvim/map.h b/src/nvim/map.h
index c9c89bf2fd..00f72386a7 100644
--- a/src/nvim/map.h
+++ b/src/nvim/map.h
@@ -47,6 +47,7 @@ MAP_DECLS(String, MsgpackRpcRequestHandler)
MAP_DECLS(HlEntry, int)
MAP_DECLS(String, handle_T)
MAP_DECLS(String, int)
+MAP_DECLS(int, String)
MAP_DECLS(ColorKey, ColorItem)