diff options
author | Gregory Anders <greg@gpanders.com> | 2022-03-19 19:16:19 -0600 |
---|---|---|
committer | bfredl <bjorn.linse@gmail.com> | 2022-04-08 15:12:54 +0200 |
commit | 30bc02c6364f384e437a6f53b057522d585492fc (patch) | |
tree | 39cbdcf894f902a18664129ed444d01479909764 /src | |
parent | dc9e436986bec15b027c2a8d78782f514c046a8b (diff) | |
download | rneovim-30bc02c6364f384e437a6f53b057522d585492fc.tar.gz rneovim-30bc02c6364f384e437a6f53b057522d585492fc.tar.bz2 rneovim-30bc02c6364f384e437a6f53b057522d585492fc.zip |
feat(api)!: pass args table to autocommand callbacks
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/autocmd.c | 16 | ||||
-rw-r--r-- | src/nvim/autocmd.c | 55 |
2 files changed, 60 insertions, 11 deletions
diff --git a/src/nvim/api/autocmd.c b/src/nvim/api/autocmd.c index 57f392f98e..ccf4ae3d02 100644 --- a/src/nvim/api/autocmd.c +++ b/src/nvim/api/autocmd.c @@ -366,7 +366,7 @@ cleanup: /// {"CursorHold", "BufPreWrite", "BufPostWrite"} /// </pre> /// -/// @param event (String|Array) The event or events to register this autocommand +/// @param event (string|array) The event or events to register this autocommand /// @param opts Dictionary of autocommand options: /// - group (string|integer) optional: the autocommand group name or /// id to match against. @@ -375,8 +375,18 @@ cleanup: /// - buffer (integer) optional: buffer number for buffer local autocommands /// |autocmd-buflocal|. Cannot be used with {pattern}. /// - desc (string) optional: description of the autocommand. -/// - callback (function|string) optional: Lua function or Vim function (as string) to -/// execute on event. Cannot be used with {command} +/// - callback (function|string) optional: if a string, the name of a Vimscript function +/// to call when this autocommand is triggered. Otherwise, a Lua function which is +/// called when this autocommand is triggered. Cannot be used with {command}. Lua +/// callbacks can return true to delete the autocommand; in addition, they accept a +/// single table argument with the following keys: +/// - id: (number) the autocommand id +/// - event: (string) the name of the event that triggered the autocommand +/// |autocmd-events| +/// - group: (number|nil) the autocommand group id, if it exists +/// - match: (string) the expanded value of |<amatch>| +/// - buf: (number) the expanded value of |<abuf>| +/// - file: (string) the expanded value of |<afile>| /// - command (string) optional: Vim command to execute on event. Cannot be used with /// {callback} /// - once (boolean) optional: defaults to false. Run the autocommand diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 5fc36a8412..48c1bb740d 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -2005,6 +2005,50 @@ void auto_next_pat(AutoPatCmd *apc, int stop_at_last) } } +static bool call_autocmd_callback(const AutoCmd *ac, const AutoPatCmd *apc) +{ + bool ret = false; + Callback callback = ac->exec.callable.cb; + if (callback.type == kCallbackLua) { + Dictionary data = ARRAY_DICT_INIT; + PUT(data, "id", INTEGER_OBJ(ac->id)); + PUT(data, "event", CSTR_TO_OBJ(event_nr2name(apc->event))); + PUT(data, "match", CSTR_TO_OBJ((char *)autocmd_match)); + PUT(data, "file", CSTR_TO_OBJ((char *)autocmd_fname)); + PUT(data, "buf", INTEGER_OBJ(autocmd_bufnr)); + + int group = apc->curpat->group; + switch (group) { + case AUGROUP_ERROR: + abort(); // unreachable + case AUGROUP_DEFAULT: + case AUGROUP_ALL: + case AUGROUP_DELETED: + // omit group in these cases + break; + default: + PUT(data, "group", INTEGER_OBJ(group)); + break; + } + + FIXED_TEMP_ARRAY(args, 1); + args.items[0] = DICTIONARY_OBJ(data); + + Object result = nlua_call_ref(callback.data.luaref, NULL, args, true, NULL); + if (result.type == kObjectTypeBoolean) { + ret = result.data.boolean; + } + api_free_dictionary(data); + api_free_object(result); + } else { + typval_T argsin = TV_INITIAL_VALUE; + typval_T rettv = TV_INITIAL_VALUE; + callback_call(&callback, 0, &argsin, &rettv); + } + + return ret; +} + /// Get next autocommand command. /// Called by do_cmdline() to get the next line for ":if". /// @return allocated string, or NULL for end of autocommands. @@ -2069,16 +2113,11 @@ char_u *getnextac(int c, void *cookie, int indent, bool do_concat) current_sctx = ac->script_ctx; if (ac->exec.type == CALLABLE_CB) { - typval_T argsin = TV_INITIAL_VALUE; - typval_T rettv = TV_INITIAL_VALUE; - if (callback_call(&ac->exec.callable.cb, 0, &argsin, &rettv)) { - if (ac->exec.callable.cb.type == kCallbackLua) { - // If a Lua callback returns 'true' then the autocommand is removed - oneshot = true; - } + if (call_autocmd_callback(ac, acp)) { + // If an autocommand callback returns true, delete the autocommand + oneshot = true; } - // TODO(tjdevries): // // Major Hack Alert: |