aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/api/autocmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/api/autocmd.c')
-rw-r--r--src/nvim/api/autocmd.c104
1 files changed, 46 insertions, 58 deletions
diff --git a/src/nvim/api/autocmd.c b/src/nvim/api/autocmd.c
index 22932fd1a2..d436dbb7f1 100644
--- a/src/nvim/api/autocmd.c
+++ b/src/nvim/api/autocmd.c
@@ -2,7 +2,6 @@
#include <lauxlib.h>
#include <stdbool.h>
#include <stdint.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -23,6 +22,7 @@
#include "nvim/globals.h"
#include "nvim/lua/executor.h"
#include "nvim/memory.h"
+#include "nvim/memory_defs.h"
#include "nvim/strings.h"
#include "nvim/types_defs.h"
#include "nvim/vim_defs.h"
@@ -68,32 +68,31 @@ static int64_t next_autocmd_id = 1;
/// match any combination of them.
///
/// @param opts Dict with at least one of the following:
-/// - group (string|integer): the autocommand group name or id to match against.
-/// - event (string|array): event or events to match against |autocmd-events|.
-/// - pattern (string|array): pattern or patterns to match against |autocmd-pattern|.
-/// Cannot be used with {buffer}
-/// - buffer: Buffer number or list of buffer numbers for buffer local autocommands
+/// - buffer: (integer) Buffer number or list of buffer numbers for buffer local autocommands
/// |autocmd-buflocal|. Cannot be used with {pattern}
+/// - event: (string|table) event or events to match against |autocmd-events|.
+/// - id: (integer) Autocommand ID to match.
+/// - group: (string|table) the autocommand group name or id to match against.
+/// - pattern: (string|table) pattern or patterns to match against |autocmd-pattern|.
+/// Cannot be used with {buffer}
/// @return Array of autocommands matching the criteria, with each item
/// containing the following fields:
-/// - id (number): the autocommand id (only when defined with the API).
-/// - group (integer): the autocommand group id.
-/// - group_name (string): the autocommand group name.
-/// - desc (string): the autocommand description.
-/// - event (string): the autocommand event.
-/// - command (string): the autocommand command. Note: this will be empty if a callback is set.
-/// - callback (function|string|nil): Lua function or name of a Vim script function
+/// - buffer: (integer) the buffer number.
+/// - buflocal: (boolean) true if the autocommand is buffer local.
+/// - command: (string) the autocommand command. Note: this will be empty if a callback is set.
+/// - callback: (function|string|nil): Lua function or name of a Vim script function
/// which is executed when this autocommand is triggered.
-/// - once (boolean): whether the autocommand is only run once.
-/// - pattern (string): the autocommand pattern.
+/// - desc: (string) the autocommand description.
+/// - event: (string) the autocommand event.
+/// - id: (integer) the autocommand id (only when defined with the API).
+/// - group: (integer) the autocommand group id.
+/// - group_name: (string) the autocommand group name.
+/// - once: (boolean) whether the autocommand is only run once.
+/// - pattern: (string) the autocommand pattern.
/// If the autocommand is buffer local |autocmd-buffer-local|:
-/// - buflocal (boolean): true if the autocommand is buffer local.
-/// - buffer (number): the buffer number.
Array nvim_get_autocmds(Dict(get_autocmds) *opts, Arena *arena, Error *err)
FUNC_API_SINCE(9)
{
- // TODO(tjdevries): Would be cool to add nvim_get_autocmds({ id = ... })
-
ArrayBuilder autocmd_list = KV_INITIAL_VALUE;
kvi_init(autocmd_list);
char *pattern_filters[AUCMD_MAX_PATTERNS];
@@ -127,6 +126,8 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Arena *arena, Error *err)
});
}
+ int id = (HAS_KEY(opts, get_autocmds, id)) ? (int)opts->id : -1;
+
if (HAS_KEY(opts, get_autocmds, event)) {
check_event = true;
@@ -237,6 +238,10 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Arena *arena, Error *err)
continue;
}
+ if (id != -1 && ac->id != id) {
+ continue;
+ }
+
// Skip autocmds from invalid groups if passed.
if (group != 0 && ap->group != group) {
continue;
@@ -285,10 +290,12 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Arena *arena, Error *err)
PUT_C(autocmd_info, "desc", CSTR_AS_OBJ(ac->desc));
}
- if (ac->exec.type == CALLABLE_CB) {
+ if (ac->handler_cmd) {
+ PUT_C(autocmd_info, "command", CSTR_AS_OBJ(ac->handler_cmd));
+ } else {
PUT_C(autocmd_info, "command", STRING_OBJ(STRING_INIT));
- Callback *cb = &ac->exec.callable.cb;
+ Callback *cb = &ac->handler_fn;
switch (cb->type) {
case kCallbackLua:
if (nlua_ref_is_function(cb->data.luaref)) {
@@ -302,8 +309,6 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Arena *arena, Error *err)
case kCallbackNone:
abort();
}
- } else {
- PUT_C(autocmd_info, "command", CSTR_AS_OBJ(ac->exec.callable.cmd));
}
PUT_C(autocmd_info, "pattern", CSTR_AS_OBJ(ap->pat));
@@ -317,23 +322,6 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Arena *arena, Error *err)
PUT_C(autocmd_info, "buflocal", BOOLEAN_OBJ(false));
}
- // TODO(sctx): It would be good to unify script_ctx to actually work with lua
- // right now it's just super weird, and never really gives you the info that
- // you would expect from this.
- //
- // I think we should be able to get the line number, filename, etc. from lua
- // when we're executing something, and it should be easy to then save that
- // info here.
- //
- // I think it's a big loss not getting line numbers of where options, autocmds,
- // etc. are set (just getting "Sourced (lua)" or something is not that helpful.
- //
- // Once we do that, we can put these into the autocmd_info, but I don't think it's
- // useful to do that at this time.
- //
- // PUT_C(autocmd_info, "sid", INTEGER_OBJ(ac->script_ctx.sc_sid));
- // PUT_C(autocmd_info, "lnum", INTEGER_OBJ(ac->script_ctx.sc_lnum));
-
kvi_push(autocmd_list, DICT_OBJ(autocmd_info));
}
}
@@ -386,9 +374,9 @@ cleanup:
/// - id: (number) autocommand id
/// - event: (string) name of the triggered event |autocmd-events|
/// - group: (number|nil) autocommand group id, if any
-/// - match: (string) expanded value of [<amatch>]
-/// - buf: (number) expanded value of [<abuf>]
-/// - file: (string) expanded value of [<afile>]
+/// - file: (string) [<afile>] (not expanded to a full path)
+/// - match: (string) [<amatch>] (expanded to a full path)
+/// - buf: (number) [<abuf>]
/// - data: (any) arbitrary data passed from [nvim_exec_autocmds()] [event-data]()
/// - command (string) optional: Vim command to execute on event. Cannot be used with
/// {callback}
@@ -406,8 +394,8 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc
{
int64_t autocmd_id = -1;
char *desc = NULL;
- AucmdExecutable aucmd = AUCMD_EXECUTABLE_INIT;
- Callback cb = CALLBACK_NONE;
+ char *handler_cmd = NULL;
+ Callback handler_fn = CALLBACK_NONE;
Array event_array = unpack_string_or_array(event, "event", true, arena, err);
if (ERROR_SET(err)) {
@@ -432,13 +420,13 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc
goto cleanup;
});
- cb.type = kCallbackLua;
- cb.data.luaref = callback->data.luaref;
+ handler_fn.type = kCallbackLua;
+ handler_fn.data.luaref = callback->data.luaref;
callback->data.luaref = LUA_NOREF;
break;
case kObjectTypeString:
- cb.type = kCallbackFuncref;
- cb.data.funcref = string_to_cstr(callback->data.string);
+ handler_fn.type = kCallbackFuncref;
+ handler_fn.data.funcref = string_to_cstr(callback->data.string);
break;
default:
VALIDATE_EXP(false, "callback", "Lua function or Vim function name",
@@ -446,12 +434,8 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc
goto cleanup;
});
}
-
- aucmd.type = CALLABLE_CB;
- aucmd.callable.cb = cb;
} else if (HAS_KEY(opts, create_autocmd, command)) {
- aucmd.type = CALLABLE_EX;
- aucmd.callable.cmd = string_to_cstr(opts->command);
+ handler_cmd = string_to_cstr(opts->command);
} else {
VALIDATE(false, "%s", "Required: 'command' or 'callback'", {
goto cleanup;
@@ -491,7 +475,6 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc
int retval;
FOREACH_ITEM(patterns, pat, {
- // See: TODO(sctx)
WITH_SCRIPT_CONTEXT(channel_id, {
retval = autocmd_register(autocmd_id,
event_nr,
@@ -501,7 +484,8 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc
opts->once,
opts->nested,
desc,
- aucmd);
+ handler_cmd,
+ &handler_fn);
});
if (retval == FAIL) {
@@ -512,7 +496,11 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc
});
cleanup:
- aucmd_exec_free(&aucmd);
+ if (handler_cmd) {
+ XFREE_CLEAR(handler_cmd);
+ } else {
+ callback_free(&handler_fn);
+ }
return autocmd_id;
}
@@ -631,7 +619,7 @@ Integer nvim_create_augroup(uint64_t channel_id, String name, Dict(create_augrou
FUNC_API_SINCE(9)
{
char *augroup_name = name.data;
- bool clear_autocmds = api_object_to_bool(opts->clear, "clear", true, err);
+ bool clear_autocmds = GET_BOOL_OR_TRUE(opts, create_augroup, clear);
int augroup = -1;
WITH_SCRIPT_CONTEXT(channel_id, {