diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index 45b82eb733..753d2c1823 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -2159,6 +2159,7 @@ nvim_create_autocmd({event}, {opts}) *nvim_create_autocmd()* < Attributes: ~ + |api-fast| Since: 0.7.0 Parameters: ~ diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 4e5ba1b508..ab2b6f27e4 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -179,6 +179,8 @@ API • |nvim_set_option_value()| accepts a new `operation` field to modify the existing option value. • |nvim_set_option_value()| returns the new option value. +• |nvim_create_autocmd()| is now |api-fast|, so it can be called from a fast + event context (e.g. |vim.uv| callbacks). BUILD diff --git a/src/nvim/api/autocmd.c b/src/nvim/api/autocmd.c index cc04a91c14..f193ae8594 100644 --- a/src/nvim/api/autocmd.c +++ b/src/nvim/api/autocmd.c @@ -391,6 +391,7 @@ cleanup: Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autocmd) *opts, Arena *arena, Error *err) FUNC_API_SINCE(9) + FUNC_API_FAST { int64_t autocmd_id = -1; char *desc = NULL; diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 1bfcb681da..2faa727147 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -1022,7 +1022,8 @@ int autocmd_register(int64_t id, event_T event, const char *pat, int patlen, int ap->buflocal_nr = 0; char *reg_pat = file_pat_to_reg_pat(pat, pat + patlen, &ap->allow_dirs, true); if (reg_pat != NULL) { - ap->reg_prog = vim_regcomp(reg_pat, RE_MAGIC); + // RE_NOBREAK: autocmd-pattern matching (aucmd_next()) must not os_breakcheck(). #35071 + ap->reg_prog = vim_regcomp(reg_pat, RE_MAGIC | RE_NOBREAK); } xfree(reg_pat); if (reg_pat == NULL || ap->reg_prog == NULL) { diff --git a/test/functional/api/fast_spec.lua b/test/functional/api/fast_spec.lua index 507fbc4c2c..d8f4ed3dfa 100644 --- a/test/functional/api/fast_spec.lua +++ b/test/functional/api/fast_spec.lua @@ -24,7 +24,11 @@ describe('|api-fast| functions', function() keycode = vim.keycode(''), keytrans = vim.fn.keytrans(vim.keycode('')), nr2char = vim.fn.nr2char(65), - replace_termcodes = vim.api.nvim_replace_termcodes('', true, true, true), + nvim_create_autocmd = vim.api.nvim_create_autocmd('User', { + pattern = 'Fast', + callback = function() end, + }) > 0, + nvim_replace_termcodes = vim.api.nvim_replace_termcodes('', true, true, true), str2list = vim.fn.str2list('AB'), strcharlen = vim.fn.strcharlen('abc'), strcharpart = vim.fn.strcharpart('héllo', 1, 2), @@ -53,7 +57,8 @@ describe('|api-fast| functions', function() keycode = '\1', -- keytrans = '', nr2char = 'A', - replace_termcodes = '\27', -- + nvim_create_autocmd = true, + nvim_replace_termcodes = '\27', -- str2list = { 65, 66 }, strcharlen = 3, strcharpart = 'él', @@ -87,6 +92,9 @@ describe('|api-fast| functions', function() -- for `veryfast_breakcheck`). Small input could pass (false negative). local big = ('héllo wörld '):rep(100000) -- 1.2M chars. + local aupat = ('a'):rep(80000) -- Must stay under the "E339: Pattern too long" limit. + vim.api.nvim_create_autocmd('User', { pattern = aupat, callback = function() end }) + local cases = { byteidx = function() vim.fn.byteidx(big, 500000) @@ -106,7 +114,10 @@ describe('|api-fast| functions', function() nr2char = function() vim.fn.nr2char(65) end, - replace_termcodes = function() + nvim_create_autocmd = function() + vim.api.nvim_exec_autocmds('User', { pattern = aupat }) + end, + nvim_replace_termcodes = function() vim.api.nvim_replace_termcodes('', true, true, true) end, str2list = function()