diff options
author | Evgeni Chasnovski <evgeni.chasnovski@gmail.com> | 2023-03-25 18:58:48 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-25 09:58:48 -0700 |
commit | fe9cbcb3a5c82932ecfb8f49d07e98a1fc2b31e5 (patch) | |
tree | b2828838c29b0a30befd703cf49a8d6cd16b89a0 /src | |
parent | 257d894d75bc583bb16f4dbe441907eb273d20ad (diff) | |
download | rneovim-fe9cbcb3a5c82932ecfb8f49d07e98a1fc2b31e5.tar.gz rneovim-fe9cbcb3a5c82932ecfb8f49d07e98a1fc2b31e5.tar.bz2 rneovim-fe9cbcb3a5c82932ecfb8f49d07e98a1fc2b31e5.zip |
feat(api): nvim_exec2(), deprecate nvim_exec() #19032
Problem:
The signature of nvim_exec() is not extensible per ":help api-contract".
Solution:
Introduce nvim_exec2() and deprecate nvim_exec().
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/command.c | 2 | ||||
-rw-r--r-- | src/nvim/api/deprecated.c | 17 | ||||
-rw-r--r-- | src/nvim/api/keysets.lua | 3 | ||||
-rw-r--r-- | src/nvim/api/vimscript.c | 36 | ||||
-rw-r--r-- | src/nvim/context.c | 7 |
5 files changed, 52 insertions, 13 deletions
diff --git a/src/nvim/api/command.c b/src/nvim/api/command.c index 1455f28050..26ee9205b2 100644 --- a/src/nvim/api/command.c +++ b/src/nvim/api/command.c @@ -307,7 +307,7 @@ end: /// /// On execution error: fails with VimL error, updates v:errmsg. /// -/// @see |nvim_exec()| +/// @see |nvim_exec2()| /// @see |nvim_command()| /// /// @param cmd Command to execute. Must be a Dictionary that can contain the same values as diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index b1e2e6811e..6a12cfe2da 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -27,13 +27,26 @@ # include "api/deprecated.c.generated.h" #endif +/// @deprecated Use nvim_exec2() instead. +/// @see nvim_exec2 +String nvim_exec(uint64_t channel_id, String src, Boolean output, Error *err) + FUNC_API_SINCE(7) + FUNC_API_DEPRECATED_SINCE(11) +{ + Dict(exec_opts) opts = { 0 }; + opts.output = BOOLEAN_OBJ(output); + return exec_impl(channel_id, src, &opts, err); +} + /// @deprecated -/// @see nvim_exec +/// @see nvim_exec2 String nvim_command_output(uint64_t channel_id, String command, Error *err) FUNC_API_SINCE(1) FUNC_API_DEPRECATED_SINCE(7) { - return nvim_exec(channel_id, command, true, err); + Dict(exec_opts) opts = { 0 }; + opts.output = BOOLEAN_OBJ(true); + return exec_impl(channel_id, command, &opts, err); } /// @deprecated Use nvim_exec_lua() instead. diff --git a/src/nvim/api/keysets.lua b/src/nvim/api/keysets.lua index b2b327d73e..ce29001787 100644 --- a/src/nvim/api/keysets.lua +++ b/src/nvim/api/keysets.lua @@ -232,4 +232,7 @@ return { { 'echo_opts', { "verbose"; }}; + { 'exec_opts', { + "output"; + }}; } diff --git a/src/nvim/api/vimscript.c b/src/nvim/api/vimscript.c index 32dcbdec3f..2438a5cf1d 100644 --- a/src/nvim/api/vimscript.c +++ b/src/nvim/api/vimscript.c @@ -45,13 +45,33 @@ /// @see |nvim_cmd()| /// /// @param src Vimscript code -/// @param output Capture and return all (non-error, non-shell |:!|) output +/// @param opts Optional parameters. +/// - output: (boolean, default false) Whether to capture and return +/// all (non-error, non-shell |:!|) output. /// @param[out] err Error details (Vim error), if any -/// @return Output (non-error, non-shell |:!|) if `output` is true, -/// else empty string. -String nvim_exec(uint64_t channel_id, String src, Boolean output, Error *err) - FUNC_API_SINCE(7) +/// @return Dictionary containing information about execution, with these keys: +/// - output: (string|nil) Output if `opts.output` is true. +Dictionary nvim_exec2(uint64_t channel_id, String src, Dict(exec_opts) *opts, Error *err) + FUNC_API_SINCE(11) { + Dictionary result = ARRAY_DICT_INIT; + + String output = exec_impl(channel_id, src, opts, err); + if (ERROR_SET(err)) { + return result; + } + + if (HAS_KEY(opts->output) && api_object_to_bool(opts->output, "opts.output", false, err)) { + PUT(result, "output", STRING_OBJ(output)); + } + + return result; +} + +String exec_impl(uint64_t channel_id, String src, Dict(exec_opts) *opts, Error *err) +{ + Boolean output = api_object_to_bool(opts->output, "opts.output", false, err); + const int save_msg_silent = msg_silent; garray_T *const save_capture_ga = capture_ga; const int save_msg_col = msg_col; @@ -69,7 +89,7 @@ String nvim_exec(uint64_t channel_id, String src, Boolean output, Error *err) const sctx_T save_current_sctx = api_set_sctx(channel_id); - do_source_str(src.data, "nvim_exec()"); + do_source_str(src.data, "nvim_exec2()"); if (output) { capture_ga = save_capture_ga; msg_silent = save_msg_silent; @@ -108,8 +128,8 @@ theend: /// /// On execution error: fails with VimL error, updates v:errmsg. /// -/// Prefer using |nvim_cmd()| or |nvim_exec()| over this. To evaluate multiple lines of Vim script -/// or an Ex command directly, use |nvim_exec()|. To construct an Ex command using a structured +/// Prefer using |nvim_cmd()| or |nvim_exec2()| over this. To evaluate multiple lines of Vim script +/// or an Ex command directly, use |nvim_exec2()|. To construct an Ex command using a structured /// format and then execute it, use |nvim_cmd()|. To modify an Ex command before evaluating it, use /// |nvim_parse_cmd()| in conjunction with |nvim_cmd()|. /// diff --git a/src/nvim/context.c b/src/nvim/context.c index 9de6c16536..b13a331eff 100644 --- a/src/nvim/context.c +++ b/src/nvim/context.c @@ -10,6 +10,7 @@ #include <string.h> #include "nvim/api/private/converter.h" +#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/api/vimscript.h" #include "nvim/context.h" @@ -271,8 +272,10 @@ static inline void ctx_save_funcs(Context *ctx, bool scriptonly) size_t cmd_len = sizeof("func! ") + strlen(name); char *cmd = xmalloc(cmd_len); snprintf(cmd, cmd_len, "func! %s", name); - String func_body = nvim_exec(VIML_INTERNAL_CALL, cstr_as_string(cmd), - true, &err); + Dict(exec_opts) opts = { 0 }; + opts.output = BOOLEAN_OBJ(true); + String func_body = exec_impl(VIML_INTERNAL_CALL, cstr_as_string(cmd), + &opts, &err); xfree(cmd); if (!ERROR_SET(&err)) { ADD(ctx->funcs, STRING_OBJ(func_body)); |