diff options
Diffstat (limited to 'src/nvim/api')
| -rw-r--r-- | src/nvim/api/keysets.lua | 1 | ||||
| -rw-r--r-- | src/nvim/api/private/dispatch.c | 33 | ||||
| -rw-r--r-- | src/nvim/api/private/dispatch.h | 1 | ||||
| -rw-r--r-- | src/nvim/api/private/helpers.c | 17 | ||||
| -rw-r--r-- | src/nvim/api/vim.c | 13 | ||||
| -rw-r--r-- | src/nvim/api/vimscript.c | 16 |
6 files changed, 43 insertions, 38 deletions
diff --git a/src/nvim/api/keysets.lua b/src/nvim/api/keysets.lua index d4882abffe..881a83e606 100644 --- a/src/nvim/api/keysets.lua +++ b/src/nvim/api/keysets.lua @@ -53,6 +53,7 @@ return { "force"; "keepscript"; "nargs"; + "preview"; "range"; "register"; }; diff --git a/src/nvim/api/private/dispatch.c b/src/nvim/api/private/dispatch.c index ba2e560d63..3da2c2cde4 100644 --- a/src/nvim/api/private/dispatch.c +++ b/src/nvim/api/private/dispatch.c @@ -32,37 +32,22 @@ #include "nvim/api/window.h" #include "nvim/ui_client.h" -static Map(String, MsgpackRpcRequestHandler) methods = MAP_INIT; - -static void msgpack_rpc_add_method_handler(String method, MsgpackRpcRequestHandler handler) -{ - map_put(String, MsgpackRpcRequestHandler)(&methods, method, handler); -} - -void msgpack_rpc_add_redraw(void) -{ - msgpack_rpc_add_method_handler(STATIC_CSTR_AS_STRING("redraw"), - (MsgpackRpcRequestHandler) { .fn = ui_client_handle_redraw, - .fast = true }); -} +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "api/private/dispatch_wrappers.generated.h" +#endif /// @param name API method name /// @param name_len name size (includes terminating NUL) MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name, size_t name_len, Error *error) { - String m = { .data = (char *)name, .size = name_len }; - MsgpackRpcRequestHandler rv = - map_get(String, MsgpackRpcRequestHandler)(&methods, m); + int hash = msgpack_rpc_get_handler_for_hash(name, name_len); - if (!rv.fn) { + if (hash < 0) { api_set_error(error, kErrorTypeException, "Invalid method: %.*s", - m.size > 0 ? (int)m.size : (int)sizeof("<empty>"), - m.size > 0 ? m.data : "<empty>"); + name_len > 0 ? (int)name_len : (int)sizeof("<empty>"), + name_len > 0 ? name : "<empty>"); + return (MsgpackRpcRequestHandler){ 0 }; } - return rv; + return method_handlers[hash]; } - -#ifdef INCLUDE_GENERATED_DECLARATIONS -# include "api/private/dispatch_wrappers.generated.h" -#endif diff --git a/src/nvim/api/private/dispatch.h b/src/nvim/api/private/dispatch.h index bad5a13934..4b7c394944 100644 --- a/src/nvim/api/private/dispatch.h +++ b/src/nvim/api/private/dispatch.h @@ -10,6 +10,7 @@ typedef Object (*ApiDispatchWrapper)(uint64_t channel_id, /// The rpc_method_handlers table, used in msgpack_rpc_dispatch(), stores /// functions of this type. typedef struct { + const char *name; ApiDispatchWrapper fn; bool fast; // Function is safe to be executed immediately while running the // uv loop (the loop is run very frequently due to breakcheck). diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 3cccbc3cdf..af4aaf01aa 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -678,11 +678,7 @@ void modify_keymap(uint64_t channel_id, Buffer buffer, bool is_unmap, String mod if (rhs.size == 0) { // assume that the user wants RHS to be a <Nop> parsed_args.rhs_is_noop = true; } else { - // the given RHS was nonempty and not a <Nop>, but was parsed as if it - // were empty? - assert(false && "Failed to parse nonempty RHS!"); - api_set_error(err, kErrorTypeValidation, "Parsing of nonempty RHS failed: %s", rhs.data); - goto fail_and_free; + abort(); // should never happen } } else if (is_unmap && (parsed_args.rhs_len || parsed_args.rhs_lua != LUA_NOREF)) { if (parsed_args.rhs_len) { @@ -1438,6 +1434,7 @@ void create_user_command(String name, Object command, Dict(user_command) *opts, char *rep = NULL; LuaRef luaref = LUA_NOREF; LuaRef compl_luaref = LUA_NOREF; + LuaRef preview_luaref = LUA_NOREF; if (!uc_validate_name(name.data)) { api_set_error(err, kErrorTypeValidation, "Invalid command name"); @@ -1592,6 +1589,14 @@ void create_user_command(String name, Object command, Dict(user_command) *opts, goto err; } + if (opts->preview.type == kObjectTypeLuaRef) { + argt |= EX_PREVIEW; + preview_luaref = api_new_luaref(opts->preview.data.luaref); + } else if (HAS_KEY(opts->preview)) { + api_set_error(err, kErrorTypeValidation, "Invalid value for 'preview'"); + goto err; + } + switch (command.type) { case kObjectTypeLuaRef: luaref = api_new_luaref(command.data.luaref); @@ -1611,7 +1616,7 @@ void create_user_command(String name, Object command, Dict(user_command) *opts, } if (uc_add_command(name.data, name.size, rep, argt, def, flags, compl, compl_arg, compl_luaref, - addr_type_arg, luaref, force) != OK) { + preview_luaref, addr_type_arg, luaref, force) != OK) { api_set_error(err, kErrorTypeException, "Failed to create user command"); // Do not goto err, since uc_add_command now owns luaref, compl_luaref, and compl_arg } diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index dd0b75bbfb..9430a37d27 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -45,6 +45,7 @@ #include "nvim/move.h" #include "nvim/msgpack_rpc/channel.h" #include "nvim/msgpack_rpc/helpers.h" +#include "nvim/msgpack_rpc/unpacker.h" #include "nvim/ops.h" #include "nvim/option.h" #include "nvim/os/input.h" @@ -156,7 +157,6 @@ Dictionary nvim__get_hl_defs(Integer ns_id, Error *err) /// - reverse: boolean /// - nocombine: boolean /// - link: name of another highlight group to link to, see |:hi-link|. -/// Additionally, the following keys are recognized: /// - default: Don't override existing definition |:hi-default| /// - ctermfg: Sets foreground of cterm color |highlight-ctermfg| /// - ctermbg: Sets background of cterm color |highlight-ctermbg| @@ -480,7 +480,7 @@ Object nvim_notify(String msg, Integer log_level, Dictionary opts, Error *err) } /// Calculates the number of display cells occupied by `text`. -/// <Tab> counts as one cell. +/// Control characters including <Tab> count as one cell. /// /// @param text Some text /// @param[out] err Error details, if any @@ -2188,6 +2188,12 @@ void nvim__screenshot(String path) ui_call_screenshot(path); } +Object nvim__unpack(String str, Error *err) + FUNC_API_FAST +{ + return unpack(str.data, str.size, err); +} + /// Deletes an uppercase/file named mark. See |mark-motions|. /// /// @note fails with error if a lowercase or buffer local named mark is used. @@ -2501,6 +2507,8 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * /// - count: (number) Any count supplied |<count>| /// - reg: (string) The optional register, if specified |<reg>| /// - mods: (string) Command modifiers, if any |<mods>| +/// - smods: (table) Command modifiers in a structured format. Has the same +/// structure as the "mods" key of |nvim_parse_cmd()|. /// @param opts Optional command attributes. See |command-attributes| for more details. To use /// boolean attributes (such as |:command-bang| or |:command-bar|) set the value to /// "true". In addition to the string options listed in |:command-complete|, the @@ -2509,6 +2517,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * /// - desc: (string) Used for listing the command when a Lua function is used for /// {command}. /// - force: (boolean, default true) Override any previous definition. +/// - preview: (function) Preview callback for 'inccommand' |:command-preview| /// @param[out] err Error details, if any. void nvim_create_user_command(String name, Object command, Dict(user_command) *opts, Error *err) FUNC_API_SINCE(9) diff --git a/src/nvim/api/vimscript.c b/src/nvim/api/vimscript.c index e71f1a11ec..4b4404ea09 100644 --- a/src/nvim/api/vimscript.c +++ b/src/nvim/api/vimscript.c @@ -1241,10 +1241,12 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error } if (HAS_KEY(mods.verbose)) { - if (mods.verbose.type != kObjectTypeInteger || mods.verbose.data.integer <= 0) { - VALIDATION_ERROR("'mods.verbose' must be a non-negative Integer"); + if (mods.verbose.type != kObjectTypeInteger) { + VALIDATION_ERROR("'mods.verbose' must be a Integer"); + } else if (mods.verbose.data.integer >= 0) { + // Silently ignore negative integers to allow mods.verbose to be set to -1. + cmdinfo.verbose = mods.verbose.data.integer; } - cmdinfo.verbose = mods.verbose.data.integer; } bool vertical; @@ -1256,8 +1258,10 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error VALIDATION_ERROR("'mods.split' must be a String"); } - if (STRCMP(mods.split.data.string.data, "aboveleft") == 0 - || STRCMP(mods.split.data.string.data, "leftabove") == 0) { + if (*mods.split.data.string.data == NUL) { + // Empty string, do nothing. + } else if (STRCMP(mods.split.data.string.data, "aboveleft") == 0 + || STRCMP(mods.split.data.string.data, "leftabove") == 0) { cmdinfo.cmdmod.split |= WSP_ABOVE; } else if (STRCMP(mods.split.data.string.data, "belowright") == 0 || STRCMP(mods.split.data.string.data, "rightbelow") == 0) { @@ -1311,7 +1315,7 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error } WITH_SCRIPT_CONTEXT(channel_id, { - execute_cmd(&ea, &cmdinfo); + execute_cmd(&ea, &cmdinfo, false); }); if (output) { |