aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/api/autocmd.c39
-rw-r--r--test/functional/api/autocmd_spec.lua22
2 files changed, 38 insertions, 23 deletions
diff --git a/src/nvim/api/autocmd.c b/src/nvim/api/autocmd.c
index 3a35e49dc8..a4f98b3ef2 100644
--- a/src/nvim/api/autocmd.c
+++ b/src/nvim/api/autocmd.c
@@ -781,14 +781,12 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err)
bool modeline = true;
buf_T *buf = curbuf;
- bool set_buf = false;
-
- char *pattern = NULL;
- Object *data = NULL;
- bool set_pattern = false;
+ Array patterns = ARRAY_DICT_INIT;
Array event_array = ARRAY_DICT_INIT;
+ Object *data = NULL;
+
if (!unpack_string_or_array(&event_array, &event, "event", true, err)) {
goto cleanup;
}
@@ -826,21 +824,18 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err)
}
buf = find_buffer_by_handle((Buffer)buf_obj.data.integer, err);
- set_buf = true;
if (ERROR_SET(err)) {
goto cleanup;
}
}
- if (opts->pattern.type != kObjectTypeNil) {
- if (opts->pattern.type != kObjectTypeString) {
- api_set_error(err, kErrorTypeValidation, "'pattern' must be a string");
- goto cleanup;
- }
+ if (!get_patterns_from_pattern_or_buf(&patterns, opts->pattern, opts->buffer, err)) {
+ goto cleanup;
+ }
- pattern = string_to_cstr(opts->pattern.data.string);
- set_pattern = true;
+ if (patterns.size == 0) {
+ ADD(patterns, STRING_OBJ(STATIC_CSTR_TO_STRING("*")));
}
if (opts->data.type != kObjectTypeNil) {
@@ -849,16 +844,16 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err)
modeline = api_object_to_bool(opts->modeline, "modeline", true, err);
- if (set_pattern && set_buf) {
- api_set_error(err, kErrorTypeValidation, "must not set 'buffer' and 'pattern'");
- goto cleanup;
- }
-
bool did_aucmd = false;
FOREACH_ITEM(event_array, event_str, {
GET_ONE_EVENT(event_nr, event_str, cleanup)
- did_aucmd |= apply_autocmds_group(event_nr, pattern, NULL, true, au_group, buf, NULL, data);
+ for (size_t i = 0; i < patterns.size; i++) {
+ Object pat = patterns.items[i];
+ char *fname = opts->buffer.type == kObjectTypeNil ? pat.data.string.data : NULL;
+ did_aucmd |=
+ apply_autocmds_group(event_nr, fname, NULL, true, au_group, buf, NULL, data);
+ }
})
if (did_aucmd && modeline) {
@@ -867,7 +862,7 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err)
cleanup:
api_free_array(event_array);
- XFREE_CLEAR(pattern);
+ api_free_array(patterns);
}
static bool check_autocmd_string_array(Array arr, char *k, Error *err)
@@ -988,11 +983,11 @@ static bool get_patterns_from_pattern_or_buf(Array *patterns, Object pattern, Ob
} else {
api_set_error(err,
kErrorTypeValidation,
- "'pattern' must be a string");
+ "'pattern' must be a string or table");
return false;
}
} else if (buffer.type != kObjectTypeNil) {
- if (buffer.type != kObjectTypeInteger) {
+ if (buffer.type != kObjectTypeInteger && buffer.type != kObjectTypeBuffer) {
api_set_error(err,
kErrorTypeValidation,
"'buffer' must be an integer");
diff --git a/test/functional/api/autocmd_spec.lua b/test/functional/api/autocmd_spec.lua
index 5dfcd09438..a923f5df0e 100644
--- a/test/functional/api/autocmd_spec.lua
+++ b/test/functional/api/autocmd_spec.lua
@@ -686,6 +686,26 @@ describe('autocmd api', function()
eq(true, meths.get_var("autocmd_executed"))
end)
+ it("can trigger multiple patterns", function()
+ meths.set_var("autocmd_executed", 0)
+
+ meths.create_autocmd("BufReadPost", {
+ pattern = "*",
+ command = "let g:autocmd_executed += 1",
+ })
+
+ meths.exec_autocmds("BufReadPost", { pattern = { "*.lua", "*.vim" } })
+ eq(2, meths.get_var("autocmd_executed"))
+
+ meths.create_autocmd("BufReadPre", {
+ pattern = { "bar", "foo" },
+ command = "let g:autocmd_executed += 10",
+ })
+
+ meths.exec_autocmds("BufReadPre", { pattern = { "foo", "bar", "baz", "frederick" }})
+ eq(22, meths.get_var("autocmd_executed"))
+ end)
+
it("can pass the buffer", function()
meths.set_var("buffer_executed", -1)
eq(-1, meths.get_var("buffer_executed"))
@@ -742,7 +762,7 @@ describe('autocmd api', function()
meths.exec_autocmds("CursorHoldI", { buffer = 1 })
eq('none', meths.get_var("filename_executed"))
- meths.exec_autocmds("CursorHoldI", { buffer = tonumber(meths.get_current_buf()) })
+ meths.exec_autocmds("CursorHoldI", { buffer = meths.get_current_buf() })
eq('__init__.py', meths.get_var("filename_executed"))
-- Reset filename