mirror of
https://github.com/neovim/neovim.git
synced 2024-12-20 03:05:11 -07:00
feat(api): remove Lua autocommand callbacks when they return true (#17784)
This copies the semantics of nvim_buf_attach callbacks, and is a convenient way to create oneshot autocommands gated by some condition.
This commit is contained in:
parent
77eb6f9dc7
commit
be35d3c5ad
@ -2013,6 +2013,7 @@ char_u *getnextac(int c, void *cookie, int indent, bool do_concat)
|
||||
}
|
||||
|
||||
AutoCmd *ac = acp->nextcmd;
|
||||
bool oneshot = ac->once;
|
||||
|
||||
if (p_verbose >= 9) {
|
||||
verbose_enter_scroll();
|
||||
@ -2024,7 +2025,13 @@ char_u *getnextac(int c, void *cookie, int indent, bool do_concat)
|
||||
if (ac->exec.type == CALLABLE_CB) {
|
||||
typval_T argsin = TV_INITIAL_VALUE;
|
||||
typval_T rettv = TV_INITIAL_VALUE;
|
||||
callback_call(&ac->exec.callable.cb, 0, &argsin, &rettv);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO(tjdevries):
|
||||
//
|
||||
@ -2042,7 +2049,7 @@ char_u *getnextac(int c, void *cookie, int indent, bool do_concat)
|
||||
}
|
||||
|
||||
// Remove one-shot ("once") autocmd in anticipation of its execution.
|
||||
if (ac->once) {
|
||||
if (oneshot) {
|
||||
aucmd_del(ac);
|
||||
}
|
||||
autocmd_nested = ac->nested;
|
||||
|
@ -7730,6 +7730,7 @@ bool callback_call(Callback *const callback, const int argcount_in, typval_T *co
|
||||
partial_T *partial;
|
||||
char_u *name;
|
||||
Array args = ARRAY_DICT_INIT;
|
||||
Object rv;
|
||||
switch (callback->type) {
|
||||
case kCallbackFuncref:
|
||||
name = callback->data.funcref;
|
||||
@ -7742,10 +7743,13 @@ bool callback_call(Callback *const callback, const int argcount_in, typval_T *co
|
||||
break;
|
||||
|
||||
case kCallbackLua:
|
||||
nlua_call_ref(callback->data.luaref, NULL, args, false, NULL);
|
||||
|
||||
return false;
|
||||
break;
|
||||
rv = nlua_call_ref(callback->data.luaref, NULL, args, true, NULL);
|
||||
switch (rv.type) {
|
||||
case kObjectTypeBoolean:
|
||||
return rv.data.boolean;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
case kCallbackNone:
|
||||
return false;
|
||||
|
@ -154,6 +154,34 @@ describe('autocmd api', function()
|
||||
eq(1, #aus, aus)
|
||||
end)
|
||||
end)
|
||||
|
||||
it('removes an autocommand if the callback returns true', function()
|
||||
meths.set_var("some_condition", false)
|
||||
|
||||
exec_lua [[
|
||||
vim.api.nvim_create_autocmd("User", {
|
||||
pattern = "Test",
|
||||
desc = "A test autocommand",
|
||||
callback = function()
|
||||
return vim.g.some_condition
|
||||
end,
|
||||
})
|
||||
]]
|
||||
|
||||
meths.do_autocmd("User", {pattern = "Test"})
|
||||
eq({{
|
||||
buflocal = false,
|
||||
command = 'A test autocommand',
|
||||
desc = 'A test autocommand',
|
||||
event = 'User',
|
||||
id = 1,
|
||||
once = false,
|
||||
pattern = 'Test',
|
||||
}}, meths.get_autocmds({event = "User", pattern = "Test"}))
|
||||
meths.set_var("some_condition", true)
|
||||
meths.do_autocmd("User", {pattern = "Test"})
|
||||
eq({}, meths.get_autocmds({event = "User", pattern = "Test"}))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('nvim_get_autocmds', function()
|
||||
|
Loading…
Reference in New Issue
Block a user