diff options
| author | Josh Rahm <joshuarahm@gmail.com> | 2024-03-09 14:57:57 -0700 |
|---|---|---|
| committer | Josh Rahm <joshuarahm@gmail.com> | 2024-03-09 14:57:57 -0700 |
| commit | c324271b99eee4c621463f368914d57cd729bd9c (patch) | |
| tree | 5d979d333a2d5f9c080991d5482fd5916f8579c6 /src/nvim/api | |
| parent | 931bffbda3668ddc609fc1da8f9eb576b170aa52 (diff) | |
| parent | ade1b12f49c3b3914c74847d791eb90ea90b56b7 (diff) | |
| download | rneovim-c324271b99eee4c621463f368914d57cd729bd9c.tar.gz rneovim-c324271b99eee4c621463f368914d57cd729bd9c.tar.bz2 rneovim-c324271b99eee4c621463f368914d57cd729bd9c.zip | |
Merge remote-tracking branch 'upstream/master' into userreg
Diffstat (limited to 'src/nvim/api')
| -rw-r--r-- | src/nvim/api/autocmd.c | 252 | ||||
| -rw-r--r-- | src/nvim/api/buffer.c | 347 | ||||
| -rw-r--r-- | src/nvim/api/buffer.h | 3 | ||||
| -rw-r--r-- | src/nvim/api/command.c | 218 | ||||
| -rw-r--r-- | src/nvim/api/deprecated.c | 114 | ||||
| -rw-r--r-- | src/nvim/api/deprecated.h | 1 | ||||
| -rw-r--r-- | src/nvim/api/dispatch_deprecated.lua | 132 | ||||
| -rw-r--r-- | src/nvim/api/extmark.c | 360 | ||||
| -rw-r--r-- | src/nvim/api/keysets_defs.h | 76 | ||||
| -rw-r--r-- | src/nvim/api/options.c | 344 | ||||
| -rw-r--r-- | src/nvim/api/private/converter.c | 121 | ||||
| -rw-r--r-- | src/nvim/api/private/defs.h | 10 | ||||
| -rw-r--r-- | src/nvim/api/private/dispatch.h | 16 | ||||
| -rw-r--r-- | src/nvim/api/private/helpers.c | 282 | ||||
| -rw-r--r-- | src/nvim/api/private/helpers.h | 30 | ||||
| -rw-r--r-- | src/nvim/api/private/validate.h | 2 | ||||
| -rw-r--r-- | src/nvim/api/tabpage.c | 54 | ||||
| -rw-r--r-- | src/nvim/api/ui.c | 499 | ||||
| -rw-r--r-- | src/nvim/api/ui.h | 19 | ||||
| -rw-r--r-- | src/nvim/api/ui_events.in.h | 2 | ||||
| -rw-r--r-- | src/nvim/api/vim.c | 600 | ||||
| -rw-r--r-- | src/nvim/api/vimscript.c | 285 | ||||
| -rw-r--r-- | src/nvim/api/win_config.c | 630 | ||||
| -rw-r--r-- | src/nvim/api/window.c | 45 |
24 files changed, 2248 insertions, 2194 deletions
diff --git a/src/nvim/api/autocmd.c b/src/nvim/api/autocmd.c index 08d9d8e117..d71bcc4bcf 100644 --- a/src/nvim/api/autocmd.c +++ b/src/nvim/api/autocmd.c @@ -14,13 +14,17 @@ #include "nvim/api/private/helpers.h" #include "nvim/api/private/validate.h" #include "nvim/autocmd.h" +#include "nvim/autocmd_defs.h" #include "nvim/buffer.h" +#include "nvim/buffer_defs.h" #include "nvim/eval/typval.h" +#include "nvim/eval/typval_defs.h" #include "nvim/ex_cmds_defs.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/lua/executor.h" #include "nvim/memory.h" +#include "nvim/strings.h" +#include "nvim/types_defs.h" #include "nvim/vim_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -30,12 +34,12 @@ #define AUCMD_MAX_PATTERNS 256 // Copy string or array of strings into an empty array. -// Get the event number, unless it is an error. Then goto `goto_name`. -#define GET_ONE_EVENT(event_nr, event_str, goto_name) \ +// Get the event number, unless it is an error. Then do `or_else`. +#define GET_ONE_EVENT(event_nr, event_str, or_else) \ event_T event_nr = \ event_name2nr_str(event_str.data.string); \ VALIDATE_S((event_nr < NUM_EVENTS), "event", event_str.data.string.data, { \ - goto goto_name; \ + or_else; \ }); // ID for associating autocmds created via nvim_create_autocmd @@ -71,7 +75,7 @@ static int64_t next_autocmd_id = 1; /// - buffer: Buffer number or list of buffer numbers for buffer local autocommands /// |autocmd-buflocal|. Cannot be used with {pattern} /// @return Array of autocommands matching the criteria, with each item -/// containing the following fields: +/// 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. @@ -79,20 +83,20 @@ static int64_t next_autocmd_id = 1; /// - 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 -/// which is executed when this autocommand is triggered. +/// which is executed when this autocommand is triggered. /// - once (boolean): whether the autocommand is only run once. /// - pattern (string): the autocommand pattern. -/// If the autocommand is buffer local |autocmd-buffer-local|: +/// 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, Error *err) +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 = ... }) - Array autocmd_list = ARRAY_DICT_INIT; + ArrayBuilder autocmd_list = KV_INITIAL_VALUE; + kvi_init(autocmd_list); char *pattern_filters[AUCMD_MAX_PATTERNS]; - char pattern_buflocal[BUFLOCAL_PAT_LEN]; Array buffers = ARRAY_DICT_INIT; @@ -128,7 +132,7 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Error *err) Object v = opts->event; if (v.type == kObjectTypeString) { - GET_ONE_EVENT(event_nr, v, cleanup); + GET_ONE_EVENT(event_nr, v, goto cleanup); event_set[event_nr] = true; } else if (v.type == kObjectTypeArray) { FOREACH_ITEM(v.data.array, event_v, { @@ -136,7 +140,7 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Error *err) goto cleanup; }); - GET_ONE_EVENT(event_nr, event_v, cleanup); + GET_ONE_EVENT(event_nr, event_v, goto cleanup); event_set[event_nr] = true; }) } else { @@ -184,8 +188,9 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Error *err) goto cleanup; } - snprintf(pattern_buflocal, BUFLOCAL_PAT_LEN, "<buffer=%d>", (int)buf->handle); - ADD(buffers, CSTR_TO_OBJ(pattern_buflocal)); + String pat = arena_printf(arena, "<buffer=%d>", (int)buf->handle); + buffers = arena_array(arena, 1); + ADD_C(buffers, STRING_OBJ(pat)); } else if (opts->buffer.type == kObjectTypeArray) { if (opts->buffer.data.array.size > AUCMD_MAX_PATTERNS) { api_set_error(err, kErrorTypeValidation, "Too many buffers (maximum of %d)", @@ -193,6 +198,7 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Error *err) goto cleanup; } + buffers = arena_array(arena, kv_size(opts->buffer.data.array)); FOREACH_ITEM(opts->buffer.data.array, bufnr, { VALIDATE_EXP((bufnr.type == kObjectTypeInteger || bufnr.type == kObjectTypeBuffer), "buffer", "Integer", api_typename(bufnr.type), { @@ -204,8 +210,7 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Error *err) goto cleanup; } - snprintf(pattern_buflocal, BUFLOCAL_PAT_LEN, "<buffer=%d>", (int)buf->handle); - ADD(buffers, CSTR_TO_OBJ(pattern_buflocal)); + ADD_C(buffers, STRING_OBJ(arena_printf(arena, "<buffer=%d>", (int)buf->handle))); }); } else if (HAS_KEY(opts, get_autocmds, buffer)) { VALIDATE_EXP(false, "buffer", "Integer or Array", api_typename(opts->buffer.type), { @@ -247,6 +252,7 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Error *err) char *pat = pattern_filters[j]; int patlen = (int)strlen(pat); + char pattern_buflocal[BUFLOCAL_PAT_LEN]; if (aupat_is_buflocal(pat, patlen)) { aupat_normalize_buflocal_pat(pattern_buflocal, pat, patlen, aupat_get_buflocal_nr(pat, patlen)); @@ -264,51 +270,51 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Error *err) } } - Dictionary autocmd_info = ARRAY_DICT_INIT; + Dictionary autocmd_info = arena_dict(arena, 11); if (ap->group != AUGROUP_DEFAULT) { - PUT(autocmd_info, "group", INTEGER_OBJ(ap->group)); - PUT(autocmd_info, "group_name", CSTR_TO_OBJ(augroup_name(ap->group))); + PUT_C(autocmd_info, "group", INTEGER_OBJ(ap->group)); + PUT_C(autocmd_info, "group_name", CSTR_AS_OBJ(augroup_name(ap->group))); } if (ac->id > 0) { - PUT(autocmd_info, "id", INTEGER_OBJ(ac->id)); + PUT_C(autocmd_info, "id", INTEGER_OBJ(ac->id)); } if (ac->desc != NULL) { - PUT(autocmd_info, "desc", CSTR_TO_OBJ(ac->desc)); + PUT_C(autocmd_info, "desc", CSTR_AS_OBJ(ac->desc)); } if (ac->exec.type == CALLABLE_CB) { - PUT(autocmd_info, "command", STRING_OBJ(STRING_INIT)); + PUT_C(autocmd_info, "command", STRING_OBJ(STRING_INIT)); Callback *cb = &ac->exec.callable.cb; switch (cb->type) { case kCallbackLua: if (nlua_ref_is_function(cb->data.luaref)) { - PUT(autocmd_info, "callback", LUAREF_OBJ(api_new_luaref(cb->data.luaref))); + PUT_C(autocmd_info, "callback", LUAREF_OBJ(api_new_luaref(cb->data.luaref))); } break; case kCallbackFuncref: case kCallbackPartial: - PUT(autocmd_info, "callback", CSTR_AS_OBJ(callback_to_string(cb))); + PUT_C(autocmd_info, "callback", CSTR_AS_OBJ(callback_to_string(cb, arena))); break; case kCallbackNone: abort(); } } else { - PUT(autocmd_info, "command", CSTR_TO_OBJ(ac->exec.callable.cmd)); + PUT_C(autocmd_info, "command", CSTR_AS_OBJ(ac->exec.callable.cmd)); } - PUT(autocmd_info, "pattern", CSTR_TO_OBJ(ap->pat)); - PUT(autocmd_info, "event", CSTR_TO_OBJ(event_nr2name(event))); - PUT(autocmd_info, "once", BOOLEAN_OBJ(ac->once)); + PUT_C(autocmd_info, "pattern", CSTR_AS_OBJ(ap->pat)); + PUT_C(autocmd_info, "event", CSTR_AS_OBJ(event_nr2name(event))); + PUT_C(autocmd_info, "once", BOOLEAN_OBJ(ac->once)); if (ap->buflocal_nr) { - PUT(autocmd_info, "buflocal", BOOLEAN_OBJ(true)); - PUT(autocmd_info, "buffer", INTEGER_OBJ(ap->buflocal_nr)); + PUT_C(autocmd_info, "buflocal", BOOLEAN_OBJ(true)); + PUT_C(autocmd_info, "buffer", INTEGER_OBJ(ap->buflocal_nr)); } else { - PUT(autocmd_info, "buflocal", BOOLEAN_OBJ(false)); + PUT_C(autocmd_info, "buflocal", BOOLEAN_OBJ(false)); } // TODO(sctx): It would be good to unify script_ctx to actually work with lua @@ -325,16 +331,15 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Error *err) // 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(autocmd_info, "sid", INTEGER_OBJ(ac->script_ctx.sc_sid)); - // PUT(autocmd_info, "lnum", INTEGER_OBJ(ac->script_ctx.sc_lnum)); + // PUT_C(autocmd_info, "sid", INTEGER_OBJ(ac->script_ctx.sc_sid)); + // PUT_C(autocmd_info, "lnum", INTEGER_OBJ(ac->script_ctx.sc_lnum)); - ADD(autocmd_list, DICTIONARY_OBJ(autocmd_info)); + kvi_push(autocmd_list, DICTIONARY_OBJ(autocmd_info)); } } cleanup: - api_free_array(buffers); - return autocmd_list; + return arena_take_arraybuilder(arena, &autocmd_list); } /// Creates an |autocommand| event handler, defined by `callback` (Lua function or Vimscript @@ -375,15 +380,16 @@ cleanup: /// |autocmd-buflocal|. Cannot be used with {pattern}. /// - desc (string) optional: description (for documentation and troubleshooting). /// - callback (function|string) optional: Lua function (or Vimscript function name, if -/// string) called when the event(s) is triggered. Lua callback can return true to -/// delete the autocommand, and receives a table argument with these keys: +/// string) called when the event(s) is triggered. Lua callback can return a truthy +/// value (not `false` or `nil`) to delete the autocommand. Receives a table argument +/// with these keys: /// - 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>| -/// - data: (any) arbitrary data passed from |nvim_exec_autocmds()| +/// - match: (string) expanded value of [<amatch>] +/// - buf: (number) expanded value of [<abuf>] +/// - file: (string) expanded value of [<afile>] +/// - data: (any) arbitrary data passed from [nvim_exec_autocmds()] /// - command (string) optional: Vim command to execute on event. Cannot be used with /// {callback} /// - once (boolean) optional: defaults to false. Run the autocommand @@ -395,17 +401,16 @@ cleanup: /// @see |autocommand| /// @see |nvim_del_autocmd()| Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autocmd) *opts, - Error *err) + Arena *arena, Error *err) FUNC_API_SINCE(9) { int64_t autocmd_id = -1; char *desc = NULL; - Array patterns = ARRAY_DICT_INIT; - Array event_array = ARRAY_DICT_INIT; AucmdExecutable aucmd = AUCMD_EXECUTABLE_INIT; Callback cb = CALLBACK_NONE; - if (!unpack_string_or_array(&event_array, &event, "event", true, err)) { + Array event_array = unpack_string_or_array(event, "event", true, arena, err); + if (ERROR_SET(err)) { goto cleanup; } @@ -428,7 +433,8 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc }); cb.type = kCallbackLua; - cb.data.luaref = api_new_luaref(callback->data.luaref); + cb.data.luaref = callback->data.luaref; + callback->data.luaref = LUA_NOREF; break; case kObjectTypeString: cb.type = kCallbackFuncref; @@ -464,7 +470,9 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc goto cleanup; }); - if (!get_patterns_from_pattern_or_buf(&patterns, opts->pattern, has_buffer, opts->buffer, err)) { + Array patterns = get_patterns_from_pattern_or_buf(opts->pattern, has_buffer, opts->buffer, "*", + arena, err); + if (ERROR_SET(err)) { goto cleanup; } @@ -472,17 +480,13 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc desc = opts->desc.data; } - if (patterns.size == 0) { - ADD(patterns, STATIC_CSTR_TO_OBJ("*")); - } - VALIDATE_R((event_array.size > 0), "event", { goto cleanup; }); autocmd_id = next_autocmd_id++; FOREACH_ITEM(event_array, event_str, { - GET_ONE_EVENT(event_nr, event_str, cleanup); + GET_ONE_EVENT(event_nr, event_str, goto cleanup); int retval; @@ -509,8 +513,6 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc cleanup: aucmd_exec_free(&aucmd); - api_free_array(event_array); - api_free_array(patterns); return autocmd_id; } @@ -534,9 +536,9 @@ void nvim_del_autocmd(Integer id, Error *err) /// @param opts Parameters /// - event: (string|table) /// Examples: -/// - event: "pat1" -/// - event: { "pat1" } -/// - event: { "pat1", "pat2", "pat3" } +/// - event: "pat1" +/// - event: { "pat1" } +/// - event: { "pat1", "pat2", "pat3" } /// - pattern: (string|table) /// - pattern or patterns to match exactly. /// - For example, if you have `*.py` as that pattern for the autocmd, @@ -550,7 +552,7 @@ void nvim_del_autocmd(Integer id, Error *err) /// - group: (string|int) The augroup name or id. /// - NOTE: If not passed, will only delete autocmds *not* in any group. /// -void nvim_clear_autocmds(Dict(clear_autocmds) *opts, Error *err) +void nvim_clear_autocmds(Dict(clear_autocmds) *opts, Arena *arena, Error *err) FUNC_API_SINCE(9) { // TODO(tjdevries): Future improvements: @@ -559,33 +561,29 @@ void nvim_clear_autocmds(Dict(clear_autocmds) *opts, Error *err) // - group: Allow passing "*" or true or something like that to force doing all // autocmds, regardless of their group. - Array patterns = ARRAY_DICT_INIT; - Array event_array = ARRAY_DICT_INIT; - - if (!unpack_string_or_array(&event_array, &opts->event, "event", false, err)) { - goto cleanup; + Array event_array = unpack_string_or_array(opts->event, "event", false, arena, err); + if (ERROR_SET(err)) { + return; } bool has_buffer = HAS_KEY(opts, clear_autocmds, buffer); VALIDATE((!HAS_KEY(opts, clear_autocmds, pattern) || !has_buffer), "%s", "Cannot use both 'pattern' and 'buffer'", { - goto cleanup; + return; }); int au_group = get_augroup_from_object(opts->group, err); if (au_group == AUGROUP_ERROR) { - goto cleanup; - } - - if (!get_patterns_from_pattern_or_buf(&patterns, opts->pattern, has_buffer, opts->buffer, err)) { - goto cleanup; + return; } // When we create the autocmds, we want to say that they are all matched, so that's * // but when we clear them, we want to say that we didn't pass a pattern, so that's NUL - if (patterns.size == 0) { - ADD(patterns, STATIC_CSTR_TO_OBJ("")); + Array patterns = get_patterns_from_pattern_or_buf(opts->pattern, has_buffer, opts->buffer, "", + arena, err); + if (ERROR_SET(err)) { + return; } // If we didn't pass any events, that means clear all events. @@ -594,26 +592,22 @@ void nvim_clear_autocmds(Dict(clear_autocmds) *opts, Error *err) FOREACH_ITEM(patterns, pat_object, { char *pat = pat_object.data.string.data; if (!clear_autocmd(event, pat, au_group, err)) { - goto cleanup; + return; } }); } } else { FOREACH_ITEM(event_array, event_str, { - GET_ONE_EVENT(event_nr, event_str, cleanup); + GET_ONE_EVENT(event_nr, event_str, return ); FOREACH_ITEM(patterns, pat_object, { char *pat = pat_object.data.string.data; if (!clear_autocmd(event_nr, pat, au_group, err)) { - goto cleanup; + return; } }); }); } - -cleanup: - api_free_array(event_array); - api_free_array(patterns); } /// Create or get an autocommand group |autocmd-groups|. @@ -700,11 +694,11 @@ void nvim_del_augroup_by_name(String name, Error *err) /// - buffer (integer) optional: buffer number |autocmd-buflocal|. Cannot be used with /// {pattern}. /// - modeline (bool) optional: defaults to true. Process the -/// modeline after the autocommands |<nomodeline>|. +/// modeline after the autocommands [<nomodeline>]. /// - data (any): arbitrary data to send to the autocommand callback. See /// |nvim_create_autocmd()| for details. /// @see |:doautocmd| -void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err) +void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Arena *arena, Error *err) FUNC_API_SINCE(9) { int au_group = AUGROUP_ALL; @@ -712,13 +706,11 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err) buf_T *buf = curbuf; - Array patterns = ARRAY_DICT_INIT; - Array event_array = ARRAY_DICT_INIT; - Object *data = NULL; - if (!unpack_string_or_array(&event_array, &event, "event", true, err)) { - goto cleanup; + Array event_array = unpack_string_or_array(event, "event", true, arena, err); + if (ERROR_SET(err)) { + return; } switch (opts->group.type) { @@ -727,19 +719,19 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err) case kObjectTypeString: au_group = augroup_find(opts->group.data.string.data); VALIDATE_S((au_group != AUGROUP_ERROR), "group", opts->group.data.string.data, { - goto cleanup; + return; }); break; case kObjectTypeInteger: au_group = (int)opts->group.data.integer; char *name = au_group == 0 ? NULL : augroup_name(au_group); VALIDATE_INT(augroup_exists(name), "group", (int64_t)au_group, { - goto cleanup; + return; }); break; default: VALIDATE_EXP(false, "group", "String or Integer", api_typename(opts->group.type), { - goto cleanup; + return; }); } @@ -747,23 +739,21 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err) if (HAS_KEY(opts, exec_autocmds, buffer)) { VALIDATE((!HAS_KEY(opts, exec_autocmds, pattern)), "%s", "Cannot use both 'pattern' and 'buffer' for the same autocmd", { - goto cleanup; + return; }); has_buffer = true; buf = find_buffer_by_handle(opts->buffer, err); if (ERROR_SET(err)) { - goto cleanup; + return; } } - if (!get_patterns_from_pattern_or_buf(&patterns, opts->pattern, has_buffer, opts->buffer, err)) { - goto cleanup; - } - - if (patterns.size == 0) { - ADD(patterns, STATIC_CSTR_TO_OBJ("")); + Array patterns = get_patterns_from_pattern_or_buf(opts->pattern, has_buffer, opts->buffer, "", + arena, err); + if (ERROR_SET(err)) { + return; } if (HAS_KEY(opts, exec_autocmds, data)) { @@ -774,7 +764,7 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err) bool did_aucmd = false; FOREACH_ITEM(event_array, event_str, { - GET_ONE_EVENT(event_nr, event_str, cleanup) + GET_ONE_EVENT(event_nr, event_str, return ) FOREACH_ITEM(patterns, pat, { char *fname = !has_buffer ? pat.data.string.data : NULL; @@ -785,28 +775,26 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err) if (did_aucmd && modeline) { do_modelines(0); } - -cleanup: - api_free_array(event_array); - api_free_array(patterns); } -static bool unpack_string_or_array(Array *array, Object *v, char *k, bool required, Error *err) +static Array unpack_string_or_array(Object v, char *k, bool required, Arena *arena, Error *err) { - if (v->type == kObjectTypeString) { - ADD(*array, copy_object(*v, NULL)); - } else if (v->type == kObjectTypeArray) { - if (!check_string_array(v->data.array, k, true, err)) { - return false; + if (v.type == kObjectTypeString) { + Array arr = arena_array(arena, 1); + ADD_C(arr, v); + return arr; + } else if (v.type == kObjectTypeArray) { + if (!check_string_array(v.data.array, k, true, err)) { + return (Array)ARRAY_DICT_INIT; } - *array = copy_array(v->data.array, NULL); + return v.data.array; } else { - VALIDATE_EXP(!required, k, "Array or String", api_typename(v->type), { - return false; + VALIDATE_EXP(!required, k, "Array or String", api_typename(v.type), { + return (Array)ARRAY_DICT_INIT; }); } - return true; + return (Array)ARRAY_DICT_INIT; } // Returns AUGROUP_ERROR if there was a problem with {group} @@ -838,55 +826,57 @@ static int get_augroup_from_object(Object group, Error *err) } } -static bool get_patterns_from_pattern_or_buf(Array *patterns, Object pattern, bool has_buffer, - Buffer buffer, Error *err) +static Array get_patterns_from_pattern_or_buf(Object pattern, bool has_buffer, Buffer buffer, + char *fallback, Arena *arena, Error *err) { - const char pattern_buflocal[BUFLOCAL_PAT_LEN]; + ArrayBuilder patterns = ARRAY_DICT_INIT; + kvi_init(patterns); if (pattern.type != kObjectTypeNil) { - Object *v = &pattern; - - if (v->type == kObjectTypeString) { - const char *pat = v->data.string.data; + if (pattern.type == kObjectTypeString) { + const char *pat = pattern.data.string.data; size_t patlen = aucmd_pattern_length(pat); while (patlen) { - ADD(*patterns, STRING_OBJ(cbuf_to_string(pat, patlen))); + kvi_push(patterns, CBUF_TO_ARENA_OBJ(arena, pat, patlen)); pat = aucmd_next_pattern(pat, patlen); patlen = aucmd_pattern_length(pat); } - } else if (v->type == kObjectTypeArray) { - if (!check_string_array(v->data.array, "pattern", true, err)) { - return false; + } else if (pattern.type == kObjectTypeArray) { + if (!check_string_array(pattern.data.array, "pattern", true, err)) { + return (Array)ARRAY_DICT_INIT; } - Array array = v->data.array; + Array array = pattern.data.array; FOREACH_ITEM(array, entry, { const char *pat = entry.data.string.data; size_t patlen = aucmd_pattern_length(pat); while (patlen) { - ADD(*patterns, STRING_OBJ(cbuf_to_string(pat, patlen))); + kvi_push(patterns, CBUF_TO_ARENA_OBJ(arena, pat, patlen)); pat = aucmd_next_pattern(pat, patlen); patlen = aucmd_pattern_length(pat); } }) } else { - VALIDATE_EXP(false, "pattern", "String or Table", api_typename(v->type), { - return false; + VALIDATE_EXP(false, "pattern", "String or Table", api_typename(pattern.type), { + return (Array)ARRAY_DICT_INIT; }); } } else if (has_buffer) { buf_T *buf = find_buffer_by_handle(buffer, err); if (ERROR_SET(err)) { - return false; + return (Array)ARRAY_DICT_INIT; } - snprintf((char *)pattern_buflocal, BUFLOCAL_PAT_LEN, "<buffer=%d>", (int)buf->handle); - ADD(*patterns, CSTR_TO_OBJ(pattern_buflocal)); + kvi_push(patterns, STRING_OBJ(arena_printf(arena, "<buffer=%d>", (int)buf->handle))); } - return true; + if (kv_size(patterns) == 0 && fallback) { + kvi_push(patterns, CSTR_AS_OBJ(fallback)); + } + + return arena_take_arraybuilder(arena, &patterns); } static bool clear_autocmd(event_T event, char *pat, int au_group, Error *err) diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 0df231868d..7f195de959 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -12,10 +12,12 @@ #include "nvim/api/buffer.h" #include "nvim/api/keysets_defs.h" #include "nvim/api/private/defs.h" +#include "nvim/api/private/dispatch.h" #include "nvim/api/private/helpers.h" #include "nvim/api/private/validate.h" #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" +#include "nvim/autocmd_defs.h" #include "nvim/buffer.h" #include "nvim/buffer_defs.h" #include "nvim/buffer_updates.h" @@ -24,28 +26,32 @@ #include "nvim/drawscreen.h" #include "nvim/ex_cmds.h" #include "nvim/extmark.h" -#include "nvim/func_attr.h" +#include "nvim/extmark_defs.h" #include "nvim/globals.h" #include "nvim/lua/executor.h" #include "nvim/mapping.h" #include "nvim/mark.h" +#include "nvim/mark_defs.h" +#include "nvim/marktree_defs.h" #include "nvim/memline.h" +#include "nvim/memline_defs.h" #include "nvim/memory.h" +#include "nvim/memory_defs.h" #include "nvim/move.h" #include "nvim/ops.h" #include "nvim/pos_defs.h" #include "nvim/state_defs.h" #include "nvim/types_defs.h" #include "nvim/undo.h" +#include "nvim/undo_defs.h" #include "nvim/vim_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "api/buffer.c.generated.h" #endif -/// \defgroup api-buffer -/// -/// \brief For more information on buffers, see |buffers| +/// @brief <pre>help +/// For more information on buffers, see |buffers|. /// /// Unloaded Buffers: ~ /// @@ -57,6 +63,7 @@ /// /// You can use |nvim_buf_is_loaded()| or |nvim_buf_line_count()| to check /// whether a buffer is loaded. +/// </pre> /// Returns the number of lines in the given buffer. /// @@ -105,7 +112,7 @@ Integer nvim_buf_line_count(Buffer buffer, Error *err) /// Not for Lua callbacks. /// @param opts Optional parameters. /// - on_lines: Lua callback invoked on change. -/// Return `true` to detach. Args: +/// Return a truthy value (not `false` or `nil`) to detach. Args: /// - the string "lines" /// - buffer handle /// - b:changedtick @@ -118,8 +125,7 @@ Integer nvim_buf_line_count(Buffer buffer, Error *err) /// - on_bytes: Lua callback invoked on change. /// This callback receives more granular information about the /// change compared to on_lines. -/// Return `true` to detach. -/// Args: +/// Return a truthy value (not `false` or `nil`) to detach. Args: /// - the string "bytes" /// - buffer handle /// - b:changedtick @@ -127,11 +133,13 @@ Integer nvim_buf_line_count(Buffer buffer, Error *err) /// - start column of the changed text /// - byte offset of the changed text (from the start of /// the buffer) -/// - old end row of the changed text +/// - old end row of the changed text (offset from start row) /// - old end column of the changed text +/// (if old end row = 0, offset from start column) /// - old end byte length of the changed text -/// - new end row of the changed text +/// - new end row of the changed text (offset from start row) /// - new end column of the changed text +/// (if new end row = 0, offset from start column) /// - new end byte length of the changed text /// - on_changedtick: Lua callback invoked on changedtick /// increment without text change. Args: @@ -153,7 +161,7 @@ Integer nvim_buf_line_count(Buffer buffer, Error *err) /// @return False if attach failed (invalid parameter, or buffer isn't loaded); /// otherwise True. TODO: LUA_API_NO_EVAL Boolean nvim_buf_attach(uint64_t channel_id, Buffer buffer, Boolean send_buffer, - DictionaryOf(LuaRef) opts, Error *err) + Dict(buf_attach) *opts, Error *err) FUNC_API_SINCE(4) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -162,64 +170,40 @@ Boolean nvim_buf_attach(uint64_t channel_id, Buffer buffer, Boolean send_buffer, return false; } - bool is_lua = (channel_id == LUA_INTERNAL_CALL); BufUpdateCallbacks cb = BUF_UPDATE_CALLBACKS_INIT; - struct { - const char *name; - LuaRef *dest; - } cbs[] = { - { "on_lines", &cb.on_lines }, - { "on_bytes", &cb.on_bytes }, - { "on_changedtick", &cb.on_changedtick }, - { "on_detach", &cb.on_detach }, - { "on_reload", &cb.on_reload }, - { NULL, NULL }, - }; - - for (size_t i = 0; i < opts.size; i++) { - String k = opts.items[i].key; - Object *v = &opts.items[i].value; - bool key_used = false; - if (is_lua) { - for (size_t j = 0; cbs[j].name; j++) { - if (strequal(cbs[j].name, k.data)) { - VALIDATE_T(cbs[j].name, kObjectTypeLuaRef, v->type, { - goto error; - }); - *(cbs[j].dest) = v->data.luaref; - v->data.luaref = LUA_NOREF; - key_used = true; - break; - } - } - if (key_used) { - continue; - } else if (strequal("utf_sizes", k.data)) { - VALIDATE_T("utf_sizes", kObjectTypeBoolean, v->type, { - goto error; - }); - cb.utf_sizes = v->data.boolean; - key_used = true; - } else if (strequal("preview", k.data)) { - VALIDATE_T("preview", kObjectTypeBoolean, v->type, { - |