diff options
| author | Josh Rahm <joshuarahm@gmail.com> | 2024-11-19 22:57:13 +0000 |
|---|---|---|
| committer | Josh Rahm <joshuarahm@gmail.com> | 2024-11-19 22:57:13 +0000 |
| commit | 9be89f131f87608f224f0ee06d199fcd09d32176 (patch) | |
| tree | 11022dcfa9e08cb4ac5581b16734196128688d48 /src/nvim/api | |
| parent | ff7ed8f586589d620a806c3758fac4a47a8e7e15 (diff) | |
| parent | 88085c2e80a7e3ac29aabb6b5420377eed99b8b6 (diff) | |
| download | rneovim-9be89f131f87608f224f0ee06d199fcd09d32176.tar.gz rneovim-9be89f131f87608f224f0ee06d199fcd09d32176.tar.bz2 rneovim-9be89f131f87608f224f0ee06d199fcd09d32176.zip | |
Merge remote-tracking branch 'upstream/master' into mix_20240309
Diffstat (limited to 'src/nvim/api')
| -rw-r--r-- | src/nvim/api/autocmd.c | 10 | ||||
| -rw-r--r-- | src/nvim/api/buffer.c | 28 | ||||
| -rw-r--r-- | src/nvim/api/command.c | 40 | ||||
| -rw-r--r-- | src/nvim/api/deprecated.c | 12 | ||||
| -rw-r--r-- | src/nvim/api/extmark.c | 191 | ||||
| -rw-r--r-- | src/nvim/api/extmark.h | 15 | ||||
| -rw-r--r-- | src/nvim/api/keysets_defs.h | 53 | ||||
| -rw-r--r-- | src/nvim/api/options.c | 23 | ||||
| -rw-r--r-- | src/nvim/api/private/converter.c | 43 | ||||
| -rw-r--r-- | src/nvim/api/private/defs.h | 24 | ||||
| -rw-r--r-- | src/nvim/api/private/helpers.c | 86 | ||||
| -rw-r--r-- | src/nvim/api/private/helpers.h | 10 | ||||
| -rw-r--r-- | src/nvim/api/private/validate.c | 2 | ||||
| -rw-r--r-- | src/nvim/api/private/validate.h | 8 | ||||
| -rw-r--r-- | src/nvim/api/ui.c | 52 | ||||
| -rw-r--r-- | src/nvim/api/vim.c | 233 | ||||
| -rw-r--r-- | src/nvim/api/vimscript.c | 48 | ||||
| -rw-r--r-- | src/nvim/api/win_config.c | 101 | ||||
| -rw-r--r-- | src/nvim/api/window.c | 8 |
19 files changed, 537 insertions, 450 deletions
diff --git a/src/nvim/api/autocmd.c b/src/nvim/api/autocmd.c index ca8367b7ce..22932fd1a2 100644 --- a/src/nvim/api/autocmd.c +++ b/src/nvim/api/autocmd.c @@ -67,7 +67,7 @@ static int64_t next_autocmd_id = 1; /// NOTE: When multiple patterns or events are provided, it will find all the autocommands that /// match any combination of them. /// -/// @param opts Dictionary with at least one of the following: +/// @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|. @@ -270,7 +270,7 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Arena *arena, Error *err) } } - Dictionary autocmd_info = arena_dict(arena, 11); + Dict autocmd_info = arena_dict(arena, 11); if (ap->group != AUGROUP_DEFAULT) { PUT_C(autocmd_info, "group", INTEGER_OBJ(ap->group)); @@ -334,7 +334,7 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Arena *arena, Error *err) // 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, DICTIONARY_OBJ(autocmd_info)); + kvi_push(autocmd_list, DICT_OBJ(autocmd_info)); } } @@ -621,7 +621,7 @@ void nvim_clear_autocmds(Dict(clear_autocmds) *opts, Arena *arena, Error *err) /// ``` /// /// @param name String: The name of the group -/// @param opts Dictionary Parameters +/// @param opts Dict Parameters /// - clear (bool) optional: defaults to true. Clear existing /// commands if the group already exists |autocmd-groups|. /// @return Integer id of the created group. @@ -686,7 +686,7 @@ void nvim_del_augroup_by_name(String name, Error *err) /// Execute all autocommands for {event} that match the corresponding /// {opts} |autocmd-execute|. /// @param event (String|Array) The event or events to execute -/// @param opts Dictionary of autocommand options: +/// @param opts Dict of autocommand options: /// - group (string|integer) optional: the autocommand group name or /// id to match against. |autocmd-groups|. /// - pattern (string|array) optional: defaults to "*" |autocmd-pattern|. Cannot be used diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 7e64808709..9480292d9a 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -462,12 +462,8 @@ end: /// = row` and `start_col = end_col = col`. To delete the text in a range, use /// `replacement = {}`. /// -/// Prefer |nvim_buf_set_lines()| if you are only adding or deleting entire lines. -/// -/// Prefer |nvim_put()| if you want to insert text at the cursor position. -/// -/// @see |nvim_buf_set_lines()| -/// @see |nvim_put()| +/// @note Prefer |nvim_buf_set_lines()| (for performance) to add or delete entire lines. +/// @note Prefer |nvim_paste()| or |nvim_put()| to insert (instead of replace) text at cursor. /// /// @param channel_id /// @param buffer Buffer handle, or 0 for current buffer @@ -866,7 +862,7 @@ Integer nvim_buf_get_changedtick(Buffer buffer, Error *err) /// @param[out] err Error details, if any /// @returns Array of |maparg()|-like dictionaries describing mappings. /// The "buffer" key holds the associated buffer handle. -ArrayOf(Dictionary) nvim_buf_get_keymap(Buffer buffer, String mode, Arena *arena, Error *err) +ArrayOf(Dict) nvim_buf_get_keymap(Buffer buffer, String mode, Arena *arena, Error *err) FUNC_API_SINCE(3) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -1183,12 +1179,12 @@ ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Arena *arena, return rv; } -/// call a function with buffer as temporary current buffer +/// Call a function with buffer as temporary current buffer. /// /// This temporarily switches current buffer to "buffer". -/// If the current window already shows "buffer", the window is not switched +/// If the current window already shows "buffer", the window is not switched. /// If a window inside the current tabpage (including a float) already shows the -/// buffer One of these windows will be set as current window temporarily. +/// buffer, then one of these windows will be set as current window temporarily. /// Otherwise a temporary scratch window (called the "autocmd window" for /// historical reasons) will be used. /// @@ -1221,14 +1217,14 @@ Object nvim_buf_call(Buffer buffer, LuaRef fun, Error *err) } /// @nodoc -Dictionary nvim__buf_stats(Buffer buffer, Arena *arena, Error *err) +Dict nvim__buf_stats(Buffer buffer, Arena *arena, Error *err) { buf_T *buf = find_buffer_by_handle(buffer, err); if (!buf) { - return (Dictionary)ARRAY_DICT_INIT; + return (Dict)ARRAY_DICT_INIT; } - Dictionary rv = arena_dict(arena, 7); + Dict rv = arena_dict(arena, 7); // Number of times the cached line was flushed. // This should generally not increase while editing the same // line in the same mode. @@ -1375,7 +1371,7 @@ static inline void init_line_array(lua_State *lstate, Array *a, size_t size, Are /// @param s String to push /// @param len Size of string /// @param idx 0-based index to place s (only used for Lua) -/// @param replace_nl Replace newlines ('\n') with null ('\0') +/// @param replace_nl Replace newlines ('\n') with null (NUL) static void push_linestr(lua_State *lstate, Array *a, const char *s, size_t len, int idx, bool replace_nl, Arena *arena) { @@ -1384,7 +1380,7 @@ static void push_linestr(lua_State *lstate, Array *a, const char *s, size_t len, if (s && replace_nl && strchr(s, '\n')) { // TODO(bfredl): could manage scratch space in the arena, for the NUL case char *tmp = xmemdupz(s, len); - strchrsub(tmp, '\n', '\0'); + strchrsub(tmp, '\n', NUL); lua_pushlstring(lstate, tmp, len); xfree(tmp); } else { @@ -1397,7 +1393,7 @@ static void push_linestr(lua_State *lstate, Array *a, const char *s, size_t len, str = CBUF_TO_ARENA_STR(arena, s, len); if (replace_nl) { // Vim represents NULs as NLs, but this may confuse clients. - strchrsub(str.data, '\n', '\0'); + strchrsub(str.data, '\n', NUL); } } diff --git a/src/nvim/api/command.c b/src/nvim/api/command.c index 779e216c74..ab57d5c009 100644 --- a/src/nvim/api/command.c +++ b/src/nvim/api/command.c @@ -46,7 +46,7 @@ /// @param str Command line string to parse. Cannot contain "\n". /// @param opts Optional parameters. Reserved for future use. /// @param[out] err Error details, if any. -/// @return Dictionary containing command information, with these keys: +/// @return Dict containing command information, with these keys: /// - cmd: (string) Command name. /// - range: (array) (optional) Command range ([<line1>] [<line2>]). /// Omitted if command doesn't accept a range. @@ -63,13 +63,13 @@ /// - nargs: (string) Value of |:command-nargs|. /// - nextcmd: (string) Next command if there are multiple commands separated by a |:bar|. /// Empty if there isn't a next command. -/// - magic: (dictionary) Which characters have special meaning in the command arguments. +/// - magic: (dict) Which characters have special meaning in the command arguments. /// - file: (boolean) The command expands filenames. Which means characters such as "%", /// "#" and wildcards are expanded. /// - bar: (boolean) The "|" character is treated as a command separator and the double /// quote character (") is treated as the start of a comment. -/// - mods: (dictionary) |:command-modifiers|. -/// - filter: (dictionary) |:filter|. +/// - mods: (dict) |:command-modifiers|. +/// - filter: (dict) |:filter|. /// - pattern: (string) Filter pattern. Empty string if there is no filter. /// - force: (boolean) Whether filter is inverted or not. /// - silent: (boolean) |:silent|. @@ -193,7 +193,7 @@ Dict(cmd) nvim_parse_cmd(String str, Dict(empty) *opts, Arena *arena, Error *err } else { nargs[0] = '0'; } - nargs[1] = '\0'; + nargs[1] = NUL; PUT_KEY(result, cmd, nargs, CSTR_TO_ARENA_OBJ(arena, nargs)); char *addr; @@ -230,12 +230,12 @@ Dict(cmd) nvim_parse_cmd(String str, Dict(empty) *opts, Arena *arena, Error *err PUT_KEY(result, cmd, nextcmd, CSTR_AS_OBJ(ea.nextcmd)); // TODO(bfredl): nested keydict would be nice.. - Dictionary mods = arena_dict(arena, 20); + Dict mods = arena_dict(arena, 20); - Dictionary filter = arena_dict(arena, 2); + Dict filter = arena_dict(arena, 2); PUT_C(filter, "pattern", CSTR_TO_ARENA_OBJ(arena, cmdinfo.cmdmod.cmod_filter_pat)); PUT_C(filter, "force", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_filter_force)); - PUT_C(mods, "filter", DICTIONARY_OBJ(filter)); + PUT_C(mods, "filter", DICT_OBJ(filter)); PUT_C(mods, "silent", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_SILENT)); PUT_C(mods, "emsg_silent", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_ERRSILENT)); @@ -272,7 +272,7 @@ Dict(cmd) nvim_parse_cmd(String str, Dict(empty) *opts, Arena *arena, Error *err PUT_KEY(result, cmd, mods, mods); - Dictionary magic = arena_dict(arena, 2); + Dict magic = arena_dict(arena, 2); PUT_C(magic, "file", BOOLEAN_OBJ(cmdinfo.magic.file)); PUT_C(magic, "bar", BOOLEAN_OBJ(cmdinfo.magic.bar)); PUT_KEY(result, cmd, magic, magic); @@ -284,7 +284,7 @@ end: /// Executes an Ex command. /// -/// Unlike |nvim_command()| this command takes a structured Dictionary instead of a String. This +/// Unlike |nvim_command()| this command takes a structured Dict instead of a String. This /// allows for easier construction and manipulation of an Ex command. This also allows for things /// such as having spaces inside a command argument, expanding filenames in a command that otherwise /// doesn't expand filenames, etc. Command arguments may also be Number, Boolean or String. @@ -298,7 +298,7 @@ end: /// @see |nvim_exec2()| /// @see |nvim_command()| /// -/// @param cmd Command to execute. Must be a Dictionary that can contain the same values as +/// @param cmd Command to execute. Must be a Dict that can contain the same values as /// the return value of |nvim_parse_cmd()| except "addr", "nargs" and "nextcmd" /// which are ignored if provided. All values except for "cmd" are optional. /// @param opts Optional parameters. @@ -391,7 +391,7 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Arena case kObjectTypeBoolean: data_str = arena_alloc(arena, 2, false); data_str[0] = elem.data.boolean ? '1' : '0'; - data_str[1] = '\0'; + data_str[1] = NUL; ADD_C(args, CSTR_AS_OBJ(data_str)); break; case kObjectTypeBuffer: @@ -515,7 +515,7 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Arena if (HAS_KEY(cmd, cmd, magic)) { Dict(cmd_magic) magic[1] = KEYDICT_INIT; - if (!api_dict_to_keydict(magic, KeyDict_cmd_magic_get_field, cmd->magic, err)) { + if (!api_dict_to_keydict(magic, DictHash(cmd_magic), cmd->magic, err)) { goto end; } @@ -533,14 +533,14 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Arena if (HAS_KEY(cmd, cmd, mods)) { Dict(cmd_mods) mods[1] = KEYDICT_INIT; - if (!api_dict_to_keydict(mods, KeyDict_cmd_mods_get_field, cmd->mods, err)) { + if (!api_dict_to_keydict(mods, DictHash(cmd_mods), cmd->mods, err)) { goto end; } if (HAS_KEY(mods, cmd_mods, filter)) { Dict(cmd_mods_filter) filter[1] = KEYDICT_INIT; - if (!api_dict_to_keydict(&filter, KeyDict_cmd_mods_filter_get_field, + if (!api_dict_to_keydict(&filter, DictHash(cmd_mods_filter), mods->filter, err)) { goto end; } @@ -1166,7 +1166,7 @@ err: /// @param[out] err Error details, if any. /// /// @returns Map of maps describing commands. -Dictionary nvim_get_commands(Dict(get_commands) *opts, Arena *arena, Error *err) +Dict nvim_get_commands(Dict(get_commands) *opts, Arena *arena, Error *err) FUNC_API_SINCE(4) { return nvim_buf_get_commands(-1, opts, arena, err); @@ -1179,25 +1179,25 @@ Dictionary nvim_get_commands(Dict(get_commands) *opts, Arena *arena, Error *err) /// @param[out] err Error details, if any. /// /// @returns Map of maps describing commands. -Dictionary nvim_buf_get_commands(Buffer buffer, Dict(get_commands) *opts, Arena *arena, Error *err) +Dict nvim_buf_get_commands(Buffer buffer, Dict(get_commands) *opts, Arena *arena, Error *err) FUNC_API_SINCE(4) { bool global = (buffer == -1); if (ERROR_SET(err)) { - return (Dictionary)ARRAY_DICT_INIT; + return (Dict)ARRAY_DICT_INIT; } if (global) { if (opts->builtin) { api_set_error(err, kErrorTypeValidation, "builtin=true not implemented"); - return (Dictionary)ARRAY_DICT_INIT; + return (Dict)ARRAY_DICT_INIT; } return commands_array(NULL, arena); } buf_T *buf = find_buffer_by_handle(buffer, err); if (opts->builtin || !buf) { - return (Dictionary)ARRAY_DICT_INIT; + return (Dict)ARRAY_DICT_INIT; } return commands_array(buf, arena); } diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index af3bfe2c03..6376011106 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -170,7 +170,7 @@ Integer nvim_buf_set_virtual_text(Buffer buffer, Integer src_id, Integer line, A DecorInline decor = { .ext = true, .data.ext.vt = vt, .data.ext.sh_idx = DECOR_ID_INVALID }; extmark_set(buf, ns_id, NULL, (int)line, 0, -1, -1, decor, 0, true, - false, false, false, false, NULL); + false, false, false, NULL); return src_id; } @@ -183,11 +183,11 @@ Integer nvim_buf_set_virtual_text(Buffer buffer, Integer src_id, Integer line, A /// @param[out] err Error details, if any /// @return Highlight definition map /// @see nvim_get_hl_by_name -Dictionary nvim_get_hl_by_id(Integer hl_id, Boolean rgb, Arena *arena, Error *err) +Dict nvim_get_hl_by_id(Integer hl_id, Boolean rgb, Arena *arena, Error *err) FUNC_API_SINCE(3) FUNC_API_DEPRECATED_SINCE(9) { - Dictionary dic = ARRAY_DICT_INIT; + Dict dic = ARRAY_DICT_INIT; VALIDATE_INT((syn_get_final_id((int)hl_id) != 0), "highlight id", hl_id, { return dic; }); @@ -204,11 +204,11 @@ Dictionary nvim_get_hl_by_id(Integer hl_id, Boolean rgb, Arena *arena, Error *er /// @param[out] err Error details, if any /// @return Highlight definition map /// @see nvim_get_hl_by_id -Dictionary nvim_get_hl_by_name(String name, Boolean rgb, Arena *arena, Error *err) +Dict nvim_get_hl_by_name(String name, Boolean rgb, Arena *arena, Error *err) FUNC_API_SINCE(3) FUNC_API_DEPRECATED_SINCE(9) { - Dictionary result = ARRAY_DICT_INIT; + Dict result = ARRAY_DICT_INIT; int id = syn_name2id(name.data); VALIDATE_S((id != 0), "highlight name", name.data, { @@ -515,7 +515,7 @@ static int64_t convert_index(int64_t index) /// @param name Option name /// @param[out] err Error details, if any /// @return Option Information -Dictionary nvim_get_option_info(String name, Arena *arena, Error *err) +Dict nvim_get_option_info(String name, Arena *arena, Error *err) FUNC_API_SINCE(7) FUNC_API_DEPRECATED_SINCE(11) { diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c index 85cce45560..7786c30624 100644 --- a/src/nvim/api/extmark.c +++ b/src/nvim/api/extmark.c @@ -18,6 +18,7 @@ #include "nvim/decoration_provider.h" #include "nvim/drawscreen.h" #include "nvim/extmark.h" +#include "nvim/globals.h" #include "nvim/grid.h" #include "nvim/highlight_group.h" #include "nvim/map_defs.h" @@ -41,6 +42,7 @@ void api_extmark_free_all_mem(void) xfree(name.data); }) map_destroy(String, &namespace_ids); + set_destroy(uint32_t, &namespace_localscope); } /// Creates a new namespace or gets an existing one. [namespace]() @@ -72,10 +74,10 @@ Integer nvim_create_namespace(String name) /// Gets existing, non-anonymous |namespace|s. /// /// @return dict that maps from names to namespace ids. -Dictionary nvim_get_namespaces(Arena *arena) +Dict nvim_get_namespaces(Arena *arena) FUNC_API_SINCE(5) { - Dictionary retval = arena_dict(arena, map_size(&namespace_ids)); + Dict retval = arena_dict(arena, map_size(&namespace_ids)); String name; handle_T id; @@ -156,7 +158,7 @@ static Array extmark_to_array(MTPair extmark, bool id, bool add_dict, bool hl_na if (add_dict) { // TODO(bfredl): coding the size like this is a bit fragile. // We want ArrayOf(Dict(set_extmark)) as the return type.. - Dictionary dict = arena_dict(arena, ARRAY_SIZE(set_extmark_table)); + Dict dict = arena_dict(arena, ARRAY_SIZE(set_extmark_table)); PUT_C(dict, "ns_id", INTEGER_OBJ((Integer)start.ns)); @@ -179,13 +181,9 @@ static Array extmark_to_array(MTPair extmark, bool id, bool add_dict, bool hl_na PUT_C(dict, "invalid", BOOLEAN_OBJ(true)); } - if (mt_scoped(start)) { - PUT_C(dict, "scoped", BOOLEAN_OBJ(true)); - } - decor_to_dict_legacy(&dict, mt_decor(start), hl_name, arena); - ADD_C(rv, DICTIONARY_OBJ(dict)); + ADD_C(rv, DICT_OBJ(dict)); } return rv; @@ -489,8 +487,6 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e /// used together with virt_text. /// - url: A URL to associate with this extmark. In the TUI, the OSC 8 control /// sequence is used to generate a clickable hyperlink to this URL. -/// - scoped: boolean (EXPERIMENTAL) enables "scoping" for the extmark. See -/// |nvim__win_add_ns()| /// /// @param[out] err Error details, if any /// @return Id of the created/updated extmark @@ -575,7 +571,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer String c = opts->conceal; if (c.size > 0) { int ch; - hl.conceal_char = utfc_ptr2schar_len(c.data, (int)c.size, &ch); + hl.conceal_char = utfc_ptr2schar(c.data, &ch); if (!hl.conceal_char || !vim_isprintc(ch)) { api_set_error(err, kErrorTypeValidation, "conceal char has to be printable"); goto error; @@ -691,6 +687,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer if (HAS_KEY(opts, set_extmark, url)) { url = string_to_cstr(opts->url); + has_hl = true; } if (opts->ui_watched) { @@ -749,11 +746,6 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer } if (opts->ephemeral && decor_state.win && decor_state.win->w_buffer == buf) { - if (opts->scoped) { - api_set_error(err, kErrorTypeException, "not yet implemented"); - goto error; - } - int r = (int)line; int c = (int)col; if (line2 == -1) { @@ -767,13 +759,9 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer if (kv_size(virt_lines.data.virt_lines)) { decor_range_add_virt(&decor_state, r, c, line2, col2, decor_put_vt(virt_lines, NULL), true); } - if (url != NULL) { - DecorSignHighlight sh = DECOR_SIGN_HIGHLIGHT_INIT; - sh.url = url; - decor_range_add_sh(&decor_state, r, c, line2, col2, &sh, true, 0, 0); - } if (has_hl) { DecorSignHighlight sh = decor_sh_from_inline(hl); + sh.url = url; decor_range_add_sh(&decor_state, r, c, line2, col2, &sh, true, (uint32_t)ns_id, id); } } else { @@ -797,12 +785,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer } uint32_t decor_indexed = DECOR_ID_INVALID; - if (url != NULL) { - DecorSignHighlight sh = DECOR_SIGN_HIGHLIGHT_INIT; - sh.url = url; - sh.next = decor_indexed; - decor_indexed = decor_put_sh(sh); - } + if (sign.flags & kSHIsSign) { sign.next = decor_indexed; decor_indexed = decor_put_sh(sign); @@ -815,9 +798,11 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer } DecorInline decor = DECOR_INLINE_INIT; - if (decor_alloc || decor_indexed != DECOR_ID_INVALID || schar_high(hl.conceal_char)) { + if (decor_alloc || decor_indexed != DECOR_ID_INVALID || url != NULL + || schar_high(hl.conceal_char)) { if (has_hl) { DecorSignHighlight sh = decor_sh_from_inline(hl); + sh.url = url; sh.next = decor_indexed; decor_indexed = decor_put_sh(sh); } @@ -834,7 +819,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer extmark_set(buf, (uint32_t)ns_id, &id, (int)line, (colnr_T)col, line2, col2, decor, decor_flags, right_gravity, opts->end_right_gravity, !GET_BOOL_OR_TRUE(opts, set_extmark, undo_restore), - opts->invalidate, opts->scoped, err); + opts->invalidate, err); if (ERROR_SET(err)) { decor_free(decor); return 0; @@ -960,7 +945,7 @@ Integer nvim_buf_add_highlight(Buffer buffer, Integer ns_id, String hl_group, In decor.data.hl.hl_id = hl_id; extmark_set(buf, ns, NULL, (int)line, (colnr_T)col_start, end_line, (colnr_T)col_end, - decor, MT_FLAG_DECOR_HL, true, false, false, false, false, NULL); + decor, MT_FLAG_DECOR_HL, true, false, false, false, NULL); return ns_id; } @@ -1011,7 +996,7 @@ void nvim_buf_clear_namespace(Buffer buffer, Integer ns_id, Integer line_start, /// Note: this function should not be called often. Rather, the callbacks /// themselves can be used to throttle unneeded callbacks. the `on_start` /// callback can return `false` to disable the provider until the next redraw. -/// Similarly, return `false` in `on_win` will skip the `on_lines` calls +/// Similarly, return `false` in `on_win` will skip the `on_line` calls /// for that window (but any extmarks set in `on_win` will still be used). /// A plugin managing multiple sources of decoration should ideally only set /// one provider, and merge the sources internally. You can use multiple `ns_id` @@ -1020,10 +1005,10 @@ void nvim_buf_clear_namespace(Buffer buffer, Integer ns_id, Integer line_start, /// Note: doing anything other than setting extmarks is considered experimental. /// Doing things like changing options are not explicitly forbidden, but is /// likely to have unexpected consequences (such as 100% CPU consumption). -/// doing `vim.rpcnotify` should be OK, but `vim.rpcrequest` is quite dubious +/// Doing `vim.rpcnotify` should be OK, but `vim.rpcrequest` is quite dubious /// for the moment. /// -/// Note: It is not allowed to remove or update extmarks in 'on_line' callbacks. +/// Note: It is not allowed to remove or update extmarks in `on_line` callbacks. /// /// @param ns_id Namespace id from |nvim_create_namespace()| /// @param opts Table of callbacks: @@ -1038,7 +1023,7 @@ void nvim_buf_clear_namespace(Buffer buffer, Integer ns_id, Integer line_start, /// ``` /// - on_win: called when starting to redraw a specific window. /// ``` -/// ["win", winid, bufnr, topline, botline] +/// ["win", winid, bufnr, toprow, botrow] /// ``` /// - on_line: called for each buffer line being redrawn. /// (The interaction with fold lines is subject to change) @@ -1217,77 +1202,119 @@ String nvim__buf_debug_extmarks(Buffer buffer, Boolean keys, Boolean dot, Error /// EXPERIMENTAL: this API will change in the future. /// -/// Scopes a namespace to the a window, so extmarks in the namespace will be active only in the -/// given window. +/// Set some properties for namespace /// -/// @param window Window handle, or 0 for current window /// @param ns_id Namespace -/// @return true if the namespace was added, else false -Boolean nvim__win_add_ns(Window window, Integer ns_id, Error *err) +/// @param opts Optional parameters to set: +/// - wins: a list of windows to be scoped in +/// +void nvim__ns_set(Integer ns_id, Dict(ns_opts) *opts, Error *err) { - win_T *win = find_window_by_handle(window, err); - if (!win) { - return false; - } - VALIDATE_INT(ns_initialized((uint32_t)ns_id), "ns_id", ns_id, { - return false; + return; }); - set_put(uint32_t, &win->w_ns_set, (uint32_t)ns_id); + bool set_scoped = true; - if (map_has(uint32_t, win->w_buffer->b_extmark_ns, (uint32_t)ns_id)) { - changed_window_setting(win); - } + if (HAS_KEY(opts, ns_opts, wins)) { + if (opts->wins.size == 0) { + set_scoped = false; + } - return true; -} + Set(ptr_t) windows = SET_INIT; + for (size_t i = 0; i < opts->wins.size; i++) { + Integer win = opts->wins.items[i].data.integer; -/// EXPERIMENTAL: this API will change in the future. -/// -/// Gets the namespace scopes for a given window. -/// -/// @param window Window handle, or 0 for current window -/// @return a list of namespaces ids -ArrayOf(Integer) nvim__win_get_ns(Window window, Arena *arena, Error *err) -{ - win_T *win = find_window_by_handle(window, err); - if (!win) { - return (Array)ARRAY_DICT_INIT; + win_T *wp = find_window_by_handle((Window)win, err); + if (!wp) { + return; + } + + set_put(ptr_t, &windows, wp); + } + + FOR_ALL_TAB_WINDOWS(tp, wp) { + if (set_has(ptr_t, &windows, wp) && !set_has(uint32_t, &wp->w_ns_set, (uint32_t)ns_id)) { + set_put(uint32_t, &wp->w_ns_set, (uint32_t)ns_id); + + if (map_has(uint32_t, wp->w_buffer->b_extmark_ns, (uint32_t)ns_id)) { + changed_window_setting(wp); + } + } + + if (set_has(uint32_t, &wp->w_ns_set, (uint32_t)ns_id) && !set_has(ptr_t, &windows, wp)) { + set_del(uint32_t, &wp->w_ns_set, (uint32_t)ns_id); + + if (map_has(uint32_t, wp->w_buffer->b_extmark_ns, (uint32_t)ns_id)) { + changed_window_setting(wp); + } + } + } + + set_destroy(ptr_t, &windows); } - Array rv = arena_array(arena, set_size(&win->w_ns_set)); - uint32_t i; - set_foreach(&win->w_ns_set, i, { - ADD_C(rv, INTEGER_OBJ((Integer)(i))); - }); + if (set_scoped && !set_has(uint32_t, &namespace_localscope, (uint32_t)ns_id)) { + set_put(uint32_t, &namespace_localscope, (uint32_t)ns_id); - return rv; + // When a namespace becomes scoped, any window which contains + // elements associated with namespace needs to be redrawn + FOR_ALL_TAB_WINDOWS(tp, wp) { + if (map_has(uint32_t, wp->w_buffer->b_extmark_ns, (uint32_t)ns_id)) { + changed_window_setting(wp); + } + } + } else if (!set_scoped && set_has(uint32_t, &namespace_localscope, (uint32_t)ns_id)) { + set_del(uint32_t, &namespace_localscope, (uint32_t)ns_id); + + // When a namespace becomes unscoped, any window which does not + // contain elements associated with namespace needs to be redrawn + FOR_ALL_TAB_WINDOWS(tp, wp) { + if (map_has(uint32_t, wp->w_buffer->b_extmark_ns, (uint32_t)ns_id)) { + changed_window_setting(wp); + } + } + } } /// EXPERIMENTAL: this API will change in the future. /// -/// Unscopes a namespace (un-binds it from the given scope). +/// Get the properties for namespace /// -/// @param window Window handle, or 0 for current window -/// @param ns_id the namespace to remove -/// @return true if the namespace was removed, else false -Boolean nvim__win_del_ns(Window window, Integer ns_id, Error *err) +/// @param ns_id Namespace +/// @return Map defining the namespace properties, see |nvim__ns_set()| +Dict(ns_opts) nvim__ns_get(Integer ns_id, Arena *arena, Error *err) { - win_T *win = find_window_by_handle(window, err); - if (!win) { - return false; + Dict(ns_opts) opts = KEYDICT_INIT; + + Array windows = ARRAY_DICT_INIT; + + PUT_KEY(opts, ns_opts, wins, windows); + + VALIDATE_INT(ns_initialized((uint32_t)ns_id), "ns_id", ns_id, { + return opts; + }); + + if (!set_has(uint32_t, &namespace_localscope, (uint32_t)ns_id)) { + return opts; } - if (!set_has(uint32_t, &win->w_ns_set, (uint32_t)ns_id)) { - return false; + size_t count = 0; + FOR_ALL_TAB_WINDOWS(tp, wp) { + if (set_has(uint32_t, &wp->w_ns_set, (uint32_t)ns_id)) { + count++; + } } - set_del(uint32_t, &win->w_ns_set, (uint32_t)ns_id); + windows = arena_array(arena, count); - if (map_has(uint32_t, win->w_buffer->b_extmark_ns, (uint32_t)ns_id)) { - changed_window_setting(win); + FOR_ALL_TAB_WINDOWS(tp, wp) { + if (set_has(uint32_t, &wp->w_ns_set, (uint32_t)ns_id)) { + ADD(windows, INTEGER_OBJ(wp->handle)); + } } - return true; + PUT_KEY(opts, ns_opts, wins, windows); + + return opts; } diff --git a/src/nvim/api/extmark.h b/src/nvim/api/extmark.h index 124feaabfb..af2d51c95c 100644 --- a/src/nvim/api/extmark.h +++ b/src/nvim/api/extmark.h @@ -4,14 +4,29 @@ #include "nvim/api/keysets_defs.h" // IWYU pragma: keep #include "nvim/api/private/defs.h" // IWYU pragma: keep +#include "nvim/buffer_defs.h" #include "nvim/decoration_defs.h" // IWYU pragma: keep #include "nvim/macros_defs.h" #include "nvim/map_defs.h" #include "nvim/types_defs.h" EXTERN Map(String, int) namespace_ids INIT( = MAP_INIT); +/// Non-global namespaces. A locally-scoped namespace may be "orphaned" if all +/// window(s) it was scoped to, are destroyed. Such orphans are tracked here to +/// avoid being mistaken as "global scope". +EXTERN Set(uint32_t) namespace_localscope INIT( = SET_INIT); EXTERN handle_T next_namespace_id INIT( = 1); +/// Returns true if the namespace is global or scoped in the given window. +static inline bool ns_in_win(uint32_t ns_id, win_T *wp) +{ + if (!set_has(uint32_t, &namespace_localscope, ns_id)) { + return true; + } + + return set_has(uint32_t, &wp->w_ns_set, ns_id); +} + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "api/extmark.h.generated.h" #endif diff --git a/src/nvim/api/keysets_defs.h b/src/nvim/api/keysets_defs.h index 00d8aa8428..552612dd13 100644 --- a/src/nvim/api/keysets_defs.h +++ b/src/nvim/api/keysets_defs.h @@ -103,7 +103,7 @@ typedef struct { Object nargs; Object preview; Object range; - Boolean register_; + Boolean register_ DictKey(register); } Dict(user_command); typedef struct { @@ -170,7 +170,7 @@ typedef struct { Boolean reverse; Boolean altfont; Boolean nocombine; - Boolean default_; + Boolean default_ DictKey(default); Object cterm; Object foreground; Object fg; @@ -275,8 +275,8 @@ typedef struct { String reg; Boolean bang; Array args; - Dictionary magic; - Dictionary mods; + Dict magic; + Dict mods; Object nargs; Object addr; Object nextcmd; @@ -293,7 +293,7 @@ typedef struct { Boolean silent; Boolean emsg_silent; Boolean unsilent; - Dictionary filter; |