diff options
Diffstat (limited to 'src')
45 files changed, 455 insertions, 426 deletions
diff --git a/src/clint.py b/src/clint.py index 78eabb698f..062901b43a 100755 --- a/src/clint.py +++ b/src/clint.py @@ -152,8 +152,10 @@ _ERROR_CATEGORIES = [ 'build/endif_comment', 'build/header_guard', 'build/include_defs', + 'build/defs_header', 'build/printf_format', 'build/storage_class', + 'build/init_macro', 'readability/bool', 'readability/multiline_comment', 'readability/multiline_string', @@ -2086,6 +2088,11 @@ def CheckLanguage(filename, clean_lines, linenum, error): " named ('k' followed by CamelCase) compile-time constant for" " the size.") + # INIT() macro should only be used in header files. + if not filename.endswith('.h') and Search(r' INIT\(', line): + error(filename, linenum, 'build/init_macro', 4, + 'INIT() macro should only be used in header files.') + # Detect TRUE and FALSE. match = Search(r'\b(TRUE|FALSE)\b', line) if match: diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 751fc1c32d..183483b329 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -264,6 +264,7 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id, Integer start, Integer end, Boolean strict_indexing, + Arena *arena, lua_State *lstate, Error *err) FUNC_API_SINCE(1) @@ -295,18 +296,10 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id, size_t size = (size_t)(end - start); - init_line_array(lstate, &rv, size); + init_line_array(lstate, &rv, size, arena); - if (!buf_collect_lines(buf, size, (linenr_T)start, 0, (channel_id != VIML_INTERNAL_CALL), &rv, - lstate, err)) { - goto end; - } - -end: - if (ERROR_SET(err)) { - api_free_array(rv); - rv.items = NULL; - } + buf_collect_lines(buf, size, (linenr_T)start, 0, (channel_id != VIML_INTERNAL_CALL), &rv, + lstate, arena); return rv; } @@ -763,8 +756,8 @@ early_end: ArrayOf(String) nvim_buf_get_text(uint64_t channel_id, Buffer buffer, Integer start_row, Integer start_col, Integer end_row, Integer end_col, - Dict(empty) *opts, lua_State *lstate, - Error *err) + Dict(empty) *opts, + Arena *arena, lua_State *lstate, Error *err) FUNC_API_SINCE(9) { Array rv = ARRAY_DICT_INIT; @@ -799,44 +792,38 @@ ArrayOf(String) nvim_buf_get_text(uint64_t channel_id, Buffer buffer, size_t size = (size_t)(end_row - start_row) + 1; - init_line_array(lstate, &rv, size); + init_line_array(lstate, &rv, size, arena); if (start_row == end_row) { String line = buf_get_text(buf, start_row, start_col, end_col, err); if (ERROR_SET(err)) { goto end; } - push_linestr(lstate, &rv, line.data, line.size, 0, replace_nl); + push_linestr(lstate, &rv, line.data, line.size, 0, replace_nl, arena); return rv; } String str = buf_get_text(buf, start_row, start_col, MAXCOL - 1, err); - - push_linestr(lstate, &rv, str.data, str.size, 0, replace_nl); - if (ERROR_SET(err)) { goto end; } + push_linestr(lstate, &rv, str.data, str.size, 0, replace_nl, arena); + if (size > 2) { - if (!buf_collect_lines(buf, size - 2, (linenr_T)start_row + 1, 1, replace_nl, &rv, lstate, - err)) { - goto end; - } + buf_collect_lines(buf, size - 2, (linenr_T)start_row + 1, 1, replace_nl, &rv, lstate, arena); } str = buf_get_text(buf, end_row, 0, end_col, err); - push_linestr(lstate, &rv, str.data, str.size, (int)(size - 1), replace_nl); - if (ERROR_SET(err)) { goto end; } + push_linestr(lstate, &rv, str.data, str.size, (int)(size - 1), replace_nl, arena); + end: if (ERROR_SET(err)) { - api_free_array(rv); - rv.size = 0; - rv.items = NULL; + return (Array)ARRAY_DICT_INIT; } return rv; @@ -1394,13 +1381,12 @@ static void fix_cursor_cols(win_T *win, linenr_T start_row, colnr_T start_col, l /// @param lstate Lua state. When NULL the Array is initialized instead. /// @param a Array to initialize /// @param size Size of array -static inline void init_line_array(lua_State *lstate, Array *a, size_t size) +static inline void init_line_array(lua_State *lstate, Array *a, size_t size, Arena *arena) { if (lstate) { lua_createtable(lstate, (int)size, 0); } else { - a->size = size; - a->items = xcalloc(a->size, sizeof(Object)); + *a = arena_array(arena, size); } } @@ -1413,14 +1399,15 @@ static inline void init_line_array(lua_State *lstate, Array *a, size_t size) /// @param a Array to push onto when not using Lua /// @param s String to push /// @param len Size of string -/// @param idx 0-based index to place s +/// @param idx 0-based index to place s (only used for Lua) /// @param replace_nl Replace newlines ('\n') with null ('\0') static void push_linestr(lua_State *lstate, Array *a, const char *s, size_t len, int idx, - bool replace_nl) + bool replace_nl, Arena *arena) { if (lstate) { // Vim represents NULs as NLs if (s && replace_nl && strchr(s, '\n')) { + // TODO(bfredl): could manage scratch space in the arena, for the NUL case char *tmp = xmemdupz(s, len); strchrsub(tmp, '\n', '\0'); lua_pushlstring(lstate, tmp, len); @@ -1431,15 +1418,15 @@ static void push_linestr(lua_State *lstate, Array *a, const char *s, size_t len, lua_rawseti(lstate, -2, idx + 1); } else { String str = STRING_INIT; - if (s) { - str = cbuf_to_string(s, len); + if (len > 0) { + str = arena_string(arena, cbuf_as_string((char *)s, len)); if (replace_nl) { // Vim represents NULs as NLs, but this may confuse clients. strchrsub(str.data, '\n', '\0'); } } - a->items[idx] = STRING_OBJ(str); + ADD_C(*a, STRING_OBJ(str)); } } @@ -1450,27 +1437,17 @@ static void push_linestr(lua_State *lstate, Array *a, const char *s, size_t len, /// @param n Number of lines to collect /// @param replace_nl Replace newlines ("\n") with NUL /// @param start Line number to start from -/// @param start_idx First index to push to +/// @param start_idx First index to push to (only used for Lua) /// @param[out] l If not NULL, Lines are copied here /// @param[out] lstate If not NULL, Lines are pushed into a table onto the stack /// @param err[out] Error, if any /// @return true unless `err` was set -bool buf_collect_lines(buf_T *buf, size_t n, linenr_T start, int start_idx, bool replace_nl, - Array *l, lua_State *lstate, Error *err) +void buf_collect_lines(buf_T *buf, size_t n, linenr_T start, int start_idx, bool replace_nl, + Array *l, lua_State *lstate, Arena *arena) { for (size_t i = 0; i < n; i++) { linenr_T lnum = start + (linenr_T)i; - - if (lnum >= MAXLNUM) { - if (err != NULL) { - api_set_error(err, kErrorTypeValidation, "Line index is too high"); - } - return false; - } - char *bufstr = ml_get_buf(buf, lnum); - push_linestr(lstate, l, bufstr, strlen(bufstr), start_idx + (int)i, replace_nl); + push_linestr(lstate, l, bufstr, strlen(bufstr), start_idx + (int)i, replace_nl, arena); } - - return true; } diff --git a/src/nvim/api/command.c b/src/nvim/api/command.c index db0a918f5c..bafc45e543 100644 --- a/src/nvim/api/command.c +++ b/src/nvim/api/command.c @@ -96,15 +96,15 @@ /// - "belowright": |:belowright|. /// - "topleft": |:topleft|. /// - "botright": |:botright|. -Dictionary nvim_parse_cmd(String str, Dict(empty) *opts, Error *err) +Dict(cmd) nvim_parse_cmd(String str, Dict(empty) *opts, Arena *arena, Error *err) FUNC_API_SINCE(10) FUNC_API_FAST { - Dictionary result = ARRAY_DICT_INIT; + Dict(cmd) result = { 0 }; // Parse command line exarg_T ea; CmdParseInfo cmdinfo; - char *cmdline = string_to_cstr(str); + char *cmdline = arena_memdupz(arena, str.data, str.size); const char *errormsg = NULL; if (!parse_cmdline(cmdline, &ea, &cmdinfo, &errormsg)) { @@ -124,22 +124,23 @@ Dictionary nvim_parse_cmd(String str, Dict(empty) *opts, Error *err) // otherwise split arguments by whitespace. if (ea.argt & EX_NOSPC) { if (*ea.arg != NUL) { - ADD(args, STRING_OBJ(cstrn_to_string(ea.arg, length))); + args = arena_array(arena, 1); + ADD_C(args, STRING_OBJ(cstrn_as_string(ea.arg, length))); } } else { size_t end = 0; size_t len = 0; - char *buf = xcalloc(length, sizeof(char)); + char *buf = arena_alloc(arena, length + 1, false); bool done = false; + args = arena_array(arena, uc_nargs_upper_bound(ea.arg, length)); while (!done) { done = uc_split_args_iter(ea.arg, length, &end, buf, &len); if (len > 0) { - ADD(args, STRING_OBJ(cstrn_to_string(buf, len))); + ADD_C(args, STRING_OBJ(cstrn_as_string(buf, len))); + buf += len + 1; } } - - xfree(buf); } ucmd_T *cmd = NULL; @@ -149,40 +150,32 @@ Dictionary nvim_parse_cmd(String str, Dict(empty) *opts, Error *err) cmd = USER_CMD_GA(&curbuf->b_ucmds, ea.useridx); } - if (cmd != NULL) { - PUT(result, "cmd", CSTR_TO_OBJ(cmd->uc_name)); - } else { - PUT(result, "cmd", CSTR_TO_OBJ(get_command_name(NULL, ea.cmdidx))); - } + char *name = (cmd != NULL ? cmd->uc_name : get_command_name(NULL, ea.cmdidx)); + PUT_KEY(result, cmd, cmd, cstr_as_string(name)); if (ea.argt & EX_RANGE) { - Array range = ARRAY_DICT_INIT; + Array range = arena_array(arena, 2); if (ea.addr_count > 0) { if (ea.addr_count > 1) { - ADD(range, INTEGER_OBJ(ea.line1)); + ADD_C(range, INTEGER_OBJ(ea.line1)); } - ADD(range, INTEGER_OBJ(ea.line2)); + ADD_C(range, INTEGER_OBJ(ea.line2)); } - PUT(result, "range", ARRAY_OBJ(range)); + PUT_KEY(result, cmd, range, range); } if (ea.argt & EX_COUNT) { - if (ea.addr_count > 0) { - PUT(result, "count", INTEGER_OBJ(ea.line2)); - } else if (cmd != NULL) { - PUT(result, "count", INTEGER_OBJ(cmd->uc_def)); - } else { - PUT(result, "count", INTEGER_OBJ(0)); - } + Integer count = ea.addr_count > 0 ? ea.line2 : (cmd != NULL ? cmd->uc_def : 0); + PUT_KEY(result, cmd, count, count); } if (ea.argt & EX_REGSTR) { char reg[2] = { (char)ea.regname, NUL }; - PUT(result, "reg", CSTR_TO_OBJ(reg)); + PUT_KEY(result, cmd, reg, CSTR_TO_ARENA_STR(arena, reg)); } - PUT(result, "bang", BOOLEAN_OBJ(ea.forceit)); - PUT(result, "args", ARRAY_OBJ(args)); + PUT_KEY(result, cmd, bang, ea.forceit); + PUT_KEY(result, cmd, args, args); char nargs[2]; if (ea.argt & EX_EXTRA) { @@ -201,9 +194,9 @@ Dictionary nvim_parse_cmd(String str, Dict(empty) *opts, Error *err) nargs[0] = '0'; } nargs[1] = '\0'; - PUT(result, "nargs", CSTR_TO_OBJ(nargs)); + PUT_KEY(result, cmd, nargs, CSTR_TO_ARENA_OBJ(arena, nargs)); - const char *addr; + char *addr; switch (ea.addr_type) { case ADDR_LINES: addr = "line"; @@ -233,38 +226,37 @@ Dictionary nvim_parse_cmd(String str, Dict(empty) *opts, Error *err) addr = "?"; break; } - PUT(result, "addr", CSTR_TO_OBJ(addr)); - PUT(result, "nextcmd", CSTR_TO_OBJ(ea.nextcmd)); - - Dictionary mods = ARRAY_DICT_INIT; - - Dictionary filter = ARRAY_DICT_INIT; - PUT(filter, "pattern", cmdinfo.cmdmod.cmod_filter_pat - ? CSTR_TO_OBJ(cmdinfo.cmdmod.cmod_filter_pat) - : STATIC_CSTR_TO_OBJ("")); - PUT(filter, "force", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_filter_force)); - PUT(mods, "filter", DICTIONARY_OBJ(filter)); - - PUT(mods, "silent", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_SILENT)); - PUT(mods, "emsg_silent", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_ERRSILENT)); - PUT(mods, "unsilent", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_UNSILENT)); - PUT(mods, "sandbox", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_SANDBOX)); - PUT(mods, "noautocmd", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_NOAUTOCMD)); - PUT(mods, "tab", INTEGER_OBJ(cmdinfo.cmdmod.cmod_tab - 1)); - PUT(mods, "verbose", INTEGER_OBJ(cmdinfo.cmdmod.cmod_verbose - 1)); - PUT(mods, "browse", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_BROWSE)); - PUT(mods, "confirm", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_CONFIRM)); - PUT(mods, "hide", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_HIDE)); - PUT(mods, "keepalt", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_KEEPALT)); - PUT(mods, "keepjumps", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_KEEPJUMPS)); - PUT(mods, "keepmarks", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_KEEPMARKS)); - PUT(mods, "keeppatterns", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_KEEPPATTERNS)); - PUT(mods, "lockmarks", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_LOCKMARKS)); - PUT(mods, "noswapfile", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_NOSWAPFILE)); - PUT(mods, "vertical", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_split & WSP_VERT)); - PUT(mods, "horizontal", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_split & WSP_HOR)); - - const char *split; + PUT_KEY(result, cmd, addr, CSTR_AS_OBJ(addr)); + PUT_KEY(result, cmd, nextcmd, CSTR_AS_OBJ(ea.nextcmd)); + + // TODO(bfredl): nested keydict would be nice.. + Dictionary mods = arena_dict(arena, 20); + + Dictionary filter = arena_dict(arena, 2); + PUT_C(filter, "pattern", CSTR_TO_ARENA_OBJ(arena, cmdinfo.cmdmod.cmod_filter_pat)); + PUT_C(filter, "force", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_filter_force)); + PUT_C(mods, "filter", DICTIONARY_OBJ(filter)); + + PUT_C(mods, "silent", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_SILENT)); + PUT_C(mods, "emsg_silent", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_ERRSILENT)); + PUT_C(mods, "unsilent", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_UNSILENT)); + PUT_C(mods, "sandbox", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_SANDBOX)); + PUT_C(mods, "noautocmd", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_NOAUTOCMD)); + PUT_C(mods, "tab", INTEGER_OBJ(cmdinfo.cmdmod.cmod_tab - 1)); + PUT_C(mods, "verbose", INTEGER_OBJ(cmdinfo.cmdmod.cmod_verbose - 1)); + PUT_C(mods, "browse", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_BROWSE)); + PUT_C(mods, "confirm", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_CONFIRM)); + PUT_C(mods, "hide", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_HIDE)); + PUT_C(mods, "keepalt", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_KEEPALT)); + PUT_C(mods, "keepjumps", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_KEEPJUMPS)); + PUT_C(mods, "keepmarks", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_KEEPMARKS)); + PUT_C(mods, "keeppatterns", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_KEEPPATTERNS)); + PUT_C(mods, "lockmarks", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_LOCKMARKS)); + PUT_C(mods, "noswapfile", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_NOSWAPFILE)); + PUT_C(mods, "vertical", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_split & WSP_VERT)); + PUT_C(mods, "horizontal", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_split & WSP_HOR)); + + char *split; if (cmdinfo.cmdmod.cmod_split & WSP_BOT) { split = "botright"; } else if (cmdinfo.cmdmod.cmod_split & WSP_TOP) { @@ -276,18 +268,17 @@ Dictionary nvim_parse_cmd(String str, Dict(empty) *opts, Error *err) } else { split = ""; } - PUT(mods, "split", CSTR_TO_OBJ(split)); + PUT_C(mods, "split", CSTR_AS_OBJ(split)); - PUT(result, "mods", DICTIONARY_OBJ(mods)); + PUT_KEY(result, cmd, mods, mods); - Dictionary magic = ARRAY_DICT_INIT; - PUT(magic, "file", BOOLEAN_OBJ(cmdinfo.magic.file)); - PUT(magic, "bar", BOOLEAN_OBJ(cmdinfo.magic.bar)); - PUT(result, "magic", DICTIONARY_OBJ(magic)); + Dictionary magic = arena_dict(arena, 2); + PUT_C(magic, "file", BOOLEAN_OBJ(cmdinfo.magic.file)); + PUT_C(magic, "bar", BOOLEAN_OBJ(cmdinfo.magic.bar)); + PUT_KEY(result, cmd, magic, magic); undo_cmdmod(&cmdinfo.cmdmod); end: - xfree(cmdline); return result; } diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index b09645a819..dccaeb6922 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -245,20 +245,18 @@ void buffer_insert(Buffer buffer, Integer lnum, ArrayOf(String) lines, Error *er /// @param index Line index /// @param[out] err Error details, if any /// @return Line string -String buffer_get_line(Buffer buffer, Integer index, Error *err) +String buffer_get_line(Buffer buffer, Integer index, Arena *arena, Error *err) FUNC_API_DEPRECATED_SINCE(1) { String rv = { .size = 0 }; index = convert_index(index); - Array slice = nvim_buf_get_lines(0, buffer, index, index + 1, true, NULL, err); + Array slice = nvim_buf_get_lines(0, buffer, index, index + 1, true, arena, NULL, err); if (!ERROR_SET(err) && slice.size) { rv = slice.items[0].data.string; } - xfree(slice.items); - return rv; } @@ -319,12 +317,13 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer, Integer end, Boolean include_start, Boolean include_end, + Arena *arena, Error *err) FUNC_API_DEPRECATED_SINCE(1) { start = convert_index(start) + !include_start; end = convert_index(end) + include_end; - return nvim_buf_get_lines(0, buffer, start, end, false, NULL, err); + return nvim_buf_get_lines(0, buffer, start, end, false, arena, NULL, err); } /// Replaces a line range on the buffer @@ -514,11 +513,11 @@ static int64_t convert_index(int64_t index) /// @param name Option name /// @param[out] err Error details, if any /// @return Option Information -Dictionary nvim_get_option_info(String name, Error *err) +Dictionary nvim_get_option_info(String name, Arena *arena, Error *err) FUNC_API_SINCE(7) FUNC_API_DEPRECATED_SINCE(11) { - return get_vimoption(name, OPT_GLOBAL, curbuf, curwin, err); + return get_vimoption(name, OPT_GLOBAL, curbuf, curwin, arena, err); } /// Sets the global value of an option. diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index fce4a85804..8128fdf67b 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -263,10 +263,10 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict( /// @see |nvim_get_commands()| /// /// @return dictionary of all options -Dictionary nvim_get_all_options_info(Error *err) +Dictionary nvim_get_all_options_info(Arena *arena, Error *err) FUNC_API_SINCE(7) { - return get_all_vimoptions(); + return get_all_vimoptions(arena); } /// Gets the option information for one option from arbitrary buffer or window @@ -302,7 +302,7 @@ Dictionary nvim_get_all_options_info(Error *err) /// Implies {scope} is "local". /// @param[out] err Error details, if any /// @return Option Information -Dictionary nvim_get_option_info2(String name, Dict(option) *opts, Error *err) +Dictionary nvim_get_option_info2(String name, Dict(option) *opts, Arena *arena, Error *err) FUNC_API_SINCE(11) { OptIndex opt_idx = 0; @@ -317,5 +317,5 @@ Dictionary nvim_get_option_info2(String name, Dict(option) *opts, Error *err) buf_T *buf = (req_scope == kOptReqBuf) ? (buf_T *)from : curbuf; win_T *win = (req_scope == kOptReqWin) ? (win_T *)from : curwin; - return get_vimoption(name, scope, buf, win, err); + return get_vimoption(name, scope, buf, win, arena, err); } diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index cc95f46baf..8b45af7c71 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -425,12 +425,12 @@ String cstrn_as_string(char *str, size_t maxsize) /// @param str the C string to use /// @return The resulting String, or an empty String if /// str was NULL -String cstr_as_string(char *str) FUNC_ATTR_PURE +String cstr_as_string(const char *str) FUNC_ATTR_PURE { if (str == NULL) { return (String)STRING_INIT; } - return (String){ .data = str, .size = strlen(str) }; + return (String){ .data = (char *)str, .size = strlen(str) }; } /// Return the owned memory of a ga as a String diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h index 0dbe3d2fb6..9ee812f45c 100644 --- a/src/nvim/api/private/helpers.h +++ b/src/nvim/api/private/helpers.h @@ -32,7 +32,8 @@ #define CSTR_AS_OBJ(s) STRING_OBJ(cstr_as_string(s)) #define CSTR_TO_OBJ(s) STRING_OBJ(cstr_to_string(s)) -#define CSTR_TO_ARENA_OBJ(arena, s) STRING_OBJ(arena_string(arena, cstr_as_string(s))) +#define CSTR_TO_ARENA_STR(arena, s) arena_string(arena, cstr_as_string(s)) +#define CSTR_TO_ARENA_OBJ(arena, s) STRING_OBJ(CSTR_TO_ARENA_STR(arena, s)) #define BUFFER_OBJ(s) ((Object) { \ .type = kObjectTypeBuffer, \ diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index f955b315a8..5c8ebfb861 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -247,10 +247,9 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, Dictiona void ui_attach(uint64_t channel_id, Integer width, Integer height, Boolean enable_rgb, Error *err) FUNC_API_DEPRECATED_SINCE(1) { - Dictionary opts = ARRAY_DICT_INIT; - PUT(opts, "rgb", BOOLEAN_OBJ(enable_rgb)); + MAXSIZE_TEMP_DICT(opts, 1); + PUT_C(opts, "rgb", BOOLEAN_OBJ(enable_rgb)); nvim_ui_attach(channel_id, width, height, opts, err); - api_free_dictionary(opts); } /// Tells the nvim server if focus was gained or lost by the GUI @@ -789,7 +788,7 @@ void remote_ui_hl_attr_define(UI *ui, Integer id, HlAttrs rgb_attrs, HlAttrs cte // system. So we add them here. if (rgb_attrs.url >= 0) { const char *url = hl_get_url((uint32_t)rgb_attrs.url); - PUT_C(rgb, "url", STRING_OBJ(cstr_as_string((char *)url))); + PUT_C(rgb, "url", CSTR_AS_OBJ(url)); } ADD_C(args, DICTIONARY_OBJ(rgb)); @@ -857,7 +856,7 @@ void remote_ui_put(UI *ui, const char *cell) UIData *data = ui->data; data->client_col++; Array args = data->call_buf; - ADD_C(args, CSTR_AS_OBJ((char *)cell)); + ADD_C(args, CSTR_AS_OBJ(cell)); push_call(ui, "put", args); } @@ -1113,9 +1112,3 @@ void remote_ui_event(UI *ui, char *name, Array args) free_ret: arena_mem_free(arena_finish(&arena)); } - -void remote_ui_inspect(UI *ui, Dictionary *info) -{ - UIData *data = ui->data; - PUT(*info, "chan", INTEGER_OBJ((Integer)data->channel_id)); -} diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 1453de30d4..78c2561bbd 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -656,10 +656,10 @@ void nvim_set_current_dir(String dir, Error *err) /// /// @param[out] err Error details, if any /// @return Current line string -String nvim_get_current_line(Error *err) +String nvim_get_current_line(Arena *arena, Error *err) FUNC_API_SINCE(1) { - return buffer_get_line(curbuf->handle, curwin->w_cursor.lnum - 1, err); + return buffer_get_line(curbuf->handle, curwin->w_cursor.lnum - 1, arena, err); } /// Sets the current line. @@ -1866,10 +1866,10 @@ Dictionary nvim__stats(Arena *arena) /// - "rgb" true if the UI uses RGB colors (false implies |cterm-colors|) /// - "ext_..." Requested UI extensions, see |ui-option| /// - "chan" |channel-id| of remote UI -Array nvim_list_uis(void) +Array nvim_list_uis(Arena *arena) FUNC_API_SINCE(4) { - return ui_array(); + return ui_array(arena); } /// Gets the immediate children of process `pid`. @@ -2005,7 +2005,7 @@ Array nvim__inspect_cell(Integer grid, Integer row, Integer col, Arena *arena, E ADD_C(ret, DICTIONARY_OBJ(hl_get_attr_by_id(attr, true, arena, err))); // will not work first time if (!highlight_use_hlstate()) { - ADD_C(ret, ARRAY_OBJ(hl_inspect(attr))); + ADD_C(ret, ARRAY_OBJ(hl_inspect(attr, arena))); } return ret; } @@ -2289,7 +2289,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Arena * opts->use_winbar, stc_hl_id); PUT_C(hl_info, "start", INTEGER_OBJ(0)); - PUT_C(hl_info, "group", CSTR_AS_OBJ((char *)grpname)); + PUT_C(hl_info, "group", CSTR_AS_OBJ(grpname)); ADD_C(hl_values, DICTIONARY_OBJ(hl_info)); } @@ -2308,7 +2308,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Arena * snprintf(user_group, sizeof(user_group), "User%d", sp->userhl); grpname = arena_memdupz(arena, user_group, strlen(user_group)); } - PUT_C(hl_info, "group", CSTR_AS_OBJ((char *)grpname)); + PUT_C(hl_info, "group", CSTR_AS_OBJ(grpname)); ADD_C(hl_values, DICTIONARY_OBJ(hl_info)); } PUT_C(result, "highlights", ARRAY_OBJ(hl_values)); diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c index 22a321149b..52372b838e 100644 --- a/src/nvim/api/win_config.c +++ b/src/nvim/api/win_config.c @@ -257,7 +257,7 @@ Window nvim_open_win(Buffer buffer, Boolean enter, Dict(win_config) *config, Err restore_win(&switchwin, true); } if (wp) { - wp->w_float_config = fconfig; + wp->w_config = fconfig; } } else { wp = win_new_float(NULL, false, fconfig, err); @@ -345,7 +345,7 @@ void nvim_win_set_config(Window window, Dict(win_config) *config, Error *err) bool has_split = HAS_KEY_X(config, split); bool has_vertical = HAS_KEY_X(config, vertical); // reuse old values, if not overridden - WinConfig fconfig = win->w_float_config; + WinConfig fconfig = win->w_config; bool to_split = config->relative.size == 0 && !(HAS_KEY_X(config, external) ? config->external : fconfig.external) @@ -387,7 +387,7 @@ void nvim_win_set_config(Window window, Dict(win_config) *config, Error *err) } } } - win->w_float_config = fconfig; + win->w_config = fconfig; // If there's no "vertical" or "split" set, or if "split" is unchanged, // then we can just change the size of the window. @@ -477,7 +477,7 @@ void nvim_win_set_config(Window window, Dict(win_config) *config, Error *err) } else { win_remove(win, win_tp == curtab ? NULL : win_tp); ui_comp_remove_grid(&win->w_grid_alloc); - if (win->w_float_config.external) { + if (win->w_config.external) { for (tabpage_T *tp = first_tabpage; tp != NULL; tp = tp->tp_next) { if (tp == curtab) { continue; @@ -607,7 +607,7 @@ Dict(win_config) nvim_win_get_config(Window window, Arena *arena, Error *err) return rv; } - WinConfig *config = &wp->w_float_config; + WinConfig *config = &wp->w_config; PUT_KEY_X(rv, focusable, config->focusable); PUT_KEY_X(rv, external, config->external); @@ -626,7 +626,7 @@ Dict(win_config) nvim_win_get_config(Window window, Arena *arena, Error *err) PUT_KEY_X(rv, bufpos, pos); } } - PUT_KEY_X(rv, anchor, cstr_as_string((char *)float_anchor_str[config->anchor])); + PUT_KEY_X(rv, anchor, cstr_as_string(float_anchor_str[config->anchor])); PUT_KEY_X(rv, row, config->row); PUT_KEY_X(rv, col, config->col); PUT_KEY_X(rv, zindex, config->zindex); @@ -659,12 +659,12 @@ Dict(win_config) nvim_win_get_config(Window window, Arena *arena, Error *err) PUT_KEY_X(rv, width, wp->w_width); PUT_KEY_X(rv, height, wp->w_height); WinSplit split = win_split_dir(wp); - PUT_KEY_X(rv, split, cstr_as_string((char *)win_split_str[split])); + PUT_KEY_X(rv, split, cstr_as_string(win_split_str[split])); } const char *rel = (wp->w_floating && !config->external ? float_relative_str[config->relative] : ""); - PUT_KEY_X(rv, relative, cstr_as_string((char *)rel)); + PUT_KEY_X(rv, relative, cstr_as_string(rel)); return rv; } diff --git a/src/nvim/arglist.c b/src/nvim/arglist.c index e9108f72cc..a02c22deae 100644 --- a/src/nvim/arglist.c +++ b/src/nvim/arglist.c @@ -1093,11 +1093,6 @@ static void do_arg_all(int count, int forceit, int keep_tabs) // When the ":tab" modifier was used do this for all tab pages. arg_all_close_unused_windows(&aall); - // Now set the last used tabpage to where we started. - if (valid_tabpage(new_lu_tp)) { - lastused_tabpage = new_lu_tp; - } - // Open a window for files in the argument list that don't have one. // ARGCOUNT may change while doing this, because of autocommands. if (count > aall.opened_len || count <= 0) { @@ -1134,6 +1129,12 @@ static void do_arg_all(int count, int forceit, int keep_tabs) if (valid_tabpage(aall.new_curtab)) { goto_tabpage_tp(aall.new_curtab, true, true); } + + // Now set the last used tabpage to where we started. + if (valid_tabpage(new_lu_tp)) { + lastused_tabpage = new_lu_tp; + } + if (win_valid(aall.new_curwin)) { win_enter(aall.new_curwin, false); } diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index a385161beb..1edc60f230 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -121,7 +121,7 @@ static void augroup_map_del(int id, const char *name) { if (name != NULL) { String key; - map_del(String, int)(&map_augroup_name_to_id, cstr_as_string((char *)name), &key); + map_del(String, int)(&map_augroup_name_to_id, cstr_as_string(name), &key); api_free_string(key); } if (id > 0) { @@ -476,7 +476,7 @@ void augroup_del(char *name, bool stupid_legacy_mode) int augroup_find(const char *name) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { - int existing_id = map_get(String, int)(&map_augroup_name_to_id, cstr_as_string((char *)name)); + int existing_id = map_get(String, int)(&map_augroup_name_to_id, cstr_as_string(name)); if (existing_id == AUGROUP_DELETED) { return existing_id; } @@ -1335,7 +1335,7 @@ void aucmd_prepbuf(aco_save_T *aco, buf_T *buf) if (need_append) { win_append(lastwin, auc_win); pmap_put(int)(&window_handles, auc_win->handle, auc_win); - win_config_float(auc_win, auc_win->w_float_config); + win_config_float(auc_win, auc_win->w_config); } // Prevent chdir() call in win_enter_ext(), through do_autochdir() int save_acd = p_acd; diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 7c0d415099..38c3ee13aa 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -2773,7 +2773,7 @@ void get_winopts(buf_T *buf) curwin->w_changelistidx = wip->wi_changelistidx; } - if (curwin->w_float_config.style == kWinStyleMinimal) { + if (curwin->w_config.style == kWinStyleMinimal) { didset_window_options(curwin, false); win_set_minimal_style(curwin); } diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index adbece20f2..80e8b88182 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -913,6 +913,7 @@ typedef enum { kBorderTextFooter = 1, } BorderTextType; +/// See ":help nvim_open_win()" for documentation. typedef struct { Window window; lpos_T bufpos; @@ -1278,7 +1279,7 @@ struct window_S { bool w_pos_changed; // true if window position changed bool w_floating; ///< whether the window is floating bool w_float_is_info; // the floating window is info float - WinConfig w_float_config; + WinConfig w_config; // w_fraction is the fractional row of the cursor within the window, from // 0 at the top row to FRACTION_MULT at the last row. diff --git a/src/nvim/buffer_updates.c b/src/nvim/buffer_updates.c index a91a890d0e..1a02ac78d7 100644 --- a/src/nvim/buffer_updates.c +++ b/src/nvim/buffer_updates.c @@ -55,36 +55,33 @@ bool buf_updates_register(buf_T *buf, uint64_t channel_id, BufUpdateCallbacks cb kv_push(buf->update_channels, channel_id); if (send_buffer) { - Array args = ARRAY_DICT_INIT; - args.size = 6; - args.items = xcalloc(args.size, sizeof(Object)); + MAXSIZE_TEMP_ARRAY(args, 6); // the first argument is always the buffer handle - args.items[0] = BUFFER_OBJ(buf->handle); - args.items[1] = INTEGER_OBJ(buf_get_changedtick(buf)); + ADD_C(args, BUFFER_OBJ(buf->handle)); + ADD_C(args, INTEGER_OBJ(buf_get_changedtick(buf))); // the first line that changed (zero-indexed) - args.items[2] = INTEGER_OBJ(0); + ADD_C(args, INTEGER_OBJ(0)); // the last line that was changed - args.items[3] = INTEGER_OBJ(-1); - Array linedata = ARRAY_DICT_INIT; + ADD_C(args, INTEGER_OBJ(-1)); // collect buffer contents STATIC_ASSERT(SIZE_MAX >= MAXLNUM, "size_t smaller than MAXLNUM"); size_t line_count = (size_t)buf->b_ml.ml_line_count; - if (line_count >= 1) { - linedata.size = line_count; - linedata.items = xcalloc(line_count, sizeof(Object)); - - buf_collect_lines(buf, line_count, 1, 0, true, &linedata, NULL, NULL); + Array linedata = ARRAY_DICT_INIT; + Arena arena = ARENA_EMPTY; + if (line_count > 0) { + linedata = arena_array(&arena, line_count); + buf_collect_lines(buf, line_count, 1, 0, true, &linedata, NULL, &arena); } - args.items[4] = ARRAY_OBJ(linedata); - args.items[5] = BOOLEAN_OBJ(false); + ADD_C(args, ARRAY_OBJ(linedata)); + ADD_C(args, BOOLEAN_OBJ(false)); rpc_send_event(channel_id, "nvim_buf_lines_event", args); - api_free_array(args); // TODO(bfredl): no + arena_mem_free(arena_finish(&arena)); } else { buf_updates_changedtick_single(buf, channel_id); } @@ -176,13 +173,10 @@ void buf_updates_unload(buf_T *buf, bool can_reload) } if (thecb != LUA_NOREF) { - Array args = ARRAY_DICT_INIT; - Object items[1]; - args.size = 1; - args.items = items; + MAXSIZE_TEMP_ARRAY(args, 1); // the first argument is always the buffer handle - args.items[0] = BUFFER_OBJ(buf->handle); + ADD_C(args, BUFFER_OBJ(buf->handle)); TEXTLOCK_WRAP({ nlua_call_ref(thecb, keep ? "reload" : "detach", args, false, NULL); @@ -219,45 +213,43 @@ void buf_updates_send_changes(buf_T *buf, linenr_T firstline, int64_t num_added, // if one the channels doesn't work, put its ID here so we can remove it later uint64_t badchannelid = 0; + Arena arena = ARENA_EMPTY; + Array linedata = ARRAY_DICT_INIT; + if (num_added > 0 && kv_size(buf->update_channels)) { + STATIC_ASSERT(SIZE_MAX >= MAXLNUM, "size_t smaller than MAXLNUM"); + linedata = arena_array(&arena, (size_t)num_added); + buf_collect_lines(buf, (size_t)num_added, firstline, 0, true, &linedata, + NULL, &arena); + } + // notify each of the active channels for (size_t i = 0; i < kv_size(buf->update_channels); i++) { uint64_t channelid = kv_A(buf->update_channels, i); // send through the changes now channel contents now - Array args = ARRAY_DICT_INIT; - args.size = 6; - args.items = xcalloc(args.size, sizeof(Object)); + MAXSIZE_TEMP_ARRAY(args, 6); // the first argument is always the buffer handle - args.items[0] = BUFFER_OBJ(buf->handle); + ADD_C(args, BUFFER_OBJ(buf->handle)); // next argument is b:changedtick - args.items[1] = send_tick ? INTEGER_OBJ(buf_get_changedtick(buf)) : NIL; + ADD_C(args, send_tick ? INTEGER_OBJ(buf_get_changedtick(buf)) : NIL); // the first line that changed (zero-indexed) - args.items[2] = INTEGER_OBJ(firstline - 1); + ADD_C(args, INTEGER_OBJ(firstline - 1)); // the last line that was changed - args.items[3] = INTEGER_OBJ(firstline - 1 + num_removed); + ADD_C(args, INTEGER_OBJ(firstline - 1 + num_removed)); // linedata of lines being swapped in - Array linedata = ARRAY_DICT_INIT; - if (num_added > 0) { - STATIC_ASSERT(SIZE_MAX >= MAXLNUM, "size_t smaller than MAXLNUM"); - linedata.size = (size_t)num_added; - linedata.items = xcalloc((size_t)num_added, sizeof(Object)); - buf_collect_lines(buf, (size_t)num_added, firstline, 0, true, &linedata, - NULL, NULL); - } - args.items[4] = ARRAY_OBJ(linedata); - args.items[5] = BOOLEAN_OBJ(false); + ADD_C(args, ARRAY_OBJ(linedata)); + ADD_C(args, BOOLEAN_OBJ(false)); if (!rpc_send_event(channelid, "nvim_buf_lines_event", args)) { // We can't unregister the channel while we're iterating over the // update_channels array, so we remember its ID to unregister it at // the end. badchannelid = channelid; } - api_free_array(args); // TODO(bfredl): no } // We can only ever remove one dead channel at a time. This is OK because the @@ -268,38 +260,37 @@ void buf_updates_send_changes(buf_T *buf, linenr_T firstline, int64_t num_added, buf_updates_unregister(buf, badchannelid); } - // notify each of the active channels + // callbacks don't use linedata + arena_mem_free(arena_finish(&arena)); + + // notify each of the active callbacks size_t j = 0; for (size_t i = 0; i < kv_size(buf->update_callbacks); i++) { BufUpdateCallbacks cb = kv_A(buf->update_callbacks, i); bool keep = true; if (cb.on_lines != LUA_NOREF && (cb.preview || !cmdpreview)) { - Array args = ARRAY_DICT_INIT; - Object items[8]; - args.size = 6; // may be increased to 8 below - args.items = items; + MAXSIZE_TEMP_ARRAY(args, 8); // 6 or 8 used // the first argument is always the buffer handle - args.items[0] = BUFFER_OBJ(buf->handle); + ADD_C(args, BUFFER_OBJ(buf->handle)); // next argument is b:changedtick - args.items[1] = send_tick ? INTEGER_OBJ(buf_get_changedtick(buf)) : NIL; + ADD_C(args, send_tick ? INTEGER_OBJ(buf_get_changedtick(buf)) : NIL); // the first line that changed (zero-indexed) - args.items[2] = INTEGER_OBJ(firstline - 1); + ADD_C(args, INTEGER_OBJ(firstline - 1)); // the last line that was changed - args.items[3] = INTEGER_OBJ(firstline - 1 + num_removed); + ADD_C(args, INTEGER_OBJ(firstline - 1 + num_removed)); // the last line in the updated range - args.items[4] = INTEGER_OBJ(firstline - 1 + num_added); + ADD_C(args, INTEGER_OBJ(firstline - 1 + num_added)); // byte count of previous contents - args.items[5] = INTEGER_OBJ((Integer)deleted_bytes); + ADD_C(args, INTEGER_OBJ((Integer)deleted_bytes)); if (cb.utf_sizes) { - args.size = 8; - args.items[6] = INTEGER_OBJ((Integer)deleted_codepoints); - args.items[7] = INTEGER_OBJ((Integer)deleted_codeunits); + ADD_C(args, INTEGER_OBJ((Integer)deleted_codepoints)); + ADD_C(args, INTEGER_OBJ((Integer)deleted_codeunits)); } Object res; diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 05148801f4..1dc1208696 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -962,10 +962,11 @@ Dictionary channel_info(uint64_t id) } /// Simple int64_t comparison function for use with qsort() -static int int64_t_cmp(const void *a, const void *b) +static int int64_t_cmp(const void *pa, const void *pb) { - int64_t diff = *(int64_t *)a - *(int64_t *)b; - return (diff < 0) ? -1 : (diff > 0); + const int64_t a = *(const int64_t *)pa; + const int64_t b = *(const int64_t *)pb; + return a == b ? 0 : a > b ? 1 : -1; } Array channel_all_info(void) diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index a593b8eda1..9767c44897 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -673,10 +673,20 @@ int sign_item_cmp(const void *p1, const void *p2) { const SignItem *s1 = (SignItem *)p1; const SignItem *s2 = (SignItem *)p2; - int n = s2->sh->priority - s1->sh->priority; - return n ? n : (n = (int)(s2->id - s1->id)) - ? n : (s2->sh->sign_add_id - s1->sh->sign_add_id); + if (s1->sh->priority != s2->sh->priority) { + return s1->sh->priority < s2->sh->priority ? 1 : -1; + } + + if (s1->id != s2->id) { + return s1->id < s2->id ? 1 : -1; + } + + if (s1->sh->sign_add_id != s2->sh->sign_add_id) { + return s1->sh->sign_add_id > s2->sh->sign_add_id ? 1 : -1; + } + + return 0; } static const uint32_t sign_filter[4] = {[kMTMetaSignText] = kMTFilterSelect, @@ -977,12 +987,12 @@ void decor_to_dict_legacy(Dictionary *dict, DecorInline decor, bool hl_name, Are } if (sh_hl.url != NULL) { - PUT_C(*dict, "url", STRING_OBJ(cstr_as_string((char *)sh_hl.url))); + PUT_C(*dict, "url", STRING_OBJ(cstr_as_string(sh_hl.url))); } if (virt_text) { if (virt_text->hl_mode) { - PUT_C(*dict, "hl_mode", CSTR_AS_OBJ((char *)hl_mode_str[virt_text->hl_mode])); + PUT_C(*dict, "hl_mode", CSTR_AS_OBJ(hl_mode_str[virt_text->hl_mode])); } Array chunks = virt_text_to_array(virt_text->data.virt_text, hl_name, arena); @@ -992,7 +1002,7 @@ void decor_to_dict_legacy(Dictionary *dict, DecorInline decor, bool hl_name, Are if (virt_text->pos == kVPosWinCol) { PUT_C(*dict, "virt_text_win_col", INTEGER_OBJ(virt_text->col)); } - PUT_C(*dict, "virt_text_pos", CSTR_AS_OBJ((char *)virt_text_pos_str[virt_text->pos])); + PUT_C(*dict, "virt_text_pos", CSTR_AS_OBJ(virt_text_pos_str[virt_text->pos])); priority = virt_text->priority; } diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 3d048d178e..4df01d9476 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -738,7 +738,7 @@ int win_get_bordertext_col(int total_col, int text_width, AlignTextPos align) static void win_redr_border(win_T *wp) { wp->w_redr_border = false; - if (!(wp->w_floating && wp->w_float_config.border)) { + if (!(wp->w_floating && wp->w_config.border)) { return; } @@ -746,9 +746,9 @@ static void win_redr_border(win_T *wp) schar_T chars[8]; for (int i = 0; i < 8; i++) { - chars[i] = schar_from_str(wp->w_float_config.border_chars[i]); + chars[i] = schar_from_str(wp->w_config.border_chars[i]); } - int *attrs = wp->w_float_config.border_attr; + int *attrs = wp->w_config.border_attr; int *adj = wp->w_border_adj; int irow = wp->w_height_inner + wp->w_winbar_height; @@ -764,10 +764,10 @@ static void win_redr_border(win_T *wp) grid_line_put_schar(i + adj[3], chars[1], attrs[1]); } - if (wp->w_float_config.title) { - int title_col = win_get_bordertext_col(icol, wp->w_float_config.title_width, - wp->w_float_config.title_pos); - win_redr_bordertext(wp, wp->w_float_config.title_chunks, title_col); + if (wp->w_config.title) { + int title_col = win_get_bordertext_col(icol, wp->w_config.title_width, + wp->w_config.title_pos); + win_redr_bordertext(wp, wp->w_config.title_chunks, title_col); } if (adj[1]) { grid_line_put_schar(icol + adj[3], chars[2], attrs[2]); @@ -800,10 +800,10 @@ static void win_redr_border(win_T *wp) grid_line_put_schar(i + adj[3], chars[ic], attrs[ic]); } - if (wp->w_float_config.footer) { - int footer_col = win_get_bordertext_col(icol, wp->w_float_config.footer_width, - wp->w_float_config.footer_pos); - win_redr_bordertext(wp, wp->w_float_config.footer_chunks, footer_col); + if (wp->w_config.footer) { + int footer_col = win_get_bordertext_col(icol, wp->w_config.footer_width, + wp->w_config.footer_pos); + win_redr_bordertext(wp, wp->w_config.footer_chunks, footer_col); } if (adj[1]) { grid_line_put_schar(icol + adj[3], chars[4], attrs[4]); @@ -1149,11 +1149,11 @@ void clearmode(void) static void recording_mode(int attr) { - msg_puts_attr(_("recording"), attr); if (shortmess(SHM_RECORDING)) { return; } + msg_puts_attr(_("recording"), attr); char s[4]; snprintf(s, ARRAY_SIZE(s), " @%c", reg_recording); msg_puts_attr(s, attr); diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 655d6c9ab3..e4d2a219d9 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -2093,8 +2093,8 @@ static void f_feedkeys(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) flags = tv_get_string_buf(&argvars[1], nbuf); } - nvim_feedkeys(cstr_as_string((char *)keys), - cstr_as_string((char *)flags), true); + nvim_feedkeys(cstr_as_string(keys), + cstr_as_string(flags), true); } /// "filereadable()" function @@ -4528,7 +4528,7 @@ static void f_luaeval(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) return; } - nlua_typval_eval(cstr_as_string((char *)str), &argvars[1], rettv); + nlua_typval_eval(cstr_as_string(str), &argvars[1], rettv); } static void find_some_match(typval_T *const argvars, typval_T *const rettv, diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index e265dc139a..70146a8602 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -406,18 +406,16 @@ static int sort_compare(const void *s1, const void *s2) // number. if (sort_nr) { if (l1.st_u.num.is_number != l2.st_u.num.is_number) { - result = l1.st_u.num.is_number - l2.st_u.num.is_number; + result = l1.st_u.num.is_number > l2.st_u.num.is_number ? 1 : -1; } else { result = l1.st_u.num.value == l2.st_u.num.value ? 0 - : l1.st_u.num.value > l2.st_u.num.value - ? 1 - : -1; + : l1.st_u.num.value > l2.st_u.num.value ? 1 : -1; } } else if (sort_flt) { result = l1.st_u.value_flt == l2.st_u.value_flt - ? 0 : l1.st_u.value_flt > l2.st_u.value_flt - ? 1 : -1; + ? 0 + : l1.st_u.value_flt > l2.st_u.value_flt ? 1 : -1; } else { // We need to copy one line into "sortbuf1", because there is no // guarantee that the first pointer becomes invalid when obtaining the diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 484b3572ab..8016e37ca7 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -551,7 +551,7 @@ void ex_listdo(exarg_T *eap) break; } assert(wp); - execute = !wp->w_floating || wp->w_float_config.focusable; + execute = !wp->w_floating || wp->w_config.focusable; if (execute) { win_goto(wp); if (curwin != wp) { diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index da3010878d..04fe43b712 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -55,15 +55,15 @@ local function add_function(fn) -- for specifying errors fn.parameters[#fn.parameters] = nil end + if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'lstate' then + fn.has_lua_imp = true + fn.parameters[#fn.parameters] = nil + end if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'arena' then -- return value is allocated in an arena fn.arena_return = true fn.parameters[#fn.parameters] = nil end - if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'lstate' then - fn.has_lua_imp = true - fn.parameters[#fn.parameters] = nil - end end end diff --git a/src/nvim/globals.h b/src/nvim/globals.h index bcac32a252..22f7daa823 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -978,9 +978,7 @@ EXTERN const char bot_top_msg[] INIT(= N_("search hit BOTTOM, continuing at TOP" EXTERN const char line_msg[] INIT(= N_(" line ")); -EXTERN FILE *time_fd INIT(= NULL); // where to write startup timing -#define STARTUP_TIME_BUF_SIZE 8192 -EXTERN char *startuptime_buf INIT(= NULL); // --startuptime buffer +EXTERN FILE *time_fd INIT(= NULL); // Where to write --startuptime report. // Some compilers warn for not using a return value, but in some situations we // can't do anything useful with the value. Assign to this variable to avoid diff --git a/src/nvim/grid.c b/src/nvim/grid.c index e0caa3841b..b6a8a8bd9f 100644 --- a/src/nvim/grid.c +++ b/src/nvim/grid.c @@ -912,7 +912,7 @@ void win_grid_alloc(win_T *wp) grid_alloc(grid_allocated, total_rows, total_cols, wp->w_grid_alloc.valid, false); grid_allocated->valid = true; - if (wp->w_floating && wp->w_float_config.border) { + if (wp->w_floating && wp->w_config.border) { wp->w_redr_border = true; } was_resized = true; diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c index 17d743784f..e74ae817d0 100644 --- a/src/nvim/highlight.c +++ b/src/nvim/highlight.c @@ -116,12 +116,13 @@ retry: {} // new attr id, send event to remote ui:s int id = (int)k; - Array inspect = hl_inspect(id); + Arena arena = ARENA_EMPTY; + Array inspect = hl_inspect(id, &arena); // Note: internally we don't distinguish between cterm and rgb attributes, // remote_ui_hl_attr_define will however. ui_call_hl_attr_define(id, entry.attr, entry.attr, inspect); - api_free_array(inspect); + arena_mem_free(arena_finish(&arena)); return id; } @@ -129,13 +130,14 @@ retry: {} void ui_send_all_hls(UI *ui) { for (size_t i = 1; i < set_size(&attr_entries); i++) { - Array inspect = hl_inspect((int)i); + Arena arena = ARENA_EMPTY; + Array inspect = hl_inspect((int)i, &arena); HlAttrs attr = attr_entry(i).attr; remote_ui_hl_attr_define(ui, (Integer)i, attr, attr, inspect); - api_free_array(inspect); + arena_mem_free(arena_finish(&arena)); } for (size_t hlf = 0; hlf < HLF_COUNT; hlf++) { - remote_ui_hl_group_set(ui, cstr_as_string((char *)hlf_names[hlf]), + remote_ui_hl_group_set(ui, cstr_as_string(hlf_names[hlf]), highlight_attr[hlf]); } } @@ -204,7 +206,7 @@ int ns_get_hl(NS *ns_hl, int hl_id, bool link, bool nodefault) if (!valid_item && p->hl_def != LUA_NOREF && !recursive) { MAXSIZE_TEMP_ARRAY(args, 3); ADD_C(args, INTEGER_OBJ((Integer)ns_id)); - ADD_C(args, CSTR_TO_OBJ(syn_id2name(hl_id))); + ADD_C(args, CSTR_AS_OBJ(syn_id2name(hl_id))); ADD_C(args, BOOLEAN_OBJ(link)); // TODO(bfredl): preload the "global" attr dict? @@ -367,7 +369,7 @@ void update_window_hl(win_T *wp, bool invalid) // wp->w_hl_attr_normal group. HL_ATTR(HLF_NFLOAT) is always named. // determine window specific background set in 'winhighlight' - bool float_win = wp->w_floating && !wp->w_float_config.external; + bool float_win = wp->w_floating && !wp->w_config.external; if (float_win && hl_def[HLF_NFLOAT] != 0) { wp->w_hl_attr_normal = hl_def[HLF_NFLOAT]; } else if (hl_def[HLF_COUNT] > 0) { @@ -380,19 +382,19 @@ void update_window_hl(win_T *wp, bool invalid) wp->w_hl_attr_normal = hl_apply_winblend(wp, wp->w_hl_attr_normal); } - wp->w_float_config.shadow = false; - if (wp->w_floating && wp->w_float_config.border) { + wp->w_config.shadow = false; + if (wp->w_floating && wp->w_config.border) { for (int i = 0; i < 8; i++) { int attr = hl_def[HLF_BORDER]; - if (wp->w_float_config.border_hl_ids[i]) { + if (wp->w_config.border_hl_ids[i]) { attr = hl_get_ui_attr(ns_id, HLF_BORDER, - wp->w_float_config.border_hl_ids[i], false); + wp->w_config.border_hl_ids[i], false); } attr = hl_apply_winblend(wp, attr); if (syn_attr2entry(attr).hl_blend > 0) { - wp->w_float_config.shadow = true; + wp->w_config.shadow = true; } - wp->w_float_config.border_attr[i] = attr; + wp->w_config.border_attr[i] = attr; } } @@ -1176,17 +1178,30 @@ int object_to_color(Object val, char *key, bool rgb, Error *err) } } -Array hl_inspect(int attr) +Array hl_inspect(int attr, Arena *arena) { - // TODO(bfredl): use arena allocation - Array ret = ARRAY_DICT_INIT; - if (hlstate_active) { - hl_inspect_impl(&ret, attr); + if (!hlstate_active) { + return (Array)ARRAY_DICT_INIT; } + Array ret = arena_array(arena, hl_inspect_size(attr)); + hl_inspect_impl(&ret, attr, arena); return ret; } -static void hl_inspect_impl(Array *arr, int attr) +static size_t hl_inspect_size(int attr) +{ + if (attr <= 0 || attr >= (int)set_size(&attr_entries)) { + return 0; + } + + HlEntry e = attr_entry(attr); + if (e.kind == kHlCombine || e.kind == kHlBlend || e.kind == kHlBlendThrough) { + return hl_inspect_size(e.id1) + hl_inspect_size(e.id2); + } + return 1; +} + +static void hl_inspect_impl(Array *arr, int attr, Arena *arena) { Dictionary item = ARRAY_DICT_INIT; if (attr <= 0 || attr >= (int)set_size(&attr_entries)) { @@ -1196,35 +1211,36 @@ static void hl_inspect_impl(Array *arr, int attr) HlEntry e = attr_entry(attr); switch (e.kind) { case kHlSyntax: - PUT(item, "kind", CSTR_TO_OBJ("syntax")); - PUT(item, "hi_name", - CSTR_TO_OBJ(syn_id2name(e.id1))); + item = arena_dict(arena, 3); + PUT_C(item, "kind", CSTR_AS_OBJ("syntax")); + PUT_C(item, "hi_name", CSTR_AS_OBJ(syn_id2name(e.id1))); break; case kHlUI: - PUT(item, "kind", CSTR_TO_OBJ("ui")); + item = arena_dict(arena, 4); + PUT_C(item, "kind", CSTR_AS_OBJ("ui")); const char *ui_name = (e.id1 == -1) ? "Normal" : hlf_names[e.id1]; - PUT(item, "ui_name", CSTR_TO_OBJ(ui_name)); - PUT(item, "hi_name", - CSTR_TO_OBJ(syn_id2name(e.id2))); + PUT_C(item, "ui_name", CSTR_AS_OBJ(ui_name)); + PUT_C(item, "hi_name", CSTR_AS_OBJ(syn_id2name(e.id2))); break; case kHlTerminal: - PUT(item, "kind", CSTR_TO_OBJ("term")); + item = arena_dict(arena, 2); + PUT_C(item, "kind", CSTR_AS_OBJ("term")); break; case kHlCombine: case kHlBlend: case kHlBlendThrough: // attribute combination is associative, so flatten to an array - hl_inspect_impl(arr, e.id1); - hl_inspect_impl(arr, e.id2); + hl_inspect_impl(arr, e.id1, arena); + hl_inspect_impl(arr, e.id2, arena); return; case kHlUnknown: case kHlInvalid: return; } - PUT(item, "id", INTEGER_OBJ(attr)); - ADD(*arr, DICTIONARY_OBJ(item)); + PUT_C(item, "id", INTEGER_OBJ(attr)); + ADD_C(*arr, DICTIONARY_OBJ(item)); } diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c index 67b33e6ef7..75c23c5bc4 100644 --- a/src/nvim/highlight_group.c +++ b/src/nvim/highlight_group.c @@ -1672,10 +1672,7 @@ Dictionary ns_get_hl_defs(NS ns_id, Dict(get_highlight) *opts, Arena *arena, Err return rv; cleanup: - api_free_integer(id); - api_free_boolean(link); - Dictionary empty = ARRAY_DICT_INIT; - return empty; + return (Dictionary)ARRAY_DICT_INIT; } /// Outputs a highlight when doing ":hi MyHighlight" @@ -2241,7 +2238,7 @@ void highlight_changed(void) HlAttrs attrs = syn_attr2entry(highlight_attr[hlf]); msg_grid.blending = attrs.hl_blend > -1; } - ui_call_hl_group_set(cstr_as_string((char *)hlf_names[hlf]), + ui_call_hl_group_set(cstr_as_string(hlf_names[hlf]), highlight_attr[hlf]); highlight_attr_last[hlf] = highlight_attr[hlf]; } diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index 8583b236c7..fd353d8a67 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -2792,8 +2792,10 @@ static int tv_nr_compare(const void *a1, const void *a2) { const listitem_T *const li1 = tv_list_first(*(const list_T **)a1); const listitem_T *const li2 = tv_list_first(*(const list_T **)a2); + const varnumber_T n1 = TV_LIST_ITEM_TV(li1)->vval.v_number; + const varnumber_T n2 = TV_LIST_ITEM_TV(li2)->vval.v_number; - return (int)(TV_LIST_ITEM_TV(li1)->vval.v_number - TV_LIST_ITEM_TV(li2)->vval.v_number); + return n1 == n2 ? 0 : n1 > n2 ? 1 : -1; } /// "setcellwidths()" function diff --git a/src/nvim/message.c b/src/nvim/message.c index cb89d34e23..d879fa1423 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -210,7 +210,11 @@ void msg_grid_validate(void) msg_grid_adj.target = &default_grid; redraw_cmdline = true; } else if (msg_grid.chars && !msg_scrolled && msg_grid_pos != max_rows) { + int diff = msg_grid_pos - max_rows; msg_grid_set_pos(max_rows, false); + if (diff > 0) { + grid_clear(&msg_grid_adj, Rows - diff, Rows, 0, Columns, HL_ATTR(HLF_MSG)); + } } msg_grid_adj.cols = Columns; @@ -3017,7 +3021,7 @@ void msg_ext_ui_flush(void) msg_ext_emit_chunk(); if (msg_ext_chunks.size > 0) { - ui_call_msg_show(cstr_as_string((char *)msg_ext_kind), + ui_call_msg_show(cstr_as_string(msg_ext_kind), msg_ext_chunks, msg_ext_overwrite); if (!msg_ext_overwrite) { msg_ext_visible++; diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 4dbe31a07f..f4d1be5b2f 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1722,7 +1722,7 @@ static win_T *mouse_find_grid_win(int *gridp, int *rowp, int *colp) } else if (*gridp > 1) { win_T *wp = get_win_by_grid_handle(*gridp); if (wp && wp->w_grid_alloc.chars - && !(wp->w_floating && !wp->w_float_config.focusable)) { + && !(wp->w_floating && !wp->w_config.focusable)) { *rowp = MIN(*rowp - wp->w_grid.row_offset, wp->w_grid.rows - 1); *colp = MIN(*colp - wp->w_grid.col_offset, wp->w_grid.cols - 1); return wp; diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 0178ef622b..36fa7e77fc 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -547,7 +547,7 @@ static void send_error(Channel *chan, MsgpackRpcRequestHandler handler, MessageT static void send_request(Channel *channel, uint32_t id, const char *name, Array args) { - const String method = cstr_as_string((char *)name); + const String method = cstr_as_string(name); channel_write(channel, serialize_request(channel->id, id, method, @@ -558,7 +558,7 @@ static void send_request(Channel *channel, uint32_t id, const char *name, Array static void send_event(Channel *channel, const char *name, Array args) { - const String method = cstr_as_string((char *)name); + const String method = cstr_as_string(name); channel_write(channel, serialize_request(channel->id, 0, method, @@ -583,7 +583,7 @@ static void broadcast_event(const char *name, Array args) goto end; } - const String method = cstr_as_string((char *)name); + const String method = cstr_as_string(name); WBuffer *buffer = serialize_request(0, 0, method, diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 8b6ef62873..d69e43e6b3 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -375,7 +375,7 @@ static int nv_compare(const void *s1, const void *s2) if (c2 < 0) { c2 = -c2; } - return c1 - c2; + return c1 == c2 ? 0 : c1 > c2 ? 1 : -1; } /// Initialize the nv_cmd_idx[] table. diff --git a/src/nvim/option.c b/src/nvim/option.c index db013b460e..42ccc1fbd4 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1790,7 +1790,7 @@ bool valid_name(const char *val, const char *allowed) void check_blending(win_T *wp) { wp->w_grid_alloc.blending = - wp->w_p_winbl > 0 || (wp->w_floating && wp->w_float_config.shadow); + wp->w_p_winbl > 0 || (wp->w_floating && wp->w_config.shadow); } /// Handle setting `winhighlight' in window "wp" @@ -6314,32 +6314,33 @@ int get_sidescrolloff_value(win_T *wp) return (int)(wp->w_p_siso < 0 ? p_siso : wp->w_p_siso); } -Dictionary get_vimoption(String name, int scope, buf_T *buf, win_T *win, Error *err) +Dictionary get_vimoption(String name, int scope, buf_T *buf, win_T *win, Arena *arena, Error *err) { OptIndex opt_idx = find_option_len(name.data, name.size); VALIDATE_S(opt_idx != kOptInvalid, "option (not found)", name.data, { return (Dictionary)ARRAY_DICT_INIT; }); - return vimoption2dict(&options[opt_idx], scope, buf, win); + return vimoption2dict(&options[opt_idx], scope, buf, win, arena); } -Dictionary get_all_vimoptions(void) +Dictionary get_all_vimoptions(Arena *arena) { - Dictionary retval = ARRAY_DICT_INIT; + Dictionary retval = arena_dict(arena, kOptIndexCount); for (OptIndex opt_idx = 0; opt_idx < kOptIndexCount; opt_idx++) { - Dictionary opt_dict = vimoption2dict(&options[opt_idx], OPT_GLOBAL, curbuf, curwin); - PUT(retval, options[opt_idx].fullname, DICTIONARY_OBJ(opt_dict)); + Dictionary opt_dict = vimoption2dict(&options[opt_idx], OPT_GLOBAL, curbuf, curwin, arena); + PUT_C(retval, options[opt_idx].fullname, DICTIONARY_OBJ(opt_dict)); } return retval; } -static Dictionary vimoption2dict(vimoption_T *opt, int req_scope, buf_T *buf, win_T *win) +static Dictionary vimoption2dict(vimoption_T *opt, int req_scope, buf_T *buf, win_T *win, + Arena *arena) { - Dictionary dict = ARRAY_DICT_INIT; + Dictionary dict = arena_dict(arena, 13); - PUT(dict, "name", CSTR_TO_OBJ(opt->fullname)); - PUT(dict, "shortname", CSTR_TO_OBJ(opt->shortname)); + PUT_C(dict, "name", CSTR_AS_OBJ(opt->fullname)); + PUT_C(dict, "shortname", CSTR_AS_OBJ(opt->shortname)); const char *scope; if (opt->indir & PV_BUF) { @@ -6350,14 +6351,14 @@ static Dictionary vimoption2dict(vimoption_T *opt, int req_scope, buf_T *buf, wi scope = "global"; } - PUT(dict, "scope", CSTR_TO_OBJ(scope)); + PUT_C(dict, "scope", CSTR_AS_OBJ(scope)); // welcome to the jungle - PUT(dict, "global_local", BOOLEAN_OBJ(opt->indir & PV_BOTH)); - PUT(dict, "commalist", BOOLEAN_OBJ(opt->flags & P_COMMA)); - PUT(dict, "flaglist", BOOLEAN_OBJ(opt->flags & P_FLAGLIST)); + PUT_C(dict, "global_local", BOOLEAN_OBJ(opt->indir & PV_BOTH)); + PUT_C(dict, "commalist", BOOLEAN_OBJ(opt->flags & P_COMMA)); + PUT_C(dict, "flaglist", BOOLEAN_OBJ(opt->flags & P_FLAGLIST)); - PUT(dict, "was_set", BOOLEAN_OBJ(opt->flags & P_WAS_SET)); + PUT_C(dict, "was_set", BOOLEAN_OBJ(opt->flags & P_WAS_SET)); LastSet last_set = { .channel_id = 0 }; if (req_scope == OPT_GLOBAL) { @@ -6375,16 +6376,16 @@ static Dictionary vimoption2dict(vimoption_T *opt, int req_scope, buf_T *buf, wi } } - PUT(dict, "last_set_sid", INTEGER_OBJ(last_set.script_ctx.sc_sid)); - PUT(dict, "last_set_linenr", INTEGER_OBJ(last_set.script_ctx.sc_lnum)); - PUT(dict, "last_set_chan", INTEGER_OBJ((int64_t)last_set.channel_id)); + PUT_C(dict, "last_set_sid", INTEGER_OBJ(last_set.script_ctx.sc_sid)); + PUT_C(dict, "last_set_linenr", INTEGER_OBJ(last_set.script_ctx.sc_lnum)); + PUT_C(dict, "last_set_chan", INTEGER_OBJ((int64_t)last_set.channel_id)); // TODO(bfredl): do you even nocp? OptVal def = optval_from_varp(get_opt_idx(opt), &opt->def_val); - PUT(dict, "type", CSTR_TO_OBJ(optval_type_get_name(def.type))); - PUT(dict, "default", optval_as_object(optval_copy(def))); - PUT(dict, "allows_duplicates", BOOLEAN_OBJ(!(opt->flags & P_NODUP))); + PUT_C(dict, "type", CSTR_AS_OBJ(optval_type_get_name(def.type))); + PUT_C(dict, "default", optval_as_object(def)); + PUT_C(dict, "allows_duplicates", BOOLEAN_OBJ(!(opt->flags & P_NODUP))); return dict; } diff --git a/src/nvim/option_vars.h b/src/nvim/option_vars.h index 3dc82f8fdf..a389516bd3 100644 --- a/src/nvim/option_vars.h +++ b/src/nvim/option_vars.h @@ -218,7 +218,7 @@ enum { SHM_INTRO = 'I', ///< Intro messages. SHM_COMPLETIONMENU = 'c', ///< Completion menu messages. SHM_COMPLETIONSCAN = 'C', ///< Completion scanning messages. - SHM_RECORDING = 'q', ///< Short recording message. + SHM_RECORDING = 'q', ///< No recording message. SHM_FILEINFO = 'F', ///< No file info messages. SHM_SEARCHCOUNT = 'S', ///< No search stats: '[1/10]' }; diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 5c0d249ac3..b993a50b18 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -7329,7 +7329,7 @@ return { match", "Pattern not found", "Back at original", etc. C don't give messages while scanning for ins-completion *shm-C* items, for instance "scanning tags" - q use "recording" instead of "recording @a" *shm-q* + q do not show "recording @a" when recording a macro *shm-q* F don't give the file info when editing a file, like *shm-F* `:silent` was used for the command S do not show search count message when searching, e.g. *shm-S* diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 566d51f30a..ade745df2c 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -95,7 +95,7 @@ int os_chdir(const char *path) } int err = uv_chdir(path); if (err == 0) { - ui_call_chdir(cstr_as_string((char *)path)); + ui_call_chdir(cstr_as_string(path)); } return err; } diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c index 3f2d27edd0..e34d6fd97f 100644 --- a/src/nvim/popupmenu.c +++ b/src/nvim/popupmenu.c @@ -488,7 +488,7 @@ void pum_redraw(void) if (ui_has(kUIMultigrid)) { const char *anchor = pum_above ? "SW" : "NW"; int row_off = pum_above ? -pum_height : 0; - ui_call_win_float_pos(pum_grid.handle, -1, cstr_as_string((char *)anchor), pum_anchor_grid, + ui_call_win_float_pos(pum_grid.handle, -1, cstr_as_string(anchor), pum_anchor_grid, pum_row - row_off, pum_left_col, false, pum_grid.zindex); } @@ -744,16 +744,16 @@ static void pum_adjust_float_position(win_T *wp, int height, int width) { // when floating window in right and right no enough room to show // but left has enough room, adjust floating window to left. - if (wp->w_float_config.width < width && wp->w_float_config.col > pum_col) { + if (wp->w_config.width < width && wp->w_config.col > pum_col) { if ((pum_col - 2) > width) { - wp->w_float_config.width = width; - wp->w_float_config.col = pum_col - width - 1; + wp->w_config.width = width; + wp->w_config.col = pum_col - width - 1; } } - wp->w_float_config.width = MIN(wp->w_float_config.width, width); - wp->w_float_config.height = MIN(Rows, height); - wp->w_float_config.hide = false; - win_config_float(wp, wp->w_float_config); + wp->w_config.width = MIN(wp->w_config.width, width); + wp->w_config.height = MIN(Rows, height); + wp->w_config.hide = false; + win_config_float(wp, wp->w_config); } /// used in nvim_complete_set diff --git a/src/nvim/profile.c b/src/nvim/profile.c index 84b58de4a3..b88b08d3f0 100644 --- a/src/nvim/profile.c +++ b/src/nvim/profile.c @@ -45,6 +45,7 @@ typedef struct { #define PRL_ITEM(si, idx) (((sn_prl_T *)(si)->sn_prl_ga.ga_data)[(idx)]) static proftime_T prof_wait_time; +static char *startuptime_buf = NULL; // --startuptime buffer /// Gets the current time. /// @@ -945,29 +946,27 @@ void time_msg(const char *mesg, const proftime_T *start) fprintf(time_fd, ": %s\n", mesg); } -/// Initializes the time time_fd stream used to write startup times +/// Initializes the `time_fd` stream for the --startuptime report. /// -/// @param startup_time_file the startuptime report file path -/// @param process_name the name of the current process to write in the report. -void time_init(const char *startup_time_file, const char *process_name) +/// @param fname startuptime report file path +/// @param process_name name of the current Nvim process to write in the report. +void time_init(const char *fname, const char *process_name) { - time_fd = fopen(startup_time_file, "a"); + const size_t bufsize = 8192; // Big enough for the entire --startuptime report. + time_fd = fopen(fname, "a"); if (time_fd == NULL) { - semsg(_(e_notopen), startup_time_file); + semsg(_(e_notopen), fname); return; } - startuptime_buf = xmalloc(sizeof(char) * (STARTUP_TIME_BUF_SIZE + 1)); - // The startuptime file is (potentially) written by multiple nvim processes concurrently. So - // startuptime info is buffered, and flushed to disk only after startup completed. To achieve that - // we set a buffer big enough to store all startup times. The `_IOFBF` mode ensures the buffer is - // not auto-flushed ("controlled buffering"). - // The times are flushed to disk manually when "time_finish" is called. - int r = setvbuf(time_fd, startuptime_buf, _IOFBF, STARTUP_TIME_BUF_SIZE + 1); + startuptime_buf = xmalloc(sizeof(char) * (bufsize + 1)); + // The startuptime file is (potentially) written by multiple Nvim processes concurrently. So each + // report is buffered, and flushed to disk (`time_finish`) once after startup. `_IOFBF` mode + // ensures the buffer is not auto-flushed ("controlled buffering"). + int r = setvbuf(time_fd, startuptime_buf, _IOFBF, bufsize + 1); if (r != 0) { - xfree(startuptime_buf); + XFREE_CLEAR(startuptime_buf); fclose(time_fd); time_fd = NULL; - // Might as well ELOG also I guess. ELOG("time_init: setvbuf failed: %d %s", r, uv_err_name(r)); semsg("time_init: setvbuf failed: %d %s", r, uv_err_name(r)); return; diff --git a/src/nvim/search.c b/src/nvim/search.c index 273a924876..48e41c290d 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -3197,7 +3197,11 @@ static int fuzzy_match_item_compare(const void *const s1, const void *const s2) const int idx1 = ((const fuzzyItem_T *)s1)->idx; const int idx2 = ((const fuzzyItem_T *)s2)->idx; - return v1 == v2 ? (idx1 - idx2) : v1 > v2 ? -1 : 1; + if (v1 == v2) { + return idx1 == idx2 ? 0 : idx1 > idx2 ? 1 : -1; + } else { + return v1 > v2 ? -1 : 1; + } } /// Fuzzy search the string "str" in a list of "items" and return the matching @@ -3436,7 +3440,11 @@ static int fuzzy_match_str_compare(const void *const s1, const void *const s2) const int idx1 = ((fuzmatch_str_T *)s1)->idx; const int idx2 = ((fuzmatch_str_T *)s2)->idx; - return v1 == v2 ? (idx1 - idx2) : v1 > v2 ? -1 : 1; + if (v1 == v2) { + return idx1 == idx2 ? 0 : idx1 > idx2 ? 1 : -1; + } else { + return v1 > v2 ? -1 : 1; + } } /// Sort fuzzy matches by score @@ -3465,7 +3473,11 @@ static int fuzzy_match_func_compare(const void *const s1, const void *const s2) if (*str1 == '<' && *str2 != '<') { return 1; } - return v1 == v2 ? (idx1 - idx2) : v1 > v2 ? -1 : 1; + if (v1 == v2) { + return idx1 == idx2 ? 0 : idx1 > idx2 ? 1 : -1; + } else { + return v1 > v2 ? -1 : 1; + } } /// Sort fuzzy matches of function names by score. diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 61c43e271b..2c8685adc7 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -1875,9 +1875,7 @@ static int compare_file_marks(const void *a, const void *b) const FileMarks *const *const b_fms = b; return ((*a_fms)->greatest_timestamp == (*b_fms)->greatest_timestamp ? 0 - : ((*a_fms)->greatest_timestamp > (*b_fms)->greatest_timestamp - ? -1 - : 1)); + : ((*a_fms)->greatest_timestamp > (*b_fms)->greatest_timestamp ? -1 : 1)); } /// Parse msgpack object that has given length diff --git a/src/nvim/sign.c b/src/nvim/sign.c index dc09bcc5a0..bd7979153e 100644 --- a/src/nvim/sign.c +++ b/src/nvim/sign.c @@ -55,8 +55,8 @@ # include "sign.c.generated.h" #endif -static PMap(cstr_t) sign_map INIT( = MAP_INIT); -static kvec_t(Integer) sign_ns INIT( = MAP_INIT); +static PMap(cstr_t) sign_map = MAP_INIT; +static kvec_t(Integer) sign_ns = KV_INITIAL_VALUE; static char *cmds[] = { "define", @@ -84,7 +84,7 @@ static int64_t group_get_ns(const char *group) return UINT32_MAX; // All namespaces } // Specific or non-existing namespace - int ns = map_get(String, int)(&namespace_ids, cstr_as_string((char *)group)); + int ns = map_get(String, int)(&namespace_ids, cstr_as_string(group)); return ns ? ns : -1; } @@ -172,20 +172,28 @@ int sign_cmp(const void *p1, const void *p2) { const MTKey *s1 = (MTKey *)p1; const MTKey *s2 = (MTKey *)p2; - int n = s1->pos.row - s2->pos.row; - if (n) { - return n; + if (s1->pos.row != s2->pos.row) { + return s1->pos.row > s2->pos.row ? 1 : -1; } DecorSignHighlight *sh1 = decor_find_sign(mt_decor(*s1)); DecorSignHighlight *sh2 = decor_find_sign(mt_decor(*s2)); assert(sh1 && sh2); - n = sh2->priority - sh1->priority; + if (sh1->priority != sh2->priority) { + return sh1->priority < sh2->priority ? 1 : -1; + } + + if (s1->id != s2->id) { + return s1->id < s2->id ? 1 : -1; + } + + if (sh1->sign_add_id != sh2->sign_add_id) { + return sh1->sign_add_id < sh2->sign_add_id ? 1 : -1; + } - return n ? n : (n = (int)(s2->id - s1->id)) - ? n : (sh2->sign_add_id - sh1->sign_add_id); + return 0; } /// Delete the specified sign(s) diff --git a/src/nvim/spellsuggest.c b/src/nvim/spellsuggest.c index 887ad3a62a..5c0e295f88 100644 --- a/src/nvim/spellsuggest.c +++ b/src/nvim/spellsuggest.c @@ -3221,10 +3221,10 @@ static int sug_compare(const void *s1, const void *s2) { suggest_T *p1 = (suggest_T *)s1; suggest_T *p2 = (suggest_T *)s2; - int n = p1->st_score - p2->st_score; + int n = p1->st_score == p2->st_score ? 0 : p1->st_score > p2->st_score ? 1 : -1; if (n == 0) { - n = p1->st_altscore - p2->st_altscore; + n = p1->st_altscore == p2->st_altscore ? 0 : p1->st_altscore > p2->st_altscore ? 1 : -1; if (n == 0) { n = STRICMP(p1->st_word, p2->st_word); } diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 2744f68951..debd2fe511 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -229,7 +229,7 @@ void ui_refresh(void) } ui_ext[i] = ext_widgets[i]; if (i < kUIGlobalCount) { - ui_call_option_set(cstr_as_string((char *)ui_ext_names[i]), + ui_call_option_set(cstr_as_string(ui_ext_names[i]), BOOLEAN_OBJ(ext_widgets[i])); } } @@ -451,8 +451,7 @@ void ui_set_ext_option(UI *ui, UIExtension ext, bool active) return; } if (ui_ext_names[ext][0] != '_' || active) { - remote_ui_option_set(ui, cstr_as_string((char *)ui_ext_names[ext]), - BOOLEAN_OBJ(active)); + remote_ui_option_set(ui, cstr_as_string(ui_ext_names[ext]), BOOLEAN_OBJ(active)); } if (ext == kUITermColors) { ui_default_colors_set(); @@ -646,34 +645,35 @@ bool ui_has(UIExtension ext) return ui_ext[ext]; } -Array ui_array(void) +Array ui_array(Arena *arena) { - Array all_uis = ARRAY_DICT_INIT; + Array all_uis = arena_array(arena, ui_count); for (size_t i = 0; i < ui_count; i++) { UI *ui = uis[i]; - Dictionary info = ARRAY_DICT_INIT; - PUT(info, "width", INTEGER_OBJ(ui->width)); - PUT(info, "height", INTEGER_OBJ(ui->height)); - PUT(info, "rgb", BOOLEAN_OBJ(ui->rgb)); - PUT(info, "override", BOOLEAN_OBJ(ui->override)); + Dictionary info = arena_dict(arena, 10 + kUIExtCount); + PUT_C(info, "width", INTEGER_OBJ(ui->width)); + PUT_C(info, "height", INTEGER_OBJ(ui->height)); + PUT_C(info, "rgb", BOOLEAN_OBJ(ui->rgb)); + PUT_C(info, "override", BOOLEAN_OBJ(ui->override)); // TUI fields. (`stdin_fd` is intentionally omitted.) - PUT(info, "term_name", CSTR_TO_OBJ(ui->term_name)); + PUT_C(info, "term_name", CSTR_AS_OBJ(ui->term_name)); // term_background is deprecated. Populate with an empty string - PUT(info, "term_background", CSTR_TO_OBJ("")); + PUT_C(info, "term_background", STATIC_CSTR_AS_OBJ("")); - PUT(info, "term_colors", INTEGER_OBJ(ui->term_colors)); - PUT(info, "stdin_tty", BOOLEAN_OBJ(ui->stdin_tty)); - PUT(info, "stdout_tty", BOOLEAN_OBJ(ui->stdout_tty)); + PUT_C(info, "term_colors", INTEGER_OBJ(ui->term_colors)); + PUT_C(info, "stdin_tty", BOOLEAN_OBJ(ui->stdin_tty)); + PUT_C(info, "stdout_tty", BOOLEAN_OBJ(ui->stdout_tty)); for (UIExtension j = 0; j < kUIExtCount; j++) { if (ui_ext_names[j][0] != '_' || ui->ui_ext[j]) { - PUT(info, ui_ext_names[j], BOOLEAN_OBJ(ui->ui_ext[j])); + PUT_C(info, (char *)ui_ext_names[j], BOOLEAN_OBJ(ui->ui_ext[j])); } } - remote_ui_inspect(ui, &info); - ADD(all_uis, DICTIONARY_OBJ(info)); + PUT_C(info, "chan", INTEGER_OBJ((Integer)ui->data->channel_id)); + + ADD_C(all_uis, DICTIONARY_OBJ(info)); } return all_uis; } @@ -692,9 +692,9 @@ void ui_grid_resize(handle_T grid_handle, int width, int height, Error *err) if (wp->w_floating) { if (width != wp->w_width || height != wp->w_height) { - wp->w_float_config.width = width; - wp->w_float_config.height = height; - win_config_float(wp, wp->w_float_config); + wp->w_config.width = width; + wp->w_config.height = height; + win_config_float(wp, wp->w_config); } } else { // non-positive indicates no request diff --git a/src/nvim/usercmd.c b/src/nvim/usercmd.c index e20c3f6044..729e57cb2b 100644 --- a/src/nvim/usercmd.c +++ b/src/nvim/usercmd.c @@ -1136,6 +1136,20 @@ bool uc_split_args_iter(const char *arg, size_t arglen, size_t *end, char *buf, return true; } +size_t uc_nargs_upper_bound(const char *arg, size_t arglen) +{ + bool was_white = true; // space before first arg + size_t nargs = 0; + for (size_t i = 0; i < arglen; i++) { + bool is_white = ascii_iswhite(arg[i]); + if (was_white && !is_white) { + nargs++; + } + was_white = is_white; + } + return nargs; +} + /// split and quote args for <f-args> static char *uc_split_args(const char *arg, char **args, const size_t *arglens, size_t argc, size_t *lenp) diff --git a/src/nvim/window.c b/src/nvim/window.c index c63d27976a..f7f22c85ae 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -328,13 +328,13 @@ newwindow: wp = lastwin; // wrap around } while (wp != NULL && wp->w_floating - && !wp->w_float_config.focusable) { + && !wp->w_config.focusable) { wp = wp->w_prev; } } else { // go to next window wp = curwin->w_next; while (wp != NULL && wp->w_floating - && !wp->w_float_config.focusable) { + && !wp->w_config.focusable) { wp = wp->w_next; } if (wp == NULL) { @@ -763,7 +763,7 @@ void ui_ext_win_position(win_T *wp, bool validate) return; } - WinConfig c = wp->w_float_config; + WinConfig c = wp->w_config; if (!c.external) { ScreenGrid *grid = &default_grid; Float row = c.row; @@ -794,9 +794,9 @@ void ui_ext_win_position(win_T *wp, bool validate) } } - wp->w_grid_alloc.zindex = wp->w_float_config.zindex; + wp->w_grid_alloc.zindex = wp->w_config.zindex; if (ui_has(kUIMultigrid)) { - String anchor = cstr_as_string((char *)float_anchor_str[c.anchor]); + String anchor = cstr_as_string(float_anchor_str[c.anchor]); if (!c.hide) { ui_call_win_float_pos(wp->w_grid_alloc.handle, wp->handle, anchor, grid->handle, row, col, c.focusable, @@ -830,7 +830,7 @@ void ui_ext_win_position(win_T *wp, bool validate) ui_comp_put_grid(&wp->w_grid_alloc, comp_row, comp_col, wp->w_height_outer, wp->w_width_outer, valid, false); ui_check_cursor_grid(wp->w_grid_alloc.handle); - wp->w_grid_alloc.focusable = wp->w_float_config.focusable; + wp->w_grid_alloc.focusable = wp->w_config.focusable; if (!valid) { wp->w_grid_alloc.valid = false; redraw_later(wp, UPD_NOT_VALID); @@ -1213,7 +1213,7 @@ win_T *win_split_ins(int size, int flags, win_T *new_wp, int dir) new_frame(wp); wp->w_floating = false; // non-floating window doesn't store float config or have a border. - wp->w_float_config = WIN_CONFIG_INIT; + wp->w_config = WIN_CONFIG_INIT; CLEAR_FIELD(wp->w_border_adj); } @@ -2757,7 +2757,7 @@ int win_close(win_T *win, bool free_buf, bool force) if (win->w_floating) { ui_comp_remove_grid(&win->w_grid_alloc); assert(first_tabpage != NULL); // suppress clang "Dereference of NULL pointer" - if (win->w_float_config.external) { + if (win->w_config.external) { for (tabpage_T *tp = first_tabpage; tp != NULL; tp = tp->tp_next) { if (tp == curtab) { continue; @@ -4328,7 +4328,7 @@ static void tabpage_check_windows(tabpage_T *old_curtab) for (win_T *wp = old_curtab->tp_firstwin; wp; wp = next_wp) { next_wp = wp->w_next; if (wp->w_floating) { - if (wp->w_float_config.external) { + if (wp->w_config.external) { win_remove(wp, old_curtab); win_append(lastwin_nofloating(), wp); } else { @@ -4339,8 +4339,8 @@ static void tabpage_check_windows(tabpage_T *old_curtab) } for (win_T *wp = firstwin; wp; wp = wp->w_next) { - if (wp->w_floating && !wp->w_float_config.external) { - win_config_float(wp, wp->w_float_config); + if (wp->w_floating && !wp->w_config.external) { + win_config_float(wp, wp->w_config); } wp->w_pos_changed = true; } @@ -4983,7 +4983,7 @@ win_T *win_alloc(win_T *after, bool hidden) new_wp->w_cursor.lnum = 1; new_wp->w_scbind_pos = 1; new_wp->w_floating = 0; - new_wp->w_float_config = WIN_CONFIG_INIT; + new_wp->w_config = WIN_CONFIG_INIT; new_wp->w_viewport_invalid = true; new_wp->w_viewport_last_topline = 1; @@ -5097,8 +5097,8 @@ void win_free(win_T *wp, tabpage_T *tp) } // free the border text - clear_virttext(&wp->w_float_config.title_chunks); - clear_virttext(&wp->w_float_config.footer_chunks); + clear_virttext(&wp->w_config.title_chunks); + clear_virttext(&wp->w_config.footer_chunks); clear_matches(wp); @@ -5622,7 +5622,7 @@ int win_comp_pos(void) for (win_T *wp = lastwin; wp && wp->w_floating; wp = wp->w_prev) { // float might be anchored to moved window - if (wp->w_float_config.relative == kFloatRelativeWindow) { + if (wp->w_config.relative == kFloatRelativeWindow) { wp->w_pos_changed = true; } } @@ -5681,8 +5681,8 @@ void win_setheight_win(int height, win_T *win) height = MAX(height, (int)(win == curwin ? MAX(p_wmh, 1) : p_wmh) + win->w_winbar_height); if (win->w_floating) { - win->w_float_config.height = height; - win_config_float(win, win->w_float_config); + win->w_config.height = height; + win_config_float(win, win->w_config); redraw_later(win, UPD_VALID); } else { frame_setheight(win->w_frame, height + win->w_hsep_height + win->w_status_height); @@ -5893,8 +5893,8 @@ void win_setwidth_win(int width, win_T *wp) width = 0; } if (wp->w_floating) { - wp->w_float_config.width = width; - win_config_float(wp, wp->w_float_config); + wp->w_config.width = width; + win_config_float(wp, wp->w_config); redraw_later(wp, UPD_NOT_VALID); } else { frame_setwidth(wp->w_frame, width + wp->w_vsep_width); @@ -7359,9 +7359,17 @@ static bool frame_check_width(const frame_T *topfrp, int width) } /// Simple int comparison function for use with qsort() -static int int_cmp(const void *a, const void *b) +static int int_cmp(const void *pa, const void *pb) { - return *(const int *)a - *(const int *)b; + const int a = *(const int *)pa; + const int b = *(const int *)pb; + if (a > b) { + return 1; + } + if (a < b) { + return -1; + } + return 0; } /// Handle setting 'colorcolumn' or 'textwidth' in window "wp". diff --git a/src/nvim/winfloat.c b/src/nvim/winfloat.c index f22c0f3cfa..83a04a1bcf 100644 --- a/src/nvim/winfloat.c +++ b/src/nvim/winfloat.c @@ -161,17 +161,17 @@ void win_config_float(win_T *wp, WinConfig fconfig) } } - bool change_external = fconfig.external != wp->w_float_config.external; - bool change_border = (fconfig.border != wp->w_float_config.border + bool change_external = fconfig.external != wp->w_config.external; + bool change_border = (fconfig.border != wp->w_config.border || memcmp(fconfig.border_hl_ids, - wp->w_float_config.border_hl_ids, + wp->w_config.border_hl_ids, sizeof fconfig.border_hl_ids) != 0); - wp->w_float_config = fconfig; + wp->w_config = fconfig; - bool has_border = wp->w_floating && wp->w_float_config.border; + bool has_border = wp->w_floating && wp->w_config.border; for (int i = 0; i < 4; i++) { - int new_adj = has_border && wp->w_float_config.border_chars[2 * i + 1][0]; + int new_adj = has_border && wp->w_config.border_chars[2 * i + 1][0]; if (new_adj != wp->w_border_adj[i]) { change_border = true; wp->w_border_adj[i] = new_adj; @@ -193,11 +193,11 @@ void win_config_float(win_T *wp, WinConfig fconfig) } // compute initial position - if (wp->w_float_config.relative == kFloatRelativeWindow) { - int row = (int)wp->w_float_config.row; - int col = (int)wp->w_float_config.col; + if (wp->w_config.relative == kFloatRelativeWindow) { + int row = (int)wp->w_config.row; + int col = (int)wp->w_config.col; Error dummy = ERROR_INIT; - win_T *parent = find_window_by_handle(wp->w_float_config.window, &dummy); + win_T *parent = find_window_by_handle(wp->w_config.window, &dummy); if (parent) { row += parent->w_winrow; col += parent->w_wincol; @@ -207,9 +207,9 @@ void win_config_float(win_T *wp, WinConfig fconfig) grid_adjust(&grid, &row_off, &col_off); row += row_off; col += col_off; - if (wp->w_float_config.bufpos.lnum >= 0) { - pos_T pos = { wp->w_float_config.bufpos.lnum + 1, - wp->w_float_config.bufpos.col, 0 }; + if (wp->w_config.bufpos.lnum >= 0) { + pos_T pos = { wp->w_config.bufpos.lnum + 1, + wp->w_config.bufpos.col, 0 }; int trow, tcol, tcolc, tcole; textpos2screenpos(parent, &pos, &trow, &tcol, &tcolc, &tcole, true); row += trow - 1; @@ -233,7 +233,9 @@ void win_config_float(win_T *wp, WinConfig fconfig) static int float_zindex_cmp(const void *a, const void *b) { - return (*(win_T **)b)->w_float_config.zindex - (*(win_T **)a)->w_float_config.zindex; + int za = (*(win_T **)a)->w_config.zindex; + int zb = (*(win_T **)b)->w_config.zindex; + return za == zb ? 0 : za < zb ? 1 : -1; } void win_float_remove(bool bang, int count) @@ -263,8 +265,8 @@ void win_check_anchored_floats(win_T *win) { for (win_T *wp = lastwin; wp && wp->w_floating; wp = wp->w_prev) { // float might be anchored to moved window - if (wp->w_float_config.relative == kFloatRelativeWindow - && wp->w_float_config.window == win->handle) { + if (wp->w_config.relative == kFloatRelativeWindow + && wp->w_config.window == win->handle) { wp->w_pos_changed = true; } } @@ -273,7 +275,7 @@ void win_check_anchored_floats(win_T *win) void win_reconfig_floats(void) { for (win_T *wp = lastwin; wp && wp->w_floating; wp = wp->w_prev) { - win_config_float(wp, wp->w_float_config); + win_config_float(wp, wp->w_config); } } |