diff options
-rw-r--r-- | src/nvim/api/autocmd.c | 39 | ||||
-rw-r--r-- | test/functional/api/autocmd_spec.lua | 22 |
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 |