diff options
Diffstat (limited to 'src')
88 files changed, 1883 insertions, 1590 deletions
diff --git a/src/cjson/lua_cjson.c b/src/cjson/lua_cjson.c index 92d07963bd..cf9e82c38e 100644 --- a/src/cjson/lua_cjson.c +++ b/src/cjson/lua_cjson.c @@ -171,10 +171,18 @@ typedef struct { } json_config_t; typedef struct { + /* convert null in json objects to lua nil instead of vim.NIL */ + int luanil_object; + /* convert null in json arrays to lua nil instead of vim.NIL */ + int luanil_array; +} json_options_t; + +typedef struct { const char *data; const char *ptr; strbuf_t *tmp; /* Temporary storage for strings */ json_config_t *cfg; + json_options_t *options; int current_depth; } json_parse_t; @@ -865,7 +873,7 @@ static int json_encode(lua_State *l) /* ===== DECODING ===== */ static void json_process_value(lua_State *l, json_parse_t *json, - json_token_t *token); + json_token_t *token, bool use_luanil); static int hexdigit2int(char hex) { @@ -1296,7 +1304,7 @@ static void json_parse_object_context(lua_State *l, json_parse_t *json) /* Fetch value */ json_next_token(json, &token); - json_process_value(l, json, &token); + json_process_value(l, json, &token, json->options->luanil_object); /* Set key = value */ lua_rawset(l, -3); @@ -1343,7 +1351,7 @@ static void json_parse_array_context(lua_State *l, json_parse_t *json) } for (i = 1; ; i++) { - json_process_value(l, json, &token); + json_process_value(l, json, &token, json->options->luanil_array); lua_rawseti(l, -2, i); /* arr[i] = value */ json_next_token(json, &token); @@ -1362,7 +1370,7 @@ static void json_parse_array_context(lua_State *l, json_parse_t *json) /* Handle the "value" context */ static void json_process_value(lua_State *l, json_parse_t *json, - json_token_t *token) + json_token_t *token, bool use_luanil) { switch (token->type) { case T_STRING: @@ -1381,7 +1389,11 @@ static void json_process_value(lua_State *l, json_parse_t *json, json_parse_array_context(l, json); break;; case T_NULL: - nlua_pushref(l, nlua_nil_ref); + if (use_luanil) { + lua_pushnil(l); + } else { + nlua_pushref(l, nlua_nil_ref); + } break;; default: json_throw_parse_error(l, json, "value", token); @@ -1392,12 +1404,46 @@ static int json_decode(lua_State *l) { json_parse_t json; json_token_t token; + json_options_t options = { .luanil_object = false, .luanil_array = false }; + + size_t json_len; - luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument"); + switch (lua_gettop(l)) { + case 1: + break; + case 2: + luaL_checktype(l, 2, LUA_TTABLE); + lua_getfield(l, 2, "luanil"); + + /* We only handle the luanil option for now */ + if (lua_isnil(l, -1)) { + lua_pop(l, 1); + break; + } + + luaL_checktype(l, -1, LUA_TTABLE); + + lua_getfield(l, -1, "object"); + if (!lua_isnil(l, -1)) { + options.luanil_object = true; + } + lua_pop(l, 1); + + lua_getfield(l, -1, "array"); + if (!lua_isnil(l, -1)) { + options.luanil_array = true; + } + /* Also pop the luanil table */ + lua_pop(l, 2); + break; + default: + return luaL_error (l, "expected 1 or 2 arguments"); + } json.cfg = json_fetch_config(l); json.data = luaL_checklstring(l, 1, &json_len); + json.options = &options; json.current_depth = 0; json.ptr = json.data; @@ -1415,7 +1461,7 @@ static int json_decode(lua_State *l) json.tmp = strbuf_new(json_len); json_next_token(&json, &token); - json_process_value(l, &json, &token); + json_process_value(l, &json, &token, json.options->luanil_object); /* Ensure there is no more input left */ json_next_token(&json, &token); diff --git a/src/mpack/conv.c b/src/mpack/conv.c index 31297a8784..6bd446ca49 100644 --- a/src/mpack/conv.c +++ b/src/mpack/conv.c @@ -301,7 +301,6 @@ MPACK_API double mpack_unpack_number(mpack_token_t t) */ if (!hi) { assert(t.length <= 4); - hi = 0; lo = (~lo & (((mpack_uint32_t)1 << ((t.length * 8) - 1)) - 1)); } else { hi = ~hi; diff --git a/src/mpack/lmpack.c b/src/mpack/lmpack.c index 4b0e132a3a..24d27fd17a 100644 --- a/src/mpack/lmpack.c +++ b/src/mpack/lmpack.c @@ -204,14 +204,14 @@ static void lmpack_pushnil(lua_State *L) static mpack_uint32_t lmpack_objlen(lua_State *L, int *is_array) { size_t len, max; - int isarr, type; + int isarr; lua_Number n; #ifndef NDEBUG int top = lua_gettop(L); assert(top); #endif - if ((type = lua_type(L, -1)) != LUA_TTABLE) { + if ((lua_type(L, -1)) != LUA_TTABLE) { #if LUA_VERSION_NUM >= 502 len = lua_rawlen(L, -1); #elif LUA_VERSION_NUM == 501 @@ -445,7 +445,6 @@ static int lmpack_unpacker_unpack_str(lua_State *L, Unpacker *unpacker, if (rv == MPACK_NOMEM) { unpacker->parser = lmpack_grow_parser(unpacker->parser); if (!unpacker->parser) { - unpacker->unpacking = 0; return luaL_error(L, "failed to grow Unpacker capacity"); } } @@ -799,7 +798,6 @@ static int lmpack_packer_pack(lua_State *L) if (result == MPACK_NOMEM) { packer->parser = lmpack_grow_parser(packer->parser); if (!packer->parser) { - packer->packing = 0; return luaL_error(L, "Failed to grow Packer capacity"); } } diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 34d7f6e32d..569c0c9771 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -418,7 +418,7 @@ void nvim_buf_set_lines(uint64_t channel_id, Buffer buffer, Integer start, Integ try_start(); aco_save_T aco; - aucmd_prepbuf(&aco, (buf_T *)buf); + aucmd_prepbuf(&aco, buf); if (!MODIFIABLE(buf)) { api_set_error(err, kErrorTypeException, "Buffer is not 'modifiable'"); @@ -624,7 +624,8 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In if (replacement.size == 1) { firstlen += last_part_len; } - char *first = xmallocz(firstlen), *last = NULL; + char *first = xmallocz(firstlen); + char *last = NULL; memcpy(first, str_at_start, (size_t)start_col); memcpy(first+start_col, first_item.data, first_item.size); memchrsub(first+start_col, NUL, NL, first_item.size); @@ -637,7 +638,7 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In memcpy(last+last_item.size, str_at_end+end_col, last_part_len); } - char **lines = (new_len != 0) ? xcalloc(new_len, sizeof(char *)) : NULL; + char **lines = xcalloc(new_len, sizeof(char *)); lines[0] = first; new_byte += (bcount_t)(first_item.size); for (size_t i = 1; i < new_len-1; i++) { @@ -656,7 +657,7 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In try_start(); aco_save_T aco; - aucmd_prepbuf(&aco, (buf_T *)buf); + aucmd_prepbuf(&aco, buf); if (!MODIFIABLE(buf)) { api_set_error(err, kErrorTypeException, "Buffer is not 'modifiable'"); @@ -1108,14 +1109,97 @@ Boolean nvim_buf_is_valid(Buffer buffer) return ret; } -/// Return a tuple (row,col) representing the position of the named mark. +/// Deletes a named mark in the buffer. See |mark-motions|. +/// +/// @note only deletes marks set in the buffer, if the mark is not set +/// in the buffer it will return false. +/// @param buffer Buffer to set the mark on +/// @param name Mark name +/// @return true if the mark was deleted, else false. +/// @see |nvim_buf_set_mark()| +/// @see |nvim_del_mark()| +Boolean nvim_buf_del_mark(Buffer buffer, String name, Error *err) + FUNC_API_SINCE(8) +{ + bool res = false; + buf_T *buf = find_buffer_by_handle(buffer, err); + + if (!buf) { + return res; + } + + if (name.size != 1) { + api_set_error(err, kErrorTypeValidation, + "Mark name must be a single character"); + return res; + } + + pos_T *pos = getmark_buf(buf, *name.data, false); + + // pos point to NULL when there's no mark with name + if (pos == NULL) { + api_set_error(err, kErrorTypeValidation, "Invalid mark name: '%c'", + *name.data); + return res; + } + + // pos->lnum is 0 when the mark is not valid in the buffer, or is not set. + if (pos->lnum != 0) { + // since the mark belongs to the buffer delete it. + res = set_mark(buf, name, 0, 0, err); + } + + return res; +} + +/// Sets a named mark in the given buffer, all marks are allowed +/// file/uppercase, visual, last change, etc. See |mark-motions|. +/// +/// Marks are (1,0)-indexed. |api-indexing| +/// +/// @note Passing 0 as line deletes the mark +/// +/// @param buffer Buffer to set the mark on +/// @param name Mark name +/// @param line Line number +/// @param col Column/row number +/// @return true if the mark was set, else false. +/// @see |nvim_buf_del_mark()| +/// @see |nvim_buf_get_mark()| +Boolean nvim_buf_set_mark(Buffer buffer, String name, + Integer line, Integer col, Error *err) + FUNC_API_SINCE(8) +{ + bool res = false; + buf_T *buf = find_buffer_by_handle(buffer, err); + + if (!buf) { + return res; + } + + if (name.size != 1) { + api_set_error(err, kErrorTypeValidation, + "Mark name must be a single character"); + return res; + } + + res = set_mark(buf, name, line, col, err); + + return res; +} + +/// Returns a tuple (row,col) representing the position of the named mark. See +/// |mark-motions|. /// /// Marks are (1,0)-indexed. |api-indexing| /// /// @param buffer Buffer handle, or 0 for current buffer /// @param name Mark name /// @param[out] err Error details, if any -/// @return (row, col) tuple +/// @return (row, col) tuple, (0, 0) if the mark is not set, or is an +/// uppercase/file mark set in another buffer. +/// @see |nvim_buf_set_mark()| +/// @see |nvim_buf_del_mark()| ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err) FUNC_API_SINCE(1) { @@ -1257,7 +1341,7 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id, if (extmark.row < 0) { return rv; } - return extmark_to_array(extmark, false, (bool)details); + return extmark_to_array(extmark, false, details); } /// Gets extmarks in "traversal order" from a |charwise| region defined by @@ -1478,17 +1562,18 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer Dict(set_extmark) *opts, Error *err) FUNC_API_SINCE(7) { + Decoration decor = DECORATION_INIT; + buf_T *buf = find_buffer_by_handle(buffer, err); if (!buf) { - return 0; + goto error; } if (!ns_initialized((uint64_t)ns_id)) { api_set_error(err, kErrorTypeValidation, "Invalid ns_id"); - return 0; + goto error; } - uint64_t id = 0; if (opts->id.type == kObjectTypeInteger && opts->id.data.integer > 0) { id = (uint64_t)opts->id.data.integer; @@ -1525,8 +1610,6 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer goto error; } - Decoration decor = DECORATION_INIT; - if (HAS_KEY(opts->hl_group)) { decor.hl_id = object_to_hl_id(opts->hl_group, "hl_group", err); if (ERROR_SET(err)) { @@ -1658,7 +1741,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer if (line < 0 || line > buf->b_ml.ml_line_count) { api_set_error(err, kErrorTypeValidation, "line value outside range"); - return 0; + goto error; } else if (line < buf->b_ml.ml_line_count) { len = ephemeral ? MAXCOL : STRLEN(ml_get_buf(buf, (linenr_T)line+1, false)); } @@ -1667,7 +1750,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer col = (Integer)len; } else if (col < -1 || col > (Integer)len) { api_set_error(err, kErrorTypeValidation, "col value outside range"); - return 0; + goto error; } if (col2 >= 0) { @@ -1900,7 +1983,7 @@ Object nvim_buf_call(Buffer buffer, LuaRef fun, Error *err) } try_start(); aco_save_T aco; - aucmd_prepbuf(&aco, (buf_T *)buf); + aucmd_prepbuf(&aco, buf); Array args = ARRAY_DICT_INIT; Object res = nlua_call_ref(fun, NULL, args, true, err); diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index 332fc0ba96..907d09e5b7 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -165,6 +165,7 @@ Integer nvim_buf_set_virtual_text(Buffer buffer, Integer src_id, Integer line, A /// @param lines Array of lines /// @param[out] err Error details, if any void buffer_insert(Buffer buffer, Integer lnum, ArrayOf(String) lines, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { // "lnum" will be the index of the line after inserting, // no matter if it is negative or not @@ -184,6 +185,7 @@ void buffer_insert(Buffer buffer, Integer lnum, ArrayOf(String) lines, Error *er /// @param[out] err Error details, if any /// @return Line string String buffer_get_line(Buffer buffer, Integer index, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { String rv = { .size = 0 }; @@ -212,6 +214,7 @@ String buffer_get_line(Buffer buffer, Integer index, Error *err) /// @param line Contents of the new line /// @param[out] err Error details, if any void buffer_set_line(Buffer buffer, Integer index, String line, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { Object l = STRING_OBJ(line); Array array = { .items = &l, .size = 1 }; @@ -230,6 +233,7 @@ void buffer_set_line(Buffer buffer, Integer index, String line, Error *err) /// @param index line index /// @param[out] err Error details, if any void buffer_del_line(Buffer buffer, Integer index, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { Array array = ARRAY_DICT_INIT; index = convert_index(index); @@ -255,6 +259,7 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer, Boolean include_start, Boolean include_end, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { start = convert_index(start) + !include_start; end = convert_index(end) + include_end; @@ -278,6 +283,7 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer, /// @param[out] err Error details, if any void buffer_set_line_slice(Buffer buffer, Integer start, Integer end, Boolean include_start, Boolean include_end, ArrayOf(String) replacement, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { start = convert_index(start) + !include_start; end = convert_index(end) + include_end; @@ -298,6 +304,7 @@ void buffer_set_line_slice(Buffer buffer, Integer start, Integer end, Boolean in /// @warning It may return nil if there was no previous value /// or if previous value was `v:null`. Object buffer_set_var(Buffer buffer, String name, Object value, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -317,6 +324,7 @@ Object buffer_set_var(Buffer buffer, String name, Object value, Error *err) /// @param[out] err Error details, if any /// @return Old value Object buffer_del_var(Buffer buffer, String name, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -340,6 +348,7 @@ Object buffer_del_var(Buffer buffer, String name, Error *err) /// @warning It may return nil if there was no previous value /// or if previous value was `v:null`. Object window_set_var(Window window, String name, Object value, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { win_T *win = find_window_by_handle(window, err); @@ -359,6 +368,7 @@ Object window_set_var(Window window, String name, Object value, Error *err) /// @param[out] err Error details, if any /// @return Old value Object window_del_var(Window window, String name, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { win_T *win = find_window_by_handle(window, err); @@ -382,6 +392,7 @@ Object window_del_var(Window window, String name, Error *err) /// @warning It may return nil if there was no previous value /// or if previous value was `v:null`. Object tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { tabpage_T *tab = find_tab_by_handle(tabpage, err); @@ -401,6 +412,7 @@ Object tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err) /// @param[out] err Error details, if any /// @return Old value Object tabpage_del_var(Tabpage tabpage, String name, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { tabpage_T *tab = find_tab_by_handle(tabpage, err); @@ -417,6 +429,7 @@ Object tabpage_del_var(Tabpage tabpage, String name, Error *err) /// OR if previous value was `v:null`. /// @return Old value or nil if there was no previous value. Object vim_set_var(String name, Object value, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { return dict_set_var(&globvardict, name, value, false, true, err); } @@ -424,6 +437,7 @@ Object vim_set_var(String name, Object value, Error *err) /// @deprecated /// @see nvim_del_var Object vim_del_var(String name, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { return dict_set_var(&globvardict, name, NIL, true, true, err); } diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h index 8346e01558..663d1e16b5 100644 --- a/src/nvim/api/private/defs.h +++ b/src/nvim/api/private/defs.h @@ -1,15 +1,15 @@ #ifndef NVIM_API_PRIVATE_DEFS_H #define NVIM_API_PRIVATE_DEFS_H -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> #include <string.h> #include "nvim/func_attr.h" #include "nvim/types.h" -#define ARRAY_DICT_INIT {.size = 0, .capacity = 0, .items = NULL} -#define STRING_INIT {.data = NULL, .size = 0} +#define ARRAY_DICT_INIT { .size = 0, .capacity = 0, .items = NULL } +#define STRING_INIT { .data = NULL, .size = 0 } #define OBJECT_INIT { .type = kObjectTypeNil } #define ERROR_INIT { .type = kErrorTypeNone, .msg = NULL } #define REMOTE_TYPE(type) typedef handle_T type diff --git a/src/nvim/api/private/dispatch.c b/src/nvim/api/private/dispatch.c index 5e93ccce17..ee0cdc4c07 100644 --- a/src/nvim/api/private/dispatch.c +++ b/src/nvim/api/private/dispatch.c @@ -15,6 +15,7 @@ #include "nvim/api/ui.h" #include "nvim/api/vim.h" #include "nvim/api/window.h" +#include "nvim/api/win_config.h" #include "nvim/log.h" #include "nvim/map.h" #include "nvim/msgpack_rpc/helpers.h" diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 24fac0a916..d03a61d1cc 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -25,6 +25,7 @@ #include "nvim/lua/executor.h" #include "nvim/map.h" #include "nvim/map_defs.h" +#include "nvim/mark.h" #include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/msgpack_rpc/helpers.h" @@ -396,7 +397,7 @@ void set_option_to(uint64_t channel_id, void *to, int type, String name, Object return; } - stringval = (char *)value.data.string.data; + stringval = value.data.string.data; } const sctx_T save_current_sctx = current_sctx; @@ -817,13 +818,6 @@ Array string_to_array(const String input, bool crlf) void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String rhs, Dict(keymap) *opts, Error *err) { - char *err_msg = NULL; // the error message to report, if any - char *err_arg = NULL; // argument for the error message format string - ErrorType err_type = kErrorTypeNone; - - char_u *lhs_buf = NULL; - char_u *rhs_buf = NULL; - bool global = (buffer == -1); if (global) { buffer = 0; @@ -857,17 +851,13 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String CPO_TO_CPO_FLAGS, &parsed_args); if (parsed_args.lhs_len > MAXMAPLEN) { - err_msg = "LHS exceeds maximum map length: %s"; - err_arg = lhs.data; - err_type = kErrorTypeValidation; - goto fail_with_message; + api_set_error(err, kErrorTypeValidation, "LHS exceeds maximum map length: %s", lhs.data); + goto fail_and_free; } if (mode.size > 1) { - err_msg = "Shortname is too long: %s"; - err_arg = mode.data; - err_type = kErrorTypeValidation; - goto fail_with_message; + api_set_error(err, kErrorTypeValidation, "Shortname is too long: %s", mode.data); + goto fail_and_free; } int mode_val; // integer value of the mapping mode, to be passed to do_map() char_u *p = (char_u *)((mode.size) ? mode.data : "m"); @@ -879,18 +869,14 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String && mode.size > 0) { // get_map_mode() treats unrecognized mode shortnames as ":map". // This is an error unless the given shortname was empty string "". - err_msg = "Invalid mode shortname: \"%s\""; - err_arg = (char *)p; - err_type = kErrorTypeValidation; - goto fail_with_message; + api_set_error(err, kErrorTypeValidation, "Invalid mode shortname: \"%s\"", (char *)p); + goto fail_and_free; } } if (parsed_args.lhs_len == 0) { - err_msg = "Invalid (empty) LHS"; - err_arg = ""; - err_type = kErrorTypeValidation; - goto fail_with_message; + api_set_error(err, kErrorTypeValidation, "Invalid (empty) LHS"); + goto fail_and_free; } bool is_noremap = parsed_args.noremap; @@ -903,16 +889,13 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String // the given RHS was nonempty and not a <Nop>, but was parsed as if it // were empty? assert(false && "Failed to parse nonempty RHS!"); - err_msg = "Parsing of nonempty RHS failed: %s"; - err_arg = rhs.data; - err_type = kErrorTypeException; - goto fail_with_message; + api_set_error(err, kErrorTypeValidation, "Parsing of nonempty RHS failed: %s", rhs.data); + goto fail_and_free; } } else if (is_unmap && parsed_args.rhs_len) { - err_msg = "Gave nonempty RHS in unmap command: %s"; - err_arg = (char *)parsed_args.rhs; - err_type = kErrorTypeValidation; - goto fail_with_message; + api_set_error(err, kErrorTypeValidation, + "Gave nonempty RHS in unmap command: %s", parsed_args.rhs); + goto fail_and_free; } // buf_do_map() reads noremap/unmap as its own argument. @@ -941,19 +924,7 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String goto fail_and_free; } // switch - xfree(lhs_buf); - xfree(rhs_buf); - xfree(parsed_args.rhs); - xfree(parsed_args.orig_rhs); - - return; - -fail_with_message: - api_set_error(err, err_type, err_msg, err_arg); - fail_and_free: - xfree(lhs_buf); - xfree(rhs_buf); xfree(parsed_args.rhs); xfree(parsed_args.orig_rhs); return; @@ -1648,361 +1619,6 @@ const char *describe_ns(NS ns_id) return "(UNKNOWN PLUGIN)"; } -static bool parse_float_anchor(String anchor, FloatAnchor *out) -{ - if (anchor.size == 0) { - *out = (FloatAnchor)0; - } - char *str = anchor.data; - if (striequal(str, "NW")) { - *out = 0; // NW is the default - } else if (striequal(str, "NE")) { - *out = kFloatAnchorEast; - } else if (striequal(str, "SW")) { - *out = kFloatAnchorSouth; - } else if (striequal(str, "SE")) { - *out = kFloatAnchorSouth | kFloatAnchorEast; - } else { - return false; - } - return true; -} - -static bool parse_float_relative(String relative, FloatRelative *out) -{ - char *str = relative.data; - if (striequal(str, "editor")) { - *out = kFloatRelativeEditor; - } else if (striequal(str, "win")) { - *out = kFloatRelativeWindow; - } else if (striequal(str, "cursor")) { - *out = kFloatRelativeCursor; - } else { - return false; - } - return true; -} - -static bool parse_float_bufpos(Array bufpos, lpos_T *out) -{ - if (bufpos.size != 2 - || bufpos.items[0].type != kObjectTypeInteger - || bufpos.items[1].type != kObjectTypeInteger) { - return false; - } - out->lnum = bufpos.items[0].data.integer; - out->col = (colnr_T)bufpos.items[1].data.integer; - return true; -} - -static void parse_border_style(Object style, FloatConfig *fconfig, Error *err) -{ - struct { - const char *name; - schar_T chars[8]; - bool shadow_color; - } defaults[] = { - { "double", { "╔", "═", "╗", "║", "╝", "═", "╚", "║" }, false }, - { "single", { "┌", "─", "┐", "│", "┘", "─", "└", "│" }, false }, - { "shadow", { "", "", " ", " ", " ", " ", " ", "" }, true }, - { "rounded", { "╭", "─", "╮", "│", "╯", "─", "╰", "│" }, false }, - { "solid", { " ", " ", " ", " ", " ", " ", " ", " " }, false }, - { NULL, { { NUL } }, false }, - }; - - schar_T *chars = fconfig->border_chars; - int *hl_ids = fconfig->border_hl_ids; - - fconfig->border = true; - - if (style.type == kObjectTypeArray) { - Array arr = style.data.array; - size_t size = arr.size; - if (!size || size > 8 || (size & (size-1))) { - api_set_error(err, kErrorTypeValidation, - "invalid number of border chars"); - return; - } - for (size_t i = 0; i < size; i++) { - Object iytem = arr.items[i]; - String string; - int hl_id = 0; - if (iytem.type == kObjectTypeArray) { - Array iarr = iytem.data.array; - if (!iarr.size || iarr.size > 2) { - api_set_error(err, kErrorTypeValidation, "invalid border char"); - return; - } - if (iarr.items[0].type != kObjectTypeString) { - api_set_error(err, kErrorTypeValidation, "invalid border char"); - return; - } - string = iarr.items[0].data.string; - if (iarr.size == 2) { - hl_id = object_to_hl_id(iarr.items[1], "border char highlight", err); - if (ERROR_SET(err)) { - return; - } - } - } else if (iytem.type == kObjectTypeString) { - string = iytem.data.string; - } else { - api_set_error(err, kErrorTypeValidation, "invalid border char"); - return; - } - if (string.size - && mb_string2cells_len((char_u *)string.data, string.size) > 1) { - api_set_error(err, kErrorTypeValidation, - "border chars must be one cell"); - return; - } - size_t len = MIN(string.size, sizeof(*chars)-1); - if (len) { - memcpy(chars[i], string.data, len); - } - chars[i][len] = NUL; - hl_ids[i] = hl_id; - } - while (size < 8) { - memcpy(chars+size, chars, sizeof(*chars) * size); - memcpy(hl_ids+size, hl_ids, sizeof(*hl_ids) * size); - size <<= 1; - } - if ((chars[7][0] && chars[1][0] && !chars[0][0]) - || (chars[1][0] && chars[3][0] && !chars[2][0]) - || (chars[3][0] && chars[5][0] && !chars[4][0]) - || (chars[5][0] && chars[7][0] && !chars[6][0])) { - api_set_error(err, kErrorTypeValidation, - "corner between used edges must be specified"); - } - } else if (style.type == kObjectTypeString) { - String str = style.data.string; - if (str.size == 0 || strequal(str.data, "none")) { - fconfig->border = false; - return; - } - for (size_t i = 0; defaults[i].name; i++) { - if (strequal(str.data, defaults[i].name)) { - memcpy(chars, defaults[i].chars, sizeof(defaults[i].chars)); - memset(hl_ids, 0, 8 * sizeof(*hl_ids)); - if (defaults[i].shadow_color) { - int hl_blend = SYN_GROUP_STATIC("FloatShadow"); - int hl_through = SYN_GROUP_STATIC("FloatShadowThrough"); - hl_ids[2] = hl_through; - hl_ids[3] = hl_blend; - hl_ids[4] = hl_blend; - hl_ids[5] = hl_blend; - hl_ids[6] = hl_through; - } - return; - } - } - api_set_error(err, kErrorTypeValidation, - "invalid border style \"%s\"", str.data); - } -} - -bool parse_float_config(Dict(float_config) *config, FloatConfig *fconfig, bool reconf, bool new_win, - Error *err) -{ - bool has_relative = false, relative_is_win = false; - if (config->relative.type == kObjectTypeString) { - // ignore empty string, to match nvim_win_get_config - if (config->relative.data.string.size > 0) { - if (!parse_float_relative(config->relative.data.string, &fconfig->relative)) { - api_set_error(err, kErrorTypeValidation, "Invalid value of 'relative' key"); - return false; - } - - if (!(HAS_KEY(config->row) && HAS_KEY(config->col)) && !HAS_KEY(config->bufpos)) { - api_set_error(err, kErrorTypeValidation, - "'relative' requires 'row'/'col' or 'bufpos'"); - return false; - } - - has_relative = true; - fconfig->external = false; - if (fconfig->relative == kFloatRelativeWindow) { - relative_is_win = true; - fconfig->bufpos.lnum = -1; - } - } - } else if (HAS_KEY(config->relative)) { - api_set_error(err, kErrorTypeValidation, "'relative' key must be String"); - return false; - } - - if (config->anchor.type == kObjectTypeString) { - if (!parse_float_anchor(config->anchor.data.string, &fconfig->anchor)) { - api_set_error(err, kErrorTypeValidation, "Invalid value of 'anchor' key"); - return false; - } - } else if (HAS_KEY(config->anchor)) { - api_set_error(err, kErrorTypeValidation, "'anchor' key must be String"); - return false; - } - - if (HAS_KEY(config->row)) { - if (!has_relative) { - api_set_error(err, kErrorTypeValidation, "non-float cannot have 'row'"); - return false; - } else if (config->row.type == kObjectTypeInteger) { - fconfig->row = (double)config->row.data.integer; - } else if (config->row.type == kObjectTypeFloat) { - fconfig->row = config->row.data.floating; - } else { - api_set_error(err, kErrorTypeValidation, - "'row' key must be Integer or Float"); - return false; - } - } - - if (HAS_KEY(config->col)) { - if (!has_relative) { - api_set_error(err, kErrorTypeValidation, "non-float cannot have 'col'"); - return false; - } else if (config->col.type == kObjectTypeInteger) { - fconfig->col = (double)config->col.data.integer; - } else if (config->col.type == kObjectTypeFloat) { - fconfig->col = config->col.data.floating; - } else { - api_set_error(err, kErrorTypeValidation, - "'col' key must be Integer or Float"); - return false; - } - } - - if (HAS_KEY(config->bufpos)) { - if (!has_relative) { - api_set_error(err, kErrorTypeValidation, "non-float cannot have 'bufpos'"); - return false; - } else if (config->bufpos.type == kObjectTypeArray) { - if (!parse_float_bufpos(config->bufpos.data.array, &fconfig->bufpos)) { - api_set_error(err, kErrorTypeValidation, "Invalid value of 'bufpos' key"); - return false; - } - - if (!HAS_KEY(config->row)) { - fconfig->row = (fconfig->anchor & kFloatAnchorSouth) ? 0 : 1; - } - if (!HAS_KEY(config->col)) { - fconfig->col = 0; - } - } else { - api_set_error(err, kErrorTypeValidation, "'bufpos' key must be Array"); - return false; - } - } - - if (config->width.type == kObjectTypeInteger && config->width.data.integer > 0) { - fconfig->width = (int)config->width.data.integer; - } else if (HAS_KEY(config->width)) { - api_set_error(err, kErrorTypeValidation, "'width' key must be a positive Integer"); - return false; - } else if (!reconf) { - api_set_error(err, kErrorTypeValidation, "Must specify 'width'"); - return false; - } - - if (config->height.type == kObjectTypeInteger && config->height.data.integer > 0) { - fconfig->height = (int)config->height.data.integer; - } else if (HAS_KEY(config->height)) { - api_set_error(err, kErrorTypeValidation, "'height' key must be a positive Integer"); - return false; - } else if (!reconf) { - api_set_error(err, kErrorTypeValidation, "Must specify 'height'"); - return false; - } - - if (relative_is_win) { - fconfig->window = curwin->handle; - if (config->win.type == kObjectTypeInteger || config->win.type == kObjectTypeWindow) { - if (config->win.data.integer > 0) { - fconfig->window = (Window)config->win.data.integer; - } - } else if (HAS_KEY(config->win)) { - api_set_error(err, kErrorTypeValidation, "'win' key must be Integer or Window"); - return false; - } - } else { - if (HAS_KEY(config->win)) { - api_set_error(err, kErrorTypeValidation, "'win' key is only valid with relative='win'"); - return false; - } - } - - if (HAS_KEY(config->external)) { - fconfig->external = api_object_to_bool(config->external, "'external' key", false, err); - if (ERROR_SET(err)) { - return false; - } - if (has_relative && fconfig->external) { - api_set_error(err, kErrorTypeValidation, - "Only one of 'relative' and 'external' must be used"); - return false; - } - if (fconfig->external && !ui_has(kUIMultigrid)) { - api_set_error(err, kErrorTypeValidation, - "UI doesn't support external windows"); - return false; - } - } - - if (!reconf && (!has_relative && !fconfig->external)) { - api_set_error(err, kErrorTypeValidation, - "One of 'relative' and 'external' must be used"); - return false; - } - - - if (HAS_KEY(config->focusable)) { - fconfig->focusable = api_object_to_bool(config->focusable, "'focusable' key", false, err); - if (ERROR_SET(err)) { - return false; - } - } - - if (config->zindex.type == kObjectTypeInteger && config->zindex.data.integer > 0) { - fconfig->zindex = (int)config->zindex.data.integer; - } else if (HAS_KEY(config->zindex)) { - api_set_error(err, kErrorTypeValidation, "'zindex' key must be a positive Integer"); - return false; - } - - if (HAS_KEY(config->border)) { - parse_border_style(config->border, fconfig, err); - if (ERROR_SET(err)) { - return false; - } - } - - if (config->style.type == kObjectTypeString) { - if (config->style.data.string.data[0] == NUL) { - fconfig->style = kWinStyleUnused; - } else if (striequal(config->style.data.string.data, "minimal")) { - fconfig->style = kWinStyleMinimal; - } else { - api_set_error(err, kErrorTypeValidation, "Invalid value of 'style' key"); - } - } else if (HAS_KEY(config->style)) { - api_set_error(err, kErrorTypeValidation, "'style' key must be String"); - return false; - } - - if (HAS_KEY(config->noautocmd)) { - if (!new_win) { - api_set_error(err, kErrorTypeValidation, "Invalid key: 'noautocmd'"); - return false; - } - fconfig->noautocmd = api_object_to_bool(config->noautocmd, "'noautocmd' key", false, err); - if (ERROR_SET(err)) { - return false; - } - } - - return true; -} - bool api_dict_to_keydict(void *rv, field_hash hashy, Dictionary dict, Error *err) { for (size_t i = 0; i < dict.size; i++) { @@ -2026,3 +1642,42 @@ void api_free_keydict(void *dict, KeySetLink *table) } } +/// Set a named mark +/// buffer and mark name must be validated already +/// @param buffer Buffer to set the mark on +/// @param name Mark name +/// @param line Line number +/// @param col Column/row number +/// @return true if the mark was set, else false +bool set_mark(buf_T *buf, String name, Integer line, Integer col, Error *err) +{ + buf = buf == NULL ? curbuf : buf; + // If line == 0 the marks is being deleted + bool res = false; + bool deleting = false; + if (line == 0) { + col = 0; + deleting = true; + } else { + if (col > MAXCOL) { + api_set_error(err, kErrorTypeValidation, "Column value outside range"); + return res; + } + if (line < 1 || line > buf->b_ml.ml_line_count) { + api_set_error(err, kErrorTypeValidation, "Line value outside range"); + return res; + } + } + pos_T pos = { line, (int)col, (int)col }; + res = setmark_pos(*name.data, &pos, buf->handle); + if (!res) { + if (deleting) { + api_set_error(err, kErrorTypeException, + "Failed to delete named mark: %c", *name.data); + } else { + api_set_error(err, kErrorTypeException, + "Failed to set named mark: %c", *name.data); + } + } + return res; +} diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h index 2cdd80bffe..dc9452e832 100644 --- a/src/nvim/api/private/helpers.h +++ b/src/nvim/api/private/helpers.h @@ -4,12 +4,12 @@ #include <stdbool.h> #include "nvim/api/private/defs.h" -#include "nvim/vim.h" -#include "nvim/getchar.h" -#include "nvim/memory.h" #include "nvim/decoration.h" #include "nvim/ex_eval.h" +#include "nvim/getchar.h" #include "nvim/lib/kvec.h" +#include "nvim/memory.h" +#include "nvim/vim.h" #define OBJECT_OBJ(o) o @@ -76,7 +76,7 @@ name.size = fixsize; \ name.items = name##__items; \ -#define STATIC_CSTR_AS_STRING(s) ((String) {.data = s, .size = sizeof(s) - 1}) +#define STATIC_CSTR_AS_STRING(s) ((String) { .data = s, .size = sizeof(s) - 1 }) /// Create a new String instance, putting data in allocated memory /// @@ -137,7 +137,7 @@ typedef struct { msg_list = &private_msg_list; \ private_msg_list = NULL; \ code \ - msg_list = saved_msg_list; /* Restore the exception context. */ \ + msg_list = saved_msg_list; /* Restore the exception context. */ \ } while (0) #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 9b200dcba2..d86aecc318 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -40,7 +40,6 @@ typedef struct { static PMap(uint64_t) connected_uis = MAP_INIT; void remote_ui_disconnect(uint64_t channel_id) - FUNC_API_NOEXPORT { UI *ui = pmap_get(uint64_t)(&connected_uis, channel_id); if (!ui) { @@ -57,7 +56,6 @@ void remote_ui_disconnect(uint64_t channel_id) /// Wait until ui has connected on stdio channel. void remote_ui_wait_for_attach(void) - FUNC_API_NOEXPORT { Channel *channel = find_channel(CHAN_STDIO); if (!channel) { @@ -172,6 +170,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, Dictiona /// @deprecated 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)); diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index f80d605d9a..9b39b18c4e 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -59,7 +59,6 @@ #endif void api_vim_free_all_mem(void) - FUNC_API_NOEXPORT { String name; handle_T id; @@ -264,7 +263,6 @@ void nvim__set_hl_ns(Integer ns_id, Error *err) } static void on_redraw_event(void **argv) - FUNC_API_NOEXPORT { redraw_all_later(NOT_VALID); } @@ -1221,7 +1219,7 @@ fail: /// buffer in a configured window before calling this. For instance, for a /// floating display, first create an empty buffer using |nvim_create_buf()|, /// then display it using |nvim_open_win()|, and then call this function. -/// Then |nvim_chan_send()| cal be called immediately to process sequences +/// Then |nvim_chan_send()| can be called immediately to process sequences /// in a virtual terminal having the intended size. /// /// @param buffer the buffer to use (expected to be empty) @@ -1305,156 +1303,6 @@ void nvim_chan_send(Integer chan, String data, Error *err) } } -/// Open a new window. -/// -/// Currently this is used to open floating and external windows. -/// Floats are windows that are drawn above the split layout, at some anchor -/// position in some other window. Floats can be drawn internally or by external -/// GUI with the |ui-multigrid| extension. External windows are only supported -/// with multigrid GUIs, and are displayed as separate top-level windows. -/// -/// For a general overview of floats, see |api-floatwin|. -/// -/// Exactly one of `external` and `relative` must be specified. The `width` and -/// `height` of the new window must be specified. -/// -/// With relative=editor (row=0,col=0) refers to the top-left corner of the -/// screen-grid and (row=Lines-1,col=Columns-1) refers to the bottom-right -/// corner. Fractional values are allowed, but the builtin implementation -/// (used by non-multigrid UIs) will always round down to nearest integer. -/// -/// Out-of-bounds values, and configurations that make the float not fit inside -/// the main editor, are allowed. The builtin implementation truncates values -/// so floats are fully within the main screen grid. External GUIs -/// could let floats hover outside of the main window like a tooltip, but -/// this should not be used to specify arbitrary WM screen positions. -/// -/// Example (Lua): window-relative float -/// <pre> -/// vim.api.nvim_open_win(0, false, -/// {relative='win', row=3, col=3, width=12, height=3}) -/// </pre> -/// -/// Example (Lua): buffer-relative float (travels as buffer is scrolled) -/// <pre> -/// vim.api.nvim_open_win(0, false, -/// {relative='win', width=12, height=3, bufpos={100,10}}) -/// </pre> -/// -/// @param buffer Buffer to display, or 0 for current buffer -/// @param enter Enter the window (make it the current window) -/// @param config Map defining the window configuration. Keys: -/// - `relative`: Sets the window layout to "floating", placed at (row,col) -/// coordinates relative to: -/// - "editor" The global editor grid -/// - "win" Window given by the `win` field, or current window. -/// - "cursor" Cursor position in current window. -/// - `win`: |window-ID| for relative="win". -/// - `anchor`: Decides which corner of the float to place at (row,col): -/// - "NW" northwest (default) -/// - "NE" northeast -/// - "SW" southwest -/// - "SE" southeast -/// - `width`: Window width (in character cells). Minimum of 1. -/// - `height`: Window height (in character cells). Minimum of 1. -/// - `bufpos`: Places float relative to buffer text (only when -/// relative="win"). Takes a tuple of zero-indexed [line, column]. -/// `row` and `col` if given are applied relative to this -/// position, else they default to: -/// - `row=1` and `col=0` if `anchor` is "NW" or "NE" -/// - `row=0` and `col=0` if `anchor` is "SW" or "SE" -/// (thus like a tooltip near the buffer text). -/// - `row`: Row position in units of "screen cell height", may be fractional. -/// - `col`: Column position in units of "screen cell width", may be -/// fractional. -/// - `focusable`: Enable focus by user actions (wincmds, mouse events). -/// Defaults to true. Non-focusable windows can be entered by -/// |nvim_set_current_win()|. -/// - `external`: GUI should display the window as an external -/// top-level window. Currently accepts no other positioning -/// configuration together with this. -/// - `zindex`: Stacking order. floats with higher `zindex` go on top on -/// floats with lower indices. Must be larger than zero. The -/// following screen elements have hard-coded z-indices: -/// - 100: insert completion popupmenu -/// - 200: message scrollback -/// - 250: cmdline completion popupmenu (when wildoptions+=pum) -/// The default value for floats are 50. In general, values below 100 are -/// recommended, unless there is a good reason to overshadow builtin -/// elements. -/// - `style`: Configure the appearance of the window. Currently only takes -/// one non-empty value: -/// - "minimal" Nvim will display the window with many UI options -/// disabled. This is useful when displaying a temporary -/// float where the text should not be edited. Disables -/// 'number', 'relativenumber', 'cursorline', 'cursorcolumn', -/// 'foldcolumn', 'spell' and 'list' options. 'signcolumn' -/// is changed to `auto` and 'colorcolumn' is cleared. The -/// end-of-buffer region is hidden by setting `eob` flag of -/// 'fillchars' to a space char, and clearing the -/// |EndOfBuffer| region in 'winhighlight'. -/// - `border`: Style of (optional) window border. This can either be a string -/// or an array. The string values are -/// - "none": No border (default). -/// - "single": A single line box. -/// - "double": A double line box. -/// - "rounded": Like "single", but with rounded corners ("╭" etc.). -/// - "solid": Adds padding by a single whitespace cell. -/// - "shadow": A drop shadow effect by blending with the background. -/// - If it is an array, it should have a length of eight or any divisor of -/// eight. The array will specifify the eight chars building up the border -/// in a clockwise fashion starting with the top-left corner. As an -/// example, the double box style could be specified as -/// [ "╔", "═" ,"╗", "║", "╝", "═", "╚", "║" ]. -/// If the number of chars are less than eight, they will be repeated. Thus -/// an ASCII border could be specified as -/// [ "/", "-", "\\", "|" ], -/// or all chars the same as -/// [ "x" ]. -/// An empty string can be used to turn off a specific border, for instance, -/// [ "", "", "", ">", "", "", "", "<" ] -/// will only make vertical borders but not horizontal ones. -/// By default, `FloatBorder` highlight is used, which links to `VertSplit` -/// when not defined. It could also be specified by character: -/// [ {"+", "MyCorner"}, {"x", "MyBorder"} ]. -/// - `noautocmd`: If true then no buffer-related autocommand events such as -/// |BufEnter|, |BufLeave| or |BufWinEnter| may fire from -/// calling this function. -/// -/// @param[out] err Error details, if any -/// -/// @return Window handle, or 0 on error -Window nvim_open_win(Buffer buffer, Boolean enter, Dict(float_config) *config, Error *err) - FUNC_API_SINCE(6) - FUNC_API_CHECK_TEXTLOCK -{ - FloatConfig fconfig = FLOAT_CONFIG_INIT; - if (!parse_float_config(config, &fconfig, false, true, err)) { - return 0; - } - win_T *wp = win_new_float(NULL, fconfig, err); - if (!wp) { - return 0; - } - if (enter) { - win_enter(wp, false); - } - // autocmds in win_enter or win_set_buf below may close the window - if (win_valid(wp) && buffer > 0) { - win_set_buf(wp->handle, buffer, fconfig.noautocmd, err); - } - if (!win_valid(wp)) { - api_set_error(err, kErrorTypeException, "Window was closed immediately"); - return 0; - } - - if (fconfig.style == kWinStyleMinimal) { - win_set_minimal_style(wp); - didset_window_options(wp); - } - return wp->handle; -} - /// Gets the current list of tabpage handles. /// /// @return List of tabpage handles @@ -1510,7 +1358,7 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err) } } -/// Creates a new *namespace*, or gets an existing one. +/// Creates a new \*namespace\* or gets an existing one. /// /// Namespaces are used for buffer highlights and virtual text, see /// |nvim_buf_add_highlight()| and |nvim_buf_set_extmark()|. @@ -2931,3 +2779,106 @@ void nvim_set_decoration_provider(Integer ns_id, DictionaryOf(LuaRef) opts, Erro error: decor_provider_clear(p); } + +/// Deletes a uppercase/file named mark. See |mark-motions|. +/// +/// @note fails with error if a lowercase or buffer local named mark is used. +/// @param name Mark name +/// @return true if the mark was deleted, else false. +/// @see |nvim_buf_del_mark()| +/// @see |nvim_get_mark()| +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"); + 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); + } + return res; +} + +/// Return a tuple (row, col, buffer, buffername) representing the position of +/// the uppercase/file named mark. See |mark-motions|. +/// +/// Marks are (1,0)-indexed. |api-indexing| +/// +/// @note fails with error if a lowercase or buffer local named mark is used. +/// @param name Mark name +/// @return 4-tuple (row, col, buffer, buffername), (0, 0, 0, '') if the mark is +/// not set. +/// @see |nvim_buf_set_mark()| +/// @see |nvim_del_mark()| +Array nvim_get_mark(String name, Error *err) + FUNC_API_SINCE(8) +{ + Array rv = ARRAY_DICT_INIT; + + if (name.size != 1) { + api_set_error(err, kErrorTypeValidation, + "Mark name must be a single character"); + 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); + return rv; + } + + xfmark_T mark = get_global_mark(*name.data); + pos_T pos = mark.fmark.mark; + bool allocated = false; + int bufnr; + char *filename; + + // Marks are from an open buffer it fnum is non zero + if (mark.fmark.fnum != 0) { + bufnr = mark.fmark.fnum; + filename = (char *)buflist_nr2name(bufnr, true, true); + allocated = true; + // Marks comes from shada + } else { + filename = (char *)mark.fname; + bufnr = 0; + } + + bool exists = filename != NULL; + Integer row; + Integer col; + + if (!exists || pos.lnum <= 0) { + if (allocated) { + xfree(filename); + allocated = false; + } + filename = ""; + bufnr = 0; + row = 0; + col = 0; + } else { + row = pos.lnum; + col = pos.col; + } + + ADD(rv, INTEGER_OBJ(row)); + ADD(rv, INTEGER_OBJ(col)); + ADD(rv, INTEGER_OBJ(bufnr)); + ADD(rv, STRING_OBJ(cstr_to_string(filename))); + + if (allocated) { + xfree(filename); + } + + return rv; +} + diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c new file mode 100644 index 0000000000..d82e7e8a03 --- /dev/null +++ b/src/nvim/api/win_config.c @@ -0,0 +1,639 @@ +// 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 <assert.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +#include "nvim/api/private/defs.h" +#include "nvim/api/private/helpers.h" +#include "nvim/api/win_config.h" +#include "nvim/ascii.h" +#include "nvim/option.h" +#include "nvim/screen.h" +#include "nvim/strings.h" +#include "nvim/syntax.h" +#include "nvim/ui.h" +#include "nvim/window.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "api/win_config.c.generated.h" +#endif + + +/// Open a new window. +/// +/// Currently this is used to open floating and external windows. +/// Floats are windows that are drawn above the split layout, at some anchor +/// position in some other window. Floats can be drawn internally or by external +/// GUI with the |ui-multigrid| extension. External windows are only supported +/// with multigrid GUIs, and are displayed as separate top-level windows. +/// +/// For a general overview of floats, see |api-floatwin|. +/// +/// Exactly one of `external` and `relative` must be specified. The `width` and +/// `height` of the new window must be specified. +/// +/// With relative=editor (row=0,col=0) refers to the top-left corner of the +/// screen-grid and (row=Lines-1,col=Columns-1) refers to the bottom-right +/// corner. Fractional values are allowed, but the builtin implementation +/// (used by non-multigrid UIs) will always round down to nearest integer. +/// +/// Out-of-bounds values, and configurations that make the float not fit inside +/// the main editor, are allowed. The builtin implementation truncates values +/// so floats are fully within the main screen grid. External GUIs +/// could let floats hover outside of the main window like a tooltip, but +/// this should not be used to specify arbitrary WM screen positions. +/// +/// Example (Lua): window-relative float +/// <pre> +/// vim.api.nvim_open_win(0, false, +/// {relative='win', row=3, col=3, width=12, height=3}) +/// </pre> +/// +/// Example (Lua): buffer-relative float (travels as buffer is scrolled) +/// <pre> +/// vim.api.nvim_open_win(0, false, +/// {relative='win', width=12, height=3, bufpos={100,10}}) +/// </pre> +/// +/// @param buffer Buffer to display, or 0 for current buffer +/// @param enter Enter the window (make it the current window) +/// @param config Map defining the window configuration. Keys: +/// - `relative`: Sets the window layout to "floating", placed at (row,col) +/// coordinates relative to: +/// - "editor" The global editor grid +/// - "win" Window given by the `win` field, or current window. +/// - "cursor" Cursor position in current window. +/// - `win`: |window-ID| for relative="win". +/// - `anchor`: Decides which corner of the float to place at (row,col): +/// - "NW" northwest (default) +/// - "NE" northeast +/// - "SW" southwest +/// - "SE" southeast +/// - `width`: Window width (in character cells). Minimum of 1. +/// - `height`: Window height (in character cells). Minimum of 1. +/// - `bufpos`: Places float relative to buffer text (only when +/// relative="win"). Takes a tuple of zero-indexed [line, column]. +/// `row` and `col` if given are applied relative to this +/// position, else they default to: +/// - `row=1` and `col=0` if `anchor` is "NW" or "NE" +/// - `row=0` and `col=0` if `anchor` is "SW" or "SE" +/// (thus like a tooltip near the buffer text). +/// - `row`: Row position in units of "screen cell height", may be fractional. +/// - `col`: Column position in units of "screen cell width", may be +/// fractional. +/// - `focusable`: Enable focus by user actions (wincmds, mouse events). +/// Defaults to true. Non-focusable windows can be entered by +/// |nvim_set_current_win()|. +/// - `external`: GUI should display the window as an external +/// top-level window. Currently accepts no other positioning +/// configuration together with this. +/// - `zindex`: Stacking order. floats with higher `zindex` go on top on +/// floats with lower indices. Must be larger than zero. The +/// following screen elements have hard-coded z-indices: +/// - 100: insert completion popupmenu +/// - 200: message scrollback +/// - 250: cmdline completion popupmenu (when wildoptions+=pum) +/// The default value for floats are 50. In general, values below 100 are +/// recommended, unless there is a good reason to overshadow builtin +/// elements. +/// - `style`: Configure the appearance of the window. Currently only takes +/// one non-empty value: +/// - "minimal" Nvim will display the window with many UI options +/// disabled. This is useful when displaying a temporary +/// float where the text should not be edited. Disables +/// 'number', 'relativenumber', 'cursorline', 'cursorcolumn', +/// 'foldcolumn', 'spell' and 'list' options. 'signcolumn' +/// is changed to `auto` and 'colorcolumn' is cleared. The +/// end-of-buffer region is hidden by setting `eob` flag of +/// 'fillchars' to a space char, and clearing the +/// |EndOfBuffer| region in 'winhighlight'. +/// - `border`: Style of (optional) window border. This can either be a string +/// or an array. The string values are +/// - "none": No border (default). +/// - "single": A single line box. +/// - "double": A double line box. +/// - "rounded": Like "single", but with rounded corners ("╭" etc.). +/// - "solid": Adds padding by a single whitespace cell. +/// - "shadow": A drop shadow effect by blending with the background. +/// - If it is an array, it should have a length of eight or any divisor of +/// eight. The array will specifify the eight chars building up the border +/// in a clockwise fashion starting with the top-left corner. As an +/// example, the double box style could be specified as +/// [ "╔", "═" ,"╗", "║", "╝", "═", "╚", "║" ]. +/// If the number of chars are less than eight, they will be repeated. Thus +/// an ASCII border could be specified as +/// [ "/", "-", "\\", "|" ], +/// or all chars the same as +/// [ "x" ]. +/// An empty string can be used to turn off a specific border, for instance, +/// [ "", "", "", ">", "", "", "", "<" ] +/// will only make vertical borders but not horizontal ones. +/// By default, `FloatBorder` highlight is used, which links to `VertSplit` +/// when not defined. It could also be specified by character: +/// [ {"+", "MyCorner"}, {"x", "MyBorder"} ]. +/// - `noautocmd`: If true then no buffer-related autocommand events such as +/// |BufEnter|, |BufLeave| or |BufWinEnter| may fire from +/// calling this function. +/// +/// @param[out] err Error details, if any +/// +/// @return Window handle, or 0 on error +Window nvim_open_win(Buffer buffer, Boolean enter, Dict(float_config) *config, Error *err) + FUNC_API_SINCE(6) + FUNC_API_CHECK_TEXTLOCK +{ + FloatConfig fconfig = FLOAT_CONFIG_INIT; + if (!parse_float_config(config, &fconfig, false, true, err)) { + return 0; + } + win_T *wp = win_new_float(NULL, fconfig, err); + if (!wp) { + return 0; + } + if (enter) { + win_enter(wp, false); + } + // autocmds in win_enter or win_set_buf below may close the window + if (win_valid(wp) && buffer > 0) { + win_set_buf(wp->handle, buffer, fconfig.noautocmd, err); + } + if (!win_valid(wp)) { + api_set_error(err, kErrorTypeException, "Window was closed immediately"); + return 0; + } + + if (fconfig.style == kWinStyleMinimal) { + win_set_minimal_style(wp); + didset_window_options(wp); + } + return wp->handle; +} + +/// Configures window layout. Currently only for floating and external windows +/// (including changing a split window to those layouts). +/// +/// When reconfiguring a floating window, absent option keys will not be +/// changed. `row`/`col` and `relative` must be reconfigured together. +/// +/// @see |nvim_open_win()| +/// +/// @param window Window handle, or 0 for current window +/// @param config Map defining the window configuration, +/// see |nvim_open_win()| +/// @param[out] err Error details, if any +void nvim_win_set_config(Window window, Dict(float_config) *config, Error *err) + FUNC_API_SINCE(6) +{ + win_T *win = find_window_by_handle(window, err); + if (!win) { + return; + } + bool new_float = !win->w_floating; + // reuse old values, if not overridden + FloatConfig fconfig = new_float ? FLOAT_CONFIG_INIT : win->w_float_config; + + if (!parse_float_config(config, &fconfig, !new_float, false, err)) { + return; + } + if (new_float) { + if (!win_new_float(win, fconfig, err)) { + return; + } + redraw_later(win, NOT_VALID); + } else { + win_config_float(win, fconfig); + win->w_pos_changed = true; + } + if (fconfig.style == kWinStyleMinimal) { + win_set_minimal_style(win); + didset_window_options(win); + } +} + +/// Gets window configuration. +/// +/// The returned value may be given to |nvim_open_win()|. +/// +/// `relative` is empty for normal windows. +/// +/// @param window Window handle, or 0 for current window +/// @param[out] err Error details, if any +/// @return Map defining the window configuration, see |nvim_open_win()| +Dictionary nvim_win_get_config(Window window, Error *err) + FUNC_API_SINCE(6) +{ + Dictionary rv = ARRAY_DICT_INIT; + + win_T *wp = find_window_by_handle(window, err); + if (!wp) { + return rv; + } + + FloatConfig *config = &wp->w_float_config; + + PUT(rv, "focusable", BOOLEAN_OBJ(config->focusable)); + PUT(rv, "external", BOOLEAN_OBJ(config->external)); + + if (wp->w_floating) { + PUT(rv, "width", INTEGER_OBJ(config->width)); + PUT(rv, "height", INTEGER_OBJ(config->height)); + if (!config->external) { + if (config->relative == kFloatRelativeWindow) { + PUT(rv, "win", INTEGER_OBJ(config->window)); + if (config->bufpos.lnum >= 0) { + Array pos = ARRAY_DICT_INIT; + ADD(pos, INTEGER_OBJ(config->bufpos.lnum)); + ADD(pos, INTEGER_OBJ(config->bufpos.col)); + PUT(rv, "bufpos", ARRAY_OBJ(pos)); + } + } + PUT(rv, "anchor", STRING_OBJ(cstr_to_string(float_anchor_str[config->anchor]))); + PUT(rv, "row", FLOAT_OBJ(config->row)); + PUT(rv, "col", FLOAT_OBJ(config->col)); + PUT(rv, "zindex", INTEGER_OBJ(config->zindex)); + } + if (config->border) { + Array border = ARRAY_DICT_INIT; + for (size_t i = 0; i < 8; i++) { + Array tuple = ARRAY_DICT_INIT; + + String s = cstrn_to_string((const char *)config->border_chars[i], sizeof(schar_T)); + + int hi_id = config->border_hl_ids[i]; + char_u *hi_name = syn_id2name(hi_id); + if (hi_name[0]) { + ADD(tuple, STRING_OBJ(s)); + ADD(tuple, STRING_OBJ(cstr_to_string((const char *)hi_name))); + ADD(border, ARRAY_OBJ(tuple)); + } else { + ADD(border, STRING_OBJ(s)); + } + } + PUT(rv, "border", ARRAY_OBJ(border)); + } + } + + const char *rel = (wp->w_floating && !config->external + ? float_relative_str[config->relative] : ""); + PUT(rv, "relative", STRING_OBJ(cstr_to_string(rel))); + + return rv; +} + +static bool parse_float_anchor(String anchor, FloatAnchor *out) +{ + if (anchor.size == 0) { + *out = (FloatAnchor)0; + } + char *str = anchor.data; + if (striequal(str, "NW")) { + *out = 0; // NW is the default + } else if (striequal(str, "NE")) { + *out = kFloatAnchorEast; + } else if (striequal(str, "SW")) { + *out = kFloatAnchorSouth; + } else if (striequal(str, "SE")) { + *out = kFloatAnchorSouth | kFloatAnchorEast; + } else { + return false; + } + return true; +} + +static bool parse_float_relative(String relative, FloatRelative *out) +{ + char *str = relative.data; + if (striequal(str, "editor")) { + *out = kFloatRelativeEditor; + } else if (striequal(str, "win")) { + *out = kFloatRelativeWindow; + } else if (striequal(str, "cursor")) { + *out = kFloatRelativeCursor; + } else { + return false; + } + return true; +} + +static bool parse_float_bufpos(Array bufpos, lpos_T *out) +{ + if (bufpos.size != 2 + || bufpos.items[0].type != kObjectTypeInteger + || bufpos.items[1].type != kObjectTypeInteger) { + return false; + } + out->lnum = bufpos.items[0].data.integer; + out->col = (colnr_T)bufpos.items[1].data.integer; + return true; +} + +static void parse_border_style(Object style, FloatConfig *fconfig, Error *err) +{ + struct { + const char *name; + schar_T chars[8]; + bool shadow_color; + } defaults[] = { + { "double", { "╔", "═", "╗", "║", "╝", "═", "╚", "║" }, false }, + { "single", { "┌", "─", "┐", "│", "┘", "─", "└", "│" }, false }, + { "shadow", { "", "", " ", " ", " ", " ", " ", "" }, true }, + { "rounded", { "╭", "─", "╮", "│", "╯", "─", "╰", "│" }, false }, + { "solid", { " ", " ", " ", " ", " ", " ", " ", " " }, false }, + { NULL, { { NUL } }, false }, + }; + + schar_T *chars = fconfig->border_chars; + int *hl_ids = fconfig->border_hl_ids; + + fconfig->border = true; + + if (style.type == kObjectTypeArray) { + Array arr = style.data.array; + size_t size = arr.size; + if (!size || size > 8 || (size & (size-1))) { + api_set_error(err, kErrorTypeValidation, + "invalid number of border chars"); + return; + } + for (size_t i = 0; i < size; i++) { + Object iytem = arr.items[i]; + String string; + int hl_id = 0; + if (iytem.type == kObjectTypeArray) { + Array iarr = iytem.data.array; + if (!iarr.size || iarr.size > 2) { + api_set_error(err, kErrorTypeValidation, "invalid border char"); + return; + } + if (iarr.items[0].type != kObjectTypeString) { + api_set_error(err, kErrorTypeValidation, "invalid border char"); + return; + } + string = iarr.items[0].data.string; + if (iarr.size == 2) { + hl_id = object_to_hl_id(iarr.items[1], "border char highlight", err); + if (ERROR_SET(err)) { + return; + } + } + } else if (iytem.type == kObjectTypeString) { + string = iytem.data.string; + } else { + api_set_error(err, kErrorTypeValidation, "invalid border char"); + return; + } + if (string.size + && mb_string2cells_len((char_u *)string.data, string.size) > 1) { + api_set_error(err, kErrorTypeValidation, + "border chars must be one cell"); + return; + } + size_t len = MIN(string.size, sizeof(*chars)-1); + if (len) { + memcpy(chars[i], string.data, len); + } + chars[i][len] = NUL; + hl_ids[i] = hl_id; + } + while (size < 8) { + memcpy(chars+size, chars, sizeof(*chars) * size); + memcpy(hl_ids+size, hl_ids, sizeof(*hl_ids) * size); + size <<= 1; + } + if ((chars[7][0] && chars[1][0] && !chars[0][0]) + || (chars[1][0] && chars[3][0] && !chars[2][0]) + || (chars[3][0] && chars[5][0] && !chars[4][0]) + || (chars[5][0] && chars[7][0] && !chars[6][0])) { + api_set_error(err, kErrorTypeValidation, + "corner between used edges must be specified"); + } + } else if (style.type == kObjectTypeString) { + String str = style.data.string; + if (str.size == 0 || strequal(str.data, "none")) { + fconfig->border = false; + return; + } + for (size_t i = 0; defaults[i].name; i++) { + if (strequal(str.data, defaults[i].name)) { + memcpy(chars, defaults[i].chars, sizeof(defaults[i].chars)); + memset(hl_ids, 0, 8 * sizeof(*hl_ids)); + if (defaults[i].shadow_color) { + int hl_blend = SYN_GROUP_STATIC("FloatShadow"); + int hl_through = SYN_GROUP_STATIC("FloatShadowThrough"); + hl_ids[2] = hl_through; + hl_ids[3] = hl_blend; + hl_ids[4] = hl_blend; + hl_ids[5] = hl_blend; + hl_ids[6] = hl_through; + } + return; + } + } + api_set_error(err, kErrorTypeValidation, + "invalid border style \"%s\"", str.data); + } +} + +static bool parse_float_config(Dict(float_config) *config, FloatConfig *fconfig, bool reconf, + bool new_win, Error *err) +{ + bool has_relative = false, relative_is_win = false; + if (config->relative.type == kObjectTypeString) { + // ignore empty string, to match nvim_win_get_config + if (config->relative.data.string.size > 0) { + if (!parse_float_relative(config->relative.data.string, &fconfig->relative)) { + api_set_error(err, kErrorTypeValidation, "Invalid value of 'relative' key"); + return false; + } + + if (!(HAS_KEY(config->row) && HAS_KEY(config->col)) && !HAS_KEY(config->bufpos)) { + api_set_error(err, kErrorTypeValidation, + "'relative' requires 'row'/'col' or 'bufpos'"); + return false; + } + + has_relative = true; + fconfig->external = false; + if (fconfig->relative == kFloatRelativeWindow) { + relative_is_win = true; + fconfig->bufpos.lnum = -1; + } + } + } else if (HAS_KEY(config->relative)) { + api_set_error(err, kErrorTypeValidation, "'relative' key must be String"); + return false; + } + + if (config->anchor.type == kObjectTypeString) { + if (!parse_float_anchor(config->anchor.data.string, &fconfig->anchor)) { + api_set_error(err, kErrorTypeValidation, "Invalid value of 'anchor' key"); + return false; + } + } else if (HAS_KEY(config->anchor)) { + api_set_error(err, kErrorTypeValidation, "'anchor' key must be String"); + return false; + } + + if (HAS_KEY(config->row)) { + if (!has_relative) { + api_set_error(err, kErrorTypeValidation, "non-float cannot have 'row'"); + return false; + } else if (config->row.type == kObjectTypeInteger) { + fconfig->row = (double)config->row.data.integer; + } else if (config->row.type == kObjectTypeFloat) { + fconfig->row = config->row.data.floating; + } else { + api_set_error(err, kErrorTypeValidation, + "'row' key must be Integer or Float"); + return false; + } + } + + if (HAS_KEY(config->col)) { + if (!has_relative) { + api_set_error(err, kErrorTypeValidation, "non-float cannot have 'col'"); + return false; + } else if (config->col.type == kObjectTypeInteger) { + fconfig->col = (double)config->col.data.integer; + } else if (config->col.type == kObjectTypeFloat) { + fconfig->col = config->col.data.floating; + } else { + api_set_error(err, kErrorTypeValidation, + "'col' key must be Integer or Float"); + return false; + } + } + + if (HAS_KEY(config->bufpos)) { + if (!has_relative) { + api_set_error(err, kErrorTypeValidation, "non-float cannot have 'bufpos'"); + return false; + } else if (config->bufpos.type == kObjectTypeArray) { + if (!parse_float_bufpos(config->bufpos.data.array, &fconfig->bufpos)) { + api_set_error(err, kErrorTypeValidation, "Invalid value of 'bufpos' key"); + return false; + } + + if (!HAS_KEY(config->row)) { + fconfig->row = (fconfig->anchor & kFloatAnchorSouth) ? 0 : 1; + } + if (!HAS_KEY(config->col)) { + fconfig->col = 0; + } + } else { + api_set_error(err, kErrorTypeValidation, "'bufpos' key must be Array"); + return false; + } + } + + if (config->width.type == kObjectTypeInteger && config->width.data.integer > 0) { + fconfig->width = (int)config->width.data.integer; + } else if (HAS_KEY(config->width)) { + api_set_error(err, kErrorTypeValidation, "'width' key must be a positive Integer"); + return false; + } else if (!reconf) { + api_set_error(err, kErrorTypeValidation, "Must specify 'width'"); + return false; + } + + if (config->height.type == kObjectTypeInteger && config->height.data.integer > 0) { + fconfig->height = (int)config->height.data.integer; + } else if (HAS_KEY(config->height)) { + api_set_error(err, kErrorTypeValidation, "'height' key must be a positive Integer"); + return false; + } else if (!reconf) { + api_set_error(err, kErrorTypeValidation, "Must specify 'height'"); + return false; + } + + if (relative_is_win) { + fconfig->window = curwin->handle; + if (config->win.type == kObjectTypeInteger || config->win.type == kObjectTypeWindow) { + if (config->win.data.integer > 0) { + fconfig->window = (Window)config->win.data.integer; + } + } else if (HAS_KEY(config->win)) { + api_set_error(err, kErrorTypeValidation, "'win' key must be Integer or Window"); + return false; + } + } else { + if (HAS_KEY(config->win)) { + api_set_error(err, kErrorTypeValidation, "'win' key is only valid with relative='win'"); + return false; + } + } + + if (HAS_KEY(config->external)) { + fconfig->external = api_object_to_bool(config->external, "'external' key", false, err); + if (ERROR_SET(err)) { + return false; + } + if (has_relative && fconfig->external) { + api_set_error(err, kErrorTypeValidation, + "Only one of 'relative' and 'external' must be used"); + return false; + } + if (fconfig->external && !ui_has(kUIMultigrid)) { + api_set_error(err, kErrorTypeValidation, + "UI doesn't support external windows"); + return false; + } + } + + if (!reconf && (!has_relative && !fconfig->external)) { + api_set_error(err, kErrorTypeValidation, + "One of 'relative' and 'external' must be used"); + return false; + } + + + if (HAS_KEY(config->focusable)) { + fconfig->focusable = api_object_to_bool(config->focusable, "'focusable' key", false, err); + if (ERROR_SET(err)) { + return false; + } + } + + if (config->zindex.type == kObjectTypeInteger && config->zindex.data.integer > 0) { + fconfig->zindex = (int)config->zindex.data.integer; + } else if (HAS_KEY(config->zindex)) { + api_set_error(err, kErrorTypeValidation, "'zindex' key must be a positive Integer"); + return false; + } + + if (HAS_KEY(config->border)) { + parse_border_style(config->border, fconfig, err); + if (ERROR_SET(err)) { + return false; + } + } + + if (config->style.type == kObjectTypeString) { + if (config->style.data.string.data[0] == NUL) { + fconfig->style = kWinStyleUnused; + } else if (striequal(config->style.data.string.data, "minimal")) { + fconfig->style = kWinStyleMinimal; + } else { + api_set_error(err, kErrorTypeValidation, "Invalid value of 'style' key"); + } + } else if (HAS_KEY(config->style)) { + api_set_error(err, kErrorTypeValidation, "'style' key must be String"); + return false; + } + + if (HAS_KEY(config->noautocmd)) { + if (!new_win) { + api_set_error(err, kErrorTypeValidation, "Invalid key: 'noautocmd'"); + return false; + } + fconfig->noautocmd = api_object_to_bool(config->noautocmd, "'noautocmd' key", false, err); + if (ERROR_SET(err)) { + return false; + } + } + + return true; +} diff --git a/src/nvim/api/win_config.h b/src/nvim/api/win_config.h new file mode 100644 index 0000000000..9271c35f23 --- /dev/null +++ b/src/nvim/api/win_config.h @@ -0,0 +1,11 @@ +#ifndef NVIM_API_WIN_CONFIG_H +#define NVIM_API_WIN_CONFIG_H + +#include <stdint.h> + +#include "nvim/api/private/defs.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "api/win_config.h.generated.h" +#endif +#endif // NVIM_API_WIN_CONFIG_H diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index 95eae1af2d..6e68c057dc 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -373,117 +373,6 @@ Boolean nvim_win_is_valid(Window window) } -/// Configures window layout. Currently only for floating and external windows -/// (including changing a split window to those layouts). -/// -/// When reconfiguring a floating window, absent option keys will not be -/// changed. `row`/`col` and `relative` must be reconfigured together. -/// -/// @see |nvim_open_win()| -/// -/// @param window Window handle, or 0 for current window -/// @param config Map defining the window configuration, -/// see |nvim_open_win()| -/// @param[out] err Error details, if any -void nvim_win_set_config(Window window, Dict(float_config) *config, Error *err) - FUNC_API_SINCE(6) -{ - win_T *win = find_window_by_handle(window, err); - if (!win) { - return; - } - bool new_float = !win->w_floating; - // reuse old values, if not overridden - FloatConfig fconfig = new_float ? FLOAT_CONFIG_INIT : win->w_float_config; - - if (!parse_float_config(config, &fconfig, !new_float, false, err)) { - return; - } - if (new_float) { - if (!win_new_float(win, fconfig, err)) { - return; - } - redraw_later(win, NOT_VALID); - } else { - win_config_float(win, fconfig); - win->w_pos_changed = true; - } - if (fconfig.style == kWinStyleMinimal) { - win_set_minimal_style(win); - didset_window_options(win); - } -} - -/// Gets window configuration. -/// -/// The returned value may be given to |nvim_open_win()|. -/// -/// `relative` is empty for normal windows. -/// -/// @param window Window handle, or 0 for current window -/// @param[out] err Error details, if any -/// @return Map defining the window configuration, see |nvim_open_win()| -Dictionary nvim_win_get_config(Window window, Error *err) - FUNC_API_SINCE(6) -{ - Dictionary rv = ARRAY_DICT_INIT; - - win_T *wp = find_window_by_handle(window, err); - if (!wp) { - return rv; - } - - FloatConfig *config = &wp->w_float_config; - - PUT(rv, "focusable", BOOLEAN_OBJ(config->focusable)); - PUT(rv, "external", BOOLEAN_OBJ(config->external)); - - if (wp->w_floating) { - PUT(rv, "width", INTEGER_OBJ(config->width)); - PUT(rv, "height", INTEGER_OBJ(config->height)); - if (!config->external) { - if (config->relative == kFloatRelativeWindow) { - PUT(rv, "win", INTEGER_OBJ(config->window)); - if (config->bufpos.lnum >= 0) { - Array pos = ARRAY_DICT_INIT; - ADD(pos, INTEGER_OBJ(config->bufpos.lnum)); - ADD(pos, INTEGER_OBJ(config->bufpos.col)); - PUT(rv, "bufpos", ARRAY_OBJ(pos)); - } - } - PUT(rv, "anchor", STRING_OBJ(cstr_to_string(float_anchor_str[config->anchor]))); - PUT(rv, "row", FLOAT_OBJ(config->row)); - PUT(rv, "col", FLOAT_OBJ(config->col)); - PUT(rv, "zindex", INTEGER_OBJ(config->zindex)); - } - if (config->border) { - Array border = ARRAY_DICT_INIT; - for (size_t i = 0; i < 8; i++) { - Array tuple = ARRAY_DICT_INIT; - - String s = cstrn_to_string((const char *)config->border_chars[i], sizeof(schar_T)); - - int hi_id = config->border_hl_ids[i]; - char_u *hi_name = syn_id2name(hi_id); - if (hi_name[0]) { - ADD(tuple, STRING_OBJ(s)); - ADD(tuple, STRING_OBJ(cstr_to_string((const char *)hi_name))); - ADD(border, ARRAY_OBJ(tuple)); - } else { - ADD(border, STRING_OBJ(s)); - } - } - PUT(rv, "border", ARRAY_OBJ(border)); - } - } - - const char *rel = (wp->w_floating && !config->external - ? float_relative_str[config->relative] : ""); - PUT(rv, "relative", STRING_OBJ(cstr_to_string(rel))); - - return rv; -} - /// Closes the window and hide the buffer it contains (like |:hide| with a /// |window-ID|). /// diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 20dd94622f..6d91632dcd 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -2553,8 +2553,6 @@ void buflist_setfpos(buf_T *const buf, win_T *const win, linenr_T lnum, colnr_T if (wip->wi_next) { wip->wi_next->wi_prev = wip; } - - return; } diff --git a/src/nvim/change.c b/src/nvim/change.c index 4ac5edeaa9..2450c56838 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -413,7 +413,11 @@ void deleted_lines(linenr_T lnum, long count) /// be triggered to display the cursor. void deleted_lines_mark(linenr_T lnum, long count) { - mark_adjust(lnum, (linenr_T)(lnum + count - 1), (long)MAXLNUM, -count, + // if we deleted the entire buffer, we need to implicity add a new empty line + bool made_empty = (count > 0) && curbuf->b_ml.ml_flags & ML_EMPTY; + + mark_adjust(lnum, (linenr_T)(lnum + count - 1), (long)MAXLNUM, + -count + (made_empty?1:0), kExtmarkUndo); changed_lines(lnum, 0, lnum + count, -count, true); } @@ -625,7 +629,7 @@ void ins_char_bytes(char_u *buf, size_t charlen) // Copy bytes before the cursor. if (col > 0) { - memmove(newp, oldp, (size_t)col); + memmove(newp, oldp, col); } // Copy bytes after the changed character(s). diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 30243a3102..db0a2ff64c 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -87,7 +87,7 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error) break; case kChannelStreamProc: - proc = (Process *)&chan->stream.proc; + proc = &chan->stream.proc; if (part == kChannelPartStdin || close_main) { stream_may_close(&proc->in); } @@ -335,7 +335,7 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout, CallbackReader chan->stream.uv = libuv_process_init(&main_loop, chan); } - Process *proc = (Process *)&chan->stream.proc; + Process *proc = &chan->stream.proc; proc->argv = argv; proc->cb = channel_process_exit_cb; proc->events = chan->events; diff --git a/src/nvim/charset.c b/src/nvim/charset.c index f899ebf57c..d2f95ad81c 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -412,7 +412,7 @@ char *transstr(const char *const s, bool untab) { // Compute the length of the result, taking account of unprintable // multi-byte characters. - const size_t len = transstr_len((const char *)s, untab) + 1; + const size_t len = transstr_len(s, untab) + 1; char *const buf = xmalloc(len); transstr_buf(s, buf, len, untab); return buf; diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 5c43b2498e..3a7bd21c70 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1110,7 +1110,7 @@ static int diff_file(diffio_T *dio) // Build the diff command and execute it. Always use -a, binary // differences are of no use. Ignore errors, diff returns // non-zero when differences have been found. - vim_snprintf((char *)cmd, len, "diff %s%s%s%s%s%s%s%s %s", + vim_snprintf(cmd, len, "diff %s%s%s%s%s%s%s%s %s", diff_a_works == kFalse ? "" : "-a ", "", (diff_flags & DIFF_IWHITE) ? "-b " : "", diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 768b82b464..a281c09042 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -514,8 +514,8 @@ int var_redir_start(char_u *name, int append) ga_init(&redir_ga, (int)sizeof(char), 500); // Parse the variable name (can be a dict or list entry). - redir_endp = (char_u *)get_lval(redir_varname, NULL, redir_lval, false, false, - 0, FNE_CHECK_START); + redir_endp = get_lval(redir_varname, NULL, redir_lval, false, false, + 0, FNE_CHECK_START); if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) { clear_lval(redir_lval); @@ -597,8 +597,8 @@ void var_redir_stop(void) tv.vval.v_string = redir_ga.ga_data; // Call get_lval() again, if it's inside a Dict or List it may // have changed. - redir_endp = (char_u *)get_lval(redir_varname, NULL, redir_lval, - false, false, 0, FNE_CHECK_START); + redir_endp = get_lval(redir_varname, NULL, redir_lval, + false, false, 0, FNE_CHECK_START); if (redir_endp != NULL && redir_lval->ll_name != NULL) { set_var_lval(redir_lval, redir_endp, &tv, false, false, "."); } @@ -1711,7 +1711,7 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first) if (tofree != NULL) { name = tofree; } - if (get_var_tv((const char *)name, len, &tv, NULL, true, false) + if (get_var_tv(name, len, &tv, NULL, true, false) == FAIL) { error = true; } else { @@ -2023,7 +2023,7 @@ char_u *get_lval(char_u *const name, typval_T *const rettv, lval_T *const lp, co } lp->ll_exp_name = (char *)make_expanded_name(name, expr_start, expr_end, - (char_u *)p); + p); lp->ll_name = lp->ll_exp_name; if (lp->ll_exp_name == NULL) { /* Report an invalid expression in braces, unless the @@ -2419,7 +2419,7 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, co // handle +=, -=, *=, /=, %= and .= di = NULL; - if (get_var_tv((const char *)lp->ll_name, (int)STRLEN(lp->ll_name), + if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name), &tv, &di, true, false) == OK) { if ((di == NULL || (!var_check_ro(di->di_flags, lp->ll_name, TV_CSTRING) @@ -3004,12 +3004,12 @@ int do_unlet(const char *const name, const size_t name_len, const bool forceit) hashitem_T *hi = hash_find(ht, (const char_u *)varname); if (HASHITEM_EMPTY(hi)) { - hi = find_hi_in_scoped_ht((const char *)name, &ht); + hi = find_hi_in_scoped_ht(name, &ht); } if (hi != NULL && !HASHITEM_EMPTY(hi)) { dictitem_T *const di = TV_DICT_HI2DI(hi); - if (var_check_fixed(di->di_flags, (const char *)name, TV_CSTRING) - || var_check_ro(di->di_flags, (const char *)name, TV_CSTRING) + if (var_check_fixed(di->di_flags, name, TV_CSTRING) + || var_check_ro(di->di_flags, name, TV_CSTRING) || var_check_lock(d->dv_lock, name, TV_CSTRING)) { return FAIL; } @@ -3069,7 +3069,7 @@ static int do_lock_var(lval_T *lp, char_u *name_end FUNC_ATTR_UNUSED, exarg_T *e ret = FAIL; } else { // Normal name or expanded name. - dictitem_T *const di = find_var((const char *)lp->ll_name, lp->ll_name_len, NULL, + dictitem_T *const di = find_var(lp->ll_name, lp->ll_name_len, NULL, true); if (di == NULL) { ret = FAIL; @@ -4348,7 +4348,7 @@ static int call_func_rettv(char_u **const arg, typval_T *const rettv, const bool funcexe.selfdict = selfdict; funcexe.basetv = basetv; const int ret = get_func_tv(funcname, is_lua ? *arg - funcname : -1, rettv, - (char_u **)arg, &funcexe); + arg, &funcexe); // Clear the funcref afterwards, so that deleting it while // evaluating the arguments is possible (see test55). @@ -9444,7 +9444,7 @@ static void set_var_const(const char *name, const size_t name_len, typval_T *con // Search in parent scope which is possible to reference from lambda if (v == NULL) { - v = find_var_in_scoped_ht((const char *)name, name_len, true); + v = find_var_in_scoped_ht(name, name_len, true); } if (tv_is_func(*tv) && !var_check_func_name(name, v == NULL)) { @@ -9654,7 +9654,7 @@ bool var_check_func_name(const char *const name, const bool new_var) // Don't allow hiding a function. When "v" is not NULL we might be // assigning another function to the same var, the type is checked // below. - if (new_var && function_exists((const char *)name, false)) { + if (new_var && function_exists(name, false)) { EMSG2(_("E705: Variable name conflicts with existing function: %s"), name); return false; @@ -11325,7 +11325,7 @@ bool var_exists(const char *var) // get_name_len() takes care of expanding curly braces const char *name = var; - const int len = get_name_len((const char **)&var, &tofree, true, false); + const int len = get_name_len(&var, &tofree, true, false); if (len > 0) { typval_T tv; diff --git a/src/nvim/eval/decode.h b/src/nvim/eval/decode.h index 77fc4c78c2..f1be5a1f69 100644 --- a/src/nvim/eval/decode.h +++ b/src/nvim/eval/decode.h @@ -1,9 +1,8 @@ #ifndef NVIM_EVAL_DECODE_H #define NVIM_EVAL_DECODE_H -#include <stddef.h> - #include <msgpack.h> +#include <stddef.h> #include "nvim/eval/typval.h" #include "nvim/globals.h" diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c index 1c0afc89f5..5ef0045659 100644 --- a/src/nvim/eval/encode.c +++ b/src/nvim/eval/encode.c @@ -268,9 +268,8 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s || TV_LIST_ITEM_TV(state->li)->vval.v_string != NULL); for (size_t i = state->offset; i < state->li_length && p < buf_end; i++) { assert(TV_LIST_ITEM_TV(state->li)->vval.v_string != NULL); - const char ch = (char)( - TV_LIST_ITEM_TV(state->li)->vval.v_string[state->offset++]); - *p++ = (char)((char)ch == (char)NL ? (char)NUL : (char)ch); + const char ch = (char)(TV_LIST_ITEM_TV(state->li)->vval.v_string[state->offset++]); + *p++ = (char)(ch == (char)NL ? (char)NUL : ch); } if (p < buf_end) { state->li = TV_LIST_ITEM_NEXT(state->list, state->li); diff --git a/src/nvim/eval/encode.h b/src/nvim/eval/encode.h index 596bb49ae0..8755ff48ac 100644 --- a/src/nvim/eval/encode.h +++ b/src/nvim/eval/encode.h @@ -1,9 +1,8 @@ #ifndef NVIM_EVAL_ENCODE_H #define NVIM_EVAL_ENCODE_H -#include <stddef.h> - #include <msgpack.h> +#include <stddef.h> #include "nvim/eval.h" #include "nvim/garray.h" @@ -49,8 +48,7 @@ static inline ListReaderState encode_init_lrstate(const list_T *const list) .offset = 0, .li_length = (TV_LIST_ITEM_TV(tv_list_first(list))->vval.v_string == NULL ? 0 - : STRLEN(TV_LIST_ITEM_TV( - tv_list_first(list))->vval.v_string)), + : STRLEN(TV_LIST_ITEM_TV(tv_list_first(list))->vval.v_string)), }; } diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index b53b50e766..709ef8e5b6 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -3747,7 +3747,7 @@ static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (cur->conceal_char) { char buf[MB_MAXBYTES + 1]; - buf[utf_char2bytes((int)cur->conceal_char, (char_u *)buf)] = NUL; + buf[utf_char2bytes(cur->conceal_char, (char_u *)buf)] = NUL; tv_dict_add_str(dict, S_LEN("conceal"), buf); } @@ -5155,7 +5155,7 @@ static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr) EMSG(_(e_trailing)); } else { if (lv.ll_tv == NULL) { - di = find_var((const char *)lv.ll_name, lv.ll_name_len, NULL, true); + di = find_var(lv.ll_name, lv.ll_name_len, NULL, true); if (di != NULL) { // Consider a variable locked when: // 1. the variable itself is locked @@ -5236,7 +5236,7 @@ static void f_jobpid(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - Process *proc = (Process *)&data->stream.proc; + Process *proc = &data->stream.proc; rettv->vval.v_number = proc->pid; } @@ -5534,7 +5534,7 @@ static void f_jobstop(typval_T *argvars, typval_T *rettv, FunPtr fptr) // Ignore return code, but show error later. (void)channel_close(data->id, kChannelPartRpc, &error); } - process_stop((Process *)&data->stream.proc); + process_stop(&data->stream.proc); rettv->vval.v_number = 1; if (error) { EMSG(error); @@ -5990,7 +5990,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) static void f_luaeval(typval_T *argvars, typval_T *rettv, FunPtr fptr) FUNC_ATTR_NONNULL_ALL { - const char *const str = (const char *)tv_get_string_chk(&argvars[0]); + const char *const str = tv_get_string_chk(&argvars[0]); if (str == NULL) { return; } @@ -6141,7 +6141,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, } } - match = vim_regexec_nl(®match, str, (colnr_T)startcol); + match = vim_regexec_nl(®match, str, startcol); if (match && --nth <= 0) { break; @@ -6352,7 +6352,7 @@ static void f_matcharg(typval_T *argvars, typval_T *rettv, FunPtr fptr) : 0)); if (id >= 1 && id <= 3) { - matchitem_T *const m = (matchitem_T *)get_match(curwin, id); + matchitem_T *const m = get_match(curwin, id); if (m != NULL) { tv_list_append_string(rettv->vval.v_list, @@ -6999,7 +6999,7 @@ static void f_range(typval_T *argvars, typval_T *rettv, FunPtr fptr) } else { tv_list_alloc_ret(rettv, (end - start) / stride); for (i = start; stride > 0 ? i <= end : i >= end; i += stride) { - tv_list_append_number(rettv->vval.v_list, (varnumber_T)i); + tv_list_append_number(rettv->vval.v_list, i); } } } @@ -7302,7 +7302,7 @@ static void f_getreginfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (list == NULL) { return; } - tv_dict_add_list(dict, S_LEN("regcontents"), list); + (void)tv_dict_add_list(dict, S_LEN("regcontents"), list); char buf[NUMBUFLEN + 2]; buf[0] = NUL; @@ -7321,14 +7321,15 @@ static void f_getreginfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) case kMTUnknown: abort(); } - tv_dict_add_str(dict, S_LEN("regtype"), buf); + (void)tv_dict_add_str(dict, S_LEN("regtype"), buf); buf[0] = get_register_name(get_unname_register()); buf[1] = NUL; if (regname == '"') { - tv_dict_add_str(dict, S_LEN("points_to"), buf); + (void)tv_dict_add_str(dict, S_LEN("points_to"), buf); } else { - tv_dict_add_bool(dict, S_LEN("isunnamed"), regname == buf[0] ? kBoolVarTrue : kBoolVarFalse); + (void)tv_dict_add_bool(dict, S_LEN("isunnamed"), + regname == buf[0] ? kBoolVarTrue : kBoolVarFalse); } } @@ -11364,7 +11365,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (new_cwd && *new_cwd != NUL) { cwd = new_cwd; // The new cwd must be a directory. - if (!os_isdir_executable((const char *)cwd)) { + if (!os_isdir_executable(cwd)) { EMSG2(_(e_invarg2), "expected valid directory"); shell_free_argv(argv); return; diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 075b50a366..cfc95ba167 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -2861,7 +2861,7 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic, const boo char buf2[NUMBUFLEN]; const char *s1 = tv_get_string_buf(tv1, buf1); const char *s2 = tv_get_string_buf(tv2, buf2); - return mb_strcmp_ic((bool)ic, s1, s2) == 0; + return mb_strcmp_ic(ic, s1, s2) == 0; } case VAR_BOOL: return tv1->vval.v_bool == tv2->vval.v_bool; @@ -3260,7 +3260,7 @@ const char *tv_get_string(const typval_T *const tv) const char *tv_get_string_buf(const typval_T *const tv, char *const buf) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT { - const char *const res = (const char *)tv_get_string_buf_chk(tv, buf); + const char *const res = tv_get_string_buf_chk(tv, buf); return res != NULL ? res : ""; } diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index 5aecaccee9..a28feffd0b 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -1,23 +1,23 @@ #ifndef NVIM_EVAL_TYPVAL_H #define NVIM_EVAL_TYPVAL_H +#include <assert.h> #include <inttypes.h> +#include <stdbool.h> #include <stddef.h> #include <string.h> -#include <stdbool.h> -#include <assert.h> -#include "nvim/types.h" -#include "nvim/hashtab.h" -#include "nvim/garray.h" -#include "nvim/mbyte.h" #include "nvim/func_attr.h" -#include "nvim/lib/queue.h" -#include "nvim/profile.h" // for proftime_T -#include "nvim/pos.h" // for linenr_T +#include "nvim/garray.h" #include "nvim/gettext.h" -#include "nvim/message.h" +#include "nvim/hashtab.h" +#include "nvim/lib/queue.h" #include "nvim/macros.h" +#include "nvim/mbyte.h" +#include "nvim/message.h" +#include "nvim/pos.h" // for linenr_T +#include "nvim/profile.h" // for proftime_T +#include "nvim/types.h" #ifdef LOG_LIST_ACTIONS # include "nvim/memory.h" #endif @@ -156,8 +156,8 @@ typedef enum { typedef struct listitem_S listitem_T; struct listitem_S { - listitem_T *li_next; ///< Next item in list. - listitem_T *li_prev; ///< Previous item in list. + listitem_T *li_next; ///< Next item in list. + listitem_T *li_prev; ///< Previous item in list. typval_T li_tv; ///< Item value. }; @@ -195,25 +195,25 @@ typedef struct { } staticList10_T; #define TV_LIST_STATIC10_INIT { \ - .sl_list = { \ - .lv_first = NULL, \ - .lv_last = NULL, \ - .lv_refcount = 0, \ - .lv_len = 0, \ - .lv_watch = NULL, \ - .lv_idx_item = NULL, \ - .lv_lock = VAR_FIXED, \ - .lv_used_next = NULL, \ - .lv_used_prev = NULL, \ - }, \ - } + .sl_list = { \ + .lv_first = NULL, \ + .lv_last = NULL, \ + .lv_refcount = 0, \ + .lv_len = 0, \ + .lv_watch = NULL, \ + .lv_idx_item = NULL, \ + .lv_lock = VAR_FIXED, \ + .lv_used_next = NULL, \ + .lv_used_prev = NULL, \ + }, \ +} #define TV_DICTITEM_STRUCT(...) \ - struct { \ - typval_T di_tv; /* Structure that holds scope dictionary itself. */ \ - uint8_t di_flags; /* Flags. */ \ - char_u di_key[__VA_ARGS__]; /* Key value. */ \ - } + struct { \ + typval_T di_tv; /* Structure that holds scope dictionary itself. */ \ + uint8_t di_flags; /* Flags. */ \ + char_u di_key[__VA_ARGS__]; /* Key value. */ \ + } /// Structure to hold a scope dictionary /// @@ -321,40 +321,40 @@ struct funccall_S { /// Structure to hold info for a user function. struct ufunc { - int uf_varargs; ///< variable nr of arguments - int uf_flags; - int uf_calls; ///< nr of active calls - bool uf_cleared; ///< func_clear() was already called - garray_T uf_args; ///< arguments - garray_T uf_def_args; ///< default argument expressions - garray_T uf_lines; ///< function lines - int uf_profiling; ///< true when func is being profiled - int uf_prof_initialized; + int uf_varargs; ///< variable nr of arguments + int uf_flags; + int uf_calls; ///< nr of active calls + bool uf_cleared; ///< func_clear() was already called + garray_T uf_args; ///< arguments + garray_T uf_def_args; ///< default argument expressions + garray_T uf_lines; ///< function lines + int uf_profiling; ///< true when func is being profiled + int uf_prof_initialized; // Managing cfuncs - cfunc_T uf_cb; ///< C function extension callback + cfunc_T uf_cb; ///< C function extension callback cfunc_free_T uf_cb_free; ///< C function extension free callback - void *uf_cb_state; ///< State of C function extension. + void *uf_cb_state; ///< State of C function extension. // Profiling the function as a whole. - int uf_tm_count; ///< nr of calls - proftime_T uf_tm_total; ///< time spent in function + children - proftime_T uf_tm_self; ///< time spent in function itself - proftime_T uf_tm_children; ///< time spent in children this call + int uf_tm_count; ///< nr of calls + proftime_T uf_tm_total; ///< time spent in function + children + proftime_T uf_tm_self; ///< time spent in function itself + proftime_T uf_tm_children; ///< time spent in children this call // Profiling the function per line. - int *uf_tml_count; ///< nr of times line was executed - proftime_T *uf_tml_total; ///< time spent in a line + children - proftime_T *uf_tml_self; ///< time spent in a line itself - proftime_T uf_tml_start; ///< start time for current line - proftime_T uf_tml_children; ///< time spent in children for this line - proftime_T uf_tml_wait; ///< start wait time for current line - int uf_tml_idx; ///< index of line being timed; -1 if none - int uf_tml_execed; ///< line being timed was executed - sctx_T uf_script_ctx; ///< SCTX where function was defined, - ///< used for s: variables - int uf_refcount; ///< reference count, see func_name_refcount() - funccall_T *uf_scoped; ///< l: local variables for closure - char_u uf_name[]; ///< Name of function (actual size equals name); - ///< can start with <SNR>123_ - ///< (<SNR> is K_SPECIAL KS_EXTRA KE_SNR) + int *uf_tml_count; ///< nr of times line was executed + proftime_T *uf_tml_total; ///< time spent in a line + children + proftime_T *uf_tml_self; ///< time spent in a line itself + proftime_T uf_tml_start; ///< start time for current line + proftime_T uf_tml_children; ///< time spent in children for this line + proftime_T uf_tml_wait; ///< start wait time for current line + int uf_tml_idx; ///< index of line being timed; -1 if none + int uf_tml_execed; ///< line being timed was executed + sctx_T uf_script_ctx; ///< SCTX where function was defined, + ///< used for s: variables + int uf_refcount; ///< reference count, see func_name_refcount() + funccall_T *uf_scoped; ///< l: local variables for closure + char_u uf_name[]; ///< Name of function (actual size equals name); + ///< can start with <SNR>123_ + ///< (<SNR> is K_SPECIAL KS_EXTRA KE_SNR) }; struct partial_S { @@ -452,10 +452,8 @@ static inline void list_log(const list_T *const l, /// @param[in] li1 List item 1. /// @param[in] li2 List item 2, often used for integers and not list items. /// @param[in] action Logged action. -static inline void list_log(const list_T *const l, - const listitem_T *const li1, - const listitem_T *const li2, - const char *const action) +static inline void list_log(const list_T *const l, const listitem_T *const li1, + const listitem_T *const li2, const char *const action) { ListLog *tgt; if (list_log_first == NULL) { @@ -484,7 +482,7 @@ static inline void list_log(const list_T *const l, /// Convert a hashitem pointer to a dictitem pointer #define TV_DICT_HI2DI(hi) \ - ((dictitem_T *)((hi)->hi_key - offsetof(dictitem_T, di_key))) + ((dictitem_T *)((hi)->hi_key - offsetof(dictitem_T, di_key))) static inline void tv_list_ref(list_T *const l) REAL_FATTR_ALWAYS_INLINE; @@ -538,8 +536,7 @@ static inline VarLockStatus tv_list_locked(const list_T *const l) /// /// @param[out] l List to modify. /// @param[in] lock New lock status. -static inline void tv_list_set_lock(list_T *const l, - const VarLockStatus lock) +static inline void tv_list_set_lock(list_T *const l, const VarLockStatus lock) { if (l == NULL) { assert(lock == VAR_FIXED); @@ -554,8 +551,7 @@ static inline void tv_list_set_lock(list_T *const l, /// /// @param[out] l List to modify. /// @param[in] copyid New copyID. -static inline void tv_list_set_copyid(list_T *const l, - const int copyid) +static inline void tv_list_set_copyid(list_T *const l, const int copyid) FUNC_ATTR_NONNULL_ALL { l->lv_copyID = copyid; @@ -793,10 +789,10 @@ static inline void tv_init(typval_T *const tv) } #define TV_INITIAL_VALUE \ - ((typval_T) { \ - .v_type = VAR_UNKNOWN, \ - .v_lock = VAR_UNLOCKED, \ - }) + ((typval_T) { \ + .v_type = VAR_UNKNOWN, \ + .v_lock = VAR_UNLOCKED, \ + }) /// Empty string /// @@ -815,16 +811,16 @@ extern bool tv_in_free_unref_items; /// @param li Name of the variable with current listitem_T entry. /// @param code Cycle body. #define _TV_LIST_ITER_MOD(modifier, l, li, code) \ - do { \ - modifier list_T *const l_ = (l); \ - list_log(l_, NULL, NULL, "iter" #modifier); \ - if (l_ != NULL) { \ - for (modifier listitem_T *li = l_->lv_first; \ - li != NULL; li = li->li_next) { \ - code \ - } \ + do { \ + modifier list_T *const l_ = (l); \ + list_log(l_, NULL, NULL, "iter" #modifier); \ + if (l_ != NULL) { \ + for (modifier listitem_T *li = l_->lv_first; \ + li != NULL; li = li->li_next) { \ + code \ } \ - } while (0) + } \ + } while (0) /// Iterate over a list /// @@ -835,7 +831,7 @@ extern bool tv_in_free_unref_items; /// @param li Name of the variable with current listitem_T entry. /// @param code Cycle body. #define TV_LIST_ITER(l, li, code) \ - _TV_LIST_ITER_MOD(, l, li, code) + _TV_LIST_ITER_MOD(, l, li, code) /// Iterate over a list /// @@ -846,7 +842,7 @@ extern bool tv_in_free_unref_items; /// @param li Name of the variable with current listitem_T entry. /// @param code Cycle body. #define TV_LIST_ITER_CONST(l, li, code) \ - _TV_LIST_ITER_MOD(const, l, li, code) + _TV_LIST_ITER_MOD(const, l, li, code) // Below macros are macros to avoid duplicating code for functionally identical // const and non-const function variants. @@ -883,14 +879,14 @@ extern bool tv_in_free_unref_items; /// @param di Name of the variable with current dictitem_T entry. /// @param code Cycle body. #define TV_DICT_ITER(d, di, code) \ - HASHTAB_ITER(&(d)->dv_hashtab, di##hi_, { \ + HASHTAB_ITER(&(d)->dv_hashtab, di##hi_, { \ + { \ + dictitem_T *const di = TV_DICT_HI2DI(di##hi_); \ { \ - dictitem_T *const di = TV_DICT_HI2DI(di##hi_); \ - { \ - code \ - } \ + code \ } \ - }) + } \ + }) static inline bool tv_get_float_chk(const typval_T *const tv, float_T *const ret_f) @@ -907,8 +903,7 @@ bool emsgf(const char *const fmt, ...); /// @param[out] ret_f Location where resulting float is stored. /// /// @return true in case of success, false if tv is not a number or float. -static inline bool tv_get_float_chk(const typval_T *const tv, - float_T *const ret_f) +static inline bool tv_get_float_chk(const typval_T *const tv, float_T *const ret_f) { if (tv->v_type == VAR_FLOAT) { *ret_f = tv->vval.v_float; diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h index cd1be1eecc..ece51cb046 100644 --- a/src/nvim/eval/typval_encode.c.h +++ b/src/nvim/eval/typval_encode.c.h @@ -240,15 +240,15 @@ /// /// This name will only be used by one of the above macros which are defined by /// the caller. Functions defined here do not use first argument directly. -#include <stddef.h> -#include <inttypes.h> #include <assert.h> +#include <inttypes.h> +#include <stddef.h> -#include "nvim/lib/kvec.h" -#include "nvim/eval/typval.h" #include "nvim/eval/encode.h" -#include "nvim/func_attr.h" +#include "nvim/eval/typval.h" #include "nvim/eval/typval_encode.h" +#include "nvim/func_attr.h" +#include "nvim/lib/kvec.h" /// Dummy variable used because some macros need lvalue /// @@ -257,12 +257,12 @@ const dict_T *const TYPVAL_ENCODE_NODICT_VAR = NULL; static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( - TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, - void *const val, int *const val_copyID, - const MPConvStack *const mpstack, const int copyID, - const MPConvStackValType conv_type, - const char *const objname) - REAL_FATTR_NONNULL_ARG(2, 3, 4, 7) REAL_FATTR_WARN_UNUSED_RESULT + TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, + void *const val, int *const val_copyID, + const MPConvStack *const mpstack, const int copyID, + const MPConvStackValType conv_type, + const char *const objname) +REAL_FATTR_NONNULL_ARG(2, 3, 4, 7) REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_ALWAYS_INLINE; /// Function for checking whether container references itself @@ -280,11 +280,9 @@ static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( /// /// @return NOTDONE in case of success, what to return in case of failure. static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( - TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, - void *const val, int *const val_copyID, - const MPConvStack *const mpstack, const int copyID, - const MPConvStackValType conv_type, - const char *const objname) + TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, void *const val, int *const val_copyID, + const MPConvStack *const mpstack, const int copyID, const MPConvStackValType conv_type, + const char *const objname) { if (*val_copyID == copyID) { TYPVAL_ENCODE_CONV_RECURSE(val, conv_type); @@ -295,11 +293,11 @@ static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( } static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( - TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, - MPConvStack *const mpstack, MPConvStackVal *const cur_mpsv, - typval_T *const tv, const int copyID, - const char *const objname) - REAL_FATTR_NONNULL_ARG(2, 4, 6) REAL_FATTR_WARN_UNUSED_RESULT; + TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, + MPConvStack *const mpstack, MPConvStackVal *const cur_mpsv, + typval_T *const tv, const int copyID, + const char *const objname) +REAL_FATTR_NONNULL_ARG(2, 4, 6) REAL_FATTR_WARN_UNUSED_RESULT; /// Convert single value /// @@ -319,42 +317,35 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( /// /// @return OK in case of success, FAIL in case of failure. static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( - TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, - MPConvStack *const mpstack, MPConvStackVal *const cur_mpsv, - typval_T *const tv, const int copyID, - const char *const objname) + TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, MPConvStack *const mpstack, + MPConvStackVal *const cur_mpsv, typval_T *const tv, const int copyID, const char *const objname) { switch (tv->v_type) { - case VAR_STRING: { - TYPVAL_ENCODE_CONV_STRING(tv, tv->vval.v_string, tv_strlen(tv)); - break; - } - case VAR_NUMBER: { - TYPVAL_ENCODE_CONV_NUMBER(tv, tv->vval.v_number); - break; - } - case VAR_FLOAT: { - TYPVAL_ENCODE_CONV_FLOAT(tv, tv->vval.v_float); - break; - } - case VAR_BLOB: { - TYPVAL_ENCODE_CONV_BLOB(tv, tv->vval.v_blob, - tv_blob_len(tv->vval.v_blob)); - break; - } - case VAR_FUNC: { - TYPVAL_ENCODE_CONV_FUNC_START(tv, tv->vval.v_string); - TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, 0); - TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1); - TYPVAL_ENCODE_CONV_FUNC_END(tv); - break; - } - case VAR_PARTIAL: { - partial_T *const pt = tv->vval.v_partial; - (void)pt; - TYPVAL_ENCODE_CONV_FUNC_START( // -V547 - tv, (pt == NULL ? NULL : partial_name(pt))); - _mp_push(*mpstack, ((MPConvStackVal) { // -V779 + case VAR_STRING: + TYPVAL_ENCODE_CONV_STRING(tv, tv->vval.v_string, tv_strlen(tv)); + break; + case VAR_NUMBER: + TYPVAL_ENCODE_CONV_NUMBER(tv, tv->vval.v_number); + break; + case VAR_FLOAT: + TYPVAL_ENCODE_CONV_FLOAT(tv, tv->vval.v_float); + break; + case VAR_BLOB: + TYPVAL_ENCODE_CONV_BLOB(tv, tv->vval.v_blob, + tv_blob_len(tv->vval.v_blob)); + break; + case VAR_FUNC: + TYPVAL_ENCODE_CONV_FUNC_START(tv, tv->vval.v_string); + TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, 0); + TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1); + TYPVAL_ENCODE_CONV_FUNC_END(tv); + break; + case VAR_PARTIAL: { + partial_T *const pt = tv->vval.v_partial; + (void)pt; + TYPVAL_ENCODE_CONV_FUNC_START( // -V547 + tv, (pt == NULL ? NULL : partial_name(pt))); + _mp_push(*mpstack, ((MPConvStackVal) { // -V779 .type = kMPConvPartial, .tv = tv, .saved_copyID = copyID - 1, @@ -365,19 +356,19 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( }, }, })); + break; + } + case VAR_LIST: { + if (tv->vval.v_list == NULL || tv_list_len(tv->vval.v_list) == 0) { + TYPVAL_ENCODE_CONV_EMPTY_LIST(tv); break; } - case VAR_LIST: { - if (tv->vval.v_list == NULL || tv_list_len(tv->vval.v_list) == 0) { - TYPVAL_ENCODE_CONV_EMPTY_LIST(tv); - break; - } - const int saved_copyID = tv_list_copyid(tv->vval.v_list); - _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_list, lv_copyID, copyID, - kMPConvList); - TYPVAL_ENCODE_CONV_LIST_START(tv, tv_list_len(tv->vval.v_list)); - assert(saved_copyID != copyID); - _mp_push(*mpstack, ((MPConvStackVal) { + const int saved_copyID = tv_list_copyid(tv->vval.v_list); + _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_list, lv_copyID, copyID, + kMPConvList); + TYPVAL_ENCODE_CONV_LIST_START(tv, tv_list_len(tv->vval.v_list)); + assert(saved_copyID != copyID); + _mp_push(*mpstack, ((MPConvStackVal) { .type = kMPConvList, .tv = tv, .saved_copyID = saved_copyID, @@ -388,159 +379,151 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( }, }, })); - TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, _mp_last(*mpstack)); + TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, _mp_last(*mpstack)); + break; + } + case VAR_BOOL: + switch (tv->vval.v_bool) { + case kBoolVarTrue: + case kBoolVarFalse: + TYPVAL_ENCODE_CONV_BOOL(tv, tv->vval.v_bool == kBoolVarTrue); break; } - case VAR_BOOL: { - switch (tv->vval.v_bool) { - case kBoolVarTrue: - case kBoolVarFalse: { - TYPVAL_ENCODE_CONV_BOOL(tv, tv->vval.v_bool == kBoolVarTrue); - break; - } - } + break; + case VAR_SPECIAL: + switch (tv->vval.v_special) { + case kSpecialVarNull: + TYPVAL_ENCODE_CONV_NIL(tv); // -V1037 break; } - case VAR_SPECIAL: { - switch (tv->vval.v_special) { - case kSpecialVarNull: { - TYPVAL_ENCODE_CONV_NIL(tv); // -V1037 + break; + case VAR_DICT: { + if (tv->vval.v_dict == NULL + || tv->vval.v_dict->dv_hashtab.ht_used == 0) { + TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, tv->vval.v_dict); + break; + } + const dictitem_T *type_di; + const dictitem_T *val_di; + if (TYPVAL_ENCODE_ALLOW_SPECIALS + && tv->vval.v_dict->dv_hashtab.ht_used == 2 + && (type_di = tv_dict_find((dict_T *)tv->vval.v_dict, + S_LEN("_TYPE"))) != NULL + && type_di->di_tv.v_type == VAR_LIST + && (val_di = tv_dict_find((dict_T *)tv->vval.v_dict, + S_LEN("_VAL"))) != NULL) { + size_t i; + for (i = 0; i < ARRAY_SIZE(eval_msgpack_type_lists); i++) { + if (type_di->di_tv.vval.v_list == eval_msgpack_type_lists[i]) { break; } } - break; - } - case VAR_DICT: { - if (tv->vval.v_dict == NULL - || tv->vval.v_dict->dv_hashtab.ht_used == 0) { - TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, tv->vval.v_dict); - break; + if (i == ARRAY_SIZE(eval_msgpack_type_lists)) { + goto _convert_one_value_regular_dict; } - const dictitem_T *type_di; - const dictitem_T *val_di; - if (TYPVAL_ENCODE_ALLOW_SPECIALS - && tv->vval.v_dict->dv_hashtab.ht_used == 2 - && (type_di = tv_dict_find((dict_T *)tv->vval.v_dict, - S_LEN("_TYPE"))) != NULL - && type_di->di_tv.v_type == VAR_LIST - && (val_di = tv_dict_find((dict_T *)tv->vval.v_dict, - S_LEN("_VAL"))) != NULL) { - size_t i; - for (i = 0; i < ARRAY_SIZE(eval_msgpack_type_lists); i++) { - if (type_di->di_tv.vval.v_list == eval_msgpack_type_lists[i]) { - break; - } + switch ((MessagePackType)i) { + case kMPNil: + TYPVAL_ENCODE_CONV_NIL(tv); + break; + case kMPBoolean: + if (val_di->di_tv.v_type != VAR_NUMBER) { + goto _convert_one_value_regular_dict; } - if (i == ARRAY_SIZE(eval_msgpack_type_lists)) { + TYPVAL_ENCODE_CONV_BOOL(tv, val_di->di_tv.vval.v_number); + break; + case kMPInteger: { + const list_T *val_list; + varnumber_T sign; + varnumber_T highest_bits; + varnumber_T high_bits; + varnumber_T low_bits; + // List of 4 integers; first is signed (should be 1 or -1, but + // this is not checked), second is unsigned and have at most + // one (sign is -1) or two (sign is 1) non-zero bits (number of + // bits is not checked), other unsigned and have at most 31 + // non-zero bits (number of bits is not checked). + if (val_di->di_tv.v_type != VAR_LIST + || tv_list_len(val_list = val_di->di_tv.vval.v_list) != 4) { goto _convert_one_value_regular_dict; } - switch ((MessagePackType)i) { - case kMPNil: { - TYPVAL_ENCODE_CONV_NIL(tv); - break; - } - case kMPBoolean: { - if (val_di->di_tv.v_type != VAR_NUMBER) { - goto _convert_one_value_regular_dict; - } - TYPVAL_ENCODE_CONV_BOOL(tv, val_di->di_tv.vval.v_number); - break; - } - case kMPInteger: { - const list_T *val_list; - varnumber_T sign; - varnumber_T highest_bits; - varnumber_T high_bits; - varnumber_T low_bits; - // List of 4 integers; first is signed (should be 1 or -1, but - // this is not checked), second is unsigned and have at most - // one (sign is -1) or two (sign is 1) non-zero bits (number of - // bits is not checked), other unsigned and have at most 31 - // non-zero bits (number of bits is not checked). - if (val_di->di_tv.v_type != VAR_LIST - || tv_list_len(val_list = val_di->di_tv.vval.v_list) != 4) { - goto _convert_one_value_regular_dict; - } - const listitem_T *const sign_li = tv_list_first(val_list); - if (TV_LIST_ITEM_TV(sign_li)->v_type != VAR_NUMBER - || (sign = TV_LIST_ITEM_TV(sign_li)->vval.v_number) == 0) { - goto _convert_one_value_regular_dict; - } + const listitem_T *const sign_li = tv_list_first(val_list); + if (TV_LIST_ITEM_TV(sign_li)->v_type != VAR_NUMBER + || (sign = TV_LIST_ITEM_TV(sign_li)->vval.v_number) == 0) { + goto _convert_one_value_regular_dict; + } - const listitem_T *const highest_bits_li = ( - TV_LIST_ITEM_NEXT(val_list, sign_li)); - if (TV_LIST_ITEM_TV(highest_bits_li)->v_type != VAR_NUMBER - || ((highest_bits - = TV_LIST_ITEM_TV(highest_bits_li)->vval.v_number) - < 0)) { - goto _convert_one_value_regular_dict; - } + const listitem_T *const highest_bits_li = ( + TV_LIST_ITEM_NEXT(val_list, sign_li)); + if (TV_LIST_ITEM_TV(highest_bits_li)->v_type != VAR_NUMBER + || ((highest_bits + = TV_LIST_ITEM_TV(highest_bits_li)->vval.v_number) + < 0)) { + goto _convert_one_value_regular_dict; + } - const listitem_T *const high_bits_li = ( - TV_LIST_ITEM_NEXT(val_list, highest_bits_li)); - if (TV_LIST_ITEM_TV(high_bits_li)->v_type != VAR_NUMBER - || ((high_bits = TV_LIST_ITEM_TV(high_bits_li)->vval.v_number) - < 0)) { - goto _convert_one_value_regular_dict; - } + const listitem_T *const high_bits_li = ( + TV_LIST_ITEM_NEXT(val_list, highest_bits_li)); + if (TV_LIST_ITEM_TV(high_bits_li)->v_type != VAR_NUMBER + || ((high_bits = TV_LIST_ITEM_TV(high_bits_li)->vval.v_number) + < 0)) { + goto _convert_one_value_regular_dict; + } - const listitem_T *const low_bits_li = tv_list_last(val_list); - if (TV_LIST_ITEM_TV(low_bits_li)->v_type != VAR_NUMBER - || ((low_bits = TV_LIST_ITEM_TV(low_bits_li)->vval.v_number) - < 0)) { - goto _convert_one_value_regular_dict; - } + const listitem_T *const low_bits_li = tv_list_last(val_list); + if (TV_LIST_ITEM_TV(low_bits_li)->v_type != VAR_NUMBER + || ((low_bits = TV_LIST_ITEM_TV(low_bits_li)->vval.v_number) + < 0)) { + goto _convert_one_value_regular_dict; + } - const uint64_t number = ((uint64_t)(((uint64_t)highest_bits) << 62) - | (uint64_t)(((uint64_t)high_bits) << 31) - | (uint64_t)low_bits); - if (sign > 0) { - TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, number); - } else { - TYPVAL_ENCODE_CONV_NUMBER(tv, -number); - } - break; - } - case kMPFloat: { - if (val_di->di_tv.v_type != VAR_FLOAT) { - goto _convert_one_value_regular_dict; - } - TYPVAL_ENCODE_CONV_FLOAT(tv, val_di->di_tv.vval.v_float); - break; - } - case kMPString: - case kMPBinary: { - const bool is_string = ((MessagePackType)i == kMPString); - if (val_di->di_tv.v_type != VAR_LIST) { - goto _convert_one_value_regular_dict; - } - size_t len; - char *buf; - if (!encode_vim_list_to_buf(val_di->di_tv.vval.v_list, &len, - &buf)) { - goto _convert_one_value_regular_dict; - } - if (is_string) { - TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len); - } else { // -V523 - TYPVAL_ENCODE_CONV_STRING(tv, buf, len); - } - xfree(buf); - break; - } - case kMPArray: { - if (val_di->di_tv.v_type != VAR_LIST) { - goto _convert_one_value_regular_dict; - } - const int saved_copyID = tv_list_copyid(val_di->di_tv.vval.v_list); - _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_di->di_tv.vval.v_list, - lv_copyID, copyID, - kMPConvList); - TYPVAL_ENCODE_CONV_LIST_START( - tv, tv_list_len(val_di->di_tv.vval.v_list)); - assert(saved_copyID != copyID && saved_copyID != copyID - 1); - _mp_push(*mpstack, ((MPConvStackVal) { + const uint64_t number = ((uint64_t)(((uint64_t)highest_bits) << 62) + | (uint64_t)(((uint64_t)high_bits) << 31) + | (uint64_t)low_bits); + if (sign > 0) { + TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, number); + } else { + TYPVAL_ENCODE_CONV_NUMBER(tv, -number); + } + break; + } + case kMPFloat: + if (val_di->di_tv.v_type != VAR_FLOAT) { + goto _convert_one_value_regular_dict; + } + TYPVAL_ENCODE_CONV_FLOAT(tv, val_di->di_tv.vval.v_float); + break; + case kMPString: + case kMPBinary: { + const bool is_string = ((MessagePackType)i == kMPString); + if (val_di->di_tv.v_type != VAR_LIST) { + goto _convert_one_value_regular_dict; + } + size_t len; + char *buf; + if (!encode_vim_list_to_buf(val_di->di_tv.vval.v_list, &len, + &buf)) { + goto _convert_one_value_regular_dict; + } + if (is_string) { + TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len); + } else { // -V523 + TYPVAL_ENCODE_CONV_STRING(tv, buf, len); + } + xfree(buf); + break; + } + case kMPArray: { + if (val_di->di_tv.v_type != VAR_LIST) { + goto _convert_one_value_regular_dict; + } + const int saved_copyID = tv_list_copyid(val_di->di_tv.vval.v_list); + _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_di->di_tv.vval.v_list, + lv_copyID, copyID, + kMPConvList); + TYPVAL_ENCODE_CONV_LIST_START(tv, tv_list_len(val_di->di_tv.vval.v_list)); + assert(saved_copyID != copyID && saved_copyID != copyID - 1); + _mp_push(*mpstack, ((MPConvStackVal) { .tv = tv, .type = kMPConvList, .saved_copyID = saved_copyID, @@ -551,31 +534,31 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( }, }, })); - break; - } - case kMPMap: { - if (val_di->di_tv.v_type != VAR_LIST) { - goto _convert_one_value_regular_dict; - } - list_T *const val_list = val_di->di_tv.vval.v_list; - if (val_list == NULL || tv_list_len(val_list) == 0) { - TYPVAL_ENCODE_CONV_EMPTY_DICT( // -V501 - tv, TYPVAL_ENCODE_NODICT_VAR); - break; - } - TV_LIST_ITER_CONST(val_list, li, { + break; + } + case kMPMap: { + if (val_di->di_tv.v_type != VAR_LIST) { + goto _convert_one_value_regular_dict; + } + list_T *const val_list = val_di->di_tv.vval.v_list; + if (val_list == NULL || tv_list_len(val_list) == 0) { + TYPVAL_ENCODE_CONV_EMPTY_DICT( // -V501 + tv, TYPVAL_ENCODE_NODICT_VAR); + break; + } + TV_LIST_ITER_CONST(val_list, li, { if (TV_LIST_ITEM_TV(li)->v_type != VAR_LIST || tv_list_len(TV_LIST_ITEM_TV(li)->vval.v_list) != 2) { goto _convert_one_value_regular_dict; } }); - const int saved_copyID = tv_list_copyid(val_di->di_tv.vval.v_list); - _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_list, lv_copyID, copyID, - kMPConvPairs); - TYPVAL_ENCODE_CONV_DICT_START(tv, TYPVAL_ENCODE_NODICT_VAR, - tv_list_len(val_list)); - assert(saved_copyID != copyID && saved_copyID != copyID - 1); - _mp_push(*mpstack, ((MPConvStackVal) { + const int saved_copyID = tv_list_copyid(val_di->di_tv.vval.v_list); + _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_list, lv_copyID, copyID, + kMPConvPairs); + TYPVAL_ENCODE_CONV_DICT_START(tv, TYPVAL_ENCODE_NODICT_VAR, + tv_list_len(val_list)); + assert(saved_copyID != copyID && saved_copyID != copyID - 1); + _mp_push(*mpstack, ((MPConvStackVal) { .tv = tv, .type = kMPConvPairs, .saved_copyID = saved_copyID, @@ -586,46 +569,45 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( }, }, })); - break; - } - case kMPExt: { - const list_T *val_list; - varnumber_T type; - if (val_di->di_tv.v_type != VAR_LIST - || tv_list_len((val_list = val_di->di_tv.vval.v_list)) != 2 - || (TV_LIST_ITEM_TV(tv_list_first(val_list))->v_type - != VAR_NUMBER) - || ((type - = TV_LIST_ITEM_TV(tv_list_first(val_list))->vval.v_number) - > INT8_MAX) - || type < INT8_MIN - || (TV_LIST_ITEM_TV(tv_list_last(val_list))->v_type - != VAR_LIST)) { - goto _convert_one_value_regular_dict; - } - size_t len; - char *buf; - if (!( - encode_vim_list_to_buf( - TV_LIST_ITEM_TV(tv_list_last(val_list))->vval.v_list, &len, - &buf))) { - goto _convert_one_value_regular_dict; - } - TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type); - xfree(buf); - break; - } + break; + } + case kMPExt: { + const list_T *val_list; + varnumber_T type; + if (val_di->di_tv.v_type != VAR_LIST + || tv_list_len((val_list = val_di->di_tv.vval.v_list)) != 2 + || (TV_LIST_ITEM_TV(tv_list_first(val_list))->v_type + != VAR_NUMBER) + || ((type + = TV_LIST_ITEM_TV(tv_list_first(val_list))->vval.v_number) + > INT8_MAX) + || type < INT8_MIN + || (TV_LIST_ITEM_TV(tv_list_last(val_list))->v_type + != VAR_LIST)) { + goto _convert_one_value_regular_dict; + } + size_t len; + char *buf; + if (!( + encode_vim_list_to_buf(TV_LIST_ITEM_TV(tv_list_last(val_list))->vval.v_list, &len, + &buf))) { + goto _convert_one_value_regular_dict; } + TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type); + xfree(buf); break; } + } + break; + } _convert_one_value_regular_dict: {} - const int saved_copyID = tv->vval.v_dict->dv_copyID; - _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_dict, dv_copyID, copyID, - kMPConvDict); - TYPVAL_ENCODE_CONV_DICT_START(tv, tv->vval.v_dict, - tv->vval.v_dict->dv_hashtab.ht_used); - assert(saved_copyID != copyID); - _mp_push(*mpstack, ((MPConvStackVal) { + const int saved_copyID = tv->vval.v_dict->dv_copyID; + _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_dict, dv_copyID, copyID, + kMPConvDict); + TYPVAL_ENCODE_CONV_DICT_START(tv, tv->vval.v_dict, + tv->vval.v_dict->dv_hashtab.ht_used); + assert(saved_copyID != copyID); + _mp_push(*mpstack, ((MPConvStackVal) { .tv = tv, .type = kMPConvDict, .saved_copyID = saved_copyID, @@ -638,14 +620,13 @@ _convert_one_value_regular_dict: {} }, }, })); - TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, tv->vval.v_dict, - _mp_last(*mpstack)); - break; - } - case VAR_UNKNOWN: { - internal_error(STR(_TYPVAL_ENCODE_CONVERT_ONE_VALUE) "()"); - return FAIL; - } + TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, tv->vval.v_dict, + _mp_last(*mpstack)); + break; + } + case VAR_UNKNOWN: + internal_error(STR(_TYPVAL_ENCODE_CONVERT_ONE_VALUE) "()"); + return FAIL; } typval_encode_stop_converting_one_item: return OK; @@ -654,9 +635,9 @@ typval_encode_stop_converting_one_item: } TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE( - TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, - typval_T *const tv, const char *const objname) - REAL_FATTR_NONNULL_ARG(2, 3) REAL_FATTR_WARN_UNUSED_RESULT; + TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, + typval_T *const tv, const char *const objname) +REAL_FATTR_NONNULL_ARG(2, 3) REAL_FATTR_WARN_UNUSED_RESULT; /// Convert the whole typval /// @@ -668,8 +649,8 @@ TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE( /// /// @return OK in case of success, FAIL in case of failure. TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE( - TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, - typval_T *const top_tv, const char *const objname) + TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, typval_T *const top_tv, + const char *const objname) { const int copyID = get_copyID(); MPConvStack mpstack; @@ -687,125 +668,121 @@ typval_encode_stop_converting_one_item: MPConvStackVal *cur_mpsv = &_mp_last(mpstack); typval_T *tv = NULL; switch (cur_mpsv->type) { - case kMPConvDict: { - if (!cur_mpsv->data.d.todo) { - (void)_mp_pop(mpstack); - cur_mpsv->data.d.dict->dv_copyID = cur_mpsv->saved_copyID; - TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, *cur_mpsv->data.d.dictp); - continue; - } else if (cur_mpsv->data.d.todo - != cur_mpsv->data.d.dict->dv_hashtab.ht_used) { - TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(cur_mpsv->tv, - *cur_mpsv->data.d.dictp); - } - while (HASHITEM_EMPTY(cur_mpsv->data.d.hi)) { - cur_mpsv->data.d.hi++; - } - dictitem_T *const di = TV_DICT_HI2DI(cur_mpsv->data.d.hi); - cur_mpsv->data.d.todo--; + case kMPConvDict: { + if (!cur_mpsv->data.d.todo) { + (void)_mp_pop(mpstack); + cur_mpsv->data.d.dict->dv_copyID = cur_mpsv->saved_copyID; + TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, *cur_mpsv->data.d.dictp); + continue; + } else if (cur_mpsv->data.d.todo + != cur_mpsv->data.d.dict->dv_hashtab.ht_used) { + TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(cur_mpsv->tv, + *cur_mpsv->data.d.dictp); + } + while (HASHITEM_EMPTY(cur_mpsv->data.d.hi)) { cur_mpsv->data.d.hi++; - TYPVAL_ENCODE_CONV_STR_STRING(NULL, &di->di_key[0], - strlen((char *)&di->di_key[0])); - TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv, - *cur_mpsv->data.d.dictp); - tv = &di->di_tv; - break; } - case kMPConvList: { - if (cur_mpsv->data.l.li == NULL) { - (void)_mp_pop(mpstack); - tv_list_set_copyid(cur_mpsv->data.l.list, cur_mpsv->saved_copyID); - TYPVAL_ENCODE_CONV_LIST_END(cur_mpsv->tv); - continue; - } else if (cur_mpsv->data.l.li - != tv_list_first(cur_mpsv->data.l.list)) { - TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(cur_mpsv->tv); - } - tv = TV_LIST_ITEM_TV(cur_mpsv->data.l.li); - cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list, - cur_mpsv->data.l.li); - break; + dictitem_T *const di = TV_DICT_HI2DI(cur_mpsv->data.d.hi); + cur_mpsv->data.d.todo--; + cur_mpsv->data.d.hi++; + TYPVAL_ENCODE_CONV_STR_STRING(NULL, &di->di_key[0], + strlen((char *)&di->di_key[0])); + TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv, + *cur_mpsv->data.d.dictp); + tv = &di->di_tv; + break; + } + case kMPConvList: + if (cur_mpsv->data.l.li == NULL) { + (void)_mp_pop(mpstack); + tv_list_set_copyid(cur_mpsv->data.l.list, cur_mpsv->saved_copyID); + TYPVAL_ENCODE_CONV_LIST_END(cur_mpsv->tv); + continue; + } else if (cur_mpsv->data.l.li + != tv_list_first(cur_mpsv->data.l.list)) { + TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(cur_mpsv->tv); } - case kMPConvPairs: { - if (cur_mpsv->data.l.li == NULL) { - (void)_mp_pop(mpstack); - tv_list_set_copyid(cur_mpsv->data.l.list, cur_mpsv->saved_copyID); - TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR); - continue; - } else if (cur_mpsv->data.l.li - != tv_list_first(cur_mpsv->data.l.list)) { - TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS( - cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR); - } - const list_T *const kv_pair = ( - TV_LIST_ITEM_TV(cur_mpsv->data.l.li)->vval.v_list); - TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK( - encode_vim_to__error_ret, *TV_LIST_ITEM_TV(tv_list_first(kv_pair))); - if ( - _TYPVAL_ENCODE_CONVERT_ONE_VALUE( - TYPVAL_ENCODE_FIRST_ARG_NAME, &mpstack, cur_mpsv, - TV_LIST_ITEM_TV(tv_list_first(kv_pair)), copyID, objname) - == FAIL) { - goto encode_vim_to__error_ret; - } - TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv, - TYPVAL_ENCODE_NODICT_VAR); - tv = TV_LIST_ITEM_TV(tv_list_last(kv_pair)); - cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list, - cur_mpsv->data.l.li); - break; + tv = TV_LIST_ITEM_TV(cur_mpsv->data.l.li); + cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list, + cur_mpsv->data.l.li); + break; + case kMPConvPairs: { + if (cur_mpsv->data.l.li == NULL) { + (void)_mp_pop(mpstack); + tv_list_set_copyid(cur_mpsv->data.l.list, cur_mpsv->saved_copyID); + TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR); + continue; + } else if (cur_mpsv->data.l.li + != tv_list_first(cur_mpsv->data.l.list)) { + TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR); } - case kMPConvPartial: { - partial_T *const pt = cur_mpsv->data.p.pt; - tv = cur_mpsv->tv; - (void)tv; - switch (cur_mpsv->data.p.stage) { - case kMPConvPartialArgs: { - TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, - pt == NULL ? 0 : pt->pt_argc); - cur_mpsv->data.p.stage = kMPConvPartialSelf; - if (pt != NULL && pt->pt_argc > 0) { - TYPVAL_ENCODE_CONV_LIST_START(NULL, pt->pt_argc); - _mp_push(mpstack, ((MPConvStackVal) { - .type = kMPConvPartialList, - .tv = NULL, - .saved_copyID = copyID - 1, - .data = { - .a = { - .arg = pt->pt_argv, - .argv = pt->pt_argv, - .todo = (size_t)pt->pt_argc, - }, + const list_T *const kv_pair = ( + TV_LIST_ITEM_TV(cur_mpsv->data.l.li)->vval.v_list); + TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(encode_vim_to__error_ret, + *TV_LIST_ITEM_TV(tv_list_first(kv_pair))); + if ( + _TYPVAL_ENCODE_CONVERT_ONE_VALUE(TYPVAL_ENCODE_FIRST_ARG_NAME, &mpstack, cur_mpsv, + TV_LIST_ITEM_TV(tv_list_first(kv_pair)), copyID, objname) + == FAIL) { + goto encode_vim_to__error_ret; + } + TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv, + TYPVAL_ENCODE_NODICT_VAR); + tv = TV_LIST_ITEM_TV(tv_list_last(kv_pair)); + cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list, + cur_mpsv->data.l.li); + break; + } + case kMPConvPartial: { + partial_T *const pt = cur_mpsv->data.p.pt; + tv = cur_mpsv->tv; + (void)tv; + switch (cur_mpsv->data.p.stage) { + case kMPConvPartialArgs: + TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, + pt == NULL ? 0 : pt->pt_argc); + cur_mpsv->data.p.stage = kMPConvPartialSelf; + if (pt != NULL && pt->pt_argc > 0) { + TYPVAL_ENCODE_CONV_LIST_START(NULL, pt->pt_argc); + _mp_push(mpstack, ((MPConvStackVal) { + .type = kMPConvPartialList, + .tv = NULL, + .saved_copyID = copyID - 1, + .data = { + .a = { + .arg = pt->pt_argv, + .argv = pt->pt_argv, + .todo = (size_t)pt->pt_argc, }, - })); + }, + })); + } + break; + case kMPConvPartialSelf: { + cur_mpsv->data.p.stage = kMPConvPartialEnd; + dict_T *const dict = pt == NULL ? NULL : pt->pt_dict; + if (dict != NULL) { + TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, dict->dv_hashtab.ht_used); + if (dict->dv_hashtab.ht_used == 0) { + TYPVAL_ENCODE_CONV_EMPTY_DICT(NULL, pt->pt_dict); + continue; + } + const int saved_copyID = dict->dv_copyID; + const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(TYPVAL_ENCODE_FIRST_ARG_NAME, + dict, &dict->dv_copyID, + &mpstack, copyID, kMPConvDict, + objname); + if (te_csr_ret != NOTDONE) { + if (te_csr_ret == FAIL) { + goto encode_vim_to__error_ret; + } else { + continue; } - break; } - case kMPConvPartialSelf: { - cur_mpsv->data.p.stage = kMPConvPartialEnd; - dict_T *const dict = pt == NULL ? NULL : pt->pt_dict; - if (dict != NULL) { - TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, dict->dv_hashtab.ht_used); - if (dict->dv_hashtab.ht_used == 0) { - TYPVAL_ENCODE_CONV_EMPTY_DICT(NULL, pt->pt_dict); - continue; - } - const int saved_copyID = dict->dv_copyID; - const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( - TYPVAL_ENCODE_FIRST_ARG_NAME, - dict, &dict->dv_copyID, &mpstack, copyID, kMPConvDict, - objname); - if (te_csr_ret != NOTDONE) { - if (te_csr_ret == FAIL) { - goto encode_vim_to__error_ret; - } else { - continue; - } - } - TYPVAL_ENCODE_CONV_DICT_START(NULL, pt->pt_dict, - dict->dv_hashtab.ht_used); - assert(saved_copyID != copyID && saved_copyID != copyID - 1); - _mp_push(mpstack, ((MPConvStackVal) { + TYPVAL_ENCODE_CONV_DICT_START(NULL, pt->pt_dict, + dict->dv_hashtab.ht_used); + assert(saved_copyID != copyID && saved_copyID != copyID - 1); + _mp_push(mpstack, ((MPConvStackVal) { .type = kMPConvDict, .tv = NULL, .saved_copyID = saved_copyID, @@ -818,33 +795,31 @@ typval_encode_stop_converting_one_item: }, }, })); - TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(NULL, pt->pt_dict, - _mp_last(mpstack)); - } else { - TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1); - } - break; - } - case kMPConvPartialEnd: { - TYPVAL_ENCODE_CONV_FUNC_END(tv); - (void)_mp_pop(mpstack); - break; - } + TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(NULL, pt->pt_dict, + _mp_last(mpstack)); + } else { + TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1); } - continue; + break; } - case kMPConvPartialList: { - if (!cur_mpsv->data.a.todo) { - (void)_mp_pop(mpstack); - TYPVAL_ENCODE_CONV_LIST_END(NULL); - continue; - } else if (cur_mpsv->data.a.argv != cur_mpsv->data.a.arg) { - TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(NULL); - } - tv = cur_mpsv->data.a.arg++; - cur_mpsv->data.a.todo--; + case kMPConvPartialEnd: + TYPVAL_ENCODE_CONV_FUNC_END(tv); + (void)_mp_pop(mpstack); break; } + continue; + } + case kMPConvPartialList: + if (!cur_mpsv->data.a.todo) { + (void)_mp_pop(mpstack); + TYPVAL_ENCODE_CONV_LIST_END(NULL); + continue; + } else if (cur_mpsv->data.a.argv != cur_mpsv->data.a.arg) { + TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(NULL); + } + tv = cur_mpsv->data.a.arg++; + cur_mpsv->data.a.todo--; + break; } assert(tv != NULL); if (_TYPVAL_ENCODE_CONVERT_ONE_VALUE(TYPVAL_ENCODE_FIRST_ARG_NAME, &mpstack, diff --git a/src/nvim/eval/typval_encode.h b/src/nvim/eval/typval_encode.h index 3475f6d8b3..d5cf431870 100644 --- a/src/nvim/eval/typval_encode.h +++ b/src/nvim/eval/typval_encode.h @@ -5,14 +5,14 @@ #ifndef NVIM_EVAL_TYPVAL_ENCODE_H #define NVIM_EVAL_TYPVAL_ENCODE_H -#include <stddef.h> +#include <assert.h> #include <inttypes.h> +#include <stddef.h> #include <string.h> -#include <assert.h> -#include "nvim/lib/kvec.h" #include "nvim/eval/typval.h" #include "nvim/func_attr.h" +#include "nvim/lib/kvec.h" /// Type of the stack entry typedef enum { @@ -87,7 +87,7 @@ static inline size_t tv_strlen(const typval_T *const tv) assert(tv->v_type == VAR_STRING); return (tv->vval.v_string == NULL ? 0 - : strlen((char *) tv->vval.v_string)); + : strlen((char *)tv->vval.v_string)); } /// Code for checking whether container references itself @@ -100,19 +100,19 @@ static inline size_t tv_strlen(const typval_T *const tv) /// @param conv_type Type of the conversion, @see MPConvStackValType. #define _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val, copyID_attr, copyID, \ conv_type) \ - do { \ - const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( \ - TYPVAL_ENCODE_FIRST_ARG_NAME, \ - (val), &(val)->copyID_attr, mpstack, copyID, conv_type, objname); \ - if (te_csr_ret != NOTDONE) { \ - return te_csr_ret; \ - } \ - } while (0) + do { \ + const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(TYPVAL_ENCODE_FIRST_ARG_NAME, \ + (val), &(val)->copyID_attr, mpstack, \ + copyID, conv_type, objname); \ + if (te_csr_ret != NOTDONE) { \ + return te_csr_ret; \ + } \ + } while (0) #define _TYPVAL_ENCODE_FUNC_NAME_INNER_2(pref, name, suf) \ - pref##name##suf + pref##name##suf #define _TYPVAL_ENCODE_FUNC_NAME_INNER(pref, name, suf) \ - _TYPVAL_ENCODE_FUNC_NAME_INNER_2(pref, name, suf) + _TYPVAL_ENCODE_FUNC_NAME_INNER_2(pref, name, suf) /// Construct function name, possibly using macros /// @@ -125,22 +125,22 @@ static inline size_t tv_strlen(const typval_T *const tv) /// /// @return Concat: pref + #TYPVAL_ENCODE_NAME + suf. #define _TYPVAL_ENCODE_FUNC_NAME(pref, suf) \ - _TYPVAL_ENCODE_FUNC_NAME_INNER(pref, TYPVAL_ENCODE_NAME, suf) + _TYPVAL_ENCODE_FUNC_NAME_INNER(pref, TYPVAL_ENCODE_NAME, suf) /// Self reference checker function name #define _TYPVAL_ENCODE_CHECK_SELF_REFERENCE \ - _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _check_self_reference) + _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _check_self_reference) /// Entry point function name #define _TYPVAL_ENCODE_ENCODE \ - _TYPVAL_ENCODE_FUNC_NAME(encode_vim_to_, ) + _TYPVAL_ENCODE_FUNC_NAME(encode_vim_to_, ) /// Name of the …convert_one_value function #define _TYPVAL_ENCODE_CONVERT_ONE_VALUE \ - _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _convert_one_value) + _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _convert_one_value) /// Name of the dummy const dict_T *const variable #define TYPVAL_ENCODE_NODICT_VAR \ - _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _nodict_var) + _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _nodict_var) #endif // NVIM_EVAL_TYPVAL_ENCODE_H diff --git a/src/nvim/eval/userfunc.h b/src/nvim/eval/userfunc.h index 3f111343d2..ed86aaad4a 100644 --- a/src/nvim/eval/userfunc.h +++ b/src/nvim/eval/userfunc.h @@ -8,7 +8,7 @@ typedef struct { dict_T *fd_dict; ///< Dictionary used. char_u *fd_newkey; ///< New key in "dict" in allocated memory. - dictitem_T *fd_di; ///< Dictionary item used. + dictitem_T *fd_di; ///< Dictionary item used. } funcdict_T; typedef struct funccal_entry funccal_entry_T; diff --git a/src/nvim/event/defs.h b/src/nvim/event/defs.h index fdd4f17d5c..cf079681d0 100644 --- a/src/nvim/event/defs.h +++ b/src/nvim/event/defs.h @@ -11,7 +11,7 @@ typedef struct message { argv_callback handler; void *argv[EVENT_HANDLER_MAX_ARGC]; } Event; -typedef void(*event_scheduler)(Event event, void *data); +typedef void (*event_scheduler)(Event event, void *data); #define VA_EVENT_INIT(event, h, a) \ do { \ diff --git a/src/nvim/event/loop.h b/src/nvim/event/loop.h index f5dd23ac8b..03cf7e489a 100644 --- a/src/nvim/event/loop.h +++ b/src/nvim/event/loop.h @@ -2,12 +2,11 @@ #define NVIM_EVENT_LOOP_H #include <stdint.h> - #include <uv.h> +#include "nvim/event/multiqueue.h" #include "nvim/lib/klist.h" #include "nvim/os/time.h" -#include "nvim/event/multiqueue.h" typedef void * WatcherPtr; @@ -65,7 +64,7 @@ typedef struct loop { break; \ } else if (remaining > 0) { \ uint64_t now = os_hrtime(); \ - remaining -= (int) ((now - before) / 1000000); \ + remaining -= (int)((now - before) / 1000000); \ before = now; \ if (remaining <= 0) { \ break; \ diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h index 20c02e4900..2b22cd95dc 100644 --- a/src/nvim/event/process.h +++ b/src/nvim/event/process.h @@ -1,10 +1,10 @@ #ifndef NVIM_EVENT_PROCESS_H #define NVIM_EVENT_PROCESS_H +#include "nvim/eval/typval.h" #include "nvim/event/loop.h" #include "nvim/event/rstream.h" #include "nvim/event/wstream.h" -#include "nvim/eval/typval.h" typedef enum { kProcessTypeUv, diff --git a/src/nvim/event/rstream.h b/src/nvim/event/rstream.h index f30ad79ee5..77418c59a2 100644 --- a/src/nvim/event/rstream.h +++ b/src/nvim/event/rstream.h @@ -3,7 +3,6 @@ #include <stdbool.h> #include <stddef.h> - #include <uv.h> #include "nvim/event/loop.h" diff --git a/src/nvim/event/stream.h b/src/nvim/event/stream.h index a5c33a66a2..02e816b4be 100644 --- a/src/nvim/event/stream.h +++ b/src/nvim/event/stream.h @@ -3,7 +3,6 @@ #include <stdbool.h> #include <stddef.h> - #include <uv.h> #include "nvim/event/loop.h" @@ -18,7 +17,7 @@ typedef struct stream Stream; /// @param data User-defined data /// @param eof If the stream reached EOF. typedef void (*stream_read_cb)(Stream *stream, RBuffer *buf, size_t count, - void *data, bool eof); + void *data, bool eof); /// Type of function called when the Stream has information about a write /// request. diff --git a/src/nvim/event/wstream.h b/src/nvim/event/wstream.h index 9008de0d97..d599d29913 100644 --- a/src/nvim/event/wstream.h +++ b/src/nvim/event/wstream.h @@ -1,9 +1,8 @@ #ifndef NVIM_EVENT_WSTREAM_H #define NVIM_EVENT_WSTREAM_H -#include <stdint.h> #include <stdbool.h> - +#include <stdint.h> #include <uv.h> #include "nvim/event/loop.h" diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index bbc1dd9717..3bfbb42d87 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -702,11 +702,11 @@ void ex_sort(exarg_T *eap) mark_adjust(eap->line2, MAXLNUM, -deleted, 0L, kExtmarkNOOP); } - extmark_splice(curbuf, eap->line1-1, 0, - count, 0, old_count, - lnum - eap->line2, 0, new_count, kExtmarkUndo); - if (change_occurred || deleted != 0) { + extmark_splice(curbuf, eap->line1-1, 0, + count, 0, old_count, + lnum - eap->line2, 0, new_count, kExtmarkUndo); + changed_lines(eap->line1, 0, eap->line2 + 1, -deleted, true); } diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index a9990df58f..f4f07e0680 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -230,7 +230,22 @@ static int compl_match_arraysize; static int compl_startcol; static int compl_selected; +/// |:checkhealth| completion items +/// +/// Regenerates on every new command line prompt, to accomodate changes on the +/// runtime files. +typedef struct { + garray_T names; // healthcheck names + unsigned last_gen; // last_prompt_id where names were generated +} CheckhealthComp; + +/// Cookie used when converting filepath to name +struct healthchecks_cookie { + garray_T *names; // global healthchecks + bool is_lua; // true if the current entry is a Lua healthcheck +}; +static CheckhealthComp healthchecks = { GA_INIT(sizeof(char_u *), 10), 0 }; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ex_getln.c.generated.h" @@ -273,6 +288,68 @@ static void init_incsearch_state(incsearch_state_T *s) save_viewstate(&s->old_viewstate); } +/// Completion for |:checkhealth| command. +/// +/// Given to ExpandGeneric() to obtain all available heathcheck names. +/// @param[in] idx Index of the healthcheck item. +/// @param[in] xp Not used. +static char_u *get_healthcheck_names(expand_T *xp, int idx) +{ + // Generate the first time or on new prompt. + if (healthchecks.last_gen == 0 || healthchecks.last_gen != last_prompt_id) { + ga_clear_strings(&healthchecks.names); + char *patterns[3] = { "autoload/health/**.vim", "lua/**/**/health/init.lua", // NOLINT + "lua/**/**/health.lua" }; // NOLINT + for (int i = 0; i < 3; i++) { + struct healthchecks_cookie hcookie = { .names = &healthchecks.names, .is_lua = i != 0 }; + do_in_runtimepath((char_u *)patterns[i], DIP_ALL, get_healthcheck_cb, &hcookie); + + if (healthchecks.names.ga_len > 0) { + ga_remove_duplicate_strings(&healthchecks.names); + } + } + // Tracked to regenerate items on next prompt. + healthchecks.last_gen = last_prompt_id; + } + return idx < + (int)healthchecks.names.ga_len ? ((char_u **)(healthchecks.names.ga_data))[idx] : NULL; +} + +/// Transform healthcheck file path into it's name. +/// +/// Used as a callback for do_in_runtimepath +/// @param[in] path Expanded path to a possible healthcheck. +/// @param[out] cookie Array where names will be inserted. +static void get_healthcheck_cb(char_u *path, void *cookie) +{ + if (path != NULL) { + struct healthchecks_cookie *hcookie = (struct healthchecks_cookie *)cookie; + char *pattern; + char *sub = "\\1"; + char_u *res; + + if (hcookie->is_lua) { + // Lua: transform "../lua/vim/lsp/health.lua" into "vim.lsp" + pattern = ".*lua[\\/]\\(.\\{-}\\)[\\/]health\\([\\/]init\\)\\?\\.lua$"; + } else { + // Vim: transform "../autoload/health/provider.vim" into "provider" + pattern = ".*[\\/]\\([^\\/]*\\)\\.vim$"; + } + + res = do_string_sub(path, (char_u *)pattern, (char_u *)sub, NULL, (char_u *)"g"); + if (hcookie->is_lua && res != NULL) { + // Replace slashes with dots as represented by the healthcheck plugin. + char_u *ares = do_string_sub(res, (char_u *)"[\\/]", (char_u *)".", NULL, (char_u *)"g"); + xfree(res); + res = ares; + } + + if (res != NULL) { + GA_APPEND(char_u *, hcookie->names, res); + } + } +} + // Return true when 'incsearch' highlighting is to be done. // Sets search_first_line and search_last_line to the address range. static bool do_incsearch_highlighting(int firstc, int *search_delim, incsearch_state_T *s, @@ -3037,7 +3114,7 @@ static void ui_ext_cmdline_show(CmdlineInfo *line) line->cmdindent, line->level); if (line->special_char) { - ui_call_cmdline_special_char(cchar_to_string((char)(line->special_char)), + ui_call_cmdline_special_char(cchar_to_string(line->special_char), line->special_shift, line->level); } @@ -3135,7 +3212,7 @@ void putcmdline(char c, int shift) } msg_no_more = false; } else if (ccline.redraw_state != kCmdRedrawAll) { - ui_call_cmdline_special_char(cchar_to_string((char)(c)), shift, + ui_call_cmdline_special_char(cchar_to_string(c), shift, ccline.level); } cursorcmd(); @@ -4902,10 +4979,6 @@ static int ExpandFromContext(expand_T *xp, char_u *pat, int *num_file, char_u ** char *directories[] = { "syntax", "indent", "ftplugin", NULL }; return ExpandRTDir(pat, DIP_LUA, num_file, file, directories); } - if (xp->xp_context == EXPAND_CHECKHEALTH) { - char *directories[] = { "autoload/health", NULL }; - return ExpandRTDir(pat, 0, num_file, file, directories); - } if (xp->xp_context == EXPAND_USER_LIST) { return ExpandUserList(xp, num_file, file); } @@ -4982,6 +5055,7 @@ static int ExpandFromContext(expand_T *xp, char_u *pat, int *num_file, char_u ** { EXPAND_ENV_VARS, get_env_name, true, true }, { EXPAND_USER, get_users, true, false }, { EXPAND_ARGLIST, get_arglist_name, true, false }, + { EXPAND_CHECKHEALTH, get_healthcheck_names, true, false }, }; int i; diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index cf01c305d7..dc73e34111 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -723,7 +723,7 @@ void extmark_move_region(buf_T *buf, int start_row, colnr_T start_col, bcount_t uint64_t src2ns(Integer *src_id) { if (*src_id == 0) { - *src_id = (Integer)nvim_create_namespace((String)STRING_INIT); + *src_id = nvim_create_namespace((String)STRING_INIT); } if (*src_id < 0) { return UINT64_MAX; diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index 6ed2e5dab8..e38a0af0ec 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -33,6 +33,10 @@ local function_names = {} local c_grammar = require('generators.c_grammar') +local function startswith(String,Start) + return string.sub(String,1,string.len(Start))==Start +end + -- read each input file, parse and append to the api metadata for i = 6, #arg do local full_path = arg[i] @@ -47,7 +51,8 @@ for i = 6, #arg do local tmp = c_grammar.grammar:match(input:read('*all')) for j = 1, #tmp do local fn = tmp[j] - if not fn.noexport then + local public = startswith(fn.name, "nvim_") or fn.deprecated_since + if public and not fn.noexport then functions[#functions + 1] = tmp[j] function_names[fn.name] = true if #fn.parameters ~= 0 and fn.parameters[1][2] == 'channel_id' then @@ -76,10 +81,6 @@ local function shallowcopy(orig) return copy end -local function startswith(String,Start) - return string.sub(String,1,string.len(Start))==Start -end - -- Export functions under older deprecated names. -- These will be removed eventually. local deprecated_aliases = require("api.dispatch_deprecated") @@ -108,9 +109,10 @@ for _,f in ipairs(shallowcopy(functions)) do f.lua = f.lua_only or not f.remote_only f.eval = (not f.lua_only) and (not f.remote_only) else + f.deprecated_since = tonumber(f.deprecated_since) + assert(f.deprecated_since == 1) f.remote = true f.since = 0 - f.deprecated_since = 1 end f.method = ismethod local newname = deprecated_aliases[f.name] diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 15acd73aa5..a53742b17b 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -293,7 +293,6 @@ static void add_buff(buffheader_T *const buf, const char *const s, ptrdiff_t sle buf->bh_curr->b_next = p; buf->bh_curr = p; } - return; } /* @@ -523,7 +522,7 @@ void restoreRedobuff(save_redo_T *save_redo) void AppendToRedobuff(const char *s) { if (!block_redo) { - add_buff(&redobuff, (const char *)s, -1L); + add_buff(&redobuff, s, -1L); } } @@ -2861,7 +2860,7 @@ int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, buf_T } char_u *lhs = (char_u *)&args->lhs; - char_u *rhs = (char_u *)args->rhs; + char_u *rhs = args->rhs; char_u *orig_rhs = args->orig_rhs; // check arguments and translate function keys diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c index 76dcb58236..f236b966ca 100644 --- a/src/nvim/if_cscope.c +++ b/src/nvim/if_cscope.c @@ -1294,7 +1294,7 @@ static int cs_kill(exarg_T *eap) } } } else { - cs_kill_execute((size_t)i, stok); + cs_kill_execute(i, stok); } } @@ -1559,8 +1559,8 @@ static void cs_fill_results(char *tagstr, size_t totmatches, int *nummatches_a, assert(totmatches > 0); buf = xmalloc(CSREAD_BUFSIZE); - matches = xmalloc(sizeof(char *) * (size_t)totmatches); - cntxts = xmalloc(sizeof(char *) * (size_t)totmatches); + matches = xmalloc(sizeof(char *) * totmatches); + cntxts = xmalloc(sizeof(char *) * totmatches); for (size_t i = 0; i < csinfo_size; i++) { if (nummatches_a[i] < 1) { diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c index fd4cfc4c31..ca3c4f604a 100644 --- a/src/nvim/lua/converter.c +++ b/src/nvim/lua/converter.c @@ -1303,6 +1303,12 @@ void nlua_init_types(lua_State *const lstate) void nlua_pop_keydict(lua_State *L, void *retval, field_hash hashy, Error *err) { + if (!lua_istable(L, -1)) { + api_set_error(err, kErrorTypeValidation, "Expected lua table"); + lua_pop(L, -1); + return; + } + lua_pushnil(L); // [dict, nil] while (lua_next(L, -2)) { // [dict, key, value] diff --git a/src/nvim/lua/converter.h b/src/nvim/lua/converter.h index 43a7e06019..1c9e60e4b2 100644 --- a/src/nvim/lua/converter.h +++ b/src/nvim/lua/converter.h @@ -6,8 +6,8 @@ #include <stdint.h> #include "nvim/api/private/defs.h" -#include "nvim/func_attr.h" #include "nvim/eval.h" +#include "nvim/func_attr.h" typedef struct { LuaRef func_ref; diff --git a/src/nvim/lua/executor.h b/src/nvim/lua/executor.h index ea774ac2e3..a1f66bd02b 100644 --- a/src/nvim/lua/executor.h +++ b/src/nvim/lua/executor.h @@ -1,13 +1,13 @@ #ifndef NVIM_LUA_EXECUTOR_H #define NVIM_LUA_EXECUTOR_H -#include <lua.h> #include <lauxlib.h> +#include <lua.h> #include "nvim/api/private/defs.h" -#include "nvim/func_attr.h" #include "nvim/eval/typval.h" #include "nvim/ex_cmds_defs.h" +#include "nvim/func_attr.h" #include "nvim/lua/converter.h" // Generated by msgpack-gen.lua @@ -19,12 +19,12 @@ EXTERN LuaRef nlua_empty_dict_ref INIT(= LUA_NOREF); EXTERN int nlua_refcount INIT(= 0); #define set_api_error(s, err) \ - do { \ - Error *err_ = (err); \ - err_->type = kErrorTypeException; \ - err_->set = true; \ - memcpy(&err_->msg[0], s, sizeof(s)); \ - } while (0) + do { \ + Error *err_ = (err); \ + err_->type = kErrorTypeException; \ + err_->set = true; \ + memcpy(&err_->msg[0], s, sizeof(s)); \ + } while (0) #define NLUA_CLEAR_REF(x) \ do { \ diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index 37929093e3..bd978cc8ab 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -30,6 +30,7 @@ typedef struct { TSQueryCursor *cursor; int predicated_match; + int max_match_id; } TSLua_cursor; #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -1055,6 +1056,8 @@ static int query_next_match(lua_State *L) static int query_next_capture(lua_State *L) { + // Upvalues are: + // [ cursor, node, query, current_match ] TSLua_cursor *ud = lua_touserdata(L, lua_upvalueindex(1)); TSQueryCursor *cursor = ud->cursor; @@ -1078,9 +1081,13 @@ static int query_next_capture(lua_State *L) lua_pushinteger(L, capture.index+1); // [index] push_node(L, capture.node, lua_upvalueindex(2)); // [index, node] + // Now check if we need to run the predicates uint32_t n_pred; ts_query_predicates_for_pattern(query, match.pattern_index, &n_pred); - if (n_pred > 0 && capture_index == 0) { + + if (n_pred > 0 && (ud->max_match_id < (int)match.id)) { + ud->max_match_id = match.id; + lua_pushvalue(L, lua_upvalueindex(4)); // [index, node, match] set_match(L, &match, lua_upvalueindex(2)); lua_pushinteger(L, match.pattern_index+1); @@ -1127,6 +1134,7 @@ static int node_rawquery(lua_State *L) TSLua_cursor *ud = lua_newuserdata(L, sizeof(*ud)); // [udata] ud->cursor = cursor; ud->predicated_match = -1; + ud->max_match_id = -1; lua_getfield(L, LUA_REGISTRYINDEX, TS_META_QUERYCURSOR); lua_setmetatable(L, -2); // [udata] diff --git a/src/nvim/lua/treesitter.h b/src/nvim/lua/treesitter.h index 812166f67b..b69fb9dfae 100644 --- a/src/nvim/lua/treesitter.h +++ b/src/nvim/lua/treesitter.h @@ -1,9 +1,9 @@ #ifndef NVIM_LUA_TREESITTER_H #define NVIM_LUA_TREESITTER_H +#include <lauxlib.h> #include <lua.h> #include <lualib.h> -#include <lauxlib.h> #include "tree_sitter/api.h" diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index 7a209f2d79..5ca4cc82a5 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -433,6 +433,7 @@ function vim.notify(msg, log_level, _opts) end +---@private function vim.register_keystroke_callback() error('vim.register_keystroke_callback is deprecated, instead use: vim.on_key') end diff --git a/src/nvim/lua/xdiff.h b/src/nvim/lua/xdiff.h index cae7c98e81..b172d2f922 100644 --- a/src/nvim/lua/xdiff.h +++ b/src/nvim/lua/xdiff.h @@ -1,9 +1,9 @@ #ifndef NVIM_LUA_XDIFF_H #define NVIM_LUA_XDIFF_H +#include <lauxlib.h> #include <lua.h> #include <lualib.h> -#include <lauxlib.h> #ifdef INCLUDE_GENERATED_DECLARATIONS # include "lua/xdiff.h.generated.h" diff --git a/src/nvim/main.c b/src/nvim/main.c index f801351d2d..069c253bff 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -345,7 +345,8 @@ int main(int argc, char **argv) // Reset 'loadplugins' for "-u NONE" before "--cmd" arguments. // Allows for setting 'loadplugins' there. if (params.use_vimrc != NULL && strequal(params.use_vimrc, "NONE")) { - p_lpl = false; + // When using --clean we still want to load plugins + p_lpl = params.clean; } // Execute --cmd arguments. diff --git a/src/nvim/mark.c b/src/nvim/mark.c index b296bf39cf..835c2adbe5 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -1036,9 +1036,10 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, lo } sign_mark_adjust(line1, line2, amount, amount_after); - if (op != kExtmarkNOOP) { - extmark_adjust(curbuf, line1, line2, amount, amount_after, op); - } + } + + if (op != kExtmarkNOOP) { + extmark_adjust(curbuf, line1, line2, amount, amount_after, op); } // previous context mark @@ -1637,6 +1638,15 @@ void get_buf_local_marks(const buf_T *buf, list_T *l) add_mark(l, "'>", &buf->b_visual.vi_end, buf->b_fnum, NULL); } +/// Get a global mark +/// +/// @param[in] Name of named mark +/// @param[out] Global/file mark +xfmark_T get_global_mark(char name) +{ + return namedfm[mark_global_index(name)]; +} + /// Get information about global marks ('A' to 'Z' and '0' to '9') /// /// @param[out] l List to store global marks diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c index ebe4478bc8..e62f91e698 100644 --- a/src/nvim/marktree.c +++ b/src/nvim/marktree.c @@ -837,8 +837,8 @@ bool marktree_splice(MarkTree *b, int start_line, int start_col, int old_extent_ int old_extent_col, int new_extent_line, int new_extent_col) { mtpos_t start = { start_line, start_col }; - mtpos_t old_extent = { (int)old_extent_line, old_extent_col }; - mtpos_t new_extent = { (int)new_extent_line, new_extent_col }; + mtpos_t old_extent = { old_extent_line, old_extent_col }; + mtpos_t new_extent = { new_extent_line, new_extent_col }; bool may_delete = (old_extent.row != 0 || old_extent.col != 0); bool same_line = old_extent.row == 0 && new_extent.row == 0; diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 69598bbdda..20ae5a4042 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -1272,7 +1272,6 @@ theend: apply_autocmds(EVENT_BUFREADPOST, NULL, curbuf->b_fname, FALSE, curbuf); apply_autocmds(EVENT_BUFWINENTER, NULL, curbuf->b_fname, FALSE, curbuf); } - return; } /// Find the names of swap files in current directory and the directory given @@ -2798,7 +2797,6 @@ void ml_clearmarked(void) } lowest_marked = 0; - return; } size_t ml_flush_deleted_bytes(buf_T *buf, size_t *codepoints, size_t *codeunits) diff --git a/src/nvim/menu.c b/src/nvim/menu.c index de8503f9d0..85e062009a 100644 --- a/src/nvim/menu.c +++ b/src/nvim/menu.c @@ -857,7 +857,7 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth) MSG_PUTS(" "); } if (menu->priority) { - msg_outnum((long)menu->priority); + msg_outnum(menu->priority); MSG_PUTS(" "); } // Same highlighting as for directories!? diff --git a/src/nvim/message.c b/src/nvim/message.c index ed673b52d3..cc4319b8da 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -2363,7 +2363,7 @@ void msg_reset_scroll(void) // non-displayed part of msg_grid is considered invalid. for (int i = 0; i < MIN(msg_scrollsize(), msg_grid.Rows); i++) { grid_clear_line(&msg_grid, msg_grid.line_offset[i], - (int)msg_grid.Columns, false); + msg_grid.Columns, false); } } } else { @@ -3191,7 +3191,7 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) size_t len = maxlen == -1 ? STRLEN(s) : (size_t)maxlen; if (capture_ga) { - ga_concat_len(capture_ga, (const char *)str, len); + ga_concat_len(capture_ga, str, len); } if (redir_reg) { write_reg_contents(redir_reg, s, len, true); diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index cf463fd40a..f02c000e82 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -236,6 +236,11 @@ retnomove: redraw_curbuf_later(INVERTED); // delete the inversion } + if (grid == 0) { + row -= curwin->w_grid_alloc.comp_row+curwin->w_grid.row_offset; + col -= curwin->w_grid_alloc.comp_col+curwin->w_grid.col_offset; + } + // When clicking beyond the end of the window, scroll the screen. // Scroll by however many rows outside the window we are. if (row < 0) { @@ -476,7 +481,7 @@ win_T *mouse_find_win(int *gridp, int *rowp, int *colp) static win_T *mouse_find_grid_win(int *gridp, int *rowp, int *colp) { if (*gridp == msg_grid.handle) { - // rowp += msg_grid_pos; // PVS: dead store #11612 + *rowp += msg_grid_pos; *gridp = DEFAULT_GRID_HANDLE; } else if (*gridp > 1) { win_T *wp = get_win_by_grid_handle(*gridp); @@ -677,8 +682,8 @@ static int mouse_adjust_click(win_T *wp, int row, int col) vcol = offset; -#define incr() nudge++; ptr_end += utfc_ptr2len(ptr_end) -#define decr() nudge--; ptr_end -= utfc_ptr2len(ptr_end) +#define INCR() nudge++; ptr_end += utfc_ptr2len(ptr_end) +#define DECR() nudge--; ptr_end -= utfc_ptr2len(ptr_end) while (ptr < ptr_end && *ptr != NUL) { cwidth = win_chartabsize(curwin, ptr, vcol); @@ -687,7 +692,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col) // A tab will "absorb" any previous adjustments. cwidth = MIN(cwidth, nudge); while (cwidth > 0) { - decr(); + DECR(); cwidth--; } } @@ -695,20 +700,20 @@ static int mouse_adjust_click(win_T *wp, int row, int col) matchid = syn_get_concealed_id(wp, lnum, (colnr_T)(ptr - line)); if (matchid != 0) { if (wp->w_p_cole == 3) { - incr(); + INCR(); } else { if (!(row > 0 && ptr == ptr_row_offset) && (wp->w_p_cole == 1 || (wp->w_p_cole == 2 && (wp->w_p_lcs_chars.conceal != NUL || syn_get_sub_char() != NUL)))) { // At least one placeholder character will be displayed. - decr(); + DECR(); } prev_matchid = matchid; while (prev_matchid == matchid && *ptr != NUL) { - incr(); + INCR(); ptr += utfc_ptr2len(ptr); matchid = syn_get_concealed_id(wp, lnum, (colnr_T)(ptr - line)); } diff --git a/src/nvim/move.c b/src/nvim/move.c index c4f8e81fa3..918e0a5c4f 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -2104,7 +2104,6 @@ static void get_scroll_overlap(lineoff_T *lp, int dir) } else { *lp = loff2; // 2 lines overlap } - return; } // Scroll 'scroll' lines up or down. diff --git a/src/nvim/msgpack_rpc/channel.h b/src/nvim/msgpack_rpc/channel.h index 90e1c7d48b..eb0de47437 100644 --- a/src/nvim/msgpack_rpc/channel.h +++ b/src/nvim/msgpack_rpc/channel.h @@ -5,10 +5,10 @@ #include <uv.h> #include "nvim/api/private/defs.h" -#include "nvim/event/socket.h" +#include "nvim/channel.h" #include "nvim/event/process.h" +#include "nvim/event/socket.h" #include "nvim/vim.h" -#include "nvim/channel.h" #define METHOD_MAXLEN 512 diff --git a/src/nvim/msgpack_rpc/channel_defs.h b/src/nvim/msgpack_rpc/channel_defs.h index de328af1ce..6647779db9 100644 --- a/src/nvim/msgpack_rpc/channel_defs.h +++ b/src/nvim/msgpack_rpc/channel_defs.h @@ -1,13 +1,13 @@ #ifndef NVIM_MSGPACK_RPC_CHANNEL_DEFS_H #define NVIM_MSGPACK_RPC_CHANNEL_DEFS_H +#include <msgpack.h> #include <stdbool.h> #include <uv.h> -#include <msgpack.h> #include "nvim/api/private/defs.h" -#include "nvim/event/socket.h" #include "nvim/event/process.h" +#include "nvim/event/socket.h" #include "nvim/vim.h" typedef struct Channel Channel; diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index 549016e751..f805858904 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -22,42 +22,6 @@ static msgpack_zone zone; static msgpack_sbuffer sbuffer; -#define HANDLE_TYPE_CONVERSION_IMPL(t, lt) \ - static bool msgpack_rpc_to_##lt(const msgpack_object *const obj, \ - Integer *const arg) \ - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT \ - { \ - if (obj->type != MSGPACK_OBJECT_EXT \ - || obj->via.ext.type + EXT_OBJECT_TYPE_SHIFT != kObjectType##t) { \ - return false; \ - } \ - \ - msgpack_object data; \ - msgpack_unpack_return ret = msgpack_unpack(obj->via.ext.ptr, \ - obj->via.ext.size, \ - NULL, \ - &zone, \ - &data); \ - \ - if (ret != MSGPACK_UNPACK_SUCCESS) { \ - return false; \ - } \ - \ - *arg = (handle_T)data.via.i64; \ - return true; \ - } \ - \ - static void msgpack_rpc_from_##lt(Integer o, msgpack_packer *res) \ - FUNC_ATTR_NONNULL_ARG(2) \ - { \ - msgpack_packer pac; \ - msgpack_packer_init(&pac, &sbuffer, msgpack_sbuffer_write); \ - msgpack_pack_int64(&pac, (handle_T)o); \ - msgpack_pack_ext(res, sbuffer.size, \ - kObjectType##t - EXT_OBJECT_TYPE_SHIFT); \ - msgpack_pack_ext_body(res, sbuffer.data, sbuffer.size); \ - msgpack_sbuffer_clear(&sbuffer); \ - } void msgpack_rpc_helpers_init(void) { @@ -65,10 +29,6 @@ void msgpack_rpc_helpers_init(void) msgpack_sbuffer_init(&sbuffer); } -HANDLE_TYPE_CONVERSION_IMPL(Buffer, buffer) -HANDLE_TYPE_CONVERSION_IMPL(Window, window) -HANDLE_TYPE_CONVERSION_IMPL(Tabpage, tabpage) - typedef struct { const msgpack_object *mobj; Object *aobj; @@ -226,28 +186,18 @@ case type: { \ break; } case MSGPACK_OBJECT_EXT: - switch ((ObjectType)(cur.mobj->via.ext.type + EXT_OBJECT_TYPE_SHIFT)) { - case kObjectTypeBuffer: - cur.aobj->type = kObjectTypeBuffer; - ret = msgpack_rpc_to_buffer(cur.mobj, &cur.aobj->data.integer); - break; - case kObjectTypeWindow: - cur.aobj->type = kObjectTypeWindow; - ret = msgpack_rpc_to_window(cur.mobj, &cur.aobj->data.integer); - break; - case kObjectTypeTabpage: - cur.aobj->type = kObjectTypeTabpage; - ret = msgpack_rpc_to_tabpage(cur.mobj, &cur.aobj->data.integer); - break; - case kObjectTypeNil: - case kObjectTypeBoolean: - case kObjectTypeInteger: - case kObjectTypeFloat: - case kObjectTypeString: - case kObjectTypeArray: - case kObjectTypeDictionary: - case kObjectTypeLuaRef: - break; + if (0 <= cur.mobj->via.ext.type && cur.mobj->via.ext.type <= EXT_OBJECT_TYPE_MAX) { + cur.aobj->type = (ObjectType)(cur.mobj->via.ext.type + EXT_OBJECT_TYPE_SHIFT); + msgpack_object data; + msgpack_unpack_return status = msgpack_unpack(cur.mobj->via.ext.ptr, cur.mobj->via.ext.size, + NULL, &zone, &data); + + if (status != MSGPACK_UNPACK_SUCCESS || data.type != MSGPACK_OBJECT_POSITIVE_INTEGER) { + ret = false; + break; + } + cur.aobj->data.integer = (handle_T)data.via.i64; + ret = true; } break; #undef STR_CASE @@ -349,6 +299,17 @@ void msgpack_rpc_from_string(const String result, msgpack_packer *res) } } +static void msgpack_rpc_from_handle(ObjectType type, Integer o, msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(3) +{ + msgpack_packer pac; + msgpack_packer_init(&pac, &sbuffer, msgpack_sbuffer_write); + msgpack_pack_int64(&pac, (handle_T)o); + msgpack_pack_ext(res, sbuffer.size, (int8_t)(type - EXT_OBJECT_TYPE_SHIFT)); + msgpack_pack_ext_body(res, sbuffer.data, sbuffer.size); + msgpack_sbuffer_clear(&sbuffer); +} + typedef struct { const Object *aobj; bool container; @@ -393,13 +354,9 @@ void msgpack_rpc_from_object(const Object result, msgpack_packer *const res) msgpack_rpc_from_string(cur.aobj->data.string, res); break; case kObjectTypeBuffer: - msgpack_rpc_from_buffer(cur.aobj->data.integer, res); - break; case kObjectTypeWindow: - msgpack_rpc_from_window(cur.aobj->data.integer, res); - break; case kObjectTypeTabpage: - msgpack_rpc_from_tabpage(cur.aobj->data.integer, res); + msgpack_rpc_from_handle(cur.aobj->type, cur.aobj->data.integer, res); break; case kObjectTypeArray: { const size_t size = cur.aobj->data.array.size; diff --git a/src/nvim/msgpack_rpc/helpers.h b/src/nvim/msgpack_rpc/helpers.h index 0e4cd1be6d..e5fd92374d 100644 --- a/src/nvim/msgpack_rpc/helpers.h +++ b/src/nvim/msgpack_rpc/helpers.h @@ -1,13 +1,12 @@ #ifndef NVIM_MSGPACK_RPC_HELPERS_H #define NVIM_MSGPACK_RPC_HELPERS_H -#include <stdint.h> -#include <stdbool.h> - #include <msgpack.h> +#include <stdbool.h> +#include <stdint.h> -#include "nvim/event/wstream.h" #include "nvim/api/private/defs.h" +#include "nvim/event/wstream.h" /// Value by which objects represented as EXT type are shifted /// @@ -15,6 +14,7 @@ /// buffer/window/tabpage block inside ObjectType enum. This block yet cannot be /// split or reordered. #define EXT_OBJECT_TYPE_SHIFT kObjectTypeBuffer +#define EXT_OBJECT_TYPE_MAX (kObjectTypeTabpage - EXT_OBJECT_TYPE_SHIFT) #ifdef INCLUDE_GENERATED_DECLARATIONS # include "msgpack_rpc/helpers.h.generated.h" diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 1d737ee9fc..0668924237 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -2817,17 +2817,17 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) tv_list_append_string(list, (const char *)reg->y_array[i], -1); } tv_list_set_lock(list, VAR_FIXED); - tv_dict_add_list(dict, S_LEN("regcontents"), list); + (void)tv_dict_add_list(dict, S_LEN("regcontents"), list); // Register type. char buf[NUMBUFLEN+2]; format_reg_type(reg->y_type, reg->y_width, buf, ARRAY_SIZE(buf)); - tv_dict_add_str(dict, S_LEN("regtype"), buf); + (void)tv_dict_add_str(dict, S_LEN("regtype"), buf); // Name of requested register, or empty string for unnamed operation. buf[0] = (char)oap->regname; buf[1] = NUL; - tv_dict_add_str(dict, S_LEN("regname"), buf); + (void)tv_dict_add_str(dict, S_LEN("regname"), buf); // Motion type: inclusive or exclusive. tv_dict_add_bool(dict, S_LEN("inclusive"), @@ -2836,11 +2836,11 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) // Kind of operation: yank, delete, change). buf[0] = (char)get_op_char(oap->op_type); buf[1] = NUL; - tv_dict_add_str(dict, S_LEN("operator"), buf); + (void)tv_dict_add_str(dict, S_LEN("operator"), buf); // Selection type: visual or not. - tv_dict_add_bool(dict, S_LEN("visual"), - oap->is_VIsual ? kBoolVarTrue : kBoolVarFalse); + (void)tv_dict_add_bool(dict, S_LEN("visual"), + oap->is_VIsual ? kBoolVarTrue : kBoolVarFalse); tv_dict_set_keys_readonly(dict); textlock++; diff --git a/src/nvim/option.c b/src/nvim/option.c index 5646a62cd4..a9bff8285c 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -3899,7 +3899,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va // when 'buflisted' changes, trigger autocommands apply_autocmds(curbuf->b_p_bl ? EVENT_BUFADD : EVENT_BUFDELETE, NULL, NULL, true, curbuf); - } else if ((int *)varp == (int *)&curbuf->b_p_swf) { + } else if ((int *)varp == &curbuf->b_p_swf) { // when 'swf' is set, create swapfile, when reset remove swapfile if (curbuf->b_p_swf && p_uc) { ml_open_file(curbuf); // create the swap file @@ -6509,8 +6509,6 @@ void set_context_in_set_cmd(expand_T *xp, char_u *arg, int opt_flags) break; } } - - return; } int ExpandSettings(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file) diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index bbf70a4830..9675cfbb0f 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -134,7 +134,7 @@ bool os_isdir(const char_u *name) bool os_isdir_executable(const char *name) FUNC_ATTR_NONNULL_ALL { - int32_t mode = os_getperm((const char *)name); + int32_t mode = os_getperm(name); if (mode < 0) { return false; } diff --git a/src/nvim/os/input.h b/src/nvim/os/input.h index d571965408..7026781407 100644 --- a/src/nvim/os/input.h +++ b/src/nvim/os/input.h @@ -1,8 +1,8 @@ #ifndef NVIM_OS_INPUT_H #define NVIM_OS_INPUT_H -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> #include "nvim/api/private/defs.h" #include "nvim/event/multiqueue.h" diff --git a/src/nvim/os/os.h b/src/nvim/os/os.h index 3e89e5a94a..bff2936f8e 100644 --- a/src/nvim/os/os.h +++ b/src/nvim/os/os.h @@ -9,11 +9,11 @@ #include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS +# include "os/env.h.generated.h" # include "os/fs.h.generated.h" # include "os/mem.h.generated.h" -# include "os/env.h.generated.h" -# include "os/users.h.generated.h" # include "os/stdpaths.h.generated.h" +# include "os/users.h.generated.h" #endif #endif // NVIM_OS_OS_H diff --git a/src/nvim/os/os_defs.h b/src/nvim/os/os_defs.h index 1b7859b0d3..8049b3b80e 100644 --- a/src/nvim/os/os_defs.h +++ b/src/nvim/os/os_defs.h @@ -16,7 +16,7 @@ #define BASENAMELEN (NAME_MAX - 5) // Use the system path length if it makes sense. -# define DEFAULT_MAXPATHL 4096 +#define DEFAULT_MAXPATHL 4096 #if defined(PATH_MAX) && (PATH_MAX > DEFAULT_MAXPATHL) # define MAXPATHL PATH_MAX #else diff --git a/src/nvim/os/os_win_console.c b/src/nvim/os/os_win_console.c index 2c9cb699fc..18e2e02b81 100644 --- a/src/nvim/os/os_win_console.c +++ b/src/nvim/os/os_win_console.c @@ -46,29 +46,3 @@ void os_replace_stdout_and_stderr_to_conout(void) const int conerr_fd = _open_osfhandle((intptr_t)conout_handle, 0); assert(conerr_fd == STDERR_FILENO); } - -void os_set_vtp(bool enable) -{ - static TriState is_legacy = kNone; - if (is_legacy == kNone) { - uv_tty_vtermstate_t state; - uv_tty_get_vterm_state(&state); - is_legacy = (state == UV_TTY_UNSUPPORTED) ? kTrue : kFalse; - } - if (!is_legacy && !os_has_vti()) { - uv_tty_set_vterm_state(enable ? UV_TTY_SUPPORTED : UV_TTY_UNSUPPORTED); - } -} - -static bool os_has_vti(void) -{ - static TriState has_vti = kNone; - if (has_vti == kNone) { - HANDLE handle = (HANDLE)_get_osfhandle(input_global_fd()); - DWORD dwMode; - if (handle != INVALID_HANDLE_VALUE && GetConsoleMode(handle, &dwMode)) { - has_vti = !!(dwMode & ENABLE_VIRTUAL_TERMINAL_INPUT) ? kTrue : kFalse; - } - } - return has_vti == kTrue; -} diff --git a/src/nvim/os/process.h b/src/nvim/os/process.h index 1722d56bd3..faa4762cf1 100644 --- a/src/nvim/os/process.h +++ b/src/nvim/os/process.h @@ -2,6 +2,7 @@ #define NVIM_OS_PROCESS_H #include <stddef.h> + #include "nvim/api/private/defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/os/time.h b/src/nvim/os/time.h index ad4886446a..1b6c667dbb 100644 --- a/src/nvim/os/time.h +++ b/src/nvim/os/time.h @@ -1,8 +1,8 @@ #ifndef NVIM_OS_TIME_H #define NVIM_OS_TIME_H -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> #include <time.h> typedef uint64_t Timestamp; diff --git a/src/nvim/os/unix_defs.h b/src/nvim/os/unix_defs.h index 60a2dfa882..4ed3b51694 100644 --- a/src/nvim/os/unix_defs.h +++ b/src/nvim/os/unix_defs.h @@ -1,8 +1,8 @@ #ifndef NVIM_OS_UNIX_DEFS_H #define NVIM_OS_UNIX_DEFS_H -#include <unistd.h> #include <sys/param.h> +#include <unistd.h> // POSIX.1-2008 says that NAME_MAX should be in here #include <limits.h> diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h index 66d72de08d..efef77be7b 100644 --- a/src/nvim/os/win_defs.h +++ b/src/nvim/os/win_defs.h @@ -7,11 +7,14 @@ // winsock2.h must be first to avoid incompatibilities // with winsock.h (included by windows.h) + +// uncrustify:off #include <winsock2.h> -#include <windows.h> -#include <sys/stat.h> +// uncrustify:on #include <io.h> #include <stdio.h> +#include <sys/stat.h> +#include <windows.h> // Windows does not have S_IFLNK but libuv defines it // and sets the flag for us when calling uv_fs_stat. diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index eb0ba874f4..046e6dbd12 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -1823,7 +1823,7 @@ static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname, char_u *modu if (type != 1 && !vim_isprintc(type)) { // only printable chars allowed type = 0; } - qfp->qf_type = (char_u)type; + qfp->qf_type = type; qfp->qf_valid = valid; lastp = &qfl->qf_last; diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index e1669a8c19..c47bffd426 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -332,10 +332,10 @@ int do_in_path_and_pp(char_u *path, char_u *name, int flags, DoInRuntimepathCB c return done; } -static void push_path(RuntimeSearchPath *search_path, Map(String, handle_T) *rtp_used, - char *entry, bool after) +static void push_path(RuntimeSearchPath *search_path, Map(String, handle_T) *rtp_used, char *entry, + bool after) { - handle_T h = map_get(String, handle_T)(rtp_used, cstr_as_string((char *)entry)); + handle_T h = map_get(String, handle_T)(rtp_used, cstr_as_string(entry)); if (h == 0) { char *allocated = xstrdup(entry); map_put(String, handle_T)(rtp_used, cstr_as_string(allocated), 1); @@ -776,7 +776,7 @@ static bool pack_has_entries(char_u *buf) { int num_files; char_u **files; - char_u *(pat[]) = { (char_u *)buf }; + char_u *(pat[]) = { buf }; if (gen_expand_wildcards(1, pat, &num_files, &files, EW_DIR) == OK) { FreeWild(num_files, files); } diff --git a/src/nvim/shada.c b/src/nvim/shada.c index bf245bec51..2610df666b 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -65,26 +65,6 @@ KHASH_SET_INIT_INT64(bufset) KHASH_MAP_INIT_STR(fnamebufs, buf_T *) KHASH_SET_INIT_STR(strset) -#define copy_option_part(src, dest, ...) \ - ((char *)copy_option_part((char_u **)src, (char_u *)dest, __VA_ARGS__)) -#define find_shada_parameter(...) \ - ((const char *)find_shada_parameter(__VA_ARGS__)) -#define home_replace_save(a, b) \ - ((char *)home_replace_save(a, (char_u *)b)) -#define home_replace(a, b, c, d, e) \ - home_replace(a, (char_u *)b, (char_u *)c, d, e) -#define vim_rename(a, b) \ - (vim_rename((char_u *)a, (char_u *)b)) -#define mb_strnicmp(a, b, c) \ - (mb_strnicmp((char_u *)a, (char_u *)b, c)) -#define path_try_shorten_fname(b) \ - ((char *)path_try_shorten_fname((char_u *)b)) -#define buflist_new(ffname, sfname, ...) \ - (buflist_new((char_u *)ffname, (char_u *)sfname, __VA_ARGS__)) -#define os_isdir(f) (os_isdir((char_u *)f)) -#define regtilde(s, m) ((char *)regtilde((char_u *)s, m)) -#define path_tail_with_sep(f) ((char *)path_tail_with_sep((char_u *)f)) - #define SEARCH_KEY_MAGIC "sm" #define SEARCH_KEY_SMARTCASE "sc" #define SEARCH_KEY_HAS_LINE_OFFSET "sl" @@ -624,20 +604,6 @@ static inline void hmll_insert(HMLList *const hmll, HMLListEntry *hmll_entry, co } } -/// Iterate over HMLList in backward direction -/// -/// @param hmll Pointer to the list. -/// @param cur_entry Name of the variable to iterate over, must be already -/// defined. -/// @param code Code to execute on each iteration. -/// -/// @return `for` cycle header (use `HMLL_FORALL(hmll, cur_entry) {body}`). -#define HMLL_ITER_BACK(hmll, cur_entry, code) \ - for (cur_entry = (hmll)->last; cur_entry != NULL; \ - cur_entry = cur_entry->prev) { \ - code \ - } - /// Free linked list /// /// @param[in] hmll List to free. @@ -981,11 +947,12 @@ static void hms_insert(HistoryMergerState *const hms_p, const ShadaEntry entry, } } HMLListEntry *insert_after; - HMLL_ITER_BACK(hmll, insert_after, { + // Iterate over HMLList in backward direction + for (insert_after = hmll->last; insert_after != NULL; insert_after = insert_after->prev) { if (insert_after->data.timestamp <= entry.timestamp) { break; } - }) + } hmll_insert(hmll, insert_after, entry, can_free_entry); } @@ -1271,7 +1238,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags) // string is close to useless: you can only use it with :& or :~ and // that’s all because s//~ is not available until the first call to // regtilde. Vim was not calling this for some reason. - (void)regtilde(cur_entry.data.sub_string.sub, p_magic); + (void)(char *)regtilde((char_u *)cur_entry.data.sub_string.sub, p_magic); // Do not free shada entry: its allocated memory was saved above. break; case kSDItemHistoryEntry: @@ -1361,9 +1328,11 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags) } case kSDItemBufferList: for (size_t i = 0; i < cur_entry.data.buffer_list.size; i++) { - char *const sfname = path_try_shorten_fname(cur_entry.data.buffer_list.buffers[i].fname); - buf_T *const buf = buflist_new(cur_entry.data.buffer_list.buffers[i].fname, sfname, 0, - BLN_LISTED); + char *const sfname = + (char *)path_try_shorten_fname((char_u *)cur_entry.data.buffer_list.buffers[i].fname); + buf_T *const buf = + buflist_new((char_u *)cur_entry.data.buffer_list.buffers[i].fname, (char_u *)sfname, 0, + BLN_LISTED); if (buf != NULL) { RESET_FMARK(&buf->b_last_cursor, cur_entry.data.buffer_list.buffers[i].pos, 0); @@ -1502,7 +1471,7 @@ static char *shada_filename(const char *file) if (p_shadafile != NULL && *p_shadafile != NUL) { file = p_shadafile; } else { - if ((file = find_shada_parameter('n')) == NULL || *file == NUL) { + if ((file = (char *)find_shada_parameter('n')) == NULL || *file == NUL) { file = shada_get_default_file(); } // XXX It used to be one level lower, so that whatever is in @@ -1522,14 +1491,6 @@ static char *shada_filename(const char *file) msgpack_pack_str(spacker, sizeof(s) - 1); \ msgpack_pack_str_body(spacker, s, sizeof(s) - 1); \ } while (0) -#define PACK_STRING(s) \ - do { \ - const String s_ = (s); \ - msgpack_pack_str(spacker, s_.size); \ - if (s_.size) { \ - msgpack_pack_str_body(spacker, s_.data, s_.size); \ - } \ - } while (0) #define PACK_BIN(s) \ do { \ const String s_ = (s); \ @@ -1810,7 +1771,11 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer, ShadaEntr case kSDItemHeader: msgpack_pack_map(spacker, entry.data.header.size); for (size_t i = 0; i < entry.data.header.size; i++) { - PACK_STRING(entry.data.header.items[i].key); + const String s = entry.data.header.items[i].key; + msgpack_pack_str(spacker, s.size); + if (s.size) { + msgpack_pack_str_body(spacker, s.data, s.size); + } const Object obj = entry.data.header.items[i].value; switch (obj.type) { case kObjectTypeString: @@ -1856,7 +1821,6 @@ shada_pack_entry_error: msgpack_sbuffer_destroy(&sbuf); return ret; } -#undef PACK_STRING /// Write single ShaDa entry and free it afterwards /// @@ -2437,7 +2401,7 @@ static inline void shada_initialize_registers(WriteMergerState *const wms, int m .data = { .reg = { .contents = (char **)reg.y_array, - .contents_size = (size_t)reg.y_size, + .contents_size = reg.y_size, .type = reg.y_type, .width = (size_t)(reg.y_type == kMTBlockWise ? reg.y_width : 0), .additional_data = reg.additional_data, @@ -2694,7 +2658,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef .timestamp = sub.timestamp, .data = { .sub_string = { - .sub = (char *)sub.sub, + .sub = sub.sub, .additional_elements = sub.additional_elements, } } @@ -2957,7 +2921,6 @@ shada_write_exit: return ret; } -#undef IGNORE_BUF #undef PACK_STATIC_STR /// Write ShaDa file to a given location @@ -3037,11 +3000,11 @@ shada_write_file_open: {} } if (nomerge) { shada_write_file_nomerge: {} - char *const tail = path_tail_with_sep(fname); + char *const tail = (char *)path_tail_with_sep((char_u *)fname); if (tail != fname) { const char tail_save = *tail; *tail = NUL; - if (!os_isdir(fname)) { + if (!os_isdir((char_u *)fname)) { int ret; char *failed_dir; if ((ret = os_mkdir_recurse(fname, 0700, &failed_dir)) != 0) { @@ -3092,7 +3055,7 @@ shada_write_file_nomerge: {} // overwrite a user’s viminfo file after a "su root", with a // viminfo file that the user can't read. FileInfo old_info; - if (os_fileinfo((char *)fname, &old_info)) { + if (os_fileinfo(fname, &old_info)) { if (getuid() == ROOT_UID) { if (old_info.stat.st_uid != ROOT_UID || old_info.stat.st_gid != getgid()) { @@ -3116,7 +3079,7 @@ shada_write_file_nomerge: {} } } #endif - if (vim_rename(tempname, fname) == -1) { + if (vim_rename((char_u *)tempname, (char_u *)fname) == -1) { EMSG3(_(RNERR "Can't rename ShaDa file from %s to %s!"), tempname, fname); } else { @@ -3424,8 +3387,7 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, const sizeof(*un.data.via.map.ptr)); \ ad_ga.ga_len++; \ } -#define CONVERTED(str, len) (xmemdupz((str), (len))) -#define BIN_CONVERTED(b) CONVERTED(b.ptr, b.size) +#define BIN_CONVERTED(b) (xmemdupz((b.ptr), (b.size))) #define SET_ADDITIONAL_DATA(tgt, name) \ do { \ if (ad_ga.ga_len) { \ @@ -3982,7 +3944,6 @@ shada_read_next_item_error: goto shada_read_next_item_end; } #undef BIN_CONVERTED -#undef CONVERTED #undef CHECK_KEY #undef BOOLEAN_KEY #undef CONVERTED_STRING_KEY @@ -4015,13 +3976,13 @@ static bool shada_removable(const char *name) char part[MAXPATHL + 1]; bool retval = false; - char *new_name = home_replace_save(NULL, name); + char *new_name = (char *)home_replace_save(NULL, (char_u *)name); for (p = (char *)p_shada; *p; ) { - (void)copy_option_part(&p, part, ARRAY_SIZE(part), ", "); + (void)(char *)copy_option_part((char_u **)&p, (char_u *)part, ARRAY_SIZE(part), ", "); if (part[0] == 'r') { - home_replace(NULL, part + 1, NameBuff, MAXPATHL, true); + home_replace(NULL, (char_u *)(part + 1), (char_u *)NameBuff, MAXPATHL, true); size_t n = STRLEN(NameBuff); - if (mb_strnicmp(NameBuff, new_name, n) == 0) { + if (mb_strnicmp((char_u *)NameBuff, (char_u *)new_name, n) == 0) { retval = true; break; } diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 3e56ad561b..9ed421c8a0 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -2924,8 +2924,8 @@ void spell_suggest(int count) // Get the list of suggestions. Limit to 'lines' - 2 or the number in // 'spellsuggest', whatever is smaller. - if (sps_limit > (int)Rows - 2) { - limit = (int)Rows - 2; + if (sps_limit > Rows - 2) { + limit = Rows - 2; } else { limit = sps_limit; } @@ -6073,7 +6073,7 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) wordlen = 0; for (const char_u *s = inword; *s != NUL; ) { const char_u *t = s; - c = mb_cptr2char_adv((const char_u **)&s); + c = mb_cptr2char_adv(&s); if (slang->sl_rem_accents) { if (utf_class(c) == 0) { if (did_white) { diff --git a/src/nvim/state.c b/src/nvim/state.c index 04271d750c..4eb0073873 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.c @@ -195,6 +195,8 @@ char *get_mode(void) || restart_edit == 'V') { buf[1] = 'i'; buf[2] = (char)restart_edit; + } else if (curbuf->terminal) { + buf[1] = 't'; } } diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index d2c94d9fe8..49f54dcfe1 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -6217,6 +6217,26 @@ static const char *highlight_init_both[] = { "default link Delimiter Special", "default link SpecialComment Special", "default link Debug Special", + "default DiagnosticError ctermfg=1 guifg=Red", + "default DiagnosticWarn ctermfg=3 guifg=Orange", + "default DiagnosticInfo ctermfg=4 guifg=LightBlue", + "default DiagnosticHint ctermfg=7 guifg=LightGrey", + "default DiagnosticUnderlineError cterm=underline gui=underline guisp=Red", + "default DiagnosticUnderlineWarn cterm=underline gui=underline guisp=Orange", + "default DiagnosticUnderlineInfo cterm=underline gui=underline guisp=LightBlue", + "default DiagnosticUnderlineHint cterm=underline gui=underline guisp=LightGrey", + "default link DiagnosticVirtualTextError DiagnosticError", + "default link DiagnosticVirtualTextWarn DiagnosticWarn", + "default link DiagnosticVirtualTextInfo DiagnosticInfo", + "default link DiagnosticVirtualTextHint DiagnosticHint", + "default link DiagnosticFloatingError DiagnosticError", + "default link DiagnosticFloatingWarn DiagnosticWarn", + "default link DiagnosticFloatingInfo DiagnosticInfo", + "default link DiagnosticFloatingHint DiagnosticHint", + "default link DiagnosticSignError DiagnosticError", + "default link DiagnosticSignWarn DiagnosticWarn", + "default link DiagnosticSignInfo DiagnosticInfo", + "default link DiagnosticSignHint DiagnosticHint", NULL }; diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 6f19a9209e..fb025265f2 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -358,11 +358,21 @@ void terminal_enter(void) // Disable these options in terminal-mode. They are nonsense because cursor is // placed at end of buffer to "follow" output. #11072 win_T *save_curwin = curwin; - int save_w_p_cul = curwin->w_p_cul; + bool save_w_p_cul = curwin->w_p_cul; + char_u *save_w_p_culopt = NULL; + char_u save_w_p_culopt_flags = curwin->w_p_culopt_flags; int save_w_p_cuc = curwin->w_p_cuc; long save_w_p_so = curwin->w_p_so; long save_w_p_siso = curwin->w_p_siso; - curwin->w_p_cul = false; + if (curwin->w_p_cul && curwin->w_p_culopt_flags & CULOPT_NBR) { + if (strcmp((char *)curwin->w_p_culopt, "number")) { + save_w_p_culopt = curwin->w_p_culopt; + curwin->w_p_culopt = (char_u *)xstrdup("number"); + } + curwin->w_p_culopt_flags = CULOPT_NBR; + } else { + curwin->w_p_cul = false; + } curwin->w_p_cuc = false; curwin->w_p_so = 0; curwin->w_p_siso = 0; @@ -386,9 +396,16 @@ void terminal_enter(void) if (save_curwin == curwin) { // save_curwin may be invalid (window closed)! curwin->w_p_cul = save_w_p_cul; + if (save_w_p_culopt) { + xfree(curwin->w_p_culopt); + curwin->w_p_culopt = save_w_p_culopt; + } + curwin->w_p_culopt_flags = save_w_p_culopt_flags; curwin->w_p_cuc = save_w_p_cuc; curwin->w_p_so = save_w_p_so; curwin->w_p_siso = save_w_p_siso; + } else if (save_w_p_culopt) { + xfree(save_w_p_culopt); } // draw the unfocused cursor @@ -1224,7 +1241,7 @@ static bool send_mouse_event(Terminal *term, int c) mouse_action(term, button, row, col - offset, drag, 0); size_t len = vterm_output_read(term->vt, term->textbuf, sizeof(term->textbuf)); - terminal_send(term, term->textbuf, (size_t)len); + terminal_send(term, term->textbuf, len); return false; } diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index 9eb64f68ef..52e6ba64cc 100644 --- a/src/nvim/testdir/test_filetype.vim +++ b/src/nvim/testdir/test_filetype.vim @@ -259,7 +259,7 @@ let s:filename_checks = { \ 'jgraph': ['file.jgr'], \ 'jovial': ['file.jov', 'file.j73', 'file.jovial'], \ 'jproperties': ['file.properties', 'file.properties_xx', 'file.properties_xx_xx', 'some.properties_xx_xx_file'], - \ 'json': ['file.json', 'file.jsonp', 'file.json-patch', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb'], + \ 'json': ['file.json', 'file.jsonp', 'file.json-patch', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb', '.babelrc', '.eslintrc', '.prettierrc', '.firebaserc'], \ 'jsonc': ['file.jsonc'], \ 'jsp': ['file.jsp'], \ 'julia': ['file.jl'], @@ -492,7 +492,7 @@ let s:filename_checks = { \ 'tak': ['file.tak'], \ 'taskdata': ['pending.data', 'completed.data', 'undo.data'], \ 'taskedit': ['file.task'], - \ 'tcl': ['file.tcl', 'file.tk', 'file.itcl', 'file.itk', 'file.jacl'], + \ 'tcl': ['file.tcl', 'file.tm', 'file.tk', 'file.itcl', 'file.itk', 'file.jacl', '.tclshrc', 'tclsh.rc', '.wishrc'], \ 'teraterm': ['file.ttl'], \ 'terminfo': ['file.ti'], \ 'tex': ['file.latex', 'file.sty', 'file.dtx', 'file.ltx', 'file.bbl'], @@ -554,6 +554,7 @@ let s:filename_checks = { \ 'xml': ['/etc/blkid.tab', '/etc/blkid.tab.old', 'file.xmi', 'file.csproj', 'file.csproj.user', 'file.ui', 'file.tpm', '/etc/xdg/menus/file.menu', 'fglrxrc', 'file.xlf', 'file.xliff', 'file.xul', 'file.wsdl', 'file.wpl', 'any/etc/blkid.tab', 'any/etc/blkid.tab.old', 'any/etc/xdg/menus/file.menu'], \ 'xmodmap': ['anyXmodmap', 'Xmodmap', 'some-Xmodmap', 'some-xmodmap', 'some-xmodmap-file', 'xmodmap', 'xmodmap-file'], \ 'xf86conf': ['xorg.conf', 'xorg.conf-4'], + \ 'xpm': ['file.xpm'], \ 'xpm2': ['file.xpm2'], \ 'xquery': ['file.xq', 'file.xql', 'file.xqm', 'file.xquery', 'file.xqy'], \ 'xs': ['file.xs'], @@ -568,7 +569,6 @@ let s:filename_checks = { \ 'zsh': ['.zprofile', '/etc/zprofile', '.zfbfmarks', 'file.zsh', '.zcompdump', '.zlogin', '.zlogout', '.zshenv', '.zshrc', '.zcompdump-file', '.zlog', '.zlog-file', '.zsh', '.zsh-file', 'any/etc/zprofile', 'zlog', 'zlog-file', 'zsh', 'zsh-file'], \ \ 'help': [$VIMRUNTIME . '/doc/help.txt'], - \ 'xpm': ['file.xpm'], \ } let s:filename_case_checks = { @@ -918,4 +918,17 @@ func Test_m_file() call delete('Xfile.m') filetype off endfunc + +func Test_xpm_file() + filetype on + + call writefile(['this is XPM2'], 'file.xpm') + split file.xpm + call assert_equal('xpm2', &filetype) + bwipe! + + call delete('file.xpm') + filetype off +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim index a80c3e9bf2..a0e9f780c6 100644 --- a/src/nvim/testdir/test_functions.vim +++ b/src/nvim/testdir/test_functions.vim @@ -711,6 +711,14 @@ func Test_mode() call assert_equal('c-cv', g:current_modes) " How to test Ex mode? + if has('terminal') + term + call feedkeys("\<C-W>N", 'xt') + call assert_equal('n', mode()) + call assert_equal('nt', mode(1)) + call feedkeys("aexit\<CR>", 'xt') + endif + bwipe! iunmap <F2> xunmap <F2> diff --git a/src/nvim/testdir/test_method.vim b/src/nvim/testdir/test_method.vim index d34448e09e..cdf688b857 100644 --- a/src/nvim/testdir/test_method.vim +++ b/src/nvim/testdir/test_method.vim @@ -1,5 +1,7 @@ " Tests for ->method() +source check.vim + func Test_list_method() let l = [1, 2, 3] call assert_equal([1, 2, 3, 4], [1, 2, 3]->add(4)) @@ -118,6 +120,7 @@ func Test_method_funcref() endfunc func Test_method_float() + CheckFeature float eval 1.234->string()->assert_equal('1.234') eval -1.234->string()->assert_equal('-1.234') endfunc diff --git a/src/nvim/tui/input.h b/src/nvim/tui/input.h index ed76455189..2a8ea32a88 100644 --- a/src/nvim/tui/input.h +++ b/src/nvim/tui/input.h @@ -2,8 +2,8 @@ #define NVIM_TUI_INPUT_H #include <stdbool.h> - #include <termkey.h> + #include "nvim/event/stream.h" #include "nvim/event/time.h" diff --git a/src/nvim/tui/terminfo_defs.h b/src/nvim/tui/terminfo_defs.h index 8d77dc7225..8c328496c1 100644 --- a/src/nvim/tui/terminfo_defs.h +++ b/src/nvim/tui/terminfo_defs.h @@ -1,6 +1,8 @@ // 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 +// uncrustify:off + // // Generated by scripts/update_terminfo.sh and ncurses 6.1.20180127 // @@ -2274,3 +2276,6 @@ static const int8_t xterm_256colour_terminfo[] = { 30,2,37,0,38,0,15,0,-99,1,2,6,120,116,101,114,109,45,50,53,54,99,111,108,111,114,124,120,116,101,114,109,32,119,105,116,104,32,50,53,54,32,99,111,108,111,114,115,0,0,1,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,0,1,1,0,0,0,0,0,0,0,0,1,0,80,0,0,0,8,0,0,0,24,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,0,0,4,0,6,0,8,0,25,0,30,0,38,0,42,0,46,0,-1,-1,57,0,74,0,76,0,80,0,87,0,-1,-1,89,0,102,0,-1,-1,106,0,110,0,120,0,124,0,-1,-1,-1,-1,-128,0,-124,0,-119,0,-114,0,-1,-1,-96,0,-91,0,-86,0,-1,-1,-81,0,-76,0,-71,0,-66,0,-57,0,-53,0,-46,0,-1,-1,-28,0,-23,0,-17,0,-11,0,-1,-1,-1,-1,-1,-1,7,1,-1,-1,-1,-1,-1,-1,25,1,-1,-1,29,1,-1,-1,-1,-1,-1,-1,31,1,-1,-1,36,1,-1,-1,-1,-1,-1,-1,-1,-1,40,1,44,1,50,1,54,1,58,1,62,1,68,1,74,1,80,1,86,1,92,1,96,1,-1,-1,101,1,-1,-1,105,1,110,1,115,1,119,1,126,1,-1,-1,-123,1,-119,1,-111,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-103,1,-94,1,-1,-1,-1,-1,-85,1,-76,1,-67,1,-58,1,-49,1,-40,1,-31,1,-22,1,-13,1,-4,1,-1,-1,-1,-1,-1,-1,5,2,9,2,14,2,19,2,39,2,48,2,-1,-1,-1,-1,66,2,69,2,80,2,83,2,85,2,88,2,-75,2,-1,-1,-72,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-70,2,-1,-1,-1,-1,-1,-1,-1,-1,-66,2,-1,-1,-13,2,-1,-1,-1,-1,-9,2,-3,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,3,3,7,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,3,-1,-1,-1,-1,18,3,-1,-1,-1,-1,-1,-1,-1,-1,25,3,32,3,39,3,-1,-1,-1,-1,46,3,-1,-1,53,3,-1,-1,-1,-1,-1,-1,60,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,67,3,73,3,79,3,86,3,93,3,100,3,107,3,115,3,123,3,-125,3,-117,3,-109,3,-101,3,-93,3,-85,3,-78,3,-71,3,-64,3,-57,3,-49,3,-41,3,-33,3,-25,3,-17,3,-9,3,-1,3,7,4,14,4,21,4,28,4,35,4,43,4,51,4,59,4,67,4,75,4,83,4,91,4,99,4,106,4,113,4,120,4,127,4,-121,4,-113,4,-105,4,-97,4,-89,4,-81,4,-73,4,-65,4,-58,4,-51,4,-44,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-39,4,-28,4,-23,4,-4,4,0,5,9,5,16,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,110,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,115,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,121,5,-1,-1,-1,-1,-1,-1,125,5,-68,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-4,5,-1,5,27,91,90,0,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,50,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,63,49,50,108,27,91,63,50,53,104,0,27,91,67,0,27,91,65,0,27,91,63,49,50,59,50,53,104,0,27,91,80,0,27,91,77,0,27,40,48,0,27,91,53,109,0,27,91,49,109,0,27,91,63,49,48,52,57,104,27,91,50,50,59,48,59,48,116,0,27,91,50,109,0,27,91,52,104,0,27,91,56,109,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,27,91,37,112,49,37,100,88,0,27,40,66,0,27,40,66,27,91,109,0,27,91,63,49,48,52,57,108,27,91,50,51,59,48,59,48,116,0,27,91,52,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,91,63,53,104,36,60,49,48,48,47,62,27,91,63,53,108,0,27,91,33,112,27,91,63,51,59,52,108,27,91,52,108,27,62,0,27,91,76,0,8,0,27,91,51,126,0,27,79,66,0,27,79,80,0,27,91,50,49,126,0,27,79,81,0,27,79,82,0,27,79,83,0,27,91,49,53,126,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,79,72,0,27,91,50,126,0,27,79,68,0,27,91,54,126,0,27,91,53,126,0,27,79,67,0,27,91,49,59,50,66,0,27,91,49,59,50,65,0,27,79,65,0,27,91,63,49,108,27,62,0,27,91,63,49,104,27,61,0,27,91,63,49,48,51,52,108,0,27,91,63,49,48,51,52,104,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,84,0,27,91,37,112,49,37,100,65,0,27,91,105,0,27,91,52,105,0,27,91,53,105,0,37,112,49,37,99,27,91,37,112,50,37,123,49,125,37,45,37,100,98,0,27,99,27,93,49,48,52,7,0,27,91,33,112,27,91,63,51,59,52,108,27,91,52,108,27,62,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,37,63,37,112,57,37,116,27,40,48,37,101,27,40,66,37,59,27,91,48,37,63,37,112,54,37,116,59,49,37,59,37,63,37,112,53,37,116,59,50,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,49,37,112,51,37,124,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,37,63,37,112,55,37,116,59,56,37,59,109,0,27,72,0,9,0,27,79,69,0,96,96,97,97,102,102,103,103,105,105,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,125,126,126,0,27,91,90,0,27,91,63,55,104,0,27,91,63,55,108,0,27,79,70,0,27,79,77,0,27,91,51,59,50,126,0,27,91,49,59,50,70,0,27,91,49,59,50,72,0,27,91,50,59,50,126,0,27,91,49,59,50,68,0,27,91,54,59,50,126,0,27,91,53,59,50,126,0,27,91,49,59,50,67,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,49,59,50,80,0,27,91,49,59,50,81,0,27,91,49,59,50,82,0,27,91,49,59,50,83,0,27,91,49,53,59,50,126,0,27,91,49,55,59,50,126,0,27,91,49,56,59,50,126,0,27,91,49,57,59,50,126,0,27,91,50,48,59,50,126,0,27,91,50,49,59,50,126,0,27,91,50,51,59,50,126,0,27,91,50,52,59,50,126,0,27,91,49,59,53,80,0,27,91,49,59,53,81,0,27,91,49,59,53,82,0,27,91,49,59,53,83,0,27,91,49,53,59,53,126,0,27,91,49,55,59,53,126,0,27,91,49,56,59,53,126,0,27,91,49,57,59,53,126,0,27,91,50,48,59,53,126,0,27,91,50,49,59,53,126,0,27,91,50,51,59,53,126,0,27,91,50,52,59,53,126,0,27,91,49,59,54,80,0,27,91,49,59,54,81,0,27,91,49,59,54,82,0,27,91,49,59,54,83,0,27,91,49,53,59,54,126,0,27,91,49,55,59,54,126,0,27,91,49,56,59,54,126,0,27,91,49,57,59,54,126,0,27,91,50,48,59,54,126,0,27,91,50,49,59,54,126,0,27,91,50,51,59,54,126,0,27,91,50,52,59,54,126,0,27,91,49,59,51,80,0,27,91,49,59,51,81,0,27,91,49,59,51,82,0,27,91,49,59,51,83,0,27,91,49,53,59,51,126,0,27,91,49,55,59,51,126,0,27,91,49,56,59,51,126,0,27,91,49,57,59,51,126,0,27,91,50,48,59,51,126,0,27,91,50,49,59,51,126,0,27,91,50,51,59,51,126,0,27,91,50,52,59,51,126,0,27,91,49,59,52,80,0,27,91,49,59,52,81,0,27,91,49,59,52,82,0,27,91,49,75,0,27,91,37,105,37,100,59,37,100,82,0,27,91,54,110,0,27,91,63,37,91,59,48,49,50,51,52,53,54,55,56,57,93,99,0,27,91,99,0,27,91,51,57,59,52,57,109,0,27,93,49,48,52,7,0,27,93,52,59,37,112,49,37,100,59,114,103,98,58,37,112,50,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,47,37,112,51,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,47,37,112,52,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,27,92,0,27,91,51,109,0,27,91,50,51,109,0,27,91,60,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,51,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,57,37,112,49,37,123,56,125,37,45,37,100,37,101,51,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,52,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,49,48,37,112,49,37,123,56,125,37,45,37,100,37,101,52,56,59,53,59,37,112,49,37,100,37,59,109,0,27,108,0,27,109,0,3,0,1,0,73,0,-106,0,115,3,1,0,1,0,-1,-1,-1,-1,0,0,7,0,-1,-1,19,0,24,0,-1,-1,42,0,48,0,-1,-1,58,0,-1,-1,-1,-1,90,0,97,0,104,0,111,0,118,0,125,0,-124,0,-117,0,-110,0,-103,0,-96,0,-89,0,-82,0,-75,0,-68,0,-61,0,-1,-1,-54,0,-47,0,-40,0,-33,0,-26,0,-1,-1,-19,0,-12,0,-5,0,2,1,9,1,16,1,23,1,30,1,37,1,44,1,51,1,58,1,65,1,72,1,79,1,86,1,93,1,100,1,107,1,114,1,121,1,-128,1,-121,1,-114,1,-107,1,-100,1,-93,1,-86,1,-79,1,-72,1,-65,1,-1,-1,-1,-1,-1,-1,-1,-1,-58,1,-52,1,-47,1,0,0,3,0,6,0,9,0,12,0,15,0,18,0,21,0,24,0,27,0,30,0,33,0,36,0,39,0,42,0,48,0,54,0,59,0,64,0,69,0,74,0,79,0,83,0,88,0,93,0,98,0,103,0,108,0,114,0,120,0,126,0,-124,0,-118,0,-112,0,-106,0,-100,0,-94,0,-88,0,-82,0,-76,0,-71,0,-66,0,-61,0,-56,0,-51,0,-45,0,-39,0,-33,0,-27,0,-21,0,-15,0,-9,0,-3,0,3,1,9,1,15,1,21,1,27,1,33,1,39,1,45,1,51,1,57,1,63,1,69,1,73,1,78,1,83,1,88,1,93,1,98,1,102,1,106,1,110,1,114,1,119,1,124,1,27,93,49,49,50,7,0,27,93,49,50,59,37,112,49,37,115,7,0,27,91,51,74,0,27,93,53,50,59,37,112,49,37,115,59,37,112,50,37,115,7,0,27,91,50,32,113,0,27,91,37,112,49,37,100,32,113,0,27,91,63,49,48,48,54,59,49,48,48,48,37,63,37,112,49,37,123,49,125,37,61,37,116,104,37,101,108,37,59,0,27,91,51,59,51,126,0,27,91,51,59,52,126,0,27,91,51,59,53,126,0,27,91,51,59,54,126,0,27,91,51,59,55,126,0,27,91,49,59,50,66,0,27,91,49,59,51,66,0,27,91,49,59,52,66,0,27,91,49,59,53,66,0,27,91,49,59,54,66,0,27,91,49,59,55,66,0,27,91,49,59,51,70,0,27,91,49,59,52,70,0,27,91,49,59,53,70,0,27,91,49,59,54,70,0,27,91,49,59,55,70,0,27,91,49,59,51,72,0,27,91,49,59,52,72,0,27,91,49,59,53,72,0,27,91,49,59,54,72,0,27,91,49,59,55,72,0,27,91,50,59,51,126,0,27,91,50,59,52,126,0,27,91,50,59,53,126,0,27,91,50,59,54,126,0,27,91,50,59,55,126,0,27,91,49,59,51,68,0,27,91,49,59,52,68,0,27,91,49,59,53,68,0,27,91,49,59,54,68,0,27,91,49,59,55,68,0,27,91,54,59,51,126,0,27,91,54,59,52,126,0,27,91,54,59,53,126,0,27,91,54,59,54,126,0,27,91,54,59,55,126,0,27,91,53,59,51,126,0,27,91,53,59,52,126,0,27,91,53,59,53,126,0,27,91,53,59,54,126,0,27,91,53,59,55,126,0,27,91,49,59,51,67,0,27,91,49,59,52,67,0,27,91,49,59,53,67,0,27,91,49,59,54,67,0,27,91,49,59,55,67,0,27,91,49,59,50,65,0,27,91,49,59,51,65,0,27,91,49,59,52,65,0,27,91,49,59,53,65,0,27,91,49,59,54,65,0,27,91,49,59,55,65,0,27,91,50,57,109,0,27,91,57,109,0,27,91,60,37,112,49,37,100,59,37,112,50,37,100,59,37,112,51,37,100,59,37,63,37,112,52,37,116,77,37,101,109,37,59,0,65,88,0,71,48,0,88,84,0,85,56,0,67,114,0,67,115,0,69,48,0,69,51,0,77,115,0,83,48,0,83,101,0,83,115,0,84,83,0,88,77,0,103,114,98,111,109,0,103,115,98,111,109,0,107,68,67,51,0,107,68,67,52,0,107,68,67,53,0,107,68,67,54,0,107,68,67,55,0,107,68,78,0,107,68,78,51,0,107,68,78,52,0,107,68,78,53,0,107,68,78,54,0,107,68,78,55,0,107,69,78,68,51,0,107,69,78,68,52,0,107,69,78,68,53,0,107,69,78,68,54,0,107,69,78,68,55,0,107,69,78,68,56,0,107,72,79,77,51,0,107,72,79,77,52,0,107,72,79,77,53,0,107,72,79,77,54,0,107,72,79,77,55,0,107,72,79,77,56,0,107,73,67,51,0,107,73,67,52,0,107,73,67,53,0,107,73,67,54,0,107,73,67,55,0,107,76,70,84,51,0,107,76,70,84,52,0,107,76,70,84,53,0,107,76,70,84,54,0,107,76,70,84,55,0,107,78,88,84,51,0,107,78,88,84,52,0,107,78,88,84,53,0,107,78,88,84,54,0,107,78,88,84,55,0,107,80,82,86,51,0,107,80,82,86,52,0,107,80,82,86,53,0,107,80,82,86,54,0,107,80,82,86,55,0,107,82,73,84,51,0,107,82,73,84,52,0,107,82,73,84,53,0,107,82,73,84,54,0,107,82,73,84,55,0,107,85,80,0,107,85,80,51,0,107,85,80,52,0,107,85,80,53,0,107,85,80,54,0,107,85,80,55,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,114,109,120,120,0,115,109,120,120,0,120,109,0 // NOLINT }; #endif // NVIM_TUI_TERMINFO_DEFS_H + +// uncrustify:on + diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 803ff23cea..612eaf6667 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -1019,22 +1019,8 @@ static void tui_mouse_on(UI *ui) { TUIData *data = ui->data; if (!data->mouse_enabled) { -#ifdef WIN32 - // Windows versions with vtp(ENABLE_VIRTUAL_TERMINAL_PROCESSING) and - // no vti(ENABLE_VIRTUAL_TERMINAL_INPUT) will need to use mouse tracking of - // libuv. For this reason, vtp (vterm) state of libuv is temporarily - // disabled because the control sequence needs to be processed by libuv - // instead of Windows vtp. - // ref. https://docs.microsoft.com/en-us/windows/console/setconsolemode - flush_buf(ui); - os_set_vtp(false); -#endif unibi_out_ext(ui, data->unibi_ext.enable_mouse); data->mouse_enabled = true; -#ifdef WIN32 - flush_buf(ui); - os_set_vtp(true); -#endif } } @@ -1042,22 +1028,8 @@ static void tui_mouse_off(UI *ui) { TUIData *data = ui->data; if (data->mouse_enabled) { -#ifdef WIN32 - // Windows versions with vtp(ENABLE_VIRTUAL_TERMINAL_PROCESSING) and - // no vti(ENABLE_VIRTUAL_TERMINAL_INPUT) will need to use mouse tracking of - // libuv. For this reason, vtp (vterm) state of libuv is temporarily - // disabled because the control sequence needs to be processed by libuv - // instead of Windows vtp. - // ref. https://docs.microsoft.com/en-us/windows/console/setconsolemode - flush_buf(ui); - os_set_vtp(false); -#endif unibi_out_ext(ui, data->unibi_ext.disable_mouse); data->mouse_enabled = false; -#ifdef WIN32 - flush_buf(ui); - os_set_vtp(true); -#endif } } diff --git a/src/nvim/undo.c b/src/nvim/undo.c index af214815f8..500845ec72 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -1407,7 +1407,7 @@ void u_read_undo(char *name, const char_u *hash, const char_u *orig_name FUNC_AT FileInfo file_info_orig; FileInfo file_info_undo; if (os_fileinfo((const char *)orig_name, &file_info_orig) - && os_fileinfo((char *)file_name, &file_info_undo) + && os_fileinfo(file_name, &file_info_undo) && file_info_orig.stat.st_uid != file_info_undo.stat.st_uid && file_info_undo.stat.st_uid != getuid()) { if (p_verbose > 0) { @@ -1420,7 +1420,7 @@ void u_read_undo(char *name, const char_u *hash, const char_u *orig_name FUNC_AT } #endif } else { - file_name = (char *)name; + file_name = name; } if (p_verbose > 0) { @@ -3085,6 +3085,8 @@ void u_undoline(void) oldp = u_save_line(curbuf->b_u_line_lnum); ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, true); changed_bytes(curbuf->b_u_line_lnum, 0); + extmark_splice_cols(curbuf, (int)curbuf->b_u_line_lnum-1, 0, (colnr_T)STRLEN(oldp), + (colnr_T)STRLEN(curbuf->b_u_line_ptr), kExtmarkUndo); xfree(curbuf->b_u_line_ptr); curbuf->b_u_line_ptr = oldp; diff --git a/src/nvim/viml/parser/expressions.h b/src/nvim/viml/parser/expressions.h index 838a742271..325df643e7 100644 --- a/src/nvim/viml/parser/expressions.h +++ b/src/nvim/viml/parser/expressions.h @@ -1,13 +1,13 @@ #ifndef NVIM_VIML_PARSER_EXPRESSIONS_H #define NVIM_VIML_PARSER_EXPRESSIONS_H +#include <stdbool.h> #include <stddef.h> #include <stdint.h> -#include <stdbool.h> +#include "nvim/eval/typval.h" #include "nvim/types.h" #include "nvim/viml/parser/parser.h" -#include "nvim/eval/typval.h" // Defines whether to ignore case: // == kCCStrategyUseOption @@ -80,7 +80,7 @@ typedef enum { } ExprAssignmentType; #define EXPR_OPT_SCOPE_LIST \ - ((char[]){ kExprOptScopeGlobal, kExprOptScopeLocal }) + ((char[]){ kExprOptScopeGlobal, kExprOptScopeLocal }) /// All possible variable scopes typedef enum { @@ -96,11 +96,11 @@ typedef enum { } ExprVarScope; #define EXPR_VAR_SCOPE_LIST \ - ((char[]) { \ - kExprVarScopeScript, kExprVarScopeGlobal, kExprVarScopeVim, \ - kExprVarScopeBuffer, kExprVarScopeWindow, kExprVarScopeTabpage, \ - kExprVarScopeLocal, kExprVarScopeBuffer, kExprVarScopeArguments, \ - }) + ((char[]) { \ + kExprVarScopeScript, kExprVarScopeGlobal, kExprVarScopeVim, \ + kExprVarScopeBuffer, kExprVarScopeWindow, kExprVarScopeTabpage, \ + kExprVarScopeLocal, kExprVarScopeBuffer, kExprVarScopeArguments, \ + }) /// Lexer token typedef struct { diff --git a/src/nvim/viml/parser/parser.h b/src/nvim/viml/parser/parser.h index 7ac49709d8..b2933c3781 100644 --- a/src/nvim/viml/parser/parser.h +++ b/src/nvim/viml/parser/parser.h @@ -1,12 +1,12 @@ #ifndef NVIM_VIML_PARSER_PARSER_H #define NVIM_VIML_PARSER_PARSER_H +#include <assert.h> #include <stdbool.h> #include <stddef.h> -#include <assert.h> -#include "nvim/lib/kvec.h" #include "nvim/func_attr.h" +#include "nvim/lib/kvec.h" #include "nvim/mbyte.h" #include "nvim/memory.h" @@ -82,9 +82,9 @@ typedef struct { } ParserState; static inline void viml_parser_init( - ParserState *const ret_pstate, - const ParserLineGetter get_line, void *const cookie, - ParserHighlight *const colors) + ParserState *const ret_pstate, + const ParserLineGetter get_line, void *const cookie, + ParserHighlight *const colors) REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ARG(1, 2); /// Initialize a new parser state instance @@ -94,10 +94,8 @@ static inline void viml_parser_init( /// @param[in] cookie Argument for the get_line function. /// @param[in] colors Where to save highlighting. May be NULL if it is not /// needed. -static inline void viml_parser_init( - ParserState *const ret_pstate, - const ParserLineGetter get_line, void *const cookie, - ParserHighlight *const colors) +static inline void viml_parser_init(ParserState *const ret_pstate, const ParserLineGetter get_line, + void *const cookie, ParserHighlight *const colors) { *ret_pstate = (ParserState) { .reader = { @@ -194,8 +192,7 @@ static inline void viml_parser_advance(ParserState *const pstate, /// /// @param pstate Parser state to advance. /// @param[in] len Number of bytes to advance. -static inline void viml_parser_advance(ParserState *const pstate, - const size_t len) +static inline void viml_parser_advance(ParserState *const pstate, const size_t len) { assert(pstate->pos.line == kv_size(pstate->reader.lines) - 1); const ParserLine pline = kv_last(pstate->reader.lines); @@ -219,10 +216,8 @@ static inline void viml_parser_highlight(ParserState *const pstate, /// @param[in] start Start position of the highlight. /// @param[in] len Highlighting chunk length. /// @param[in] group Highlight group. -static inline void viml_parser_highlight(ParserState *const pstate, - const ParserPosition start, - const size_t len, - const char *const group) +static inline void viml_parser_highlight(ParserState *const pstate, const ParserPosition start, + const size_t len, const char *const group) { if (pstate->colors == NULL || len == 0) { return; @@ -231,9 +226,9 @@ static inline void viml_parser_highlight(ParserState *const pstate, || kv_Z(*pstate->colors, 0).start.line < start.line || kv_Z(*pstate->colors, 0).end_col <= start.col); kvi_push(*pstate->colors, ((ParserHighlightChunk) { - .start = start, - .end_col = start.col + len, - .group = group, + .start = start, + .end_col = start.col + len, + .group = group, })); } diff --git a/src/uncrustify.cfg b/src/uncrustify.cfg index db0c50ff22..0e1e1de87f 100644 --- a/src/uncrustify.cfg +++ b/src/uncrustify.cfg @@ -1,4 +1,4 @@ -# Uncrustify-0.73.0-195-1f883c691 +# Uncrustify-0.73.0-199-0dfafb273 # # General options @@ -44,12 +44,12 @@ disable_processing_nl_cont = false # true/false # file. # # Default: *INDENT-OFF* -disable_processing_cmt = "uncrustify:indent-off" # string +disable_processing_cmt = "uncrustify:off" # string # Specify the marker used in comments to (re)enable processing in a file. # # Default: *INDENT-ON* -enable_processing_cmt = "uncrustify:indent-on" # string +enable_processing_cmt = "uncrustify:on" # string # Enable parsing of digraphs. enable_digraphs = false # true/false @@ -472,9 +472,13 @@ sp_after_class_colon = ignore # ignore/add/remove/force/not_defined sp_before_class_colon = ignore # ignore/add/remove/force/not_defined # Add or remove space after class constructor ':'. +# +# Default: add sp_after_constr_colon = ignore # ignore/add/remove/force/not_defined # Add or remove space before class constructor ':'. +# +# Default: add sp_before_constr_colon = ignore # ignore/add/remove/force/not_defined # Add or remove space before case ':'. @@ -1103,11 +1107,16 @@ indent_class_on_colon = false # true/false # Whether to indent the stuff after a leading class initializer colon. indent_constr_colon = false # true/false -# Virtual indent from the ':' for member initializers. +# Virtual indent from the ':' for leading member initializers. # # Default: 2 indent_ctor_init_leading = 2 # unsigned number +# Virtual indent from the ':' for following member initializers. +# +# Default: 2 +indent_ctor_init_following = 2 # unsigned number + # Additional indent for constructor initializer list. # Negative values decrease indent down to the first column. indent_ctor_init = 0 # number @@ -3298,5 +3307,5 @@ set QUESTION REAL_FATTR_CONST set QUESTION REAL_FATTR_NONNULL_ALL set QUESTION REAL_FATTR_PURE set QUESTION REAL_FATTR_WARN_UNUSED_RESULT -# option(s) with 'not default' value: 62 +# option(s) with 'not default' value: 64 # |