From 4be6c6cf0ddf5e31d4103cb5df06651ba6f4897b Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Sat, 11 Feb 2023 11:05:57 +0100 Subject: refactor: replace char_u with char (#21901) refactor: replace char_u with char Work on https://github.com/neovim/neovim/issues/459 --- 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 a53b30dd8a..12ab40a687 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -554,7 +554,7 @@ static void find_runtime_cb(char *fname, void *cookie) { Array *rv = (Array *)cookie; if (fname != NULL) { - ADD(*rv, STRING_OBJ(cstr_to_string((char *)fname))); + ADD(*rv, STRING_OBJ(cstr_to_string(fname))); } } @@ -2266,7 +2266,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * for (stl_hlrec_t *sp = hltab; sp->start != NULL; sp++) { Dictionary hl_info = ARRAY_DICT_INIT; - PUT(hl_info, "start", INTEGER_OBJ((char *)sp->start - buf)); + PUT(hl_info, "start", INTEGER_OBJ(sp->start - buf)); if (sp->userhl == 0) { grpname = get_default_stl_hl(wp, use_winbar); @@ -2281,7 +2281,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * } PUT(result, "highlights", ARRAY_OBJ(hl_values)); } - PUT(result, "str", CSTR_TO_OBJ((char *)buf)); + PUT(result, "str", CSTR_TO_OBJ(buf)); return result; } -- cgit From 46a87a5d2bac598fed0870f0d3c926087f95d30f Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 14 Feb 2023 05:19:04 -0500 Subject: refactor(api): VALIDATE macros #22187 Problem: - API validation involves too much boilerplate. - API validation errors are not consistently worded. Solution: Introduce some macros. Currently these are clumsy, but they at least help with consistency and avoid some nesting. --- src/nvim/api/vim.c | 171 +++++++++++++++++++++-------------------------------- 1 file changed, 67 insertions(+), 104 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 12ab40a687..333749c42f 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -18,6 +18,7 @@ #include "nvim/api/private/defs.h" #include "nvim/api/private/dispatch.h" #include "nvim/api/private/helpers.h" +#include "nvim/api/private/validate.h" #include "nvim/api/vim.h" #include "nvim/ascii.h" #include "nvim/autocmd.h" @@ -193,10 +194,9 @@ void nvim_set_hl(Integer ns_id, String name, Dict(highlight) *val, Error *err) void nvim_set_hl_ns(Integer ns_id, Error *err) FUNC_API_SINCE(10) { - if (ns_id < 0) { - api_set_error(err, kErrorTypeValidation, "no such namespace"); + VALIDATE_INT((ns_id >= 0), "namespace", ns_id, { return; - } + }); ns_hl_global = (NS)ns_id; hl_check_ns(); @@ -500,10 +500,9 @@ Object nvim_notify(String msg, Integer log_level, Dictionary opts, Error *err) Integer nvim_strwidth(String text, Error *err) FUNC_API_SINCE(1) { - if (text.size > INT_MAX) { - api_set_error(err, kErrorTypeValidation, "String is too long"); + VALIDATE((text.size <= INT_MAX), "text length (too long)", { return 0; - } + }); return (Integer)mb_string2cells(text.data); } @@ -575,9 +574,7 @@ ArrayOf(String) nvim__get_runtime(Array pat, Boolean all, Dict(runtime) *opts, E { bool is_lua = api_object_to_bool(opts->is_lua, "is_lua", false, err); bool source = api_object_to_bool(opts->do_source, "do_source", false, err); - if (source && !nlua_is_deferred_safe()) { - api_set_error(err, kErrorTypeValidation, "'do_source' cannot be used in fast callback"); - } + VALIDATE((!source || nlua_is_deferred_safe()), "'do_source' used in fast callback", {}); if (ERROR_SET(err)) { return (Array)ARRAY_DICT_INIT; @@ -602,10 +599,9 @@ ArrayOf(String) nvim__get_runtime(Array pat, Boolean all, Dict(runtime) *opts, E void nvim_set_current_dir(String dir, Error *err) FUNC_API_SINCE(1) { - if (dir.size >= MAXPATHL) { - api_set_error(err, kErrorTypeValidation, "Directory name is too long"); + VALIDATE((dir.size < MAXPATHL), "directory name (too long)", { return; - } + }); char string[MAXPATHL]; memcpy(string, dir.data, dir.size); @@ -664,16 +660,14 @@ Object nvim_get_var(String name, Error *err) { dictitem_T *di = tv_dict_find(&globvardict, name.data, (ptrdiff_t)name.size); if (di == NULL) { // try to autoload script - if (!script_autoload(name.data, name.size, false) || aborting()) { - api_set_error(err, kErrorTypeValidation, "Key not found: %s", name.data); + VALIDATE_S((script_autoload(name.data, name.size, false) && !aborting()), "key", name.data, { return (Object)OBJECT_INIT; - } + }); di = tv_dict_find(&globvardict, name.data, (ptrdiff_t)name.size); } - if (di == NULL) { - api_set_error(err, kErrorTypeValidation, "Key not found: %s", name.data); + VALIDATE_S((di != NULL), "key (not found)", name.data, { return (Object)OBJECT_INIT; - } + }); return vim_to_object(&di->di_tv); } @@ -991,16 +985,14 @@ Integer nvim_open_term(Buffer buffer, DictionaryOf(LuaRef) opts, Error *err) String k = opts.items[i].key; Object *v = &opts.items[i].value; if (strequal("on_input", k.data)) { - if (v->type != kObjectTypeLuaRef) { - api_set_error(err, kErrorTypeValidation, - "%s is not a function", "on_input"); + VALIDATE_T("on_input", kObjectTypeLuaRef, v->type, { return 0; - } + }); cb = v->data.luaref; v->data.luaref = LUA_NOREF; break; } else { - api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data); + VALIDATE_S(false, "key", k.data, {}); } } @@ -1075,9 +1067,7 @@ void nvim_chan_send(Integer chan, String data, Error *err) channel_send((uint64_t)chan, data.data, data.size, false, &error); - if (error) { - api_set_error(err, kErrorTypeValidation, "%s", error); - } + VALIDATE(!error, error, {}); } /// Gets the current list of tabpage handles. @@ -1164,10 +1154,9 @@ Boolean nvim_paste(String data, Boolean crlf, Integer phase, Error *err) static bool draining = false; bool cancel = false; - if (phase < -1 || phase > 3) { - api_set_error(err, kErrorTypeValidation, "Invalid phase: %" PRId64, phase); + VALIDATE_INT((phase >= -1 && phase <= 3), "phase", phase, { return false; - } + }); Array args = ARRAY_DICT_INIT; Object rv = OBJECT_INIT; if (phase == -1 || phase == 1) { // Start of paste-stream. @@ -1234,20 +1223,17 @@ void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow, FUNC_API_CHECK_TEXTLOCK { yankreg_T *reg = xcalloc(1, sizeof(yankreg_T)); - if (!prepare_yankreg_from_object(reg, type, lines.size)) { - api_set_error(err, kErrorTypeValidation, "Invalid type: '%s'", type.data); + VALIDATE_S((prepare_yankreg_from_object(reg, type, lines.size)), "type", type.data, { goto cleanup; - } + }); if (lines.size == 0) { goto cleanup; // Nothing to do. } for (size_t i = 0; i < lines.size; i++) { - if (lines.items[i].type != kObjectTypeString) { - api_set_error(err, kErrorTypeValidation, - "Invalid lines (expected array of strings)"); + VALIDATE_T("line", kObjectTypeString, lines.items[i].type, { goto cleanup; - } + }); String line = lines.items[i].data.string; reg->y_array[i] = xmemdupz(line.data, line.size); memchrsub(reg->y_array[i], NUL, NL, line.size); @@ -1351,8 +1337,9 @@ Dictionary nvim_get_context(Dict(context) *opts, Error *err) if (opts->types.type == kObjectTypeArray) { types = opts->types.data.array; } else if (opts->types.type != kObjectTypeNil) { - api_set_error(err, kErrorTypeValidation, "invalid value for key: types"); - return (Dictionary)ARRAY_DICT_INIT; + VALIDATE_T("types", kObjectTypeArray, opts->types.type, { + return (Dictionary)ARRAY_DICT_INIT; + }); } int int_types = types.size > 0 ? 0 : kCtxAll; @@ -1373,8 +1360,9 @@ Dictionary nvim_get_context(Dict(context) *opts, Error *err) } else if (strequal(s, "funcs")) { int_types |= kCtxFuncs; } else { - api_set_error(err, kErrorTypeValidation, "unexpected type: %s", s); - return (Dictionary)ARRAY_DICT_INIT; + VALIDATE_S(false, "type", s, { + return (Dictionary)ARRAY_DICT_INIT; + }); } } } @@ -1651,34 +1639,20 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Arena *arena, Error *er size_t i; // also used for freeing the variables for (i = 0; i < calls.size; i++) { - if (calls.items[i].type != kObjectTypeArray) { - api_set_error(err, - kErrorTypeValidation, - "Items in calls array must be arrays"); + VALIDATE_T("calls item", kObjectTypeArray, calls.items[i].type, { goto theend; - } + }); Array call = calls.items[i].data.array; - if (call.size != 2) { - api_set_error(err, - kErrorTypeValidation, - "Items in calls array must be arrays of size 2"); + VALIDATE((call.size == 2), "Items in calls array must be arrays of size 2", { goto theend; - } - - if (call.items[0].type != kObjectTypeString) { - api_set_error(err, - kErrorTypeValidation, - "Name must be String"); + }); + VALIDATE_T("name", kObjectTypeString, call.items[0].type, { goto theend; - } + }); String name = call.items[0].data.string; - - if (call.items[1].type != kObjectTypeArray) { - api_set_error(err, - kErrorTypeValidation, - "Args must be Array"); + VALIDATE_T("args", kObjectTypeArray, call.items[1].type, { goto theend; - } + }); Array args = call.items[1].data.array; MsgpackRpcRequestHandler handler = @@ -1937,10 +1911,9 @@ void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish, Di Error *err) FUNC_API_SINCE(6) { - if (opts.size > 0) { - api_set_error(err, kErrorTypeValidation, "opts dict isn't empty"); + VALIDATE((opts.size == 0), "opts dict isn't empty", { return; - } + }); if (finish) { insert = true; @@ -1961,13 +1934,10 @@ Array nvim__inspect_cell(Integer grid, Integer row, Integer col, Arena *arena, E g = &pum_grid; } else if (grid > 1) { win_T *wp = get_win_by_grid_handle((handle_T)grid); - if (wp != NULL && wp->w_grid_alloc.chars != NULL) { - g = &wp->w_grid_alloc; - } else { - api_set_error(err, kErrorTypeValidation, - "No grid with the given handle"); + VALIDATE_INT((wp != NULL && wp->w_grid_alloc.chars != NULL), "grid handle", grid, { return ret; - } + }); + g = &wp->w_grid_alloc; } if (row < 0 || row >= g->rows @@ -2009,20 +1979,16 @@ Boolean nvim_del_mark(String name, Error *err) FUNC_API_SINCE(8) { bool res = false; - if (name.size != 1) { - api_set_error(err, kErrorTypeValidation, - "Mark name must be a single character"); + VALIDATE_S((name.size == 1), "mark name (must be a single char)", name.data, { return res; - } + }); // Only allow file/uppercase marks // TODO(muniter): Refactor this ASCII_ISUPPER macro to a proper function - if (ASCII_ISUPPER(*name.data) || ascii_isdigit(*name.data)) { - res = set_mark(NULL, name, 0, 0, err); - } else { - api_set_error(err, kErrorTypeValidation, - "Only file/uppercase marks allowed, invalid mark name: '%c'", - *name.data); - } + VALIDATE_S((ASCII_ISUPPER(*name.data) || ascii_isdigit(*name.data)), + "mark name (must be file/uppercase)", name.data, { + return res; + }); + res = set_mark(NULL, name, 0, 0, err); return res; } @@ -2043,16 +2009,13 @@ Array nvim_get_mark(String name, Dictionary opts, Error *err) { Array rv = ARRAY_DICT_INIT; - if (name.size != 1) { - api_set_error(err, kErrorTypeValidation, - "Mark name must be a single character"); + VALIDATE_S((name.size == 1), "mark name (must be a single char)", name.data, { return rv; - } else if (!(ASCII_ISUPPER(*name.data) || ascii_isdigit(*name.data))) { - api_set_error(err, kErrorTypeValidation, - "Only file/uppercase marks allowed, invalid mark name: '%c'", - *name.data); + }); + VALIDATE_S((ASCII_ISUPPER(*name.data) || ascii_isdigit(*name.data)), + "mark name (must be file/uppercase)", name.data, { return rv; - } + }); xfmark_T *mark = mark_get_global(false, *name.data); // false avoids loading the mark buffer pos_T pos = mark->fmark.mark; @@ -2137,27 +2100,28 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * if (str.size < 2 || memcmp(str.data, "%!", 2) != 0) { const char *const errmsg = check_stl_option(str.data); - if (errmsg) { - api_set_error(err, kErrorTypeValidation, "%s", errmsg); + VALIDATE(!errmsg, errmsg, { return result; - } + }); } if (HAS_KEY(opts->winid)) { - if (opts->winid.type != kObjectTypeInteger) { - api_set_error(err, kErrorTypeValidation, "winid must be an integer"); + VALIDATE_T("winid", kObjectTypeInteger, opts->winid.type, { return result; - } + }); window = (Window)opts->winid.data.integer; } if (HAS_KEY(opts->fillchar)) { - if (opts->fillchar.type != kObjectTypeString || opts->fillchar.data.string.size == 0 - || ((size_t)utf_ptr2len(opts->fillchar.data.string.data) - != opts->fillchar.data.string.size)) { - api_set_error(err, kErrorTypeValidation, "fillchar must be a single character"); + VALIDATE_T("fillchar", kObjectTypeString, opts->fillchar.type, { return result; - } + }); + VALIDATE((opts->fillchar.data.string.size != 0 + && ((size_t)utf_ptr2len(opts->fillchar.data.string.data) + == opts->fillchar.data.string.size)), + "Invalid fillchar (not a single character)", { + return result; + }); fillchar = utf_ptr2char(opts->fillchar.data.string.data); } if (HAS_KEY(opts->highlights)) { @@ -2211,10 +2175,9 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * } if (HAS_KEY(opts->maxwidth)) { - if (opts->maxwidth.type != kObjectTypeInteger) { - api_set_error(err, kErrorTypeValidation, "maxwidth must be an integer"); + VALIDATE_T("maxwidth", kObjectTypeInteger, opts->maxwidth.type, { return result; - } + }); maxwidth = (int)opts->maxwidth.data.integer; } else { -- cgit From ff3d04b75b4a9314815c37d53ebc4d035a043335 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 14 Feb 2023 08:07:38 -0500 Subject: refactor(api): VALIDATE macros #22256 - VALIDATE() takes a format string - deduplicate check_string_array - VALIDATE_RANGE - validate UI args --- src/nvim/api/vim.c | 59 +++++++++++++++++++++++------------------------------- 1 file changed, 25 insertions(+), 34 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 333749c42f..50683ac403 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -87,10 +87,9 @@ Dictionary nvim_get_hl_by_name(String name, Boolean rgb, Arena *arena, Error *er Dictionary result = ARRAY_DICT_INIT; int id = syn_name2id(name.data); - if (id == 0) { - api_set_error(err, kErrorTypeException, "Invalid highlight name: %s", name.data); + VALIDATE_S((id != 0), "highlight name", name.data, { return result; - } + }); return nvim_get_hl_by_id(id, rgb, arena, err); } @@ -104,10 +103,9 @@ Dictionary nvim_get_hl_by_id(Integer hl_id, Boolean rgb, Arena *arena, Error *er FUNC_API_SINCE(3) { Dictionary dic = ARRAY_DICT_INIT; - if (syn_get_final_id((int)hl_id) == 0) { - api_set_error(err, kErrorTypeException, "Invalid highlight id: %" PRId64, hl_id); + VALIDATE_INT((syn_get_final_id((int)hl_id) != 0), "highlight id", hl_id, { return dic; - } + }); int attrcode = syn_id2attr((int)hl_id); return hl_get_attr_by_id(attrcode, rgb, arena, err); } @@ -174,10 +172,9 @@ void nvim_set_hl(Integer ns_id, String name, Dict(highlight) *val, Error *err) FUNC_API_SINCE(7) { int hl_id = syn_check_group(name.data, name.size); - if (hl_id == 0) { - api_set_error(err, kErrorTypeException, "Invalid highlight name: %s", name.data); + VALIDATE_S((hl_id != 0), "highlight name", name.data, { return; - } + }); int link_id = -1; HlAttrs attrs = dict2hlattrs(val, true, &link_id, err); @@ -403,11 +400,9 @@ void nvim_input_mouse(String button, String action, String modifier, Integer gri continue; } int mod = name_to_mod_mask(byte); - if (mod == 0) { - api_set_error(err, kErrorTypeValidation, - "invalid modifier %c", byte); + VALIDATE((mod != 0), "Invalid modifier: %c", byte, { return; - } + }); modmask |= mod; } @@ -500,7 +495,7 @@ Object nvim_notify(String msg, Integer log_level, Dictionary opts, Error *err) Integer nvim_strwidth(String text, Error *err) FUNC_API_SINCE(1) { - VALIDATE((text.size <= INT_MAX), "text length (too long)", { + VALIDATE_S((text.size <= INT_MAX), "text length", "(too long)", { return 0; }); @@ -574,8 +569,7 @@ ArrayOf(String) nvim__get_runtime(Array pat, Boolean all, Dict(runtime) *opts, E { bool is_lua = api_object_to_bool(opts->is_lua, "is_lua", false, err); bool source = api_object_to_bool(opts->do_source, "do_source", false, err); - VALIDATE((!source || nlua_is_deferred_safe()), "'do_source' used in fast callback", {}); - + VALIDATE((!source || nlua_is_deferred_safe()), "%s", "'do_source' used in fast callback", {}); if (ERROR_SET(err)) { return (Array)ARRAY_DICT_INIT; } @@ -599,7 +593,7 @@ ArrayOf(String) nvim__get_runtime(Array pat, Boolean all, Dict(runtime) *opts, E void nvim_set_current_dir(String dir, Error *err) FUNC_API_SINCE(1) { - VALIDATE((dir.size < MAXPATHL), "directory name (too long)", { + VALIDATE_S((dir.size < MAXPATHL), "directory name", "(too long)", { return; }); @@ -1067,7 +1061,7 @@ void nvim_chan_send(Integer chan, String data, Error *err) channel_send((uint64_t)chan, data.data, data.size, false, &error); - VALIDATE(!error, error, {}); + VALIDATE(!error, "%s", error, {}); } /// Gets the current list of tabpage handles. @@ -1334,12 +1328,11 @@ Dictionary nvim_get_context(Dict(context) *opts, Error *err) FUNC_API_SINCE(6) { Array types = ARRAY_DICT_INIT; - if (opts->types.type == kObjectTypeArray) { - types = opts->types.data.array; - } else if (opts->types.type != kObjectTypeNil) { + if (HAS_KEY(opts->types)) { VALIDATE_T("types", kObjectTypeArray, opts->types.type, { return (Dictionary)ARRAY_DICT_INIT; }); + types = opts->types.data.array; } int int_types = types.size > 0 ? 0 : kCtxAll; @@ -1643,7 +1636,7 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Arena *arena, Error *er goto theend; }); Array call = calls.items[i].data.array; - VALIDATE((call.size == 2), "Items in calls array must be arrays of size 2", { + VALIDATE((call.size == 2), "%s", "calls item must be a 2-item Array", { goto theend; }); VALIDATE_T("name", kObjectTypeString, call.items[0].type, { @@ -1824,10 +1817,9 @@ Array nvim_get_proc_children(Integer pid, Error *err) Array rvobj = ARRAY_DICT_INIT; int *proc_list = NULL; - if (pid <= 0 || pid > INT_MAX) { - api_set_error(err, kErrorTypeException, "Invalid pid: %" PRId64, pid); + VALIDATE_INT((pid > 0 && pid <= INT_MAX), "pid", pid, { goto end; - } + }); size_t proc_count; int rv = os_proc_children((int)pid, &proc_list, &proc_count); @@ -1866,10 +1858,10 @@ Object nvim_get_proc(Integer pid, Error *err) rvobj.data.dictionary = (Dictionary)ARRAY_DICT_INIT; rvobj.type = kObjectTypeDictionary; - if (pid <= 0 || pid > INT_MAX) { - api_set_error(err, kErrorTypeException, "Invalid pid: %" PRId64, pid); + VALIDATE_INT((pid > 0 && pid <= INT_MAX), "pid", pid, { return NIL; - } + }); + #ifdef MSWIN rvobj.data.dictionary = os_proc_info((int)pid); if (rvobj.data.dictionary.size == 0) { // Process not found. @@ -1911,7 +1903,7 @@ void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish, Di Error *err) FUNC_API_SINCE(6) { - VALIDATE((opts.size == 0), "opts dict isn't empty", { + VALIDATE((opts.size == 0), "%s", "opts dict isn't empty", { return; }); @@ -2100,7 +2092,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * if (str.size < 2 || memcmp(str.data, "%!", 2) != 0) { const char *const errmsg = check_stl_option(str.data); - VALIDATE(!errmsg, errmsg, { + VALIDATE(!errmsg, "%s", errmsg, { return result; }); } @@ -2119,7 +2111,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * VALIDATE((opts->fillchar.data.string.size != 0 && ((size_t)utf_ptr2len(opts->fillchar.data.string.data) == opts->fillchar.data.string.size)), - "Invalid fillchar (not a single character)", { + "%s", "Invalid fillchar: expected single character", { return result; }); fillchar = utf_ptr2char(opts->fillchar.data.string.data); @@ -2145,10 +2137,9 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * return result; } } - if (use_winbar && use_tabline) { - api_set_error(err, kErrorTypeValidation, "use_winbar and use_tabline are mutually exclusive"); + VALIDATE(!(use_winbar && use_tabline), "%s", "Cannot use both 'use_winbar' and 'use_tabline'", { return result; - } + }); win_T *wp, *ewp; -- cgit From 556f8646c01d1751cf39fe4df9c622899dceab9d Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 14 Feb 2023 14:19:28 -0500 Subject: refactor(api): consistent VALIDATE messages #22262 Problem: Validation messages are not consistently formatted. - Parameter names sometimes are NOT quoted. - Descriptive names (non-parameters) sometimes ARE quoted. Solution: Always quote the `name` value passed to a VALIDATE macro _unless_ the value has whitespace. --- src/nvim/api/vim.c | 21 +++++++++++---------- 1 file changed, 11 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 50683ac403..3a93005841 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -654,12 +654,13 @@ Object nvim_get_var(String name, Error *err) { dictitem_T *di = tv_dict_find(&globvardict, name.data, (ptrdiff_t)name.size); if (di == NULL) { // try to autoload script - VALIDATE_S((script_autoload(name.data, name.size, false) && !aborting()), "key", name.data, { + bool found = script_autoload(name.data, name.size, false) && !aborting(); + VALIDATE(found, "Key not found: %s", name.data, { return (Object)OBJECT_INIT; }); di = tv_dict_find(&globvardict, name.data, (ptrdiff_t)name.size); } - VALIDATE_S((di != NULL), "key (not found)", name.data, { + VALIDATE((di != NULL), "Key not found: %s", name.data, { return (Object)OBJECT_INIT; }); return vim_to_object(&di->di_tv); @@ -986,7 +987,7 @@ Integer nvim_open_term(Buffer buffer, DictionaryOf(LuaRef) opts, Error *err) v->data.luaref = LUA_NOREF; break; } else { - VALIDATE_S(false, "key", k.data, {}); + VALIDATE_S(false, "'opts' key", k.data, {}); } } @@ -1632,18 +1633,18 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Arena *arena, Error *er size_t i; // also used for freeing the variables for (i = 0; i < calls.size; i++) { - VALIDATE_T("calls item", kObjectTypeArray, calls.items[i].type, { + VALIDATE_T("'calls' item", kObjectTypeArray, calls.items[i].type, { goto theend; }); Array call = calls.items[i].data.array; - VALIDATE((call.size == 2), "%s", "calls item must be a 2-item Array", { + VALIDATE_EXP((call.size == 2), "'calls' item", "2-item Array", NULL, { goto theend; }); VALIDATE_T("name", kObjectTypeString, call.items[0].type, { goto theend; }); String name = call.items[0].data.string; - VALIDATE_T("args", kObjectTypeArray, call.items[1].type, { + VALIDATE_T("call args", kObjectTypeArray, call.items[1].type, { goto theend; }); Array args = call.items[1].data.array; @@ -2108,10 +2109,10 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * VALIDATE_T("fillchar", kObjectTypeString, opts->fillchar.type, { return result; }); - VALIDATE((opts->fillchar.data.string.size != 0 - && ((size_t)utf_ptr2len(opts->fillchar.data.string.data) - == opts->fillchar.data.string.size)), - "%s", "Invalid fillchar: expected single character", { + VALIDATE_EXP((opts->fillchar.data.string.size != 0 + && ((size_t)utf_ptr2len(opts->fillchar.data.string.data) + == opts->fillchar.data.string.size)), + "fillchar", "single character", NULL, { return result; }); fillchar = utf_ptr2char(opts->fillchar.data.string.data); -- cgit From 6752f1005d26c93a033d856a60b7b296f3e51634 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 14 Dec 2022 19:58:18 +0100 Subject: docs: naming conventions, guidelines close #21063 --- src/nvim/api/vim.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 3a93005841..0f27040fd3 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1442,15 +1442,14 @@ ArrayOf(Dictionary) nvim_get_keymap(String mode) /// or "!" for |:map!|, or empty string for |:map|. /// @param lhs Left-hand-side |{lhs}| of the mapping. /// @param rhs Right-hand-side |{rhs}| of the mapping. -/// @param opts Optional parameters map: keys are |:map-arguments|, values are booleans (default -/// false). Accepts all |:map-arguments| as keys excluding || but including -/// |:noremap| and "desc". Unknown key is an error. -/// "desc" can be used to give a description to the mapping. -/// When called from Lua, also accepts a "callback" key that takes a Lua function to -/// call when the mapping is executed. -/// When "expr" is true, "replace_keycodes" (boolean) can be used to replace keycodes -/// in the resulting string (see |nvim_replace_termcodes()|), and a Lua callback -/// returning `nil` is equivalent to returning an empty string. +/// @param opts Optional parameters map: Accepts all |:map-arguments| as keys except ||, +/// values are booleans (default false). Also: +/// - "noremap" non-recursive mapping |:noremap| +/// - "desc" human-readable description. +/// - "callback" Lua function called when the mapping is executed. +/// - "replace_keycodes" (boolean) When "expr" is true, replace keycodes in the +/// resulting string (see |nvim_replace_termcodes()|). Returning nil from the Lua +/// "callback" is equivalent to returning an empty string. /// @param[out] err Error details, if any. void nvim_set_keymap(uint64_t channel_id, String mode, String lhs, String rhs, Dict(keymap) *opts, Error *err) -- cgit From 7dc9182cf0b27cbfb4e289db55dd7b02998ef5c8 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 11 Mar 2023 21:29:25 +0800 Subject: vim-patch:8.2.1398: autoload script sourced twice if sourced directly (#22622) Problem: Autoload script sourced twice if sourced directly. Solution: Do not source an autoload script again. (issue vim/vim#6644) https://github.com/vim/vim/commit/daa2f36573db3e1df7eb1fdbc3a09a2815644048 Cherry-pick ret_sid changes from patch 8.2.0149. Use do_in_runtimepath() as that's what source_runtime() calls in Nvim. Co-authored-by: Bram Moolenaar --- 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 0f27040fd3..315ccd13e6 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -579,7 +579,7 @@ ArrayOf(String) nvim__get_runtime(Array pat, Boolean all, Dict(runtime) *opts, E if (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); + (void)do_source(name.data, false, DOSO_NONE, NULL); } } -- cgit From 320cb344c14b30f8c1aa8c2d86803e4c2f971ae9 Mon Sep 17 00:00:00 2001 From: ii14 <59243201+ii14@users.noreply.github.com> Date: Thu, 16 Mar 2023 09:31:37 +0100 Subject: docs(api): link to nvim_set_hl_ns from nvim_set_hl (#22678) --- src/nvim/api/vim.c | 8 +++++--- 1 file changed, 5 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 315ccd13e6..a8cc7aa454 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -141,6 +141,8 @@ Dictionary nvim__get_hl_defs(Integer ns_id, Arena *arena, Error *err) /// /// @param ns_id Namespace id for this highlight |nvim_create_namespace()|. /// Use 0 to set a highlight group globally |:highlight|. +/// Highlights from non-global namespaces are not active by default, use +/// |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. @@ -183,8 +185,8 @@ void nvim_set_hl(Integer ns_id, String name, Dict(highlight) *val, Error *err) } } -/// Set active namespace for highlights. This can be set for a single window, -/// see |nvim_win_set_hl_ns()|. +/// Set active namespace for highlights defined with |nvim_set_hl()|. This can be set for +/// a single window, see |nvim_win_set_hl_ns()|. /// /// @param ns_id the namespace to use /// @param[out] err Error details, if any @@ -200,7 +202,7 @@ void nvim_set_hl_ns(Integer ns_id, Error *err) redraw_all_later(UPD_NOT_VALID); } -/// Set active namespace for highlights while redrawing. +/// Set active namespace for highlights defined with |nvim_set_hl()| while redrawing. /// /// This function meant to be called while redrawing, primarily from /// |nvim_set_decoration_provider()| on_win and on_line callbacks, which -- cgit From 3285cd6eccd9b7f33cc32f992c2607c3fc4ca13f Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Wed, 22 Mar 2023 10:09:28 +0000 Subject: refactor: do more in TRY_WRAP --- src/nvim/api/vim.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index a8cc7aa454..4689e6b5bf 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -538,10 +538,8 @@ ArrayOf(String) nvim_get_runtime_file(String name, Boolean all, Error *err) int flags = DIP_DIRFILE | (all ? DIP_ALL : 0); - TRY_WRAP({ - try_start(); + TRY_WRAP(err, { do_in_runtimepath((name.size ? name.data : ""), flags, find_runtime_cb, &rv); - try_end(err); }); return rv; } @@ -1238,14 +1236,12 @@ void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow, finish_yankreg_from_object(reg, false); - TRY_WRAP({ - try_start(); + TRY_WRAP(err, { bool VIsual_was_active = VIsual_active; msg_silent++; // Avoid "N more lines" message. do_put(0, reg, after ? FORWARD : BACKWARD, 1, follow ? PUT_CURSEND : 0); msg_silent--; VIsual_active = VIsual_was_active; - try_end(err); }); cleanup: -- cgit From c0fe6c040e19ef9102a8507ffcbd88b83186326a Mon Sep 17 00:00:00 2001 From: Null Chilly <56817415+nullchilly@users.noreply.github.com> Date: Thu, 23 Mar 2023 16:31:39 +0700 Subject: feat(api): add nvim_get_hl (#22693) Problem: no way of getting all highlight group definitions in a namespace. Solution: add `nvim_get_hl()`, deprecate `nvim_get_hl_by_name()` and `nvim_get_hl_by_id()`. --- src/nvim/api/vim.c | 56 +++++++++++++++--------------------------------------- 1 file changed, 15 insertions(+), 41 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 4689e6b5bf..ca5dd97020 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -74,42 +74,6 @@ # include "api/vim.c.generated.h" #endif -/// Gets a highlight definition by name. -/// -/// @param name Highlight group name -/// @param rgb Export RGB colors -/// @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) - FUNC_API_SINCE(3) -{ - Dictionary result = ARRAY_DICT_INIT; - int id = syn_name2id(name.data); - - VALIDATE_S((id != 0), "highlight name", name.data, { - return result; - }); - return nvim_get_hl_by_id(id, rgb, arena, err); -} - -/// Gets a highlight definition by id. |hlID()| -/// @param hl_id Highlight id as returned by |hlID()| -/// @param rgb Export RGB colors -/// @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) - FUNC_API_SINCE(3) -{ - Dictionary dic = ARRAY_DICT_INIT; - VALIDATE_INT((syn_get_final_id((int)hl_id) != 0), "highlight id", hl_id, { - return dic; - }); - int attrcode = syn_id2attr((int)hl_id); - return hl_get_attr_by_id(attrcode, rgb, arena, err); -} - /// Gets a highlight group by name /// /// similar to |hlID()|, but allocates a new ID if not present. @@ -119,12 +83,22 @@ Integer nvim_get_hl_id_by_name(String name) return syn_check_group(name.data, name.size); } -Dictionary nvim__get_hl_defs(Integer ns_id, Arena *arena, Error *err) +/// Gets all or specific highlight groups in a namespace. +/// +/// @param ns_id Get highlight groups for namespace ns_id |nvim_get_namespaces()|. +/// Use 0 to get global highlight groups |:highlight|. +/// @param opts Options dict: +/// - name: (string) Get a highlight definition by name. +/// - id: (integer) Get a highlight definition by id. +/// - link: (boolean, default true) Show linked group name instead of effective definition |:hi-link|. +/// +/// @param[out] err Error details, if any. +/// @return Highlight groups as a map from group name to a highlight definition map as in |nvim_set_hl()|, +/// or only a single highlight definition map if requested by name or id. +Dictionary nvim_get_hl(Integer ns_id, Dict(get_highlight) *opts, Arena *arena, Error *err) + FUNC_API_SINCE(11) { - if (ns_id == 0) { - return get_global_hl_defs(arena); - } - abort(); + return ns_get_hl_defs((NS)ns_id, opts, arena, err); } /// Sets a highlight group. -- cgit From b34097fe6d2ea5c84bcec65a834a430d9f58eb64 Mon Sep 17 00:00:00 2001 From: "Sindre T. Strøm" Date: Fri, 31 Mar 2023 12:52:53 +0200 Subject: fix(api): return both link and attributes with nvim_get_hl (#22824) Problem: No way to get the actual highlight attributes for a linked group through |nvim_get_hl()| (not the attributes from the link target). Solution: Return the actual attributes as well as the link target name. --- src/nvim/api/vim.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index ca5dd97020..9812313b7b 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -95,6 +95,9 @@ Integer nvim_get_hl_id_by_name(String name) /// @param[out] err Error details, if any. /// @return Highlight groups as a map from group name to a highlight definition map as in |nvim_set_hl()|, /// or only a single highlight definition map if requested by name or id. +/// +/// @note When the `link` attribute is defined in the highlight definition +/// map, other attributes will not be taking effect (see |:hi-link|). Dictionary nvim_get_hl(Integer ns_id, Dict(get_highlight) *opts, Arena *arena, Error *err) FUNC_API_SINCE(11) { @@ -113,6 +116,10 @@ Dictionary nvim_get_hl(Integer ns_id, Dict(get_highlight) *opts, Arena *arena, E /// values of the Normal group. If the Normal group has not been defined, /// using these values results in an error. /// +/// +/// @note If `link` is used in combination with other attributes; only the +/// `link` will take effect (see |:hi-link|). +/// /// @param ns_id Namespace id for this highlight |nvim_create_namespace()|. /// Use 0 to set a highlight group globally |:highlight|. /// Highlights from non-global namespaces are not active by default, use -- cgit From 7c8c1550737b34fabb3e4cecbc6b6bf3581b2235 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 4 Apr 2023 08:59:11 +0800 Subject: fix(api): avoid double hit-enter prompt with nvim_err_writeln (#22879) --- src/nvim/api/vim.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 9812313b7b..343c3b6e40 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -737,7 +737,7 @@ error: void nvim_out_write(String str) FUNC_API_SINCE(1) { - write_msg(str, false); + write_msg(str, false, false); } /// Writes a message to the Vim error buffer. Does not append "\n", the @@ -747,7 +747,7 @@ void nvim_out_write(String str) void nvim_err_write(String str) FUNC_API_SINCE(1) { - write_msg(str, true); + write_msg(str, true, false); } /// Writes a message to the Vim error buffer. Appends "\n", so the buffer is @@ -758,8 +758,7 @@ void nvim_err_write(String str) void nvim_err_writeln(String str) FUNC_API_SINCE(1) { - nvim_err_write(str); - nvim_err_write((String) { .data = "\n", .size = 1 }); + write_msg(str, true, true); } /// Gets the current list of buffer handles @@ -1672,23 +1671,24 @@ theend: /// /// @param message Message to write /// @param to_err true: message is an error (uses `emsg` instead of `msg`) -static void write_msg(String message, bool to_err) +/// @param writeln Append a trailing newline +static void write_msg(String message, bool to_err, bool writeln) { static StringBuilder out_line_buf = KV_INITIAL_VALUE; static StringBuilder err_line_buf = KV_INITIAL_VALUE; -#define PUSH_CHAR(i, line_buf, msg) \ +#define PUSH_CHAR(c, line_buf, msg) \ if (kv_max(line_buf) == 0) { \ kv_resize(line_buf, LINE_BUFFER_MIN_SIZE); \ } \ - if (message.data[i] == NL) { \ + if (c == NL) { \ kv_push(line_buf, NUL); \ msg(line_buf.items); \ kv_drop(line_buf, kv_size(line_buf)); \ kv_resize(line_buf, LINE_BUFFER_MIN_SIZE); \ - continue; \ - } \ - kv_push(line_buf, message.data[i]); + } else { \ + kv_push(line_buf, c); \ + } no_wait_return++; for (uint32_t i = 0; i < message.size; i++) { @@ -1696,9 +1696,16 @@ static void write_msg(String message, bool to_err) break; } if (to_err) { - PUSH_CHAR(i, err_line_buf, emsg); + PUSH_CHAR(message.data[i], err_line_buf, emsg); + } else { + PUSH_CHAR(message.data[i], out_line_buf, msg); + } + } + if (writeln) { + if (to_err) { + PUSH_CHAR(NL, err_line_buf, emsg); } else { - PUSH_CHAR(i, out_line_buf, msg); + PUSH_CHAR(NL, out_line_buf, msg); } } no_wait_return--; -- cgit From f0ac91c58b42ed4f38dea7352d89fd39a88142f4 Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Sat, 1 Apr 2023 14:58:52 +0200 Subject: feat(api): evaluate 'statuscolumn' with nvim_eval_statusline() --- src/nvim/api/vim.c | 59 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 9 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 343c3b6e40..383953a676 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -25,6 +25,7 @@ #include "nvim/buffer.h" #include "nvim/channel.h" #include "nvim/context.h" +#include "nvim/cursor.h" #include "nvim/drawscreen.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" @@ -59,6 +60,7 @@ #include "nvim/popupmenu.h" #include "nvim/pos.h" #include "nvim/runtime.h" +#include "nvim/sign.h" #include "nvim/state.h" #include "nvim/statusline.h" #include "nvim/strings.h" @@ -2054,6 +2056,7 @@ Array nvim_get_mark(String name, Dictionary opts, Error *err) /// - use_winbar: (boolean) Evaluate winbar instead of statusline. /// - use_tabline: (boolean) Evaluate tabline instead of statusline. When true, {winid} /// is ignored. Mutually exclusive with {use_winbar}. +/// - use_statuscol: (boolean) Evaluate statuscolumn instead of statusline. /// /// @param[out] err Error details, if any. /// @return Dictionary containing statusline information, with these keys: @@ -2071,9 +2074,11 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * int maxwidth; int fillchar = 0; + int use_bools = 0; Window window = 0; bool use_winbar = false; bool use_tabline = false; + bool use_statuscol = false; bool highlights = false; if (str.size < 2 || memcmp(str.data, "%!", 2) != 0) { @@ -2111,23 +2116,34 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * } if (HAS_KEY(opts->use_winbar)) { use_winbar = api_object_to_bool(opts->use_winbar, "use_winbar", false, err); - + use_bools++; if (ERROR_SET(err)) { return result; } } if (HAS_KEY(opts->use_tabline)) { use_tabline = api_object_to_bool(opts->use_tabline, "use_tabline", false, err); - + use_bools++; if (ERROR_SET(err)) { return result; } } - VALIDATE(!(use_winbar && use_tabline), "%s", "Cannot use both 'use_winbar' and 'use_tabline'", { + if (HAS_KEY(opts->use_statuscol)) { + use_statuscol = api_object_to_bool(opts->use_statuscol, "use_statuscol", false, err); + use_bools++; + if (ERROR_SET(err)) { + return result; + } + } + VALIDATE(use_bools <= 1, "%s", + "Can only use one of 'use_winbar', 'use_tabline' and 'use_statuscol'", { return result; }); win_T *wp, *ewp; + int stc_hl_id = 0; + statuscol_T statuscol = { 0 }; + SignTextAttrs sattrs[SIGN_SHOW_MAX] = { 0 }; if (use_tabline) { wp = NULL; @@ -2149,6 +2165,31 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * fillchar = fillchar_status(&attr, wp); } } + if (use_statuscol) { + HlPriId line = { 0 }; + HlPriId cul = { 0 }; + HlPriId num = { 0 }; + linenr_T lnum = (linenr_T)get_vim_var_nr(VV_LNUM); + int num_signs = buf_get_signattrs(wp->w_buffer, lnum, sattrs, &num, &line, &cul); + decor_redraw_signs(wp->w_buffer, lnum - 1, &num_signs, sattrs, &num, &line, &cul); + + statuscol.sattrs = sattrs; + statuscol.foldinfo = fold_info(wp, lnum); + statuscol.use_cul = wp->w_p_cul && lnum == wp->w_cursorline + && (wp->w_p_culopt_flags & CULOPT_NBR); + statuscol.sign_cul_id = statuscol.use_cul ? cul.hl_id : 0; + if (num.hl_id) { + stc_hl_id = num.hl_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_RELNUM, labs(get_cursor_rel_lnum(wp, lnum))); + set_vim_var_nr(VV_VIRTNUM, 0); + } } if (HAS_KEY(opts->maxwidth)) { @@ -2158,12 +2199,12 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * maxwidth = (int)opts->maxwidth.data.integer; } else { - maxwidth = (use_tabline || (!use_winbar && global_stl_height() > 0)) ? Columns : wp->w_width; + maxwidth = use_statuscol ? win_col_off(wp) + : (use_tabline || (!use_winbar && global_stl_height() > 0)) ? Columns : wp->w_width; } char buf[MAXPATHL]; stl_hlrec_t *hltab; - stl_hlrec_t **hltab_ptr = highlights ? &hltab : NULL; // Temporarily reset 'cursorbind' to prevent side effects from moving the cursor away and back. int p_crb_save = ewp->w_p_crb; @@ -2177,9 +2218,9 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * 0, fillchar, maxwidth, - hltab_ptr, + highlights ? &hltab : NULL, NULL, - NULL); + use_statuscol ? &statuscol : NULL); PUT(result, "width", INTEGER_OBJ(width)); @@ -2195,7 +2236,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * // 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(wp, use_winbar); + grpname = get_default_stl_hl(wp, use_winbar, stc_hl_id); PUT(hl_info, "start", INTEGER_OBJ(0)); PUT(hl_info, "group", CSTR_TO_OBJ(grpname)); @@ -2209,7 +2250,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * PUT(hl_info, "start", INTEGER_OBJ(sp->start - buf)); if (sp->userhl == 0) { - grpname = get_default_stl_hl(wp, use_winbar); + grpname = get_default_stl_hl(wp, use_winbar, stc_hl_id); } else if (sp->userhl < 0) { grpname = syn_id2name(-sp->userhl); } else { -- cgit From 25dfed6e0148771cdb659df8c616df3860583c47 Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Thu, 6 Apr 2023 03:33:57 +0200 Subject: feat(api): set statuscolumn line number in nvim_eval_statusline() Having the user set `v:lnum` before calling `nvim_eval_statusline()` is unnecesarily fragile. Redraws inbetween setting `v:lnum` and the `nvim_eval_statusline()` call will overwrite `v:lnum`. --- src/nvim/api/vim.c | 74 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 32 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 383953a676..b62521290d 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2056,7 +2056,7 @@ Array nvim_get_mark(String name, Dictionary opts, Error *err) /// - use_winbar: (boolean) Evaluate winbar instead of statusline. /// - use_tabline: (boolean) Evaluate tabline instead of statusline. When true, {winid} /// is ignored. Mutually exclusive with {use_winbar}. -/// - use_statuscol: (boolean) Evaluate statuscolumn instead of statusline. +/// - use_statuscol_lnum: (number) Evaluate statuscolumn for this line number instead of statusline. /// /// @param[out] err Error details, if any. /// @return Dictionary containing statusline information, with these keys: @@ -2075,10 +2075,10 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * int maxwidth; int fillchar = 0; int use_bools = 0; + int statuscol_lnum = 0; Window window = 0; bool use_winbar = false; bool use_tabline = false; - bool use_statuscol = false; bool highlights = false; if (str.size < 2 || memcmp(str.data, "%!", 2) != 0) { @@ -2116,47 +2116,48 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * } if (HAS_KEY(opts->use_winbar)) { use_winbar = api_object_to_bool(opts->use_winbar, "use_winbar", false, err); - use_bools++; if (ERROR_SET(err)) { return result; } + use_bools++; } if (HAS_KEY(opts->use_tabline)) { use_tabline = api_object_to_bool(opts->use_tabline, "use_tabline", false, err); - use_bools++; if (ERROR_SET(err)) { return result; } - } - if (HAS_KEY(opts->use_statuscol)) { - use_statuscol = api_object_to_bool(opts->use_statuscol, "use_statuscol", false, err); use_bools++; - if (ERROR_SET(err)) { + } + + win_T *wp = use_tabline ? curwin : find_window_by_handle(window, err); + if (wp == NULL) { + api_set_error(err, kErrorTypeException, "unknown winid %d", window); + return result; + } + + if (HAS_KEY(opts->use_statuscol_lnum)) { + VALIDATE_T("use_statuscol_lnum", kObjectTypeInteger, opts->use_statuscol_lnum.type, { return result; - } + }); + statuscol_lnum = (int)opts->use_statuscol_lnum.data.integer; + VALIDATE_RANGE(statuscol_lnum > 0 && statuscol_lnum <= wp->w_buffer->b_ml.ml_line_count, + "use_statuscol_lnum", { + return result; + }); + use_bools++; } VALIDATE(use_bools <= 1, "%s", - "Can only use one of 'use_winbar', 'use_tabline' and 'use_statuscol'", { + "Can only use one of 'use_winbar', 'use_tabline' and 'use_statuscol_lnum'", { return result; }); - win_T *wp, *ewp; int stc_hl_id = 0; statuscol_T statuscol = { 0 }; SignTextAttrs sattrs[SIGN_SHOW_MAX] = { 0 }; if (use_tabline) { - wp = NULL; - ewp = curwin; fillchar = ' '; } else { - wp = find_window_by_handle(window, err); - if (wp == NULL) { - api_set_error(err, kErrorTypeException, "unknown winid %d", window); - return result; - } - ewp = wp; - if (fillchar == 0) { if (use_winbar) { fillchar = wp->w_p_fcs_chars.wbr; @@ -2165,18 +2166,25 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * fillchar = fillchar_status(&attr, wp); } } - if (use_statuscol) { + if (statuscol_lnum) { HlPriId line = { 0 }; HlPriId cul = { 0 }; HlPriId num = { 0 }; - linenr_T lnum = (linenr_T)get_vim_var_nr(VV_LNUM); + linenr_T lnum = statuscol_lnum; int num_signs = buf_get_signattrs(wp->w_buffer, lnum, sattrs, &num, &line, &cul); decor_redraw_signs(wp->w_buffer, lnum - 1, &num_signs, sattrs, &num, &line, &cul); statuscol.sattrs = sattrs; statuscol.foldinfo = fold_info(wp, lnum); - statuscol.use_cul = wp->w_p_cul && lnum == wp->w_cursorline - && (wp->w_p_culopt_flags & CULOPT_NBR); + 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.hl_id : 0; if (num.hl_id) { stc_hl_id = num.hl_id; @@ -2187,6 +2195,8 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * } 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); } @@ -2199,7 +2209,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * maxwidth = (int)opts->maxwidth.data.integer; } else { - maxwidth = use_statuscol ? win_col_off(wp) + maxwidth = statuscol_lnum ? win_col_off(wp) : (use_tabline || (!use_winbar && global_stl_height() > 0)) ? Columns : wp->w_width; } @@ -2207,10 +2217,10 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * stl_hlrec_t *hltab; // Temporarily reset 'cursorbind' to prevent side effects from moving the cursor away and back. - int p_crb_save = ewp->w_p_crb; - ewp->w_p_crb = false; + int p_crb_save = wp->w_p_crb; + wp->w_p_crb = false; - int width = build_stl_str_hl(ewp, + int width = build_stl_str_hl(wp, buf, sizeof(buf), str.data, @@ -2220,12 +2230,12 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * maxwidth, highlights ? &hltab : NULL, NULL, - use_statuscol ? &statuscol : NULL); + statuscol_lnum ? &statuscol : NULL); PUT(result, "width", INTEGER_OBJ(width)); // Restore original value of 'cursorbind' - ewp->w_p_crb = p_crb_save; + wp->w_p_crb = p_crb_save; if (highlights) { Array hl_values = ARRAY_DICT_INIT; @@ -2236,7 +2246,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * // 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(wp, use_winbar, stc_hl_id); + grpname = get_default_stl_hl(use_tabline ? NULL : wp, use_winbar, stc_hl_id); PUT(hl_info, "start", INTEGER_OBJ(0)); PUT(hl_info, "group", CSTR_TO_OBJ(grpname)); @@ -2250,7 +2260,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * PUT(hl_info, "start", INTEGER_OBJ(sp->start - buf)); if (sp->userhl == 0) { - grpname = get_default_stl_hl(wp, use_winbar, stc_hl_id); + grpname = get_default_stl_hl(use_tabline ? NULL : wp, use_winbar, stc_hl_id); } else if (sp->userhl < 0) { grpname = syn_id2name(-sp->userhl); } else { -- cgit From d3ea9a04bc737d4b52cd7abf69b75c5563b39741 Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Sun, 9 Apr 2023 00:41:50 +0200 Subject: fix(api): update "w_scwidth" in nvim_eval_statusline() Problem: `w_scwidth` may be outdated in `nvim_eval_status()`, causing `build_stl_str_hl()` to return an empty `%s` sign segment. Solution: Update `w_scwidth` for `'statuscolumn'` evaluation. --- 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 b62521290d..c8bb22b33c 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2173,6 +2173,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * linenr_T lnum = statuscol_lnum; int num_signs = buf_get_signattrs(wp->w_buffer, lnum, sattrs, &num, &line, &cul); decor_redraw_signs(wp->w_buffer, lnum - 1, &num_signs, sattrs, &num, &line, &cul); + wp->w_scwidth = win_signcol_count(wp); statuscol.sattrs = sattrs; statuscol.foldinfo = fold_info(wp, lnum); -- cgit From ef7ae66eef4e36e15b5248b926b4b020387d8101 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 21 Apr 2023 10:55:36 +0200 Subject: fix(api): avoid integer truncation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gsrc/nvim/api/vim.c: In function ‘nvim_eval_statusline’: gsrc/nvim/api/vim.c:2268:55: warning: ‘%d’ directive output may be truncated writing between 1 and 10 bytes into a region of size 2 [-Wformat-tru ncation=] 2268 | snprintf(user_group, sizeof(user_group), "User%d", sp->userhl); | ^~ gsrc/nvim/api/vim.c:2268:50: note: directive argument in the range [1, 2147483647] 2268 | snprintf(user_group, sizeof(user_group), "User%d", sp->userhl); | ^~~~~~~~ In file included from /usr/include/stdio.h:906, from gsrc/nvim/api/vim.c:9: In function ‘snprintf’, inlined from ‘nvim_eval_statusline’ at gsrc/nvim/api/vim.c:2268:9: /usr/include/bits/stdio2.h:54:10: note: ‘__builtin___snprintf_chk’ output between 6 and 15 bytes into a destination of size 6 54 | return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 55 | __glibc_objsize (__s), __fmt, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 56 | __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~ --- 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 c8bb22b33c..d47f47e638 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2241,7 +2241,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * if (highlights) { Array hl_values = ARRAY_DICT_INIT; const char *grpname; - char user_group[6]; + 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 -- cgit From cfd4fdfea4d0e68ea50ad412b88b5289ded6fd6f Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Tue, 23 May 2023 14:25:10 +0600 Subject: refactor(api): new helper macros Adds new API helper macros `CSTR_AS_OBJ()`, `STATIC_CSTR_AS_OBJ()`, and `STATIC_CSTR_TO_OBJ()`, which cleans up a lot of the current code. These macros will also be used extensively in the upcoming option refactor PRs because then API Objects will be used to get/set options. This PR also modifies pre-existing code to use old API helper macros like `CSTR_TO_OBJ()` to make them cleaner. --- 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 d47f47e638..36163859eb 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -531,7 +531,7 @@ static void find_runtime_cb(char *fname, void *cookie) { Array *rv = (Array *)cookie; if (fname != NULL) { - ADD(*rv, STRING_OBJ(cstr_to_string(fname))); + ADD(*rv, CSTR_TO_OBJ(fname)); } } @@ -1383,7 +1383,7 @@ Dictionary nvim_get_mode(void) get_mode(modestr); bool blocked = input_blocking(); - PUT(rv, "mode", STRING_OBJ(cstr_to_string(modestr))); + PUT(rv, "mode", CSTR_TO_OBJ(modestr)); PUT(rv, "blocking", BOOLEAN_OBJ(blocked)); return rv; @@ -1926,7 +1926,7 @@ Array nvim__inspect_cell(Integer grid, Integer row, Integer col, Arena *arena, E } ret = arena_array(arena, 3); size_t off = g->line_offset[(size_t)row] + (size_t)col; - ADD_C(ret, STRING_OBJ(cstr_as_string((char *)g->chars[off]))); + ADD_C(ret, CSTR_AS_OBJ((char *)g->chars[off])); int attr = g->attrs[off]; ADD_C(ret, DICTIONARY_OBJ(hl_get_attr_by_id(attr, true, arena, err))); // will not work first time @@ -2035,7 +2035,7 @@ Array nvim_get_mark(String name, Dictionary opts, Error *err) ADD(rv, INTEGER_OBJ(row)); ADD(rv, INTEGER_OBJ(col)); ADD(rv, INTEGER_OBJ(bufnr)); - ADD(rv, STRING_OBJ(cstr_to_string(filename))); + ADD(rv, CSTR_TO_OBJ(filename)); if (allocated) { xfree(filename); -- cgit From 0e01e815520ead73b13277b68306cf03a2196ca5 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 3 Jun 2023 18:44:08 +0800 Subject: fix(folds): allow overlay virtual text on folded line (#23892) Also always check for fi_level before fi_lines. --- 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 36163859eb..4722195fe4 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2180,7 +2180,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * 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) { + 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); -- cgit From b3d5138fd0066fda26ef7724a542ae45eb42fc84 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Wed, 7 Jun 2023 06:05:16 +0600 Subject: refactor(options): remove `getoption_T` and introduce `OptVal` (#23850) Removes the `getoption_T` struct and also introduces the `OptVal` struct to unify the methods of getting/setting different option value types. This is the first of many PRs to reduce code duplication in the Vim option code as well as to make options easier to maintain. It also increases the flexibility and extensibility of options. Which opens the door for things like Array and Dictionary options. --- 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 4722195fe4..d93af6a2a4 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -910,10 +910,10 @@ Buffer nvim_create_buf(Boolean listed, Boolean scratch, Error *err) if (scratch) { aco_save_T aco; aucmd_prepbuf(&aco, buf); - set_option_value("bufhidden", 0L, "hide", OPT_LOCAL); - set_option_value("buftype", 0L, "nofile", OPT_LOCAL); - set_option_value("swapfile", 0L, NULL, OPT_LOCAL); - set_option_value("modeline", 0L, NULL, OPT_LOCAL); // 'nomodeline' + set_option_value("bufhidden", STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL); + set_option_value("buftype", STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL); + set_option_value("swapfile", BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value("modeline", BOOLEAN_OPTVAL(false), OPT_LOCAL); // 'nomodeline' aucmd_restbuf(&aco); } return buf->b_fnum; -- cgit From 42bbc4fabcf948ac6b8798b8992bcba1fc1d3e59 Mon Sep 17 00:00:00 2001 From: bfredl Date: Sun, 28 May 2023 12:09:52 +0200 Subject: feat(api): support abbreviations in nvim_set_keymap closes #19198 --- 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 d93af6a2a4..4bbbf644a8 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1420,6 +1420,7 @@ ArrayOf(Dictionary) nvim_get_keymap(String mode) /// @param channel_id /// @param mode Mode short-name (map command prefix: "n", "i", "v", "x", …) /// or "!" for |:map!|, or empty string for |:map|. +/// "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 ||, -- cgit From b6d2f49b4536f89cf2428d1f214468aa5fb21788 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 10 Jun 2023 10:44:31 +0800 Subject: test: more tests for nvim_{set,del}_keymap with abbreviation (#23970) --- 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 4bbbf644a8..62b4fd9764 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1420,7 +1420,7 @@ ArrayOf(Dictionary) nvim_get_keymap(String mode) /// @param channel_id /// @param mode Mode short-name (map command prefix: "n", "i", "v", "x", …) /// or "!" for |:map!|, or empty string for |:map|. -/// "ia", "ca" or "!a" for abbreviation in insert mode, cmdline mode, or both, respectively +/// "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 ||, -- cgit From 0eb02ea90a5a7c2e35bfcf99b701a28ff2901b4b Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 12 Jun 2023 20:08:08 +0800 Subject: docs: various clarifications (#23999) Close #18907 Close #20314 Close #23749 --- 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 62b4fd9764..368bb866d7 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1427,7 +1427,7 @@ ArrayOf(Dictionary) nvim_get_keymap(String mode) /// values are booleans (default false). Also: /// - "noremap" non-recursive mapping |:noremap| /// - "desc" human-readable description. -/// - "callback" Lua function called when the mapping is executed. +/// - "callback" Lua function called in place of {rhs}. /// - "replace_keycodes" (boolean) When "expr" is true, replace keycodes in the /// resulting string (see |nvim_replace_termcodes()|). Returning nil from the Lua /// "callback" is equivalent to returning an empty string. -- cgit From 0d149bb186390c3e40fb693050d0c30cddc8c7c5 Mon Sep 17 00:00:00 2001 From: bfredl Date: Mon, 19 Jun 2023 14:40:53 +0200 Subject: fix(docs): the runtimepath is not the runtime path --- 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 368bb866d7..a6f98a1915 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -487,7 +487,7 @@ Integer nvim_strwidth(String text, Error *err) return (Integer)mb_string2cells(text.data); } -/// Gets the paths contained in 'runtimepath'. +/// Gets the paths contained in |runtime-search-path|. /// /// @return List of paths ArrayOf(String) nvim_list_runtime_paths(Error *err) -- cgit From 4e6356559c8cd44dbcaa765d1f39e176064526ec Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 22 Jun 2023 03:44:51 -0700 Subject: test: spellcheck :help (vimdoc) files #24109 Enforce consistent terminology (defined in `gen_help_html.lua:spell_dict`) for common misspellings. This does not spellcheck English in general (perhaps a future TODO, though it may be noisy). --- 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 a6f98a1915..9996dae247 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -544,7 +544,7 @@ String nvim__get_lib_dir(void) /// /// @param pat pattern of files to search for /// @param all whether to return all matches or only the first -/// @param opts is_lua: only search lua subdirs +/// @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) FUNC_API_SINCE(8) @@ -941,7 +941,7 @@ fail: /// /// @param buffer the buffer to use (expected to be empty) /// @param opts Optional parameters. -/// - on_input: lua callback for input sent, i e keypresses in terminal +/// - on_input: Lua callback for input sent, i e keypresses in terminal /// mode. Note: keypresses are sent raw as they would be to the pty /// master end. For instance, a carriage return is sent /// as a "\r", not as a "\n". |textlock| applies. It is possible @@ -1009,7 +1009,7 @@ static void term_write(char *buf, size_t size, void *data) // NOLINT(readabilit static void term_resize(uint16_t width, uint16_t height, void *data) { - // TODO(bfredl): lua callback + // TODO(bfredl): Lua callback } static void term_close(void *data) -- cgit From 92760a7f42a95bb252966c2a38423e5bc9d57cc7 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 4 Jul 2023 07:19:02 +0800 Subject: fix(api, lua): make blank lines in a message work properly (#24244) --- 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 9996dae247..8d34a34e8a 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1687,6 +1687,7 @@ static void write_msg(String message, bool to_err, bool writeln) if (c == NL) { \ kv_push(line_buf, NUL); \ msg(line_buf.items); \ + msg_didout = true; \ kv_drop(line_buf, kv_size(line_buf)); \ kv_resize(line_buf, LINE_BUFFER_MIN_SIZE); \ } else { \ -- cgit From 77118d0da8badc4135be430f4cbb15bc95bc760f Mon Sep 17 00:00:00 2001 From: Sean Dewar Date: Thu, 20 Apr 2023 21:17:25 +0100 Subject: fix(api): use text_locked() to check textlock Problem: some API functions that check textlock (usually those that can change curwin or curbuf) can break the cmdwin. Solution: make FUNC_API_CHECK_TEXTLOCK call text_locked() instead, which already checks for textlock, cmdwin and `` status. Add FUNC_API_TEXTLOCK_ALLOW_CMDWIN to allow such functions to be usable in the cmdwin if they can work properly there; the opt-in nature of this attribute should hopefully help mitigate future bugs. Also fix a regression in #22634 that made functions checking textlock usable in `` mappings, and rename FUNC_API_CHECK_TEXTLOCK to FUNC_API_TEXTLOCK. --- 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 8d34a34e8a..eacc833c58 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -612,7 +612,7 @@ String nvim_get_current_line(Error *err) /// @param[out] err Error details, if any void nvim_set_current_line(String line, Error *err) FUNC_API_SINCE(1) - FUNC_API_CHECK_TEXTLOCK + FUNC_API_TEXTLOCK_ALLOW_CMDWIN { buffer_set_line(curbuf->handle, curwin->w_cursor.lnum - 1, line, err); } @@ -622,7 +622,7 @@ void nvim_set_current_line(String line, Error *err) /// @param[out] err Error details, if any void nvim_del_current_line(Error *err) FUNC_API_SINCE(1) - FUNC_API_CHECK_TEXTLOCK + FUNC_API_TEXTLOCK_ALLOW_CMDWIN { buffer_del_line(curbuf->handle, curwin->w_cursor.lnum - 1, err); } @@ -803,7 +803,7 @@ Buffer nvim_get_current_buf(void) /// @param[out] err Error details, if any void nvim_set_current_buf(Buffer buffer, Error *err) FUNC_API_SINCE(1) - FUNC_API_CHECK_TEXTLOCK + FUNC_API_TEXTLOCK { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -858,7 +858,7 @@ Window nvim_get_current_win(void) /// @param[out] err Error details, if any void nvim_set_current_win(Window window, Error *err) FUNC_API_SINCE(1) - FUNC_API_CHECK_TEXTLOCK + FUNC_API_TEXTLOCK { win_T *win = find_window_by_handle(window, err); @@ -1084,7 +1084,7 @@ Tabpage nvim_get_current_tabpage(void) /// @param[out] err Error details, if any void nvim_set_current_tabpage(Tabpage tabpage, Error *err) FUNC_API_SINCE(1) - FUNC_API_CHECK_TEXTLOCK + FUNC_API_TEXTLOCK { tabpage_T *tp = find_tab_by_handle(tabpage, err); @@ -1126,7 +1126,7 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err) /// - false: Client must cancel the paste. Boolean nvim_paste(String data, Boolean crlf, Integer phase, Error *err) FUNC_API_SINCE(6) - FUNC_API_CHECK_TEXTLOCK + FUNC_API_TEXTLOCK_ALLOW_CMDWIN { static bool draining = false; bool cancel = false; @@ -1197,7 +1197,7 @@ theend: /// @param[out] err Error details, if any void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow, Error *err) FUNC_API_SINCE(6) - FUNC_API_CHECK_TEXTLOCK + FUNC_API_TEXTLOCK_ALLOW_CMDWIN { yankreg_T *reg = xcalloc(1, sizeof(yankreg_T)); VALIDATE_S((prepare_yankreg_from_object(reg, type, lines.size)), "type", type.data, { -- cgit From aa4e47f704c53ab1d825260d2bf34e2872e3ca89 Mon Sep 17 00:00:00 2001 From: Sean Dewar Date: Fri, 23 Jun 2023 22:32:07 +0100 Subject: fix(api): disallow some more functions during textlock Problem: nvim_buf_set_text(), nvim_open_term() and termopen() all change buffer text, which is forbidden during textlock. Additionally, nvim_open_term() and termopen() may be used to convert the cmdwin buffer into a terminal buffer, which is weird. Solution: Allow nvim_buf_set_text() and nvim_open_term() in the cmdwin, but disallow nvim_open_term() from converting the cmdwin buffer into a terminal buffer. termopen() is not allowed in the cmdwin (as it always operates on curbuf), so just check text_locked(). Also happens to improve the error in #21055: nvim_buf_set_text() was callable during textlock, but happened to check textlock indirectly via u_save(); however, this caused the error to be overwritten by an unhelpful "Failed to save undo information" message when msg_list == NULL (e.g: an `` mapping invoked outside of do_cmdline()). --- 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 eacc833c58..8c40e5ccd7 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -951,12 +951,18 @@ fail: /// @return Channel id, or 0 on error Integer nvim_open_term(Buffer buffer, DictionaryOf(LuaRef) opts, Error *err) FUNC_API_SINCE(7) + FUNC_API_TEXTLOCK_ALLOW_CMDWIN { buf_T *buf = find_buffer_by_handle(buffer, err); if (!buf) { return 0; } + if (cmdwin_type != 0 && buf == curbuf) { + api_set_error(err, kErrorTypeException, "%s", _(e_cmdwin)); + return 0; + } + LuaRef cb = LUA_NOREF; for (size_t i = 0; i < opts.size; i++) { String k = opts.items[i].key; -- cgit From 00d2f4b96eb9c8dcb6b9f67e256bb7faa19354db Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 4 Jul 2023 19:22:04 +0200 Subject: docs: MAINTAIN.md, nvim_get_mark --- src/nvim/api/vim.c | 7 ++++--- 1 file changed, 4 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 8c40e5ccd7..3ffaaab780 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1980,12 +1980,13 @@ Boolean nvim_del_mark(String name, Error *err) return res; } -/// Return a tuple (row, col, buffer, buffername) representing the position of -/// the uppercase/file named mark. See |mark-motions|. +/// Returns a `(row, col, buffer, buffername)` tuple representing the position +/// of the uppercase/file named mark. "End of line" column position is returned +/// as |v:maxcol| (big number). See |mark-motions|. /// /// Marks are (1,0)-indexed. |api-indexing| /// -/// @note fails with error if a lowercase or buffer local named mark is used. +/// @note Lowercase name (or other buffer-local mark) is an error. /// @param name Mark name /// @param opts Optional parameters. Reserved for future use. /// @return 4-tuple (row, col, buffer, buffername), (0, 0, 0, '') if the mark is -- cgit From 3a721820c39b7524a2e6d6a73774498104a38962 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 6 Jul 2023 15:32:39 +0200 Subject: docs: "Return (multiple)" heading Problem: Lua functions that return multiple results are declared by using multiple `@return` docstring directives. But the generated docs don't make it obvious what this represents. Solution: - Generate a "Return (multiple)" heading for multiple-value functions. - Fix `@note` directives randomly placed after `@return`. --- 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 3ffaaab780..13021f9c57 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -87,6 +87,9 @@ Integer nvim_get_hl_id_by_name(String name) /// Gets all or specific highlight groups in a namespace. /// +/// @note When the `link` attribute is defined in the highlight definition +/// map, other attributes will not be taking effect (see |:hi-link|). +/// /// @param ns_id Get highlight groups for namespace ns_id |nvim_get_namespaces()|. /// Use 0 to get global highlight groups |:highlight|. /// @param opts Options dict: @@ -97,9 +100,6 @@ Integer nvim_get_hl_id_by_name(String name) /// @param[out] err Error details, if any. /// @return Highlight groups as a map from group name to a highlight definition map as in |nvim_set_hl()|, /// or only a single highlight definition map if requested by name or id. -/// -/// @note When the `link` attribute is defined in the highlight definition -/// map, other attributes will not be taking effect (see |:hi-link|). Dictionary nvim_get_hl(Integer ns_id, Dict(get_highlight) *opts, Arena *arena, Error *err) FUNC_API_SINCE(11) { -- cgit From d2e44da516816e2616b531886eb9ba7f4c271fb4 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 6 Jul 2023 22:47:27 +0200 Subject: docs: gather @notes items into one section related: 21eacbfef399 --- 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 13021f9c57..c15ec4ce53 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1958,7 +1958,7 @@ Object nvim__unpack(String str, Error *err) /// Deletes an uppercase/file named mark. See |mark-motions|. /// -/// @note fails with error if a lowercase or buffer local named mark is used. +/// @note Lowercase name (or other buffer-local mark) is an error. /// @param name Mark name /// @return true if the mark was deleted, else false. /// @see |nvim_buf_del_mark()| -- cgit From 516b173780e39de3ce1e4525f0a8f0ff250c992b Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Thu, 13 Jul 2023 10:17:19 +0100 Subject: perf(rtp): reduce rtp scans (#24191) * perf(rtp): reduce rtp scans Problem: Scanning the filesystem is expensive and particularly affects startuptime. Solution: Reduce the amount of redundant directory scans by relying less on glob patterns and handle vim and lua sourcing lower down. --- src/nvim/api/vim.c | 11 ++++++++--- 1 file changed, 8 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 c15ec4ce53..b1e472aa8c 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -527,12 +527,17 @@ ArrayOf(String) nvim_get_runtime_file(String name, Boolean all, Error *err) return rv; } -static void find_runtime_cb(char *fname, void *cookie) +static bool find_runtime_cb(int num_fnames, char **fnames, bool all, void *cookie) { Array *rv = (Array *)cookie; - if (fname != NULL) { - ADD(*rv, CSTR_TO_OBJ(fname)); + for (int i = 0; i < num_fnames; i++) { + ADD(*rv, CSTR_TO_OBJ(fnames[i])); + if (!all) { + return true; + } } + + return num_fnames > 0; } String nvim__get_lib_dir(void) -- cgit From a8cfdf43bc6226e32679ec59769ea3e48ca26193 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 23 Jul 2023 07:16:41 +0800 Subject: fix(events): trigger VimResume on next UI request (#24426) --- src/nvim/api/vim.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index b1e472aa8c..8738b3e38e 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -305,6 +305,7 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_ks) Integer nvim_input(String keys) FUNC_API_SINCE(1) FUNC_API_FAST { + may_trigger_vim_suspend_resume(false); return (Integer)input_enqueue(keys); } @@ -334,6 +335,8 @@ void nvim_input_mouse(String button, String action, String modifier, Integer gri Integer col, Error *err) FUNC_API_SINCE(6) FUNC_API_FAST { + may_trigger_vim_suspend_resume(false); + if (button.data == NULL || action.data == NULL) { goto error; } -- cgit From 6b4970f6e0ac36021b2a8bd0533f5078040d31f7 Mon Sep 17 00:00:00 2001 From: Sean Dewar Date: Sun, 23 Jul 2023 19:50:20 +0100 Subject: feat(api): allow open_win/win_set_buf in the cmdwin in some cases Problem: As discussed on Matrix, there was some interest in having `nvim_open_win` again be able to open floats in the cmdwin (e.g: displaying a hover doc related to what's in the cmdwin). After #23228, this was disallowed. Solution: Allow `nvim_open_win` in the cmdwin as long as `!enter` and `buffer != curbuf` (the former can cause all sorts of issues, and the latter can crash Nvim after closing cmdwin). Also allow `nvim_win_set_buf` in a similar fashion. Note that we're not *entirely* sure if this is 100% safe (cmdwin is a global-state-using-main-loop-calling beast), but this seems to work OK..? Also: - Check the buffer argument of `nvim_open_win` earlier, and abort if it's invalid (it used to still open a window in this case). - Untranslate `e_cmdwin` errors in the API (other errors in the API are not translated: although not detailed in the API contract yet, errors are supposed to be stable). --- 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 8738b3e38e..b4a6fa718b 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -967,7 +967,7 @@ Integer nvim_open_term(Buffer buffer, DictionaryOf(LuaRef) opts, Error *err) } if (cmdwin_type != 0 && buf == curbuf) { - api_set_error(err, kErrorTypeException, "%s", _(e_cmdwin)); + api_set_error(err, kErrorTypeException, "%s", e_cmdwin); return 0; } -- cgit From 7bc93e0e2f246dd78026a3472d929a0fe450f70d Mon Sep 17 00:00:00 2001 From: bfredl Date: Tue, 1 Aug 2023 14:01:19 +0200 Subject: refactor(api): use typed keysets Initially this is just for geting rid of boilerplate, but eventually the types could get exposed as metadata --- src/nvim/api/vim.c | 99 +++++++++++++++--------------------------------------- 1 file changed, 28 insertions(+), 71 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index b4a6fa718b..22fe69e447 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -558,16 +558,15 @@ ArrayOf(String) nvim__get_runtime(Array pat, Boolean all, Dict(runtime) *opts, E FUNC_API_SINCE(8) FUNC_API_FAST { - bool is_lua = api_object_to_bool(opts->is_lua, "is_lua", false, err); - bool source = api_object_to_bool(opts->do_source, "do_source", false, err); - VALIDATE((!source || nlua_is_deferred_safe()), "%s", "'do_source' used in fast callback", {}); + VALIDATE((!opts->do_source || nlua_is_deferred_safe()), "%s", "'do_source' used in fast callback", + {}); if (ERROR_SET(err)) { return (Array)ARRAY_DICT_INIT; } - ArrayOf(String) res = runtime_get_named(is_lua, pat, all); + ArrayOf(String) res = runtime_get_named(opts->is_lua, pat, all); - if (source) { + 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); @@ -718,15 +717,13 @@ void nvim_echo(Array chunks, Boolean history, Dict(echo_opts) *opts, Error *err) goto error; } - bool verbose = api_object_to_bool(opts->verbose, "verbose", false, err); - - if (verbose) { + if (opts->verbose) { verbose_enter(); } msg_multiattr(hl_msg, history ? "echomsg" : "echo", history); - if (verbose) { + if (opts->verbose) { verbose_leave(); verbose_stop(); // flush now } @@ -1323,11 +1320,8 @@ Dictionary nvim_get_context(Dict(context) *opts, Error *err) FUNC_API_SINCE(6) { Array types = ARRAY_DICT_INIT; - if (HAS_KEY(opts->types)) { - VALIDATE_T("types", kObjectTypeArray, opts->types.type, { - return (Dictionary)ARRAY_DICT_INIT; - }); - types = opts->types.data.array; + if (HAS_KEY(opts, context, types)) { + types = opts->types; } int int_types = types.size > 0 ? 0 : kCtxAll; @@ -2091,12 +2085,8 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * int maxwidth; int fillchar = 0; - int use_bools = 0; int statuscol_lnum = 0; Window window = 0; - bool use_winbar = false; - bool use_tabline = false; - bool highlights = false; if (str.size < 2 || memcmp(str.data, "%!", 2) != 0) { const char *const errmsg = check_stl_option(str.data); @@ -2105,58 +2095,28 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * }); } - if (HAS_KEY(opts->winid)) { - VALIDATE_T("winid", kObjectTypeInteger, opts->winid.type, { - return result; - }); - - window = (Window)opts->winid.data.integer; + if (HAS_KEY(opts, eval_statusline, winid)) { + window = opts->winid; } - if (HAS_KEY(opts->fillchar)) { - VALIDATE_T("fillchar", kObjectTypeString, opts->fillchar.type, { - return result; - }); - VALIDATE_EXP((opts->fillchar.data.string.size != 0 - && ((size_t)utf_ptr2len(opts->fillchar.data.string.data) - == opts->fillchar.data.string.size)), + if (HAS_KEY(opts, eval_statusline, fillchar)) { + VALIDATE_EXP((*opts->fillchar.data != 0 + && ((size_t)utf_ptr2len(opts->fillchar.data) == opts->fillchar.size)), "fillchar", "single character", NULL, { return result; }); - fillchar = utf_ptr2char(opts->fillchar.data.string.data); + fillchar = utf_ptr2char(opts->fillchar.data); } - if (HAS_KEY(opts->highlights)) { - highlights = api_object_to_bool(opts->highlights, "highlights", false, err); - if (ERROR_SET(err)) { - return result; - } - } - if (HAS_KEY(opts->use_winbar)) { - use_winbar = api_object_to_bool(opts->use_winbar, "use_winbar", false, err); - if (ERROR_SET(err)) { - return result; - } - use_bools++; - } - if (HAS_KEY(opts->use_tabline)) { - use_tabline = api_object_to_bool(opts->use_tabline, "use_tabline", false, err); - if (ERROR_SET(err)) { - return result; - } - use_bools++; - } + int use_bools = (int)opts->use_winbar + (int)opts->use_tabline; - win_T *wp = use_tabline ? curwin : find_window_by_handle(window, err); + win_T *wp = opts->use_tabline ? curwin : find_window_by_handle(window, err); if (wp == NULL) { api_set_error(err, kErrorTypeException, "unknown winid %d", window); return result; } - if (HAS_KEY(opts->use_statuscol_lnum)) { - VALIDATE_T("use_statuscol_lnum", kObjectTypeInteger, opts->use_statuscol_lnum.type, { - return result; - }); - statuscol_lnum = (int)opts->use_statuscol_lnum.data.integer; + if (HAS_KEY(opts, eval_statusline, use_statuscol_lnum)) { + statuscol_lnum = (int)opts->use_statuscol_lnum; VALIDATE_RANGE(statuscol_lnum > 0 && statuscol_lnum <= wp->w_buffer->b_ml.ml_line_count, "use_statuscol_lnum", { return result; @@ -2172,11 +2132,11 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * statuscol_T statuscol = { 0 }; SignTextAttrs sattrs[SIGN_SHOW_MAX] = { 0 }; - if (use_tabline) { + if (opts->use_tabline) { fillchar = ' '; } else { if (fillchar == 0) { - if (use_winbar) { + if (opts->use_winbar) { fillchar = wp->w_p_fcs_chars.wbr; } else { int attr; @@ -2220,15 +2180,12 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * } } - if (HAS_KEY(opts->maxwidth)) { - VALIDATE_T("maxwidth", kObjectTypeInteger, opts->maxwidth.type, { - return result; - }); - - maxwidth = (int)opts->maxwidth.data.integer; + if (HAS_KEY(opts, eval_statusline, maxwidth)) { + maxwidth = (int)opts->maxwidth; } else { maxwidth = statuscol_lnum ? win_col_off(wp) - : (use_tabline || (!use_winbar && global_stl_height() > 0)) ? Columns : wp->w_width; + : (opts->use_tabline + || (!opts->use_winbar && global_stl_height() > 0)) ? Columns : wp->w_width; } char buf[MAXPATHL]; @@ -2246,7 +2203,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * 0, fillchar, maxwidth, - highlights ? &hltab : NULL, + opts->highlights ? &hltab : NULL, NULL, statuscol_lnum ? &statuscol : NULL); @@ -2255,7 +2212,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * // Restore original value of 'cursorbind' wp->w_p_crb = p_crb_save; - if (highlights) { + if (opts->highlights) { Array hl_values = ARRAY_DICT_INIT; const char *grpname; char user_group[15]; // strlen("User") + strlen("2147483647") + NUL @@ -2264,7 +2221,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * // 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(use_tabline ? NULL : wp, use_winbar, stc_hl_id); + 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)); @@ -2278,7 +2235,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * PUT(hl_info, "start", INTEGER_OBJ(sp->start - buf)); if (sp->userhl == 0) { - grpname = get_default_stl_hl(use_tabline ? NULL : wp, use_winbar, stc_hl_id); + 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 { -- cgit From 713311be62db5c5453bcd0a7f1dbed8d1d1add15 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 12 Aug 2023 06:08:07 +0800 Subject: vim-patch:9.0.1687: mapset() not properly handling script ID (#24666) Problem: mapset() not properly handling script ID Solution: replace_termcodes() may accept a script ID closes: vim/vim#12699 closes: vim/vim#12697 https://github.com/vim/vim/commit/7e0bae024d4c1673cff31763227ad52b936fa56f --- 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 22fe69e447..4179ae40b8 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -431,7 +431,7 @@ String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, Bool } char *ptr = NULL; - replace_termcodes(str.data, str.size, &ptr, flags, NULL, CPO_TO_CPO_FLAGS); + replace_termcodes(str.data, str.size, &ptr, 0, flags, NULL, CPO_TO_CPO_FLAGS); return cstr_as_string(ptr); } -- cgit From 008154954791001efcc46c28146e21403f3a698b Mon Sep 17 00:00:00 2001 From: bfredl Date: Mon, 21 Aug 2023 14:52:17 +0200 Subject: refactor(change): do API changes to buffer without curbuf switch Most of the messy things when changing a non-current buffer is not about the buffer, it is about windows. In particular, it is about `curwin`. When editing a non-current buffer which is displayed in some other window in the current tabpage, one such window will be "borrowed" as the curwin. But this means if two or more non-current windows displayed the buffers, one of them will be treated differenty. this is not desirable. In particular, with nvim_buf_set_text, cursor _column_ position was only corrected for one single window. Two new tests are added: the test with just one non-current window passes, but the one with two didn't. Two corresponding such tests were also added for nvim_buf_set_lines. This already worked correctly on master, but make sure this is well-tested for future refactors. Also, nvim_create_buf no longer invokes autocmds just because you happened to use `scratch=true`. No option value was changed, therefore OptionSet must not be fired. --- src/nvim/api/vim.c | 17 ++++++++++------- 1 file changed, 10 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 4179ae40b8..b278a21d8e 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -912,14 +912,17 @@ Buffer nvim_create_buf(Boolean listed, Boolean scratch, Error *err) goto fail; } + // Only strictly needed for scratch, but could just as well be consistent + // and do this now. buffer is created NOW, not when it latter first happen + // to reach a window or aucmd_prepbuf() .. + buf_copy_options(buf, BCO_ENTER | BCO_NOHELP); + if (scratch) { - aco_save_T aco; - aucmd_prepbuf(&aco, buf); - set_option_value("bufhidden", STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL); - set_option_value("buftype", STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL); - set_option_value("swapfile", BOOLEAN_OPTVAL(false), OPT_LOCAL); - set_option_value("modeline", BOOLEAN_OPTVAL(false), OPT_LOCAL); // 'nomodeline' - aucmd_restbuf(&aco); + 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); + 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; } return buf->b_fnum; -- cgit From b46e93c5fd2c73b99b618d4954ab8d1c71ad3fb0 Mon Sep 17 00:00:00 2001 From: Alisue Date: Mon, 7 Aug 2023 00:19:51 +0900 Subject: docs(msgpack_rpc): add "msgpack-rpc" client type --- src/nvim/api/vim.c | 5 ++++- 1 file changed, 4 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 4179ae40b8..16e6ab3fe0 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1497,7 +1497,10 @@ Array nvim_get_api_info(uint64_t channel_id, Arena *arena) /// - "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. -/// - "remote" remote client connected to Nvim. +/// - "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 +/// compliant protocol. /// - "ui" gui frontend /// - "embedder" application using Nvim as a component (for example, /// IDE/editor implementing a vim mode). -- cgit From 8afb3a49c0762eb60368aee0314e6de261daa6ef Mon Sep 17 00:00:00 2001 From: glepnir Date: Thu, 7 Sep 2023 18:42:38 +0800 Subject: fix(highlight): add create param in nvim_get_hl --- 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 411d63b921..da10ab5bd4 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -96,6 +96,7 @@ Integer nvim_get_hl_id_by_name(String name) /// - name: (string) Get a highlight definition by name. /// - id: (integer) Get a highlight definition by id. /// - link: (boolean, default true) Show linked group name instead of effective definition |:hi-link|. +/// - create: (boolean, default true) When highlight group doesn't exist create it. /// /// @param[out] err Error details, if any. /// @return Highlight groups as a map from group name to a highlight definition map as in |nvim_set_hl()|, -- cgit From 2e92065686f62851318150a315591c30b8306a4b Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Thu, 14 Sep 2023 08:23:01 -0500 Subject: docs: replace
 with ``` (#25136)

---
 src/nvim/api/vim.c | 32 ++++++++++++++++++--------------
 1 file changed, 18 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 da10ab5bd4..916409b973 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -212,10 +212,11 @@ void nvim_set_hl_ns_fast(Integer ns_id, Error *err)
 /// nvim_feedkeys().
 ///
 /// Example:
-/// 
vim
-///     :let key = nvim_replace_termcodes("", v:true, v:false, v:true)
-///     :call nvim_feedkeys(key, 'n', v:false)
-/// 
+/// +/// ```vim +/// :let key = nvim_replace_termcodes("", v:true, v:false, v:true) +/// :call nvim_feedkeys(key, 'n', v:false) +/// ``` /// /// @param keys to be typed /// @param mode behavior flags, see |feedkeys()| @@ -1280,10 +1281,11 @@ void nvim_unsubscribe(uint64_t channel_id, String event) /// "#rrggbb" hexadecimal string. /// /// Example: -///
vim
-///     :echo nvim_get_color_by_name("Pink")
-///     :echo nvim_get_color_by_name("#cbcbcb")
-/// 
+/// +/// ```vim +/// :echo nvim_get_color_by_name("Pink") +/// :echo nvim_get_color_by_name("#cbcbcb") +/// ``` /// /// @param name Color name or "#rrggbb" string /// @return 24-bit RGB value, or -1 for invalid argument. @@ -1420,14 +1422,16 @@ ArrayOf(Dictionary) nvim_get_keymap(String mode) /// Empty {rhs} is ||. |keycodes| are replaced as usual. /// /// Example: -///
vim
-///     call nvim_set_keymap('n', ' ', '', {'nowait': v:true})
-/// 
+/// +/// ```vim +/// call nvim_set_keymap('n', ' ', '', {'nowait': v:true}) +/// ``` /// /// is equivalent to: -///
vim
-///     nmap   
-/// 
+/// +/// ```vim +/// nmap +/// ``` /// /// @param channel_id /// @param mode Mode short-name (map command prefix: "n", "i", "v", "x", …) -- cgit From 8da986ea877b07a5eb117446f410f2a7fc8cd9cb Mon Sep 17 00:00:00 2001 From: bfredl Date: Wed, 13 Sep 2023 13:39:18 +0200 Subject: refactor(grid): change schar_T representation to be more compact Previously, a screen cell would occupy 28+4=32 bytes per cell as we always made space for up to MAX_MCO+1 codepoints in a cell. As an example, even a pretty modest 50*80 screen would consume 50*80*2*32 = 256000, i e a quarter megabyte With the factor of two due to the TUI side buffer, and even more when using msg_grid and/or ext_multigrid. This instead stores a 4-byte union of either: - a valid UTF-8 sequence up to 4 bytes - an escape char which is invalid UTF-8 (0xFF) plus a 24-bit index to a glyph cache This avoids allocating space for huge composed glyphs _upfront_, while still keeping rendering such glyphs reasonably fast (1 hash table lookup + one plain index lookup). If the same large glyphs are using repeatedly on the screen, this is still a net reduction of memory/cache consumption. The only case which really gets worse is if you blast the screen full with crazy emojis and zalgo text and even this case only leads to 4 extra bytes per char. When only <= 4-byte glyphs are used, plus the 4-byte attribute code, i e 8 bytes in total there is a factor of four reduction of memory use. Memory which will be quite hot in cache as the screen buffer is scanned over in win_line() buffer text drawing A slight complication is that the representation depends on host byte order. I've tested this manually by compling and running this in qemu-s390x and it works fine. We might add a qemu based solution to CI at some point. --- src/nvim/api/vim.c | 9 ++++++++- 1 file changed, 8 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 916409b973..0a94b8aafc 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1947,7 +1947,9 @@ Array nvim__inspect_cell(Integer grid, Integer row, Integer col, Arena *arena, E } ret = arena_array(arena, 3); size_t off = g->line_offset[(size_t)row] + (size_t)col; - ADD_C(ret, CSTR_AS_OBJ((char *)g->chars[off])); + char *sc_buf = arena_alloc(arena, MAX_SCHAR_SIZE, false); + schar_get(sc_buf, g->chars[off]); + ADD_C(ret, CSTR_AS_OBJ(sc_buf)); int attr = g->attrs[off]; ADD_C(ret, DICTIONARY_OBJ(hl_get_attr_by_id(attr, true, arena, err))); // will not work first time @@ -1963,6 +1965,11 @@ void nvim__screenshot(String path) ui_call_screenshot(path); } +void nvim__invalidate_glyph_cache(void) +{ + schar_cache_clear_force(); +} + Object nvim__unpack(String str, Error *err) FUNC_API_FAST { -- cgit From 1b55f51d0d8468ca357514a868ac8e188b0c8722 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 20 Sep 2023 04:15:23 -0700 Subject: docs: misc #24561 fix #24699 fix #25253 --- 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 0a94b8aafc..7a5c7cc181 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1441,7 +1441,7 @@ ArrayOf(Dictionary) nvim_get_keymap(String mode) /// @param rhs Right-hand-side |{rhs}| of the mapping. /// @param opts Optional parameters map: Accepts all |:map-arguments| as keys except ||, /// values are booleans (default false). Also: -/// - "noremap" non-recursive mapping |:noremap| +/// - "noremap" disables |recursive_mapping|, like |:noremap| /// - "desc" human-readable description. /// - "callback" Lua function called in place of {rhs}. /// - "replace_keycodes" (boolean) When "expr" is true, replace keycodes in the -- cgit From b3be7b741386bbbf076e87859cb1e3d990316f5c Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 25 Sep 2023 11:06:15 +0800 Subject: fix(api): handle NUL in nvim_err_write() and nvim_out_write() (#25354) --- src/nvim/api/vim.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 7a5c7cc181..78396edef5 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1709,6 +1709,8 @@ static void write_msg(String message, bool to_err, bool writeln) msg_didout = true; \ kv_drop(line_buf, kv_size(line_buf)); \ kv_resize(line_buf, LINE_BUFFER_MIN_SIZE); \ + } else if (c == NUL) { \ + kv_push(line_buf, NL); \ } else { \ kv_push(line_buf, c); \ } -- cgit From f8ea49cfe1f4f3ed30da160d346553f0949ec1de Mon Sep 17 00:00:00 2001 From: glepnir Date: Mon, 18 Sep 2023 14:50:27 +0800 Subject: fix(highlight): add force in nvim_set_hl --- 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 916409b973..9d08e9b6c7 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -151,6 +151,7 @@ Dictionary nvim_get_hl(Integer ns_id, Dict(get_highlight) *opts, Arena *arena, E /// - cterm: cterm attribute map, like |highlight-args|. If not set, /// cterm attributes will match those from the attribute map /// documented above. +/// - force: if true force update the highlight group when it exists. /// @param[out] err Error details, if any /// // TODO(bfredl): val should take update vs reset flag -- cgit From b85f1dafc7c0a19704135617454f1c66f41202c1 Mon Sep 17 00:00:00 2001 From: bfredl Date: Wed, 27 Sep 2023 22:21:17 +0200 Subject: refactor(messages): fold msg_attr into msg problem: there are too many different functions in message.c solution: fold some of the functions into themselves --- src/nvim/api/vim.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 00641c633d..c55f9592bf 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1699,21 +1699,26 @@ static void write_msg(String message, bool to_err, bool writeln) { static StringBuilder out_line_buf = KV_INITIAL_VALUE; static StringBuilder err_line_buf = KV_INITIAL_VALUE; + StringBuilder *line_buf = to_err ? &err_line_buf : &out_line_buf; -#define PUSH_CHAR(c, line_buf, msg) \ - if (kv_max(line_buf) == 0) { \ - kv_resize(line_buf, LINE_BUFFER_MIN_SIZE); \ +#define PUSH_CHAR(c) \ + if (kv_max(*line_buf) == 0) { \ + kv_resize(*line_buf, LINE_BUFFER_MIN_SIZE); \ } \ if (c == NL) { \ - kv_push(line_buf, NUL); \ - msg(line_buf.items); \ + kv_push(*line_buf, NUL); \ + if (to_err) { \ + emsg(line_buf->items); \ + } else { \ + msg(line_buf->items, 0); \ + } \ msg_didout = true; \ - kv_drop(line_buf, kv_size(line_buf)); \ - kv_resize(line_buf, LINE_BUFFER_MIN_SIZE); \ + kv_drop(*line_buf, kv_size(*line_buf)); \ + kv_resize(*line_buf, LINE_BUFFER_MIN_SIZE); \ } else if (c == NUL) { \ - kv_push(line_buf, NL); \ + kv_push(*line_buf, NL); \ } else { \ - kv_push(line_buf, c); \ + kv_push(*line_buf, c); \ } no_wait_return++; @@ -1721,18 +1726,10 @@ static void write_msg(String message, bool to_err, bool writeln) if (got_int) { break; } - if (to_err) { - PUSH_CHAR(message.data[i], err_line_buf, emsg); - } else { - PUSH_CHAR(message.data[i], out_line_buf, msg); - } + PUSH_CHAR(message.data[i]); } if (writeln) { - if (to_err) { - PUSH_CHAR(NL, err_line_buf, emsg); - } else { - PUSH_CHAR(NL, out_line_buf, msg); - } + PUSH_CHAR(NL); } no_wait_return--; msg_end(); -- cgit From cf8b2c0e74fd5e723b0c15c2ce84e6900fd322d3 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 30 Sep 2023 12:05:28 +0800 Subject: build(iwyu): add a few more _defs.h mappings (#25435) --- src/nvim/api/vim.c | 4 +++- 1 file changed, 3 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 c55f9592bf..f064a8e82a 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -14,6 +14,7 @@ #include "lauxlib.h" #include "nvim/api/buffer.h" #include "nvim/api/deprecated.h" +#include "nvim/api/keysets.h" #include "nvim/api/private/converter.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/dispatch.h" @@ -26,12 +27,13 @@ #include "nvim/channel.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/globals.h" #include "nvim/grid.h" -- cgit From dc6d0d2daf69e2fdadda81feb97906dbc962a239 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 30 Sep 2023 14:41:34 +0800 Subject: refactor: reorganize option header files (#25437) - Move vimoption_T to option.h - option_defs.h is for option-related types - option_vars.h corresponds to Vim's option.h - option_defs.h and option_vars.h don't include each other --- 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 f064a8e82a..9d9a5080e4 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -55,6 +55,7 @@ #include "nvim/msgpack_rpc/unpacker.h" #include "nvim/ops.h" #include "nvim/option.h" +#include "nvim/option_vars.h" #include "nvim/optionstr.h" #include "nvim/os/input.h" #include "nvim/os/os_defs.h" -- cgit From 2615ed879e66a3d05920c47177e77383adc7aca0 Mon Sep 17 00:00:00 2001 From: Daniel Steinberg Date: Tue, 18 Jul 2023 17:02:45 -0400 Subject: feat(ui): allow to get the highlight namespace --- src/nvim/api/vim.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index c55f9592bf..6a38374ade 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -170,6 +170,29 @@ void nvim_set_hl(Integer ns_id, String name, Dict(highlight) *val, Error *err) } } +/// Gets the active highlight namespace. +/// +/// @param opts Optional parameters +/// - winid: (number) |window-ID| for retrieving a window's highlight +/// namespace. A value of -1 is returned when |nvim_win_set_hl_ns()| +/// has not been called for the window (or was called with a namespace +/// of -1). +/// @param[out] err Error details, if any +/// @return Namespace id, or -1 +Integer nvim_get_hl_ns(Dict(get_ns) *opts, Error *err) + FUNC_API_SINCE(12) +{ + if (HAS_KEY(opts, get_ns, winid)) { + win_T *win = find_window_by_handle(opts->winid, err); + if (!win) { + return 0; + } + return win->w_ns_hl; + } else { + return ns_hl_global; + } +} + /// Set active namespace for highlights defined with |nvim_set_hl()|. This can be set for /// a single window, see |nvim_win_set_hl_ns()|. /// -- cgit From b2a8a9314798e18c0685faf7463bda32f691d755 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 3 Oct 2023 20:54:42 +0800 Subject: fix(api): avoid immediate TextChanged with nvim_create_buf (#25492) --- 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 675aaf1006..b8e0934669 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -941,6 +941,12 @@ Buffer nvim_create_buf(Boolean listed, Boolean scratch, Error *err) goto fail; } + // Set last_changedtick to avoid triggering a TextChanged autocommand right + // after it was added. + buf->b_last_changedtick = buf_get_changedtick(buf); + buf->b_last_changedtick_i = buf_get_changedtick(buf); + buf->b_last_changedtick_pum = buf_get_changedtick(buf); + // Only strictly needed for scratch, but could just as well be consistent // and do this now. buffer is created NOW, not when it latter first happen // to reach a window or aucmd_prepbuf() .. -- cgit From 30d311ebcf9433f84bd4d98f9e049b36c9d352ac Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sun, 8 Oct 2023 11:59:54 +0200 Subject: fix(PVS/V592): expression is enclosed by parentheses twice --- 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 b8e0934669..ce3eca52b5 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -587,7 +587,7 @@ ArrayOf(String) nvim__get_runtime(Array pat, Boolean all, Dict(runtime) *opts, E FUNC_API_SINCE(8) FUNC_API_FAST { - VALIDATE((!opts->do_source || nlua_is_deferred_safe()), "%s", "'do_source' used in fast callback", + VALIDATE(!opts->do_source || nlua_is_deferred_safe(), "%s", "'do_source' used in fast callback", {}); if (ERROR_SET(err)) { return (Array)ARRAY_DICT_INIT; -- cgit From 13f55750e9bea8ec8f50550546edc64a0f0964d8 Mon Sep 17 00:00:00 2001 From: nwounkn Date: Fri, 13 Oct 2023 12:01:26 +0500 Subject: fix(ui): empty line before the next message after :silent command Problem: The next command after `silent !{cmd}` or `silent lua print('str')` prints an empty line before printing a message, because these commands set `msg_didout = true` despite not printing any messages. Solution: Set `msg_didout = true` only if `msg_silent == 0` --- src/nvim/api/vim.c | 4 +++- 1 file changed, 3 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 ce3eca52b5..6ce1f41e39 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1744,7 +1744,9 @@ static void write_msg(String message, bool to_err, bool writeln) } else { \ msg(line_buf->items, 0); \ } \ - msg_didout = true; \ + if (msg_silent == 0) { \ + msg_didout = true; \ + } \ kv_drop(*line_buf, kv_size(*line_buf)); \ kv_resize(*line_buf, LINE_BUFFER_MIN_SIZE); \ } else if (c == NUL) { \ -- cgit From 5f03a1eaabfc8de2b3a9c666fcd604763f41e152 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Fri, 20 Oct 2023 15:10:33 +0200 Subject: build(lint): remove unnecessary clint.py rules Uncrustify is the source of truth where possible. Remove any redundant checks from clint.py. --- 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 6ce1f41e39..52022cba5d 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2197,8 +2197,8 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * } if (statuscol_lnum) { HlPriId line = { 0 }; - HlPriId cul = { 0 }; - HlPriId num = { 0 }; + HlPriId cul = { 0 }; + HlPriId num = { 0 }; linenr_T lnum = statuscol_lnum; int num_signs = buf_get_signattrs(wp->w_buffer, lnum, sattrs, &num, &line, &cul); decor_redraw_signs(wp->w_buffer, lnum - 1, &num_signs, sattrs, &num, &line, &cul); -- cgit From 684e93054b82c6b5b215db7d3ecbad803eb81f0e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 25 Oct 2023 09:59:02 +0800 Subject: fix(terminal): assign channel to terminal earlier (#25771) --- src/nvim/api/vim.c | 9 ++++++--- 1 file changed, 6 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 52022cba5d..c3c619e206 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1034,9 +1034,12 @@ Integer nvim_open_term(Buffer buffer, DictionaryOf(LuaRef) opts, Error *err) topts.write_cb = term_write; topts.resize_cb = term_resize; topts.close_cb = term_close; - Terminal *term = terminal_open(buf, topts); - terminal_check_size(term); - chan->term = term; + channel_incref(chan); + terminal_open(&chan->term, buf, topts); + if (chan->term != NULL) { + terminal_check_size(chan->term); + } + channel_decref(chan); return (Integer)chan->id; } -- cgit From e9b9a86cd5a555943b87f0ba40c4527561c3c124 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 11 Nov 2023 10:21:14 +0800 Subject: fix(context): don't crash on invalid arg to nvim_get_context (#25977) Note: The crash happens in the second test case when using uninitialized memory, and therefore doesn't happen with ASAN. --- 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 c3c619e206..8446f5b383 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1402,7 +1402,7 @@ Dictionary nvim_get_context(Dict(context) *opts, Error *err) /// Sets the current editor state from the given |context| map. /// /// @param dict |Context| map. -Object nvim_load_context(Dictionary dict) +Object nvim_load_context(Dictionary dict, Error *err) FUNC_API_SINCE(6) { Context ctx = CONTEXT_INIT; @@ -1410,8 +1410,8 @@ Object nvim_load_context(Dictionary dict) int save_did_emsg = did_emsg; did_emsg = false; - ctx_from_dict(dict, &ctx); - if (!did_emsg) { + ctx_from_dict(dict, &ctx, err); + if (!ERROR_SET(err)) { ctx_restore(&ctx, kCtxAll); } -- cgit From 8e58d37f2e15ac8540377148e55ed08a039aadb6 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sat, 11 Nov 2023 11:20:08 +0100 Subject: refactor: remove redundant casts --- 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 8446f5b383..86e542a1c7 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -923,7 +923,7 @@ Buffer nvim_create_buf(Boolean listed, Boolean scratch, Error *err) FUNC_API_SINCE(6) { try_start(); - buf_T *buf = buflist_new(NULL, NULL, (linenr_T)0, + buf_T *buf = buflist_new(NULL, NULL, 0, BLN_NOOPT | BLN_NEW | (listed ? BLN_LISTED : 0)); try_end(err); if (buf == NULL) { -- cgit From 353a4be7e84fdc101318215bdcc8a7e780d737fe Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sun, 12 Nov 2023 13:13:58 +0100 Subject: build: remove PVS We already have an extensive suite of static analysis tools we use, which causes a fair bit of redundancy as we get duplicate warnings. PVS is also prone to give false warnings which creates a lot of work to identify and disable. --- src/nvim/api/vim.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 86e542a1c7..1d5898c488 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1,6 +1,3 @@ -// This is an open source non-commercial project. Dear PVS-Studio, please check -// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com - #include #include #include -- cgit From c4afb9788c4f139eb2e3b7aa4d6a6a20b67ba156 Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Sat, 11 Nov 2023 00:52:50 +0100 Subject: refactor(sign): move legacy signs to extmarks Problem: The legacy signlist data structures and associated functions are redundant since the introduction of extmark signs. Solution: Store signs defined through the legacy commands in a hashmap, placed signs in the extmark tree. Replace signlist associated functions. Usage of the legacy sign commands should yield no change in behavior with the exception of: - "orphaned signs" are now always removed when the line it is placed on is deleted. This used to depend on the value of 'signcolumn'. - It is no longer possible to place multiple signs with the same identifier in a single group on multiple lines. This will now move the sign instead. Moreover, both signs placed through the legacy sign commands and through |nvim_buf_set_extmark()|: - Will show up in both |sign-place| and |nvim_buf_get_extmarks()|. - Are displayed by increasing sign identifier, left to right. Extmark signs used to be ordered decreasingly as opposed to legacy signs. --- src/nvim/api/vim.c | 15 +++++++-------- 1 file changed, 7 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 1d5898c488..88cbdbe1de 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2196,13 +2196,12 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * } } if (statuscol_lnum) { - HlPriId line = { 0 }; - HlPriId cul = { 0 }; - HlPriId num = { 0 }; + int line_id = 0; + int cul_id = 0; + int num_id = 0; linenr_T lnum = statuscol_lnum; - int num_signs = buf_get_signattrs(wp->w_buffer, lnum, sattrs, &num, &line, &cul); - decor_redraw_signs(wp->w_buffer, lnum - 1, &num_signs, sattrs, &num, &line, &cul); 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; statuscol.foldinfo = fold_info(wp, lnum); @@ -2215,9 +2214,9 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * statuscol.use_cul = lnum == wp->w_cursorline && (wp->w_p_culopt_flags & CULOPT_NBR); } - statuscol.sign_cul_id = statuscol.use_cul ? cul.hl_id : 0; - if (num.hl_id) { - stc_hl_id = num.hl_id; + 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) { -- cgit From a6e3d93421ba13c407a96fac9cc01fa41ec7ad98 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Thu, 16 Nov 2023 10:59:11 +0100 Subject: refactor: enable formatting for ternaries This requires removing the "Inner expression should be aligned" rule from clint as it prevents essentially any formatting regarding ternary operators. --- src/nvim/api/vim.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 88cbdbe1de..27b48c0b28 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1301,9 +1301,9 @@ void nvim_subscribe(uint64_t channel_id, String event) void nvim_unsubscribe(uint64_t channel_id, String event) FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY { - size_t length = (event.size < METHOD_MAXLEN ? - event.size : - METHOD_MAXLEN); + size_t length = (event.size < METHOD_MAXLEN + ? event.size + : METHOD_MAXLEN); char e[METHOD_MAXLEN + 1]; memcpy(e, event.data, length); e[length] = NUL; @@ -2235,8 +2235,9 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * maxwidth = (int)opts->maxwidth; } else { maxwidth = statuscol_lnum ? win_col_off(wp) - : (opts->use_tabline - || (!opts->use_winbar && global_stl_height() > 0)) ? Columns : wp->w_width; + : (opts->use_tabline + || (!opts->use_winbar + && global_stl_height() > 0)) ? Columns : wp->w_width; } char buf[MAXPATHL]; -- cgit From 09541d514dd18bf86f673d3784d406236fcbdad8 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 27 Nov 2023 09:51:26 +0800 Subject: build(IWYU): replace public-to-public mappings with pragmas (#26237) --- 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 27b48c0b28..b4e9af491f 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -48,7 +48,6 @@ #include "nvim/message.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" -- cgit From 574d25642fc9ca65b396633aeab6e2d32778b642 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 27 Nov 2023 17:21:58 +0800 Subject: refactor: move Arena and ArenaMem to memory_defs.h (#26240) --- 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 b4e9af491f..7279cb9b1a 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -8,7 +9,6 @@ #include #include "klib/kvec.h" -#include "lauxlib.h" #include "nvim/api/buffer.h" #include "nvim/api/deprecated.h" #include "nvim/api/keysets.h" -- cgit From 8b428ca8b79ebb7b36c3e403ff3bcb6924a635a6 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 27 Nov 2023 16:00:21 +0100 Subject: build(IWYU): fix includes for func_attr.h --- 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 7279cb9b1a..2823319b06 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -31,6 +31,7 @@ #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 f4aedbae4cb1f206f5b7c6142697b71dd473059b Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 27 Nov 2023 18:39:38 +0100 Subject: build(IWYU): fix includes for undo_defs.h --- 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 2823319b06..5a206471fa 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -58,7 +58,7 @@ #include "nvim/os/os_defs.h" #include "nvim/os/process.h" #include "nvim/popupmenu.h" -#include "nvim/pos.h" +#include "nvim/pos_defs.h" #include "nvim/runtime.h" #include "nvim/sign.h" #include "nvim/state.h" -- cgit From e3f735ef101d670555f44226614a5c3557053b1f Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 27 Nov 2023 20:13:32 +0100 Subject: refactor: fix includes for api/autocmd.h --- 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 5a206471fa..73001cfb6a 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -11,7 +11,7 @@ #include "klib/kvec.h" #include "nvim/api/buffer.h" #include "nvim/api/deprecated.h" -#include "nvim/api/keysets.h" +#include "nvim/api/keysets_defs.h" #include "nvim/api/private/converter.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/dispatch.h" -- cgit From 6c14ae6bfaf51415b555e9a6b85d1d280976358d Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 27 Nov 2023 20:27:32 +0100 Subject: refactor: rename types.h to types_defs.h --- 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 73001cfb6a..858fda68b9 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -65,7 +65,7 @@ #include "nvim/statusline.h" #include "nvim/strings.h" #include "nvim/terminal.h" -#include "nvim/types.h" +#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/vim.h" #include "nvim/window.h" -- cgit From ae3685798deaf51f14422c568998998c03f91f2c Mon Sep 17 00:00:00 2001 From: bfredl Date: Sun, 26 Nov 2023 21:07:29 +0100 Subject: feat(decoration): allow conceal_char to be a composing char decor->text.str pointer must go. This removes it for conceal char, in preparation for a larger PR which will also handle the sign case. By actually allowing composing chars for a conceal chars, this becomes a feature and not just a refactor, as a bonus. --- src/nvim/api/vim.c | 5 ++++- 1 file changed, 4 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 858fda68b9..ad111510e5 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1999,9 +1999,12 @@ void nvim__screenshot(String path) ui_call_screenshot(path); } +/// For testing. The condition in schar_cache_clear_if_full is hard to +/// reach, so this function can be used to force a cache clear in a test. void nvim__invalidate_glyph_cache(void) { - schar_cache_clear_force(); + schar_cache_clear(); + must_redraw = UPD_CLEAR; } Object nvim__unpack(String str, Error *err) -- cgit From 79b6ff28ad1204fbb4199b9092f5c578d88cb28e Mon Sep 17 00:00:00 2001 From: dundargoc Date: Tue, 28 Nov 2023 20:31:00 +0100 Subject: refactor: fix headers with IWYU --- 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 ad111510e5..fdf12cba9e 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -18,7 +18,7 @@ #include "nvim/api/private/helpers.h" #include "nvim/api/private/validate.h" #include "nvim/api/vim.h" -#include "nvim/ascii.h" +#include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" #include "nvim/channel.h" @@ -40,7 +40,7 @@ #include "nvim/keycodes.h" #include "nvim/log.h" #include "nvim/lua/executor.h" -#include "nvim/macros.h" +#include "nvim/macros_defs.h" #include "nvim/mapping.h" #include "nvim/mark.h" #include "nvim/mbyte.h" @@ -67,7 +67,7 @@ #include "nvim/terminal.h" #include "nvim/types_defs.h" #include "nvim/ui.h" -#include "nvim/vim.h" +#include "nvim/vim_defs.h" #include "nvim/window.h" #define LINE_BUFFER_MIN_SIZE 4096 -- cgit From 64b53b71ba5d804b2c8cf186be68931b2621f53c Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 29 Nov 2023 12:10:42 +0800 Subject: refactor(IWYU): create normal_defs.h (#26293) --- 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 fdf12cba9e..d631b10af9 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -55,7 +55,6 @@ #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