mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
feat(api)!: pass args table to autocommand callbacks
This commit is contained in:
parent
dc9e436986
commit
30bc02c636
@ -3240,7 +3240,7 @@ nvim_create_autocmd({event}, {*opts}) *nvim_create_autocmd()*
|
|||||||
<
|
<
|
||||||
|
|
||||||
Parameters: ~
|
Parameters: ~
|
||||||
{event} (String|Array) The event or events to register
|
{event} (string|array) The event or events to register
|
||||||
this autocommand
|
this autocommand
|
||||||
{opts} Dictionary of autocommand options:
|
{opts} Dictionary of autocommand options:
|
||||||
• group (string|integer) optional: the
|
• group (string|integer) optional: the
|
||||||
@ -3252,9 +3252,26 @@ nvim_create_autocmd({event}, {*opts}) *nvim_create_autocmd()*
|
|||||||
Cannot be used with {pattern}.
|
Cannot be used with {pattern}.
|
||||||
• desc (string) optional: description of the
|
• desc (string) optional: description of the
|
||||||
autocommand.
|
autocommand.
|
||||||
• callback (function|string) optional: Lua
|
• callback (function|string) optional: if a
|
||||||
function or Vim function (as string) to execute
|
string, the name of a Vimscript function to
|
||||||
on event. Cannot be used with {command}
|
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
|
• command (string) optional: Vim command to
|
||||||
execute on event. Cannot be used with
|
execute on event. Cannot be used with
|
||||||
{callback}
|
{callback}
|
||||||
|
@ -366,7 +366,7 @@ cleanup:
|
|||||||
/// {"CursorHold", "BufPreWrite", "BufPostWrite"}
|
/// {"CursorHold", "BufPreWrite", "BufPostWrite"}
|
||||||
/// </pre>
|
/// </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:
|
/// @param opts Dictionary of autocommand options:
|
||||||
/// - group (string|integer) optional: the autocommand group name or
|
/// - group (string|integer) optional: the autocommand group name or
|
||||||
/// id to match against.
|
/// id to match against.
|
||||||
@ -375,8 +375,18 @@ cleanup:
|
|||||||
/// - buffer (integer) optional: buffer number for buffer local autocommands
|
/// - buffer (integer) optional: buffer number for buffer local autocommands
|
||||||
/// |autocmd-buflocal|. Cannot be used with {pattern}.
|
/// |autocmd-buflocal|. Cannot be used with {pattern}.
|
||||||
/// - desc (string) optional: description of the autocommand.
|
/// - desc (string) optional: description of the autocommand.
|
||||||
/// - callback (function|string) optional: Lua function or Vim function (as string) to
|
/// - callback (function|string) optional: if a string, the name of a Vimscript function
|
||||||
/// execute on event. Cannot be used with {command}
|
/// 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
|
/// - command (string) optional: Vim command to execute on event. Cannot be used with
|
||||||
/// {callback}
|
/// {callback}
|
||||||
/// - once (boolean) optional: defaults to false. Run the autocommand
|
/// - once (boolean) optional: defaults to false. Run the autocommand
|
||||||
|
@ -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.
|
/// Get next autocommand command.
|
||||||
/// Called by do_cmdline() to get the next line for ":if".
|
/// Called by do_cmdline() to get the next line for ":if".
|
||||||
/// @return allocated string, or NULL for end of autocommands.
|
/// @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;
|
current_sctx = ac->script_ctx;
|
||||||
|
|
||||||
if (ac->exec.type == CALLABLE_CB) {
|
if (ac->exec.type == CALLABLE_CB) {
|
||||||
typval_T argsin = TV_INITIAL_VALUE;
|
if (call_autocmd_callback(ac, acp)) {
|
||||||
typval_T rettv = TV_INITIAL_VALUE;
|
// If an autocommand callback returns true, delete the autocommand
|
||||||
if (callback_call(&ac->exec.callable.cb, 0, &argsin, &rettv)) {
|
oneshot = true;
|
||||||
if (ac->exec.callable.cb.type == kCallbackLua) {
|
|
||||||
// If a Lua callback returns 'true' then the autocommand is removed
|
|
||||||
oneshot = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO(tjdevries):
|
// TODO(tjdevries):
|
||||||
//
|
//
|
||||||
// Major Hack Alert:
|
// Major Hack Alert:
|
||||||
|
@ -182,6 +182,54 @@ describe('autocmd api', function()
|
|||||||
meths.exec_autocmds("User", {pattern = "Test"})
|
meths.exec_autocmds("User", {pattern = "Test"})
|
||||||
eq({}, meths.get_autocmds({event = "User", pattern = "Test"}))
|
eq({}, meths.get_autocmds({event = "User", pattern = "Test"}))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('receives an args table', function()
|
||||||
|
local res = exec_lua [[
|
||||||
|
local group_id = vim.api.nvim_create_augroup("TestGroup", {})
|
||||||
|
local autocmd_id = vim.api.nvim_create_autocmd("User", {
|
||||||
|
group = "TestGroup",
|
||||||
|
pattern = "Te*",
|
||||||
|
callback = function(args)
|
||||||
|
vim.g.autocmd_args = args
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
return {group_id, autocmd_id}
|
||||||
|
]]
|
||||||
|
|
||||||
|
meths.exec_autocmds("User", {pattern = "Test pattern"})
|
||||||
|
eq({
|
||||||
|
id = res[2],
|
||||||
|
group = res[1],
|
||||||
|
event = "User",
|
||||||
|
match = "Test pattern",
|
||||||
|
file = "Test pattern",
|
||||||
|
buf = 1,
|
||||||
|
}, meths.get_var("autocmd_args"))
|
||||||
|
|
||||||
|
-- Test without a group
|
||||||
|
res = exec_lua [[
|
||||||
|
local autocmd_id = vim.api.nvim_create_autocmd("User", {
|
||||||
|
pattern = "*",
|
||||||
|
callback = function(args)
|
||||||
|
vim.g.autocmd_args = args
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
return {autocmd_id}
|
||||||
|
]]
|
||||||
|
|
||||||
|
meths.exec_autocmds("User", {pattern = "some_pat"})
|
||||||
|
eq({
|
||||||
|
id = res[1],
|
||||||
|
group = nil,
|
||||||
|
event = "User",
|
||||||
|
match = "some_pat",
|
||||||
|
file = "some_pat",
|
||||||
|
buf = 1,
|
||||||
|
}, meths.get_var("autocmd_args"))
|
||||||
|
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('nvim_get_autocmds', function()
|
describe('nvim_get_autocmds', function()
|
||||||
|
Loading…
Reference in New Issue
Block a user