From 543e0256c19f397921a332e06b423215fd9aecb5 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 30 Nov 2023 15:51:05 +0800 Subject: build: don't define FUNC_ATTR_* as empty in headers (#26317) FUNC_ATTR_* should only be used in .c files with generated headers. Defining FUNC_ATTR_* as empty in headers causes misuses of them to be silently ignored. Instead don't define them by default, and only define them as empty after a .c file has included its generated header. --- src/nvim/api/vim.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index d631b10af9..270f2e4432 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -31,7 +31,6 @@ #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/getchar.h" #include "nvim/globals.h" #include "nvim/grid.h" -- cgit From 66f1563c7a48d76f99c89e32de030e57af2abfb4 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 4 Dec 2023 20:29:51 +0800 Subject: refactor(terminal): only remove const qualifier when necessary (#26386) --- src/nvim/api/vim.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 270f2e4432..db08cb8cf0 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1017,18 +1017,19 @@ Integer nvim_open_term(Buffer buffer, DictionaryOf(LuaRef) opts, Error *err) } } - TerminalOptions topts; Channel *chan = channel_alloc(kChannelStreamInternal); chan->stream.internal.cb = cb; chan->stream.internal.closed = false; - topts.data = chan; - // NB: overridden in terminal_check_size if a window is already - // displaying the buffer - topts.width = (uint16_t)MAX(curwin->w_width_inner - win_col_off(curwin), 0); - topts.height = (uint16_t)curwin->w_height_inner; - topts.write_cb = term_write; - topts.resize_cb = term_resize; - topts.close_cb = term_close; + TerminalOptions topts = { + .data = chan, + // NB: overridden in terminal_check_size if a window is already + // displaying the buffer + .width = (uint16_t)MAX(curwin->w_width_inner - win_col_off(curwin), 0), + .height = (uint16_t)curwin->w_height_inner, + .write_cb = term_write, + .resize_cb = term_resize, + .close_cb = term_close, + }; channel_incref(chan); terminal_open(&chan->term, buf, topts); if (chan->term != NULL) { @@ -1038,7 +1039,7 @@ Integer nvim_open_term(Buffer buffer, DictionaryOf(LuaRef) opts, Error *err) return (Integer)chan->id; } -static void term_write(char *buf, size_t size, void *data) // NOLINT(readability-non-const-parameter) +static void term_write(const char *buf, size_t size, void *data) { Channel *chan = data; LuaRef cb = chan->stream.internal.cb; @@ -1048,7 +1049,7 @@ static void term_write(char *buf, size_t size, void *data) // NOLINT(readabilit MAXSIZE_TEMP_ARRAY(args, 3); ADD_C(args, INTEGER_OBJ((Integer)chan->id)); ADD_C(args, BUFFER_OBJ(terminal_buf(chan->term))); - ADD_C(args, STRING_OBJ(((String){ .data = buf, .size = size }))); + ADD_C(args, STRING_OBJ(((String){ .data = (char *)buf, .size = size }))); textlock++; nlua_call_ref(cb, "input", args, false, NULL); textlock--; -- cgit From 0b74ad0a641f28d9d3da5353e98372d87078bd9d Mon Sep 17 00:00:00 2001 From: Riccardo Mazzarini Date: Tue, 5 Dec 2023 12:33:57 +0100 Subject: refactor(api): complete conversion from `Dictionary` to `Dict(opts)` (#26365) --- src/nvim/api/vim.c | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index db08cb8cf0..0842469c59 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -987,7 +987,7 @@ fail: /// ["input", term, bufnr, data] /// @param[out] err Error details, if any /// @return Channel id, or 0 on error -Integer nvim_open_term(Buffer buffer, DictionaryOf(LuaRef) opts, Error *err) +Integer nvim_open_term(Buffer buffer, Dict(open_term) *opts, Error *err) FUNC_API_SINCE(7) FUNC_API_TEXTLOCK_ALLOW_CMDWIN { @@ -1002,19 +1002,10 @@ Integer nvim_open_term(Buffer buffer, DictionaryOf(LuaRef) opts, Error *err) } LuaRef cb = LUA_NOREF; - for (size_t i = 0; i < opts.size; i++) { - String k = opts.items[i].key; - Object *v = &opts.items[i].value; - if (strequal("on_input", k.data)) { - VALIDATE_T("on_input", kObjectTypeLuaRef, v->type, { - return 0; - }); - cb = v->data.luaref; - v->data.luaref = LUA_NOREF; - break; - } else { - VALIDATE_S(false, "'opts' key", k.data, {}); - } + + if (HAS_KEY(opts, open_term, on_input)) { + cb = opts->on_input; + opts->on_input = LUA_NOREF; } Channel *chan = channel_alloc(kChannelStreamInternal); @@ -1941,14 +1932,10 @@ Object nvim_get_proc(Integer pid, Error *err) /// @param finish Finish the completion and dismiss the popup menu. Implies {insert}. /// @param opts Optional parameters. Reserved for future use. /// @param[out] err Error details, if any -void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish, Dictionary opts, +void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish, Dict(empty) *opts, Error *err) FUNC_API_SINCE(6) { - VALIDATE((opts.size == 0), "%s", "opts dict isn't empty", { - return; - }); - if (finish) { insert = true; } @@ -2049,7 +2036,7 @@ Boolean nvim_del_mark(String name, Error *err) /// not set. /// @see |nvim_buf_set_mark()| /// @see |nvim_del_mark()| -Array nvim_get_mark(String name, Dictionary opts, Error *err) +Array nvim_get_mark(String name, Dict(empty) *opts, Error *err) FUNC_API_SINCE(8) { Array rv = ARRAY_DICT_INIT; -- cgit From 4a34da82c18e6da1e46d6bf3d21082a6b6c8b947 Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Wed, 6 Dec 2023 13:34:19 +0100 Subject: perf(column): keep track of number of lines that hold up the 'signcolumn' Problem: The entire marktree needs to be traversed each time a sign is removed from the sentinel line. Solution: Remove sentinel line and instead keep track of the number of lines that hold up the 'signcolumn' in "max_count". Adjust this number for added/removed signs, and set it to 0 when the maximum number of signs on a line changes. Only when "max_count" is decremented to 0 due to sign removal do we need to check the entire buffer. Also replace "invalid_top" and "invalid_bot" with a map of invalid ranges, further reducing the number of lines to be checked. Also improve tree traversal when counting the number of signs. Instead of looping over the to be checked range and counting the overlap for each row, keep track of the overlap in an array and add this to the count. --- src/nvim/api/vim.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 0842469c59..2c937113e3 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2189,7 +2189,6 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * int cul_id = 0; int num_id = 0; linenr_T lnum = statuscol_lnum; - wp->w_scwidth = win_signcol_count(wp); decor_redraw_signs(wp, wp->w_buffer, lnum - 1, sattrs, &line_id, &cul_id, &num_id); statuscol.sattrs = sattrs; -- cgit From 6346987601a28b00564295ee8be0a8b00d9ff911 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Thu, 7 Dec 2023 23:46:57 +0600 Subject: refactor(options): reduce `findoption()` usage Problem: Many places in the code use `findoption()` to access an option using its name, even if the option index is available. This is very slow because it requires looping through the options array over and over. Solution: Use option index instead of name wherever possible. Also introduce an `OptIndex` enum which contains the index for every option as enum constants, this eliminates the need to pass static option names as strings. --- src/nvim/api/vim.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 2c937113e3..a52d7493e3 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -948,8 +948,8 @@ Buffer nvim_create_buf(Boolean listed, Boolean scratch, Error *err) buf_copy_options(buf, BCO_ENTER | BCO_NOHELP); if (scratch) { - set_string_option_direct_in_buf(buf, "bufhidden", -1, "hide", OPT_LOCAL, 0); - set_string_option_direct_in_buf(buf, "buftype", -1, "nofile", OPT_LOCAL, 0); + set_string_option_direct_in_buf(buf, kOptBufhidden, "hide", OPT_LOCAL, 0); + set_string_option_direct_in_buf(buf, kOptBuftype, "nofile", OPT_LOCAL, 0); assert(buf->b_ml.ml_mfp->mf_fd < 0); // ml_open() should not have opened swapfile already buf->b_p_swf = false; buf->b_p_ml = false; @@ -2239,7 +2239,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * buf, sizeof(buf), str.data, - NULL, + -1, 0, fillchar, maxwidth, -- cgit From 619407eb548c7df56bc99b945338e9446f846fbb Mon Sep 17 00:00:00 2001 From: Raphael Date: Thu, 14 Dec 2023 16:08:00 +0800 Subject: feat(nvim_open_term): convert LF => CRLF (#26384) Problem: Unlike termopen(), nvim_open_term() PTYs do not carriage-return the cursor on newline ("\n") input. nvim --clean :let chan_id = nvim_open_term(1, {}) :call chansend(chan_id, ["here", "are", "some", "lines"]) Actual behavior: here are some lines Expected behaviour: here are some lines Solution: Add `force_crlf` option, and enable it by default. --- src/nvim/api/vim.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index a52d7493e3..2f3d527b9e 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -985,6 +985,7 @@ fail: /// as a "\r", not as a "\n". |textlock| applies. It is possible /// to call |nvim_chan_send()| directly in the callback however. /// ["input", term, bufnr, data] +/// - force_crlf: (boolean, default true) Convert "\n" to "\r\n". /// @param[out] err Error details, if any /// @return Channel id, or 0 on error Integer nvim_open_term(Buffer buffer, Dict(open_term) *opts, Error *err) @@ -1002,7 +1003,6 @@ Integer nvim_open_term(Buffer buffer, Dict(open_term) *opts, Error *err) } LuaRef cb = LUA_NOREF; - if (HAS_KEY(opts, open_term, on_input)) { cb = opts->on_input; opts->on_input = LUA_NOREF; @@ -1020,6 +1020,7 @@ Integer nvim_open_term(Buffer buffer, Dict(open_term) *opts, Error *err) .write_cb = term_write, .resize_cb = term_resize, .close_cb = term_close, + .force_crlf = GET_BOOL_OR_TRUE(opts, open_term, force_crlf), }; channel_incref(chan); terminal_open(&chan->term, buf, topts); -- cgit From e38027ef69f75653ee953b16ebf4a8652a3fb748 Mon Sep 17 00:00:00 2001 From: mathew Date: Tue, 15 Aug 2023 18:47:14 +0800 Subject: feat(ui): completeopt support popup like vim --- src/nvim/api/vim.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 2f3d527b9e..91f908bb88 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2300,3 +2300,29 @@ void nvim_error_event(uint64_t channel_id, Integer lvl, String data) // if we fork nvim processes as async workers ELOG("async error on channel %" PRId64 ": %s", channel_id, data.size ? data.data : ""); } + +/// Set info for the completion candidate index. +/// if the info was shown in a window, then the +/// window and buffer ids are returned for further +/// customization. If the text was not shown, an +/// empty dict is returned. +/// +/// @param index the completion candidate index +/// @param opts Optional parameters. +/// - info: (string) info text. +/// @return Dictionary containing these keys: +/// - winid: (number) floating window id +/// - bufnr: (number) buffer id in floating window +Dictionary nvim_complete_set(Integer index, Dict(complete_set) *opts) + FUNC_API_SINCE(12) +{ + Dictionary rv = ARRAY_DICT_INIT; + if (HAS_KEY(opts, complete_set, info)) { + win_T *wp = pum_set_info((int)index, opts->info.data); + if (wp) { + PUT(rv, "winid", WINDOW_OBJ(wp->handle)); + PUT(rv, "bufnr", BUFFER_OBJ(wp->w_buffer->handle)); + } + } + return rv; +} -- cgit From 69bc519b53ebf78fd95c8256468e7d538ebcb948 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Tue, 12 Dec 2023 15:40:21 +0100 Subject: refactor: move non-symbols to defs.h headers --- src/nvim/api/vim.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 91f908bb88..70e6b840de 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -54,6 +54,7 @@ #include "nvim/option_vars.h" #include "nvim/optionstr.h" #include "nvim/os/input.h" +#include "nvim/os/os_defs.h" #include "nvim/os/process.h" #include "nvim/popupmenu.h" #include "nvim/pos_defs.h" -- cgit From 428edcde7068ab44040e19b43343741e5ca59770 Mon Sep 17 00:00:00 2001 From: Amanda Graven Date: Tue, 28 Nov 2023 21:05:33 +0100 Subject: feat(api): add forward and back mouse buttons --- src/nvim/api/vim.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 70e6b840de..aed286165a 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -345,7 +345,8 @@ Integer nvim_input(String keys) /// mouse input in a GUI. The deprecated pseudokey form /// ("") of |nvim_input()| has the same limitation. /// -/// @param button Mouse button: one of "left", "right", "middle", "wheel", "move". +/// @param button Mouse button: one of "left", "right", "middle", "wheel", "move", +/// "x1", "x2". /// @param action For ordinary buttons, one of "press", "drag", "release". /// For the wheel, one of "up", "down", "left", "right". Ignored for "move". /// @param modifier String of modifiers each represented by a single char. @@ -376,6 +377,10 @@ void nvim_input_mouse(String button, String action, String modifier, Integer gri code = KE_RIGHTMOUSE; } else if (strequal(button.data, "wheel")) { code = KE_MOUSEDOWN; + } else if (strequal(button.data, "x1")) { + code = KE_X1MOUSE; + } else if (strequal(button.data, "x2")) { + code = KE_X2MOUSE; } else if (strequal(button.data, "move")) { code = KE_MOUSEMOVE; } else { -- cgit From 8533adb4844b771b84dac2141fa2fa60e0487b47 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 21 Dec 2023 16:50:05 +0800 Subject: refactor(IWYU): move decor provider types to decoration_defs.h (#26692) --- src/nvim/api/vim.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index aed286165a..9ae5244fa1 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -64,7 +64,6 @@ #include "nvim/statusline.h" #include "nvim/strings.h" #include "nvim/terminal.h" -#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/vim_defs.h" #include "nvim/window.h" -- cgit From af93a74a0f4afa9a3a4f55ffdf28141eaf776d22 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 18 Dec 2023 10:55:23 +0100 Subject: refactor: run IWYU on entire repo Reference: https://github.com/neovim/neovim/issues/6371. --- src/nvim/api/vim.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 9ae5244fa1..aed286165a 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -64,6 +64,7 @@ #include "nvim/statusline.h" #include "nvim/strings.h" #include "nvim/terminal.h" +#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/vim_defs.h" #include "nvim/window.h" -- cgit From c16d5729b52d2f878cd035341b951b1f185b45c9 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 23 Dec 2023 15:53:28 +0800 Subject: refactor: remove CPO_TO_CPO_FLAGS() (#26718) Just pass p_cpo to replace_termcodes() directly. This allows removing option_vars.h from keycodes.h, and also avoids the mistake of passing 0 as cpo_flags. --- src/nvim/api/vim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index aed286165a..860cca582c 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -461,7 +461,7 @@ String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, Bool } char *ptr = NULL; - replace_termcodes(str.data, str.size, &ptr, 0, flags, NULL, CPO_TO_CPO_FLAGS); + replace_termcodes(str.data, str.size, &ptr, 0, flags, NULL, p_cpo); return cstr_as_string(ptr); } -- cgit From c89292fcb7f2ebf06efb7c1d00c28f34c6f68fec Mon Sep 17 00:00:00 2001 From: dundargoc Date: Thu, 28 Dec 2023 13:42:24 +0100 Subject: refactor: follow style guide --- src/nvim/api/vim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 860cca582c..2bb3f0fac7 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -599,7 +599,7 @@ ArrayOf(String) nvim__get_runtime(Array pat, Boolean all, Dict(runtime) *opts, E if (opts->do_source) { for (size_t i = 0; i < res.size; i++) { String name = res.items[i].data.string; - (void)do_source(name.data, false, DOSO_NONE, NULL); + do_source(name.data, false, DOSO_NONE, NULL); } } -- cgit From aeb053907d2f27713764e345b00a6618e23220d8 Mon Sep 17 00:00:00 2001 From: bfredl Date: Wed, 3 Jan 2024 13:31:39 +0100 Subject: refactor(options): use schar_T representation for fillchars and listchars A bit big, but practically it was a lot simpler to change over all fillchars and all listchars at once, to not need to maintain two parallel implementations. This is mostly an internal refactor, but it also removes an arbitrary limitation: that 'fillchars' and 'listchars' values can only be single-codepoint characters. Now any character which fits into a single screen cell can be used. --- src/nvim/api/vim.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 2bb3f0fac7..f683789945 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2132,7 +2132,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * Dictionary result = ARRAY_DICT_INIT; int maxwidth; - int fillchar = 0; + schar_T fillchar = 0; int statuscol_lnum = 0; Window window = 0; @@ -2148,11 +2148,13 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * } if (HAS_KEY(opts, eval_statusline, fillchar)) { VALIDATE_EXP((*opts->fillchar.data != 0 - && ((size_t)utf_ptr2len(opts->fillchar.data) == opts->fillchar.size)), + && ((size_t)utfc_ptr2len(opts->fillchar.data) == opts->fillchar.size)), "fillchar", "single character", NULL, { return result; }); - fillchar = utf_ptr2char(opts->fillchar.data); + int c; + fillchar = utfc_ptr2schar(opts->fillchar.data, &c); + // TODO(bfredl): actually check c is single width } int use_bools = (int)opts->use_winbar + (int)opts->use_tabline; @@ -2181,7 +2183,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * SignTextAttrs sattrs[SIGN_SHOW_MAX] = { 0 }; if (opts->use_tabline) { - fillchar = ' '; + fillchar = schar_from_ascii(' '); } else { if (fillchar == 0) { if (opts->use_winbar) { @@ -2242,16 +2244,8 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * int p_crb_save = wp->w_p_crb; wp->w_p_crb = false; - int width = build_stl_str_hl(wp, - buf, - sizeof(buf), - str.data, - -1, - 0, - fillchar, - maxwidth, - opts->highlights ? &hltab : NULL, - NULL, + int width = build_stl_str_hl(wp, buf, sizeof(buf), str.data, -1, 0, fillchar, maxwidth, + opts->highlights ? &hltab : NULL, NULL, statuscol_lnum ? &statuscol : NULL); PUT(result, "width", INTEGER_OBJ(width)); -- cgit From 1813661a6197c76ea6621284570aca1d56597099 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Thu, 4 Jan 2024 15:38:16 +0100 Subject: refactor(IWYU): fix headers Remove `export` pramgas from defs headers as it causes IWYU to believe that the definitions from the defs headers comes from main header, which is not what we really want. --- src/nvim/api/vim.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index f683789945..e5a5cc059f 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -21,20 +21,26 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" +#include "nvim/buffer_defs.h" #include "nvim/channel.h" +#include "nvim/channel_defs.h" #include "nvim/context.h" #include "nvim/cursor.h" #include "nvim/decoration.h" #include "nvim/drawscreen.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" +#include "nvim/eval/typval_defs.h" #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" #include "nvim/fold.h" #include "nvim/getchar.h" +#include "nvim/getchar_defs.h" #include "nvim/globals.h" #include "nvim/grid.h" +#include "nvim/grid_defs.h" #include "nvim/highlight.h" +#include "nvim/highlight_defs.h" #include "nvim/highlight_group.h" #include "nvim/keycodes.h" #include "nvim/log.h" @@ -42,15 +48,20 @@ #include "nvim/macros_defs.h" #include "nvim/mapping.h" #include "nvim/mark.h" +#include "nvim/mark_defs.h" #include "nvim/mbyte.h" #include "nvim/memline.h" #include "nvim/memory.h" +#include "nvim/memory_defs.h" #include "nvim/message.h" +#include "nvim/message_defs.h" #include "nvim/move.h" #include "nvim/msgpack_rpc/channel.h" +#include "nvim/msgpack_rpc/channel_defs.h" #include "nvim/msgpack_rpc/unpacker.h" #include "nvim/ops.h" #include "nvim/option.h" +#include "nvim/option_defs.h" #include "nvim/option_vars.h" #include "nvim/optionstr.h" #include "nvim/os/input.h" @@ -59,9 +70,11 @@ #include "nvim/popupmenu.h" #include "nvim/pos_defs.h" #include "nvim/runtime.h" -#include "nvim/sign.h" +#include "nvim/sign_defs.h" #include "nvim/state.h" +#include "nvim/state_defs.h" #include "nvim/statusline.h" +#include "nvim/statusline_defs.h" #include "nvim/strings.h" #include "nvim/terminal.h" #include "nvim/types_defs.h" -- cgit From 6ea6b3fee27d51607ca4a5ace46dbc38a4481bcb Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Wed, 24 Jan 2024 16:36:25 -0600 Subject: feat(ui): add support for OSC 8 hyperlinks (#27109) Extmarks can contain URLs which can then be drawn in any supporting UI. In the TUI, for example, URLs are "drawn" by emitting the OSC 8 control sequence to the TTY. On terminals which support the OSC 8 sequence this will create clickable hyperlinks. URLs are treated as inline highlights in the decoration subsystem, so are included in the `DecorSignHighlight` structure. However, unlike other inline highlights they use allocated memory which must be freed, so they set the `ext` flag in `DecorInline` so that their lifetimes are managed along with other allocated memory like virtual text. The decoration subsystem then adds the URLs as a new highlight attribute. The highlight subsystem maintains a set of unique URLs to avoid duplicating allocations for the same string. To attach a URL to an existing highlight attribute we call `hl_add_url` which finds the URL in the set (allocating and adding it if it does not exist) and sets the `url` highlight attribute to the index of the URL in the set (using an index helps keep the size of the `HlAttrs` struct small). This has the potential to lead to an increase in highlight attributes if a URL is used over a range that contains many different highlight attributes, because now each existing attribute must be combined with the URL. In practice, however, URLs typically span a range containing a single highlight (e.g. link text in Markdown), so this is likely just a pathological edge case. When a new highlight attribute is defined with a URL it is copied to all attached UIs with the `hl_attr_define` UI event. The TUI manages its own set of URLs (just like the highlight subsystem) to minimize allocations. The TUI keeps track of which URL is "active" for the cell it is printing. If no URL is active and a cell containing a URL is printed, the opening OSC 8 sequence is emitted and that URL becomes the actively tracked URL. If the cursor is moved while in the middle of a URL span, we emit the terminating OSC sequence to prevent the hyperlink from spanning multiple lines. This does not support nested hyperlinks, but that is a rare (and, frankly, bizarre) use case. If a valid use case for nested hyperlinks ever presents itself we can address that issue then. --- src/nvim/api/vim.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index e5a5cc059f..eea9b54a5c 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -176,6 +176,12 @@ void nvim_set_hl(Integer ns_id, String name, Dict(highlight) *val, Error *err) }); int link_id = -1; + // Setting URLs directly through highlight attributes is not supported + if (HAS_KEY(val, highlight, url)) { + api_free_string(val->url); + val->url = NULL_STRING; + } + HlAttrs attrs = dict2hlattrs(val, true, &link_id, err); if (!ERROR_SET(err)) { ns_hl_def((NS)ns_id, hl_id, attrs, link_id, val); -- cgit From cf140fb25b94c556396fe942a4af3e8db9effa37 Mon Sep 17 00:00:00 2001 From: Sean Dewar Date: Thu, 27 Jul 2023 01:38:23 +0100 Subject: vim-patch:9.1.0047: issues with temp curwin/buf while cmdwin is open Problem: Things that temporarily change/restore curwin/buf (e.g: win_execute, some autocmds) may break assumptions that curwin/buf is the cmdwin when "cmdwin_type != 0", causing issues. Solution: Expose the cmdwin's real win/buf and check that instead. Also try to ensure these variables are NULL if "cmdwin_type == 0", allowing them to be used directly in most cases without checking cmdwin_type. (Sean Dewar) Reset and save `cmdwin_old_curwin` in a similar fashion. Apply suitable changes for API functions and add Lua tests. https://github.com/vim/vim/commit/988f74311c26ea9917e84fbae608de226dba7e5f --- src/nvim/api/vim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index eea9b54a5c..4bd8f551db 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1022,7 +1022,7 @@ Integer nvim_open_term(Buffer buffer, Dict(open_term) *opts, Error *err) return 0; } - if (cmdwin_type != 0 && buf == curbuf) { + if (buf == cmdwin_buf) { api_set_error(err, kErrorTypeException, "%s", e_cmdwin); return 0; } -- cgit From cc197d04fc36a6ee4219f20772a7b39dd976edfd Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 1 Feb 2024 18:05:06 +0800 Subject: refactor(api): remove some unnecessary HAS_KEY() (#27283) Since keydicts are already zero-initialized, HAS_KEY() isn't needed if the zero-initialized value can satisfy some other condition. --- src/nvim/api/vim.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 4bd8f551db..edee50f411 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2153,7 +2153,6 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * int maxwidth; schar_T fillchar = 0; int statuscol_lnum = 0; - Window window = 0; if (str.size < 2 || memcmp(str.data, "%!", 2) != 0) { const char *const errmsg = check_stl_option(str.data); @@ -2162,9 +2161,8 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * }); } - if (HAS_KEY(opts, eval_statusline, winid)) { - window = opts->winid; - } + Window window = opts->winid; + if (HAS_KEY(opts, eval_statusline, fillchar)) { VALIDATE_EXP((*opts->fillchar.data != 0 && ((size_t)utfc_ptr2len(opts->fillchar.data) == opts->fillchar.size)), -- cgit From b162adbb7ca4f980e938a4a06a49218a9ed496cf Mon Sep 17 00:00:00 2001 From: nikolightsaber <103886134+nikolightsaber@users.noreply.github.com> Date: Thu, 8 Feb 2024 11:59:31 +0100 Subject: feat(api): pass 0 to nvim_get_chan_info for current channel (#27321) Getting current channel info was kind of annoying via RPC. Two functions had to be called: 1. `nvim_get_api_info` which returns `[channel_id, meta_data]`. - This results in `channel_id = api.nvim_get_api_info()[0]`. - Here the meta_data is sent but never used. 2. Finally call `nvim_get_chan_info(channel_id)`. This commit reduces the need for `nvim_get_api_info` as passing 0 returns current channel info. --- src/nvim/api/vim.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index edee50f411..b1bfdd79e7 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1612,6 +1612,7 @@ void nvim_set_client_info(uint64_t channel_id, String name, Dictionary version, /// Gets information about a channel. /// +/// @param chan channel_id, or 0 for current channel /// @returns Dictionary describing a channel, with these keys: /// - "id" Channel id. /// - "argv" (optional) Job arguments list. @@ -1633,12 +1634,17 @@ void nvim_set_client_info(uint64_t channel_id, String name, Dictionary version, /// the RPC channel), if provided by it via /// |nvim_set_client_info()|. /// -Dictionary nvim_get_chan_info(Integer chan, Error *err) +Dictionary nvim_get_chan_info(uint64_t channel_id, Integer chan, Error *err) FUNC_API_SINCE(4) { if (chan < 0) { return (Dictionary)ARRAY_DICT_INIT; } + + if (chan == 0 && !is_internal_call(channel_id)) { + assert(channel_id <= INT64_MAX); + chan = (Integer)channel_id; + } return channel_info((uint64_t)chan); } -- cgit From af5beac1bd7a68ff0a4e1a944853bacd6a6c0745 Mon Sep 17 00:00:00 2001 From: bfredl Date: Thu, 8 Feb 2024 13:40:35 +0100 Subject: refactor(api): refactor more api functions to use arena return Currently having two separate memory strategies for API return values is a bit unnecessary, and mostly a consequence of converting the hot spot cases which needed it first. But there is really no downside to using arena everywhere (which implies also directly using strings which are allocated earlier or even statically, without copy). There only restriction is we need to know the size of arrays in advance, but this info can often be passed on from some earlier stage if it is missing. This collects some "small" cases. The more complex stuff will get a PR each. --- src/nvim/api/vim.c | 82 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 40 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index b1bfdd79e7..1453de30d4 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1351,14 +1351,13 @@ Integer nvim_get_color_by_name(String name) /// (e.g. 65535). /// /// @return Map of color names and RGB values. -Dictionary nvim_get_color_map(void) +Dictionary nvim_get_color_map(Arena *arena) FUNC_API_SINCE(1) { - Dictionary colors = ARRAY_DICT_INIT; + Dictionary colors = arena_dict(arena, ARRAY_SIZE(color_name_table)); for (int i = 0; color_name_table[i].name != NULL; i++) { - PUT(colors, color_name_table[i].name, - INTEGER_OBJ(color_name_table[i].color)); + PUT_C(colors, color_name_table[i].name, INTEGER_OBJ(color_name_table[i].color)); } return colors; } @@ -1438,16 +1437,16 @@ Object nvim_load_context(Dictionary dict, Error *err) /// "blocking" is true if Nvim is waiting for input. /// /// @returns Dictionary { "mode": String, "blocking": Boolean } -Dictionary nvim_get_mode(void) +Dictionary nvim_get_mode(Arena *arena) FUNC_API_SINCE(2) FUNC_API_FAST { - Dictionary rv = ARRAY_DICT_INIT; - char modestr[MODE_MAX_LENGTH]; + Dictionary rv = arena_dict(arena, 2); + char *modestr = arena_alloc(arena, MODE_MAX_LENGTH, false); get_mode(modestr); bool blocked = input_blocking(); - PUT(rv, "mode", CSTR_TO_OBJ(modestr)); - PUT(rv, "blocking", BOOLEAN_OBJ(blocked)); + PUT_C(rv, "mode", CSTR_AS_OBJ(modestr)); + PUT_C(rv, "blocking", BOOLEAN_OBJ(blocked)); return rv; } @@ -1848,14 +1847,14 @@ Float nvim__id_float(Float flt) /// Gets internal stats. /// /// @return Map of various internal stats. -Dictionary nvim__stats(void) -{ - Dictionary rv = ARRAY_DICT_INIT; - PUT(rv, "fsync", INTEGER_OBJ(g_stats.fsync)); - PUT(rv, "log_skip", INTEGER_OBJ(g_stats.log_skip)); - PUT(rv, "lua_refcount", INTEGER_OBJ(nlua_get_global_ref_count())); - PUT(rv, "redraw", INTEGER_OBJ(g_stats.redraw)); - PUT(rv, "arena_alloc_count", INTEGER_OBJ((Integer)arena_alloc_count)); +Dictionary nvim__stats(Arena *arena) +{ + Dictionary rv = arena_dict(arena, 5); + PUT_C(rv, "fsync", INTEGER_OBJ(g_stats.fsync)); + PUT_C(rv, "log_skip", INTEGER_OBJ(g_stats.log_skip)); + PUT_C(rv, "lua_refcount", INTEGER_OBJ(nlua_get_global_ref_count())); + PUT_C(rv, "redraw", INTEGER_OBJ(g_stats.redraw)); + PUT_C(rv, "arena_alloc_count", INTEGER_OBJ((Integer)arena_alloc_count)); return rv; } @@ -2151,7 +2150,7 @@ Array nvim_get_mark(String name, Dict(empty) *opts, Error *err) /// |Dictionary| with these keys: /// - start: (number) Byte index (0-based) of first character that uses the highlight. /// - group: (string) Name of highlight group. -Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error *err) +Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Arena *arena, Error *err) FUNC_API_SINCE(8) FUNC_API_FAST { Dictionary result = ARRAY_DICT_INIT; @@ -2260,58 +2259,61 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * && global_stl_height() > 0)) ? Columns : wp->w_width; } - char buf[MAXPATHL]; + result = arena_dict(arena, 3); + char *buf = arena_alloc(arena, MAXPATHL, false); stl_hlrec_t *hltab; + size_t hltab_len = 0; // Temporarily reset 'cursorbind' to prevent side effects from moving the cursor away and back. int p_crb_save = wp->w_p_crb; wp->w_p_crb = false; - int width = build_stl_str_hl(wp, buf, sizeof(buf), str.data, -1, 0, fillchar, maxwidth, - opts->highlights ? &hltab : NULL, NULL, + int width = build_stl_str_hl(wp, buf, MAXPATHL, str.data, -1, 0, fillchar, maxwidth, + opts->highlights ? &hltab : NULL, &hltab_len, NULL, statuscol_lnum ? &statuscol : NULL); - PUT(result, "width", INTEGER_OBJ(width)); + PUT_C(result, "width", INTEGER_OBJ(width)); // Restore original value of 'cursorbind' wp->w_p_crb = p_crb_save; if (opts->highlights) { - Array hl_values = ARRAY_DICT_INIT; - const char *grpname; + Array hl_values = arena_array(arena, hltab_len + 1); char user_group[15]; // strlen("User") + strlen("2147483647") + NUL // If first character doesn't have a defined highlight, // add the default highlight at the beginning of the highlight list if (hltab->start == NULL || (hltab->start - buf) != 0) { - Dictionary hl_info = ARRAY_DICT_INIT; - grpname = get_default_stl_hl(opts->use_tabline ? NULL : wp, opts->use_winbar, stc_hl_id); + Dictionary hl_info = arena_dict(arena, 2); + const char *grpname = get_default_stl_hl(opts->use_tabline ? NULL : wp, + opts->use_winbar, stc_hl_id); - PUT(hl_info, "start", INTEGER_OBJ(0)); - PUT(hl_info, "group", CSTR_TO_OBJ(grpname)); + PUT_C(hl_info, "start", INTEGER_OBJ(0)); + PUT_C(hl_info, "group", CSTR_AS_OBJ((char *)grpname)); - ADD(hl_values, DICTIONARY_OBJ(hl_info)); + ADD_C(hl_values, DICTIONARY_OBJ(hl_info)); } for (stl_hlrec_t *sp = hltab; sp->start != NULL; sp++) { - Dictionary hl_info = ARRAY_DICT_INIT; + Dictionary hl_info = arena_dict(arena, 2); - PUT(hl_info, "start", INTEGER_OBJ(sp->start - buf)); + PUT_C(hl_info, "start", INTEGER_OBJ(sp->start - buf)); + const char *grpname; if (sp->userhl == 0) { grpname = get_default_stl_hl(opts->use_tabline ? NULL : wp, opts->use_winbar, stc_hl_id); } else if (sp->userhl < 0) { grpname = syn_id2name(-sp->userhl); } else { snprintf(user_group, sizeof(user_group), "User%d", sp->userhl); - grpname = user_group; + grpname = arena_memdupz(arena, user_group, strlen(user_group)); } - PUT(hl_info, "group", CSTR_TO_OBJ(grpname)); - ADD(hl_values, DICTIONARY_OBJ(hl_info)); + PUT_C(hl_info, "group", CSTR_AS_OBJ((char *)grpname)); + ADD_C(hl_values, DICTIONARY_OBJ(hl_info)); } - PUT(result, "highlights", ARRAY_OBJ(hl_values)); + PUT_C(result, "highlights", ARRAY_OBJ(hl_values)); } - PUT(result, "str", CSTR_TO_OBJ(buf)); + PUT_C(result, "str", CSTR_AS_OBJ(buf)); return result; } @@ -2336,15 +2338,15 @@ void nvim_error_event(uint64_t channel_id, Integer lvl, String data) /// @return Dictionary containing these keys: /// - winid: (number) floating window id /// - bufnr: (number) buffer id in floating window -Dictionary nvim_complete_set(Integer index, Dict(complete_set) *opts) +Dictionary nvim_complete_set(Integer index, Dict(complete_set) *opts, Arena *arena) FUNC_API_SINCE(12) { - Dictionary rv = ARRAY_DICT_INIT; + Dictionary rv = arena_dict(arena, 2); if (HAS_KEY(opts, complete_set, info)) { win_T *wp = pum_set_info((int)index, opts->info.data); if (wp) { - PUT(rv, "winid", WINDOW_OBJ(wp->handle)); - PUT(rv, "bufnr", BUFFER_OBJ(wp->w_buffer->handle)); + PUT_C(rv, "winid", WINDOW_OBJ(wp->handle)); + PUT_C(rv, "bufnr", BUFFER_OBJ(wp->w_buffer->handle)); } } return rv; -- cgit From e0e5b7f0ba1b0440bdc2b557e2b2cfae24706cbd Mon Sep 17 00:00:00 2001 From: bfredl Date: Fri, 9 Feb 2024 11:42:40 +0100 Subject: refactor(api): make cstr_as_string accept "const char*" In the context a String inside an Object/Dictionary etc is consumed, it is considered to be read-only. --- src/nvim/api/vim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 1453de30d4..6b46f579e4 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2289,7 +2289,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Arena * opts->use_winbar, stc_hl_id); PUT_C(hl_info, "start", INTEGER_OBJ(0)); - PUT_C(hl_info, "group", CSTR_AS_OBJ((char *)grpname)); + PUT_C(hl_info, "group", CSTR_AS_OBJ(grpname)); ADD_C(hl_values, DICTIONARY_OBJ(hl_info)); } @@ -2308,7 +2308,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Arena * snprintf(user_group, sizeof(user_group), "User%d", sp->userhl); grpname = arena_memdupz(arena, user_group, strlen(user_group)); } - PUT_C(hl_info, "group", CSTR_AS_OBJ((char *)grpname)); + PUT_C(hl_info, "group", CSTR_AS_OBJ(grpname)); ADD_C(hl_values, DICTIONARY_OBJ(hl_info)); } PUT_C(result, "highlights", ARRAY_OBJ(hl_values)); -- cgit From e9510211f0b957606685344be97350c29e3ea638 Mon Sep 17 00:00:00 2001 From: bfredl Date: Fri, 9 Feb 2024 12:40:48 +0100 Subject: refactor(api): use arena for nvim_list_uis() --- src/nvim/api/vim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 6b46f579e4..5a106288fd 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1866,10 +1866,10 @@ Dictionary nvim__stats(Arena *arena) /// - "rgb" true if the UI uses RGB colors (false implies |cterm-colors|) /// - "ext_..." Requested UI extensions, see |ui-option| /// - "chan" |channel-id| of remote UI -Array nvim_list_uis(void) +Array nvim_list_uis(Arena *arena) FUNC_API_SINCE(4) { - return ui_array(); + return ui_array(arena); } /// Gets the immediate children of process `pid`. -- cgit From 4cd43933d355b5b39b1107bfd08ad9205681f2f4 Mon Sep 17 00:00:00 2001 From: bfredl Date: Fri, 9 Feb 2024 12:41:14 +0100 Subject: refactor(api): use arena for hlstate inspection --- src/nvim/api/vim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 5a106288fd..a47694a0cf 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2005,7 +2005,7 @@ Array nvim__inspect_cell(Integer grid, Integer row, Integer col, Arena *arena, E ADD_C(ret, DICTIONARY_OBJ(hl_get_attr_by_id(attr, true, arena, err))); // will not work first time if (!highlight_use_hlstate()) { - ADD_C(ret, ARRAY_OBJ(hl_inspect(attr))); + ADD_C(ret, ARRAY_OBJ(hl_inspect(attr, arena))); } return ret; } -- cgit From 930d6e38d4eb61adbb4f0d7328f55b31408b7cd1 Mon Sep 17 00:00:00 2001 From: bfredl Date: Sat, 10 Feb 2024 13:13:52 +0100 Subject: refactor(api): use an arena for nvim_buf_get_lines and buffer updates Refactor some earlier "temporary Array" code in buffer_updates.c to use the modern style of MAXSIZE_TEMP_ARRAY and ADD_C --- src/nvim/api/vim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index a47694a0cf..78c2561bbd 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -656,10 +656,10 @@ void nvim_set_current_dir(String dir, Error *err) /// /// @param[out] err Error details, if any /// @return Current line string -String nvim_get_current_line(Error *err) +String nvim_get_current_line(Arena *arena, Error *err) FUNC_API_SINCE(1) { - return buffer_get_line(curbuf->handle, curwin->w_cursor.lnum - 1, err); + return buffer_get_line(curbuf->handle, curwin->w_cursor.lnum - 1, arena, err); } /// Sets the current line. -- cgit From 0353dd3029f9ce31c3894530385443a90f6677ee Mon Sep 17 00:00:00 2001 From: bfredl Date: Sun, 11 Feb 2024 15:46:14 +0100 Subject: refactor(lua): use Arena when converting from lua stack to API args and for return value of nlua_exec/nlua_call_ref, as this uses the same family of functions. NB: the handling of luaref:s is a bit of a mess. add api_luarefs_free_XX functions as a stop-gap as refactoring luarefs is a can of worms for another PR:s. as a minor feature/bug-fix, nvim_buf_call and nvim_win_call now preserves arbitrary return values. --- src/nvim/api/vim.c | 60 ++++++++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 31 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 78c2561bbd..769537ac98 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -496,11 +496,12 @@ String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, Bool /// or executing the Lua code. /// /// @return Return value of Lua code if present or NIL. -Object nvim_exec_lua(String code, Array args, Error *err) +Object nvim_exec_lua(String code, Array args, Arena *arena, Error *err) FUNC_API_SINCE(7) FUNC_API_REMOTE_ONLY { - return nlua_exec(code, args, err); + // TODO(bfredl): convert directly from msgpack to lua and then back again + return nlua_exec(code, args, kRetObject, arena, err); } /// Notify the user with a message @@ -512,7 +513,7 @@ Object nvim_exec_lua(String code, Array args, Error *err) /// @param log_level The log level /// @param opts Reserved for future use. /// @param[out] err Error details, if any -Object nvim_notify(String msg, Integer log_level, Dictionary opts, Error *err) +Object nvim_notify(String msg, Integer log_level, Dictionary opts, Arena *arena, Error *err) FUNC_API_SINCE(7) { MAXSIZE_TEMP_ARRAY(args, 3); @@ -520,7 +521,7 @@ Object nvim_notify(String msg, Integer log_level, Dictionary opts, Error *err) ADD_C(args, INTEGER_OBJ(log_level)); ADD_C(args, DICTIONARY_OBJ(opts)); - return NLUA_EXEC_STATIC("return vim.notify(...)", args, err); + return NLUA_EXEC_STATIC("return vim.notify(...)", args, kRetObject, arena, err); } /// Calculates the number of display cells occupied by `text`. @@ -603,7 +604,8 @@ String nvim__get_lib_dir(void) /// @param all whether to return all matches or only the first /// @param opts is_lua: only search Lua subdirs /// @return list of absolute paths to the found files -ArrayOf(String) nvim__get_runtime(Array pat, Boolean all, Dict(runtime) *opts, Error *err) +ArrayOf(String) nvim__get_runtime(Array pat, Boolean all, Dict(runtime) *opts, Arena *arena, + Error *err) FUNC_API_SINCE(8) FUNC_API_FAST { @@ -613,7 +615,7 @@ ArrayOf(String) nvim__get_runtime(Array pat, Boolean all, Dict(runtime) *opts, E return (Array)ARRAY_DICT_INIT; } - ArrayOf(String) res = runtime_get_named(opts->is_lua, pat, all); + ArrayOf(String) res = runtime_get_named(opts->is_lua, pat, all, arena); if (opts->do_source) { for (size_t i = 0; i < res.size; i++) { @@ -1068,7 +1070,7 @@ static void term_write(const char *buf, size_t size, void *data) ADD_C(args, BUFFER_OBJ(terminal_buf(chan->term))); ADD_C(args, STRING_OBJ(((String){ .data = (char *)buf, .size = size }))); textlock++; - nlua_call_ref(cb, "input", args, false, NULL); + nlua_call_ref(cb, "input", args, kRetNilBool, NULL, NULL); textlock--; } @@ -1189,7 +1191,7 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err) /// @return /// - true: Client may continue pasting. /// - false: Client must cancel the paste. -Boolean nvim_paste(String data, Boolean crlf, Integer phase, Error *err) +Boolean nvim_paste(String data, Boolean crlf, Integer phase, Arena *arena, Error *err) FUNC_API_SINCE(6) FUNC_API_TEXTLOCK_ALLOW_CMDWIN { @@ -1199,19 +1201,18 @@ Boolean nvim_paste(String data, Boolean crlf, Integer phase, Error *err) VALIDATE_INT((phase >= -1 && phase <= 3), "phase", phase, { return false; }); - Array args = ARRAY_DICT_INIT; - Object rv = OBJECT_INIT; + Array lines = ARRAY_DICT_INIT; if (phase == -1 || phase == 1) { // Start of paste-stream. draining = false; } else if (draining) { // Skip remaining chunks. Report error only once per "stream". goto theend; } - Array lines = string_to_array(data, crlf); - ADD(args, ARRAY_OBJ(lines)); - ADD(args, INTEGER_OBJ(phase)); - rv = nvim_exec_lua(STATIC_CSTR_AS_STRING("return vim.paste(...)"), args, - err); + lines = string_to_array(data, crlf); + MAXSIZE_TEMP_ARRAY(args, 2); + ADD_C(args, ARRAY_OBJ(lines)); + ADD_C(args, INTEGER_OBJ(phase)); + Object rv = NLUA_EXEC_STATIC("return vim.paste(...)", args, kRetNilBool, arena, err); if (ERROR_SET(err)) { draining = true; goto theend; @@ -1238,8 +1239,7 @@ Boolean nvim_paste(String data, Boolean crlf, Integer phase, Error *err) AppendCharToRedobuff(ESC); // Dot-repeat. } theend: - api_free_object(rv); - api_free_array(args); + api_free_array(lines); if (cancel || phase == -1 || phase == 3) { // End of paste-stream. draining = false; } @@ -1875,7 +1875,7 @@ Array nvim_list_uis(Arena *arena) /// Gets the immediate children of process `pid`. /// /// @return Array of child process ids, empty if process not found. -Array nvim_get_proc_children(Integer pid, Error *err) +Array nvim_get_proc_children(Integer pid, Arena *arena, Error *err) FUNC_API_SINCE(4) { Array rvobj = ARRAY_DICT_INIT; @@ -1892,7 +1892,7 @@ Array nvim_get_proc_children(Integer pid, Error *err) DLOG("fallback to vim._os_proc_children()"); MAXSIZE_TEMP_ARRAY(a, 1); ADD(a, INTEGER_OBJ(pid)); - Object o = NLUA_EXEC_STATIC("return vim._os_proc_children(...)", a, err); + Object o = NLUA_EXEC_STATIC("return vim._os_proc_children(...)", a, kRetObject, arena, err); if (o.type == kObjectTypeArray) { rvobj = o.data.array; } else if (!ERROR_SET(err)) { @@ -1900,11 +1900,11 @@ Array nvim_get_proc_children(Integer pid, Error *err) "Failed to get process children. pid=%" PRId64 " error=%d", pid, rv); } - goto end; - } - - for (size_t i = 0; i < proc_count; i++) { - ADD(rvobj, INTEGER_OBJ(proc_list[i])); + } else { + rvobj = arena_array(arena, proc_count); + for (size_t i = 0; i < proc_count; i++) { + ADD(rvobj, INTEGER_OBJ(proc_list[i])); + } } end: @@ -1915,19 +1915,17 @@ end: /// Gets info describing process `pid`. /// /// @return Map of process properties, or NIL if process not found. -Object nvim_get_proc(Integer pid, Error *err) +Object nvim_get_proc(Integer pid, Arena *arena, Error *err) FUNC_API_SINCE(4) { - Object rvobj = OBJECT_INIT; - rvobj.data.dictionary = (Dictionary)ARRAY_DICT_INIT; - rvobj.type = kObjectTypeDictionary; + Object rvobj = NIL; VALIDATE_INT((pid > 0 && pid <= INT_MAX), "pid", pid, { return NIL; }); #ifdef MSWIN - rvobj.data.dictionary = os_proc_info((int)pid); + rvobj = DICTIONARY_OBJ(os_proc_info((int)pid)); if (rvobj.data.dictionary.size == 0) { // Process not found. return NIL; } @@ -1935,11 +1933,11 @@ Object nvim_get_proc(Integer pid, Error *err) // Cross-platform process info APIs are miserable, so use `ps` instead. MAXSIZE_TEMP_ARRAY(a, 1); ADD(a, INTEGER_OBJ(pid)); - Object o = NLUA_EXEC_STATIC("return vim._os_proc_info(...)", a, err); + Object o = NLUA_EXEC_STATIC("return vim._os_proc_info(...)", a, kRetObject, arena, err); if (o.type == kObjectTypeArray && o.data.array.size == 0) { return NIL; // Process not found. } else if (o.type == kObjectTypeDictionary) { - rvobj.data.dictionary = o.data.dictionary; + rvobj = o; } else if (!ERROR_SET(err)) { api_set_error(err, kErrorTypeException, "Failed to get process info. pid=%" PRId64, pid); -- cgit From d60412b18e4e21f301baa2ac3f3fb7be89655e4b Mon Sep 17 00:00:00 2001 From: bfredl Date: Mon, 12 Feb 2024 20:40:27 +0100 Subject: refactor(eval): use arena when converting typvals to Object Note: this contains two _temporary_ changes which can be reverted once the Arena vs no-Arena distinction in API wrappers has been removed. Both nlua_push_Object and object_to_vim_take_luaref() has been changed to take the object argument as a pointer. This is not going to be necessary once these are only used with arena (or not at all) allocated Objects. The object_to_vim() variant which leaves luaref untouched might need to stay for a little longer. --- src/nvim/api/vim.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 769537ac98..b7cb14867d 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -690,7 +690,7 @@ void nvim_del_current_line(Error *err) /// @param name Variable name /// @param[out] err Error details, if any /// @return Variable value -Object nvim_get_var(String name, Error *err) +Object nvim_get_var(String name, Arena *arena, Error *err) FUNC_API_SINCE(1) { dictitem_T *di = tv_dict_find(&globvardict, name.data, (ptrdiff_t)name.size); @@ -704,7 +704,7 @@ Object nvim_get_var(String name, Error *err) VALIDATE((di != NULL), "Key not found: %s", name.data, { return (Object)OBJECT_INIT; }); - return vim_to_object(&di->di_tv); + return vim_to_object(&di->di_tv, arena, true); } /// Sets a global (g:) variable. @@ -715,7 +715,7 @@ Object nvim_get_var(String name, Error *err) void nvim_set_var(String name, Object value, Error *err) FUNC_API_SINCE(1) { - dict_set_var(&globvardict, name, value, false, false, err); + dict_set_var(&globvardict, name, value, false, false, NULL, err); } /// Removes a global (g:) variable. @@ -725,7 +725,7 @@ void nvim_set_var(String name, Object value, Error *err) void nvim_del_var(String name, Error *err) FUNC_API_SINCE(1) { - dict_set_var(&globvardict, name, NIL, true, false, err); + dict_set_var(&globvardict, name, NIL, true, false, NULL, err); } /// Gets a v: variable. @@ -733,10 +733,10 @@ void nvim_del_var(String name, Error *err) /// @param name Variable name /// @param[out] err Error details, if any /// @return Variable value -Object nvim_get_vvar(String name, Error *err) +Object nvim_get_vvar(String name, Arena *arena, Error *err) FUNC_API_SINCE(1) { - return dict_get_value(&vimvardict, name, err); + return dict_get_value(&vimvardict, name, arena, err); } /// Sets a v: variable, if it is not readonly. @@ -747,7 +747,7 @@ Object nvim_get_vvar(String name, Error *err) void nvim_set_vvar(String name, Object value, Error *err) FUNC_API_SINCE(6) { - dict_set_var(&vimvardict, name, value, false, false, err); + dict_set_var(&vimvardict, name, value, false, false, NULL, err); } /// Echo a message. @@ -1370,7 +1370,7 @@ Dictionary nvim_get_color_map(Arena *arena) /// @param[out] err Error details, if any /// /// @return map of global |context|. -Dictionary nvim_get_context(Dict(context) *opts, Error *err) +Dictionary nvim_get_context(Dict(context) *opts, Arena *arena, Error *err) FUNC_API_SINCE(6) { Array types = ARRAY_DICT_INIT; @@ -1406,7 +1406,7 @@ Dictionary nvim_get_context(Dict(context) *opts, Error *err) Context ctx = CONTEXT_INIT; ctx_save(&ctx, int_types); - Dictionary dict = ctx_to_dict(&ctx); + Dictionary dict = ctx_to_dict(&ctx, arena); ctx_free(&ctx); return dict; } @@ -2065,7 +2065,7 @@ Boolean nvim_del_mark(String name, Error *err) /// not set. /// @see |nvim_buf_set_mark()| /// @see |nvim_del_mark()| -Array nvim_get_mark(String name, Dict(empty) *opts, Error *err) +Array nvim_get_mark(String name, Dict(empty) *opts, Arena *arena, Error *err) FUNC_API_SINCE(8) { Array rv = ARRAY_DICT_INIT; @@ -2113,10 +2113,11 @@ Array nvim_get_mark(String name, Dict(empty) *opts, Error *err) col = pos.col; } - ADD(rv, INTEGER_OBJ(row)); - ADD(rv, INTEGER_OBJ(col)); - ADD(rv, INTEGER_OBJ(bufnr)); - ADD(rv, CSTR_TO_OBJ(filename)); + rv = arena_array(arena, 4); + ADD_C(rv, INTEGER_OBJ(row)); + ADD_C(rv, INTEGER_OBJ(col)); + ADD_C(rv, INTEGER_OBJ(bufnr)); + ADD_C(rv, CSTR_TO_ARENA_OBJ(arena, filename)); if (allocated) { xfree(filename); -- cgit From 5fd1bac65ed07310eda5fd976b651cc493002849 Mon Sep 17 00:00:00 2001 From: luukvbaal Date: Sat, 17 Feb 2024 00:44:31 +0100 Subject: fix(api): don't use stl 'fillchar' for "use_statuscol_lnum" (#27501) Problem: nvim_eval_statusline() uses "stl" from 'fillchars' with "use_statuscol_lnum". Solution: Reorder "fillchar" else chain. --- src/nvim/api/vim.c | 73 +++++++++++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 39 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index b7cb14867d..1184eb7441 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2203,49 +2203,44 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Arena * statuscol_T statuscol = { 0 }; SignTextAttrs sattrs[SIGN_SHOW_MAX] = { 0 }; - if (opts->use_tabline) { - fillchar = schar_from_ascii(' '); - } else { - if (fillchar == 0) { - if (opts->use_winbar) { - fillchar = wp->w_p_fcs_chars.wbr; - } else { - int attr; - fillchar = fillchar_status(&attr, wp); + if (statuscol_lnum) { + int line_id = 0; + int cul_id = 0; + int num_id = 0; + linenr_T lnum = statuscol_lnum; + decor_redraw_signs(wp, wp->w_buffer, lnum - 1, sattrs, &line_id, &cul_id, &num_id); + + statuscol.sattrs = sattrs; + statuscol.foldinfo = fold_info(wp, lnum); + wp->w_cursorline = win_cursorline_standout(wp) ? wp->w_cursor.lnum : 0; + + if (wp->w_p_cul) { + if (statuscol.foldinfo.fi_level != 0 && statuscol.foldinfo.fi_lines > 0) { + wp->w_cursorline = statuscol.foldinfo.fi_lnum; } + statuscol.use_cul = lnum == wp->w_cursorline && (wp->w_p_culopt_flags & CULOPT_NBR); } - if (statuscol_lnum) { - int line_id = 0; - int cul_id = 0; - int num_id = 0; - linenr_T lnum = statuscol_lnum; - decor_redraw_signs(wp, wp->w_buffer, lnum - 1, sattrs, &line_id, &cul_id, &num_id); - - statuscol.sattrs = sattrs; - statuscol.foldinfo = fold_info(wp, lnum); - wp->w_cursorline = win_cursorline_standout(wp) ? wp->w_cursor.lnum : 0; - - if (wp->w_p_cul) { - if (statuscol.foldinfo.fi_level != 0 && statuscol.foldinfo.fi_lines > 0) { - wp->w_cursorline = statuscol.foldinfo.fi_lnum; - } - statuscol.use_cul = lnum == wp->w_cursorline && (wp->w_p_culopt_flags & CULOPT_NBR); - } - statuscol.sign_cul_id = statuscol.use_cul ? cul_id : 0; - if (num_id) { - stc_hl_id = num_id; - } else if (statuscol.use_cul) { - stc_hl_id = HLF_CLN + 1; - } else if (wp->w_p_rnu) { - stc_hl_id = (lnum < wp->w_cursor.lnum ? HLF_LNA : HLF_LNB) + 1; - } else { - stc_hl_id = HLF_N + 1; - } + statuscol.sign_cul_id = statuscol.use_cul ? cul_id : 0; + if (num_id) { + stc_hl_id = num_id; + } else if (statuscol.use_cul) { + stc_hl_id = HLF_CLN + 1; + } else if (wp->w_p_rnu) { + stc_hl_id = (lnum < wp->w_cursor.lnum ? HLF_LNA : HLF_LNB) + 1; + } else { + stc_hl_id = HLF_N + 1; + } - set_vim_var_nr(VV_LNUM, lnum); - set_vim_var_nr(VV_RELNUM, labs(get_cursor_rel_lnum(wp, lnum))); - set_vim_var_nr(VV_VIRTNUM, 0); + set_vim_var_nr(VV_LNUM, lnum); + set_vim_var_nr(VV_RELNUM, labs(get_cursor_rel_lnum(wp, lnum))); + set_vim_var_nr(VV_VIRTNUM, 0); + } else if (fillchar == 0 && !opts->use_tabline) { + if (opts->use_winbar) { + fillchar = wp->w_p_fcs_chars.wbr; + } else { + int attr; + fillchar = fillchar_status(&attr, wp); } } -- cgit From f25fcc68a34c2d51b0715fadc62cb50509de338b Mon Sep 17 00:00:00 2001 From: bfredl Date: Sat, 17 Feb 2024 20:31:21 +0100 Subject: refactor(api): use an arena for mappings --- src/nvim/api/vim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 1184eb7441..195da4366e 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1456,10 +1456,10 @@ Dictionary nvim_get_mode(Arena *arena) /// @param mode Mode short-name ("n", "i", "v", ...) /// @returns Array of |maparg()|-like dictionaries describing mappings. /// The "buffer" key is always zero. -ArrayOf(Dictionary) nvim_get_keymap(String mode) +ArrayOf(Dictionary) nvim_get_keymap(String mode, Arena *arena) FUNC_API_SINCE(3) { - return keymap_array(mode, NULL); + return keymap_array(mode, NULL, arena); } /// Sets a global |mapping| for the given mode. -- cgit From 146333ca123ab85397eb089345569cd9ed2d405a Mon Sep 17 00:00:00 2001 From: bfredl Date: Sat, 17 Feb 2024 20:33:11 +0100 Subject: refactor(api): use arena for channel info and terminal info --- src/nvim/api/vim.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 195da4366e..7a19ccf295 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1633,7 +1633,7 @@ void nvim_set_client_info(uint64_t channel_id, String name, Dictionary version, /// the RPC channel), if provided by it via /// |nvim_set_client_info()|. /// -Dictionary nvim_get_chan_info(uint64_t channel_id, Integer chan, Error *err) +Dictionary nvim_get_chan_info(uint64_t channel_id, Integer chan, Arena *arena, Error *err) FUNC_API_SINCE(4) { if (chan < 0) { @@ -1644,17 +1644,17 @@ Dictionary nvim_get_chan_info(uint64_t channel_id, Integer chan, Error *err) assert(channel_id <= INT64_MAX); chan = (Integer)channel_id; } - return channel_info((uint64_t)chan); + return channel_info((uint64_t)chan, arena); } /// Get information about all open channels. /// /// @returns Array of Dictionaries, each describing a channel with /// the format specified at |nvim_get_chan_info()|. -Array nvim_list_chans(void) +Array nvim_list_chans(Arena *arena) FUNC_API_SINCE(4) { - return channel_all_info(); + return channel_all_info(arena); } /// Calls many API methods atomically. @@ -1891,7 +1891,7 @@ Array nvim_get_proc_children(Integer pid, Arena *arena, Error *err) // syscall failed (possibly because of kernel options), try shelling out. DLOG("fallback to vim._os_proc_children()"); MAXSIZE_TEMP_ARRAY(a, 1); - ADD(a, INTEGER_OBJ(pid)); + ADD_C(a, INTEGER_OBJ(pid)); Object o = NLUA_EXEC_STATIC("return vim._os_proc_children(...)", a, kRetObject, arena, err); if (o.type == kObjectTypeArray) { rvobj = o.data.array; @@ -1903,7 +1903,7 @@ Array nvim_get_proc_children(Integer pid, Arena *arena, Error *err) } else { rvobj = arena_array(arena, proc_count); for (size_t i = 0; i < proc_count; i++) { - ADD(rvobj, INTEGER_OBJ(proc_list[i])); + ADD_C(rvobj, INTEGER_OBJ(proc_list[i])); } } @@ -1925,7 +1925,7 @@ Object nvim_get_proc(Integer pid, Arena *arena, Error *err) }); #ifdef MSWIN - rvobj = DICTIONARY_OBJ(os_proc_info((int)pid)); + rvobj = DICTIONARY_OBJ(os_proc_info((int)pid, arena)); if (rvobj.data.dictionary.size == 0) { // Process not found. return NIL; } -- cgit From bbf6d4a4bc44c8e61f807d23cc4ff2c2683e1ef4 Mon Sep 17 00:00:00 2001 From: bfredl Date: Sun, 18 Feb 2024 12:51:27 +0100 Subject: refactor(api): use arena for metadata; msgpack_rpc_to_object delenda est Note: kSDItemHeader is something is _written_ by nvim in the shada file to identify it for debugging purposes outside of nvim. But this data wasn't ever used by neovim after reading the file back, So I removed the parsing of it for now. --- src/nvim/api/vim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 7a19ccf295..d161dca050 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2022,10 +2022,10 @@ void nvim__invalidate_glyph_cache(void) must_redraw = UPD_CLEAR; } -Object nvim__unpack(String str, Error *err) +Object nvim__unpack(String str, Arena *arena, Error *err) FUNC_API_FAST { - return unpack(str.data, str.size, err); + return unpack(str.data, str.size, arena, err); } /// Deletes an uppercase/file named mark. See |mark-motions|. -- cgit From abb8dcd8898d0a30db6b503682e4cea337c942a6 Mon Sep 17 00:00:00 2001 From: bfredl Date: Mon, 19 Feb 2024 12:09:07 +0100 Subject: refactor(api): use arena for runtime and client info --- src/nvim/api/vim.c | 54 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 21 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index d161dca050..0da7cec4ab 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -543,17 +543,22 @@ Integer nvim_strwidth(String text, Error *err) /// Gets the paths contained in |runtime-search-path|. /// /// @return List of paths -ArrayOf(String) nvim_list_runtime_paths(Error *err) +ArrayOf(String) nvim_list_runtime_paths(Arena *arena, Error *err) FUNC_API_SINCE(1) { - return nvim_get_runtime_file(NULL_STRING, true, err); + return nvim_get_runtime_file(NULL_STRING, true, arena, err); } -Array nvim__runtime_inspect(void) +Array nvim__runtime_inspect(Arena *arena) { - return runtime_inspect(); + return runtime_inspect(arena); } +typedef struct { + ArrayBuilder rv; + Arena *arena; +} RuntimeCookie; + /// Find files in runtime directories /// /// "name" can contain wildcards. For example @@ -566,25 +571,27 @@ Array nvim__runtime_inspect(void) /// @param name pattern of files to search for /// @param all whether to return all matches or only the first /// @return list of absolute paths to the found files -ArrayOf(String) nvim_get_runtime_file(String name, Boolean all, Error *err) +ArrayOf(String) nvim_get_runtime_file(String name, Boolean all, Arena *arena, Error *err) FUNC_API_SINCE(7) FUNC_API_FAST { - Array rv = ARRAY_DICT_INIT; + RuntimeCookie cookie = { .rv = ARRAY_DICT_INIT, .arena = arena, }; + kvi_init(cookie.rv); int flags = DIP_DIRFILE | (all ? DIP_ALL : 0); TRY_WRAP(err, { - do_in_runtimepath((name.size ? name.data : ""), flags, find_runtime_cb, &rv); + do_in_runtimepath((name.size ? name.data : ""), flags, find_runtime_cb, &cookie); }); - return rv; + return arena_take_arraybuilder(arena, &cookie.rv); } -static bool find_runtime_cb(int num_fnames, char **fnames, bool all, void *cookie) +static bool find_runtime_cb(int num_fnames, char **fnames, bool all, void *c) { - Array *rv = (Array *)cookie; + RuntimeCookie *cookie = (RuntimeCookie *)c; for (int i = 0; i < num_fnames; i++) { - ADD(*rv, CSTR_TO_OBJ(fnames[i])); + // TODO(bfredl): consider memory management of gen_expand_wildcards() itself + kvi_push(cookie->rv, CSTR_TO_ARENA_OBJ(cookie->arena, fnames[i])); if (!all) { return true; } @@ -1583,13 +1590,12 @@ Array nvim_get_api_info(uint64_t channel_id, Arena *arena) /// /// @param[out] err Error details, if any void nvim_set_client_info(uint64_t channel_id, String name, Dictionary version, String type, - Dictionary methods, Dictionary attributes, Error *err) + Dictionary methods, Dictionary attributes, Arena *arena, Error *err) FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY { - Dictionary info = ARRAY_DICT_INIT; - PUT(info, "name", copy_object(STRING_OBJ(name), NULL)); + MAXSIZE_TEMP_DICT(info, 5); + PUT_C(info, "name", STRING_OBJ(name)); - version = copy_dictionary(version, NULL); bool has_major = false; for (size_t i = 0; i < version.size; i++) { if (strequal(version.items[i].key.data, "major")) { @@ -1598,15 +1604,21 @@ void nvim_set_client_info(uint64_t channel_id, String name, Dictionary version, } } if (!has_major) { - PUT(version, "major", INTEGER_OBJ(0)); + Dictionary v = arena_dict(arena, version.size + 1); + if (version.size) { + memcpy(v.items, version.items, version.size * sizeof(v.items[0])); + v.size = version.size; + } + PUT_C(v, "major", INTEGER_OBJ(0)); + version = v; } - PUT(info, "version", DICTIONARY_OBJ(version)); + PUT_C(info, "version", DICTIONARY_OBJ(version)); - PUT(info, "type", copy_object(STRING_OBJ(type), NULL)); - PUT(info, "methods", DICTIONARY_OBJ(copy_dictionary(methods, NULL))); - PUT(info, "attributes", DICTIONARY_OBJ(copy_dictionary(attributes, NULL))); + PUT_C(info, "type", STRING_OBJ(type)); + PUT_C(info, "methods", DICTIONARY_OBJ(methods)); + PUT_C(info, "attributes", DICTIONARY_OBJ(attributes)); - rpc_set_client_info(channel_id, info); + rpc_set_client_info(channel_id, copy_dictionary(info, NULL)); } /// Gets information about a channel. -- cgit From d14eefaee9519dae76bfaf4dd42e3bd7a05c7a1e Mon Sep 17 00:00:00 2001 From: bfredl Date: Mon, 19 Feb 2024 10:44:57 +0100 Subject: refactor(api): use arena when listing objects --- src/nvim/api/vim.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 0da7cec4ab..073541d687 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -832,20 +832,19 @@ void nvim_err_writeln(String str) /// Use |nvim_buf_is_loaded()| to check if a buffer is loaded. /// /// @return List of buffer handles -ArrayOf(Buffer) nvim_list_bufs(void) +ArrayOf(Buffer) nvim_list_bufs(Arena *arena) FUNC_API_SINCE(1) { - Array rv = ARRAY_DICT_INIT; + size_t n = 0; FOR_ALL_BUFFERS(b) { - rv.size++; + n++; } - rv.items = xmalloc(sizeof(Object) * rv.size); - size_t i = 0; + Array rv = arena_array(arena, n); FOR_ALL_BUFFERS(b) { - rv.items[i++] = BUFFER_OBJ(b->handle); + ADD_C(rv, BUFFER_OBJ(b->handle)); } return rv; @@ -887,20 +886,19 @@ void nvim_set_current_buf(Buffer buffer, Error *err) /// Gets the current list of window handles. /// /// @return List of window handles -ArrayOf(Window) nvim_list_wins(void) +ArrayOf(Window) nvim_list_wins(Arena *arena) FUNC_API_SINCE(1) { - Array rv = ARRAY_DICT_INIT; + size_t n = 0; FOR_ALL_TAB_WINDOWS(tp, wp) { - rv.size++; + n++; } - rv.items = xmalloc(sizeof(Object) * rv.size); - size_t i = 0; + Array rv = arena_array(arena, n); FOR_ALL_TAB_WINDOWS(tp, wp) { - rv.items[i++] = WINDOW_OBJ(wp->handle); + ADD_C(rv, WINDOW_OBJ(wp->handle)); } return rv; @@ -1124,20 +1122,19 @@ void nvim_chan_send(Integer chan, String data, Error *err) /// Gets the current list of tabpage handles. /// /// @return List of tabpage handles -ArrayOf(Tabpage) nvim_list_tabpages(void) +ArrayOf(Tabpage) nvim_list_tabpages(Arena *arena) FUNC_API_SINCE(1) { - Array rv = ARRAY_DICT_INIT; + size_t n = 0; FOR_ALL_TABS(tp) { - rv.size++; + n++; } - rv.items = xmalloc(sizeof(Object) * rv.size); - size_t i = 0; + Array rv = arena_array(arena, n); FOR_ALL_TABS(tp) { - rv.items[i++] = TABPAGE_OBJ(tp->handle); + ADD_C(rv, TABPAGE_OBJ(tp->handle)); } return rv; -- cgit From 404707c7606389ccb6c6062bfe9e2ff30a2552af Mon Sep 17 00:00:00 2001 From: bfredl Date: Mon, 19 Feb 2024 12:07:16 +0100 Subject: refactor(api): use arena for nvim_put and nvim_paste --- src/nvim/api/vim.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 073541d687..e472f5d160 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1205,14 +1205,13 @@ Boolean nvim_paste(String data, Boolean crlf, Integer phase, Arena *arena, Error VALIDATE_INT((phase >= -1 && phase <= 3), "phase", phase, { return false; }); - Array lines = ARRAY_DICT_INIT; if (phase == -1 || phase == 1) { // Start of paste-stream. draining = false; } else if (draining) { // Skip remaining chunks. Report error only once per "stream". goto theend; } - lines = string_to_array(data, crlf); + Array lines = string_to_array(data, crlf, arena); MAXSIZE_TEMP_ARRAY(args, 2); ADD_C(args, ARRAY_OBJ(lines)); ADD_C(args, INTEGER_OBJ(phase)); @@ -1243,7 +1242,6 @@ Boolean nvim_paste(String data, Boolean crlf, Integer phase, Arena *arena, Error AppendCharToRedobuff(ESC); // Dot-repeat. } theend: - api_free_array(lines); if (cancel || phase == -1 || phase == 3) { // End of paste-stream. draining = false; } @@ -1264,24 +1262,27 @@ theend: /// @param after If true insert after cursor (like |p|), or before (like |P|). /// @param follow If true place cursor at end of inserted text. /// @param[out] err Error details, if any -void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow, Error *err) +void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow, Arena *arena, + Error *err) FUNC_API_SINCE(6) FUNC_API_TEXTLOCK_ALLOW_CMDWIN { - yankreg_T *reg = xcalloc(1, sizeof(yankreg_T)); + yankreg_T reg[1] = { 0 }; VALIDATE_S((prepare_yankreg_from_object(reg, type, lines.size)), "type", type.data, { - goto cleanup; + return; }); if (lines.size == 0) { - goto cleanup; // Nothing to do. + return; // Nothing to do. } + reg->y_array = arena_alloc(arena, lines.size * sizeof(uint8_t *), true); + reg->y_size = lines.size; for (size_t i = 0; i < lines.size; i++) { VALIDATE_T("line", kObjectTypeString, lines.items[i].type, { - goto cleanup; + return; }); String line = lines.items[i].data.string; - reg->y_array[i] = xmemdupz(line.data, line.size); + reg->y_array[i] = arena_memdupz(arena, line.data, line.size); memchrsub(reg->y_array[i], NUL, NL, line.size); } @@ -1294,10 +1295,6 @@ void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow, msg_silent--; VIsual_active = VIsual_was_active; }); - -cleanup: - free_register(reg); - xfree(reg); } /// Subscribes to event broadcasts. -- cgit From f2c73e9ee2bd094f21f55dc97c5ad8d2f3a51621 Mon Sep 17 00:00:00 2001 From: bfredl Date: Mon, 19 Feb 2024 12:00:26 +0100 Subject: refactor(api): reduce temporary allocations when replacing lines The way ml_replace_buf is implemented makes it unfriendly for being used in a loop: every call allocates a scratch buffer for putting the line into the "dirty" state. This then immediately needs to be freed as the next ml_replace_buf and/or ml_append_buf call will flush that buffer. It's better to later pay the price of allocating the scratch buffer only if the line is being immediately edited (likely when using the API to only change one line) with an extra memcpy, than allocating that buffer multiple times every time the API is called. Of course, a separate xmalloc/xfree cycle for each time the dirty line changes is unwanted to begin with. But fixing that is a later refactor. --- src/nvim/api/vim.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index e472f5d160..c6043a2871 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -675,21 +675,21 @@ String nvim_get_current_line(Arena *arena, Error *err) /// /// @param line Line contents /// @param[out] err Error details, if any -void nvim_set_current_line(String line, Error *err) +void nvim_set_current_line(String line, Arena *arena, Error *err) FUNC_API_SINCE(1) FUNC_API_TEXTLOCK_ALLOW_CMDWIN { - buffer_set_line(curbuf->handle, curwin->w_cursor.lnum - 1, line, err); + buffer_set_line(curbuf->handle, curwin->w_cursor.lnum - 1, line, arena, err); } /// Deletes the current line. /// /// @param[out] err Error details, if any -void nvim_del_current_line(Error *err) +void nvim_del_current_line(Arena *arena, Error *err) FUNC_API_SINCE(1) FUNC_API_TEXTLOCK_ALLOW_CMDWIN { - buffer_del_line(curbuf->handle, curwin->w_cursor.lnum - 1, err); + buffer_del_line(curbuf->handle, curwin->w_cursor.lnum - 1, arena, err); } /// Gets a global (g:) variable. -- cgit From 3cc54586be7760652e8bad88cae82ce74ef9432e Mon Sep 17 00:00:00 2001 From: bfredl Date: Tue, 20 Feb 2024 13:44:50 +0100 Subject: refactor(api): make freeing of return-value opt-in instead of opt out As only a few API functions make use of explicit freeing of the return value, make it opt-in instead. The arena is always present under the hood, so `Arena *arena` arg now doesn't mean anything other than getting access to this arena. Also it is in principle possible to return an allocated value while still using the arena as scratch space for other stuff (unlikely, but there no reason to not allow it). --- src/nvim/api/vim.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index c6043a2871..2888656a7a 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -461,7 +461,7 @@ error: /// @see replace_termcodes /// @see cpoptions String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, Boolean special) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) FUNC_API_RET_ALLOC { if (str.size == 0) { // Empty string @@ -601,6 +601,7 @@ static bool find_runtime_cb(int num_fnames, char **fnames, bool all, void *c) } String nvim__get_lib_dir(void) + FUNC_API_RET_ALLOC { return cstr_as_string(get_lib_dir()); } @@ -1726,7 +1727,7 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Arena *arena, Error *er // directly here. But `result` might become invalid when next api function // is called in the loop. ADD_C(results, copy_object(result, arena)); - if (!handler.arena_return) { + if (handler.ret_alloc) { api_free_object(result); } } @@ -1806,9 +1807,9 @@ static void write_msg(String message, bool to_err, bool writeln) /// @param[in] obj Object to return. /// /// @return its argument. -Object nvim__id(Object obj) +Object nvim__id(Object obj, Arena *arena) { - return copy_object(obj, NULL); + return copy_object(obj, arena); } /// Returns array given as argument. @@ -1819,9 +1820,9 @@ Object nvim__id(Object obj) /// @param[in] arr Array to return. /// /// @return its argument. -Array nvim__id_array(Array arr) +Array nvim__id_array(Array arr, Arena *arena) { - return copy_array(arr, NULL); + return copy_array(arr, arena); } /// Returns dictionary given as argument. @@ -1832,9 +1833,9 @@ Array nvim__id_array(Array arr) /// @param[in] dct Dictionary to return. /// /// @return its argument. -Dictionary nvim__id_dictionary(Dictionary dct) +Dictionary nvim__id_dictionary(Dictionary dct, Arena *arena) { - return copy_dictionary(dct, NULL); + return copy_dictionary(dct, arena); } /// Returns floating-point value given as argument. -- cgit From 6d8bbfe19df2175637a1e47ac1aafb0e96e35b38 Mon Sep 17 00:00:00 2001 From: rktjmp Date: Thu, 22 Feb 2024 00:25:08 +1100 Subject: docs: remove mention of foreground/background/special keys in nvim_set_hl (#27558) To align the output of `nvim_get_hl` with its documentation -- which points to `nvim_set_hl`, remove mentions of the keys `foreground`, `background` and `special`. The long keys are are still supported (via fallback checks inside `dict2hlattrs`), but the `fg`, `bg` and `sp` keys are preferenced. --- src/nvim/api/vim.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 2888656a7a..b3d38cde69 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -141,9 +141,9 @@ Dictionary nvim_get_hl(Integer ns_id, Dict(get_highlight) *opts, Arena *arena, E /// |nvim_set_hl_ns()| or |nvim_win_set_hl_ns()| to activate them. /// @param name Highlight group name, e.g. "ErrorMsg" /// @param val Highlight definition map, accepts the following keys: -/// - fg (or foreground): color name or "#RRGGBB", see note. -/// - bg (or background): color name or "#RRGGBB", see note. -/// - sp (or special): color name or "#RRGGBB" +/// - fg: color name or "#RRGGBB", see note. +/// - bg: color name or "#RRGGBB", see note. +/// - sp: color name or "#RRGGBB" /// - blend: integer between 0 and 100 /// - bold: boolean /// - standout: boolean -- cgit From 9beb40a4db5613601fc1a4b828a44e5977eca046 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Thu, 15 Feb 2024 17:16:04 +0000 Subject: feat(docs): replace lua2dox.lua Problem: The documentation flow (`gen_vimdoc.py`) has several issues: - it's not very versatile - depends on doxygen - doesn't work well with Lua code as it requires an awkward filter script to convert it into pseudo-C. - The intermediate XML files and filters makes it too much like a rube goldberg machine. Solution: Re-implement the flow using Lua, LPEG and treesitter. - `gen_vimdoc.py` is now replaced with `gen_vimdoc.lua` and replicates a portion of the logic. - `lua2dox.lua` is gone! - No more XML files. - Doxygen is now longer used and instead we now use: - LPEG for comment parsing (see `scripts/luacats_grammar.lua` and `scripts/cdoc_grammar.lua`). - LPEG for C parsing (see `scripts/cdoc_parser.lua`) - Lua patterns for Lua parsing (see `scripts/luacats_parser.lua`). - Treesitter for Markdown parsing (see `scripts/text_utils.lua`). - The generated `runtime/doc/*.mpack` files have been removed. - `scripts/gen_eval_files.lua` now instead uses `scripts/cdoc_parser.lua` directly. - Text wrapping is implemented in `scripts/text_utils.lua` and appears to produce more consistent results (the main contributer to the diff of this change). --- src/nvim/api/vim.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index b3d38cde69..54bf290e6b 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -123,7 +123,7 @@ Dictionary nvim_get_hl(Integer ns_id, Dict(get_highlight) *opts, Arena *arena, E /// /// @note Unlike the `:highlight` command which can update a highlight group, /// this function completely replaces the definition. For example: -/// ``nvim_set_hl(0, 'Visual', {})`` will clear the highlight group +/// `nvim_set_hl(0, 'Visual', {})` will clear the highlight group /// 'Visual'. /// /// @note The fg and bg keys also accept the string values `"fg"` or `"bg"` @@ -549,6 +549,7 @@ ArrayOf(String) nvim_list_runtime_paths(Arena *arena, Error *err) return nvim_get_runtime_file(NULL_STRING, true, arena, err); } +/// @nodoc Array nvim__runtime_inspect(Arena *arena) { return runtime_inspect(arena); @@ -600,6 +601,7 @@ static bool find_runtime_cb(int num_fnames, char **fnames, bool all, void *c) return num_fnames > 0; } +/// @nodoc String nvim__get_lib_dir(void) FUNC_API_RET_ALLOC { @@ -1547,14 +1549,14 @@ Array nvim_get_api_info(uint64_t channel_id, Arena *arena) /// @param channel_id /// @param name Short name for the connected client /// @param version Dictionary describing the version, with these -/// (optional) keys: +/// (optional) keys: /// - "major" major version (defaults to 0 if not set, for no release yet) /// - "minor" minor version /// - "patch" patch number /// - "prerelease" string describing a prerelease, like "dev" or "beta1" /// - "commit" hash or similar identifier of commit /// @param type Must be one of the following values. Client libraries should -/// default to "remote" unless overridden by the user. +/// default to "remote" unless overridden by the user. /// - "remote" remote client connected "Nvim flavored" MessagePack-RPC (responses /// must be in reverse order of requests). |msgpack-rpc| /// - "msgpack-rpc" remote client connected to Nvim via fully MessagePack-RPC @@ -1565,12 +1567,12 @@ Array nvim_get_api_info(uint64_t channel_id, Arena *arena) /// - "host" plugin host, typically started by nvim /// - "plugin" single plugin, started by nvim /// @param methods Builtin methods in the client. For a host, this does not -/// include plugin methods which will be discovered later. -/// The key should be the method name, the values are dicts with -/// these (optional) keys (more keys may be added in future -/// versions of Nvim, thus unknown keys are ignored. Clients -/// must only use keys defined in this or later versions of -/// Nvim): +/// include plugin methods which will be discovered later. +/// The key should be the method name, the values are dicts with +/// these (optional) keys (more keys may be added in future +/// versions of Nvim, thus unknown keys are ignored. Clients +/// must only use keys defined in this or later versions of +/// Nvim): /// - "async" if true, send as a notification. If false or unspecified, /// use a blocking request /// - "nargs" Number of arguments. Could be a single integer or an array @@ -1979,7 +1981,7 @@ void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish, Di pum_ext_select_item((int)item, insert, finish); } -/// NB: if your UI doesn't use hlstate, this will not return hlstate first time +/// NB: if your UI doesn't use hlstate, this will not return hlstate first time. Array nvim__inspect_cell(Integer grid, Integer row, Integer col, Arena *arena, Error *err) { Array ret = ARRAY_DICT_INIT; @@ -2015,6 +2017,7 @@ Array nvim__inspect_cell(Integer grid, Integer row, Integer col, Arena *arena, E return ret; } +/// @nodoc void nvim__screenshot(String path) FUNC_API_FAST { @@ -2029,6 +2032,7 @@ void nvim__invalidate_glyph_cache(void) must_redraw = UPD_CLEAR; } +/// @nodoc Object nvim__unpack(String str, Arena *arena, Error *err) FUNC_API_FAST { @@ -2319,6 +2323,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Arena * return result; } +/// @nodoc void nvim_error_event(uint64_t channel_id, Integer lvl, String data) FUNC_API_REMOTE_ONLY { -- cgit From de5cf09cf98e20d8d3296ad6933ff2741acf83f7 Mon Sep 17 00:00:00 2001 From: bfredl Date: Mon, 26 Feb 2024 18:00:46 +0100 Subject: refactor(metadata): generate all metadata in lua Then we can just load metadata in C as a single msgpack blob. Which also can be used directly as binarly data, instead of first unpacking all the functions and ui_events metadata to immediately pack it again, which was a bit of a silly walk (and one extra usecase of `msgpack_rpc_from_object` which will get yak shaved in the next PR) --- src/nvim/api/vim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 54bf290e6b..6a3c6bab67 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1529,7 +1529,7 @@ Array nvim_get_api_info(uint64_t channel_id, Arena *arena) assert(channel_id <= INT64_MAX); ADD_C(rv, INTEGER_OBJ((int64_t)channel_id)); - ADD_C(rv, DICTIONARY_OBJ(api_metadata())); + ADD_C(rv, api_metadata()); return rv; } -- cgit From ade1b12f49c3b3914c74847d791eb90ea90b56b7 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Fri, 8 Mar 2024 12:25:18 +0000 Subject: docs: support inline markdown - Tags are now created with `[tag]()` - References are now created with `[tag]` - Code spans are no longer wrapped --- src/nvim/api/vim.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 6a3c6bab67..84a2f24dbc 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -249,7 +249,7 @@ void nvim_set_hl_ns_fast(Integer ns_id, Error *err) /// /// On execution error: does not fail, but updates v:errmsg. /// -/// To input sequences like use |nvim_replace_termcodes()| (typically +/// To input sequences like [] use |nvim_replace_termcodes()| (typically /// with escape_ks=false) to replace |keycodes|, then pass the result to /// nvim_feedkeys(). /// @@ -337,11 +337,11 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_ks) /// /// On execution error: does not fail, but updates v:errmsg. /// -/// @note |keycodes| like are translated, so "<" is special. -/// To input a literal "<", send . +/// @note |keycodes| like [] are translated, so "<" is special. +/// To input a literal "<", send []. /// /// @note For mouse events use |nvim_input_mouse()|. The pseudokey form -/// "" is deprecated since |api-level| 6. +/// `` is deprecated since |api-level| 6. /// /// @param keys to be typed /// @return Number of bytes actually written (can be fewer than @@ -362,7 +362,7 @@ Integer nvim_input(String keys) /// by calling it multiple times in a loop: the intermediate mouse /// positions will be ignored. It should be used to implement real-time /// mouse input in a GUI. The deprecated pseudokey form -/// ("") of |nvim_input()| has the same limitation. +/// (``) of |nvim_input()| has the same limitation. /// /// @param button Mouse button: one of "left", "right", "middle", "wheel", "move", /// "x1", "x2". @@ -451,13 +451,13 @@ error: "invalid button or action"); } -/// Replaces terminal codes and |keycodes| (, , ...) in a string with +/// Replaces terminal codes and |keycodes| ([], [], ...) in a string with /// the internal representation. /// /// @param str String to be converted. /// @param from_part Legacy Vim parameter. Usually true. -/// @param do_lt Also translate . Ignored if `special` is false. -/// @param special Replace |keycodes|, e.g. becomes a "\r" char. +/// @param do_lt Also translate []. Ignored if `special` is false. +/// @param special Replace |keycodes|, e.g. [] becomes a "\r" char. /// @see replace_termcodes /// @see cpoptions String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, Boolean special) @@ -525,7 +525,7 @@ Object nvim_notify(String msg, Integer log_level, Dictionary opts, Arena *arena, } /// Calculates the number of display cells occupied by `text`. -/// Control characters including count as one cell. +/// Control characters including [] count as one cell. /// /// @param text Some text /// @param[out] err Error details, if any @@ -762,7 +762,7 @@ void nvim_set_vvar(String name, Object value, Error *err) /// Echo a message. /// -/// @param chunks A list of [text, hl_group] arrays, each representing a +/// @param chunks A list of `[text, hl_group]` arrays, each representing a /// text chunk with specified highlight. `hl_group` element /// can be omitted for no highlight. /// @param history if true, add to |message-history|. @@ -1019,7 +1019,7 @@ fail: /// master end. For instance, a carriage return is sent /// as a "\r", not as a "\n". |textlock| applies. It is possible /// to call |nvim_chan_send()| directly in the callback however. -/// ["input", term, bufnr, data] +/// `["input", term, bufnr, data]` /// - force_crlf: (boolean, default true) Convert "\n" to "\r\n". /// @param[out] err Error details, if any /// @return Channel id, or 0 on error @@ -1471,7 +1471,7 @@ ArrayOf(Dictionary) nvim_get_keymap(String mode, Arena *arena) /// To set a buffer-local mapping, use |nvim_buf_set_keymap()|. /// /// Unlike |:map|, leading/trailing whitespace is accepted as part of the {lhs} or {rhs}. -/// Empty {rhs} is ||. |keycodes| are replaced as usual. +/// Empty {rhs} is []. |keycodes| are replaced as usual. /// /// Example: /// @@ -1491,7 +1491,7 @@ ArrayOf(Dictionary) nvim_get_keymap(String mode, Arena *arena) /// "ia", "ca" or "!a" for abbreviation in Insert mode, Cmdline mode, or both, respectively /// @param lhs Left-hand-side |{lhs}| of the mapping. /// @param rhs Right-hand-side |{rhs}| of the mapping. -/// @param opts Optional parameters map: Accepts all |:map-arguments| as keys except ||, +/// @param opts Optional parameters map: Accepts all |:map-arguments| as keys except [], /// values are booleans (default false). Also: /// - "noremap" disables |recursive_mapping|, like |:noremap| /// - "desc" human-readable description. @@ -1521,7 +1521,7 @@ void nvim_del_keymap(uint64_t channel_id, String mode, String lhs, Error *err) /// Returns a 2-tuple (Array), where item 0 is the current channel id and item /// 1 is the |api-metadata| map (Dictionary). /// -/// @returns 2-tuple [{channel-id}, {api-metadata}] +/// @returns 2-tuple `[{channel-id}, {api-metadata}]` Array nvim_get_api_info(uint64_t channel_id, Arena *arena) FUNC_API_SINCE(1) FUNC_API_FAST FUNC_API_REMOTE_ONLY { @@ -1960,7 +1960,7 @@ Object nvim_get_proc(Integer pid, Arena *arena, Error *err) /// If neither |ins-completion| nor |cmdline-completion| popup menu is active /// this API call is silently ignored. /// Useful for an external UI using |ui-popupmenu| to control the popup menu with the mouse. -/// Can also be used in a mapping; use |:map-cmd| or a Lua mapping to ensure the mapping +/// Can also be used in a mapping; use [] |:map-cmd| or a Lua mapping to ensure the mapping /// doesn't end completion mode. /// /// @param item Index (zero-based) of the item to select. Value of -1 selects nothing -- cgit