aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/eval.c')
-rw-r--r--src/nvim/eval.c96
1 files changed, 89 insertions, 7 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 7c0d1b3d32..d8c2e73150 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -84,7 +84,6 @@
#include "nvim/os/channel.h"
#include "nvim/api/private/helpers.h"
#include "nvim/api/vim.h"
-#include "nvim/os/msgpack_rpc_helpers.h"
#include "nvim/os/dl.h"
#include "nvim/os/provider.h"
@@ -6307,6 +6306,8 @@ static struct fst {
{"acos", 1, 1, f_acos}, /* WJMc */
{"add", 2, 2, f_add},
{"and", 2, 2, f_and},
+ {"api_close", 1, 1, f_api_close},
+ {"api_spawn", 1, 2, f_api_spawn},
{"append", 2, 2, f_append},
{"argc", 0, 0, f_argc},
{"argidx", 0, 0, f_argidx},
@@ -7054,6 +7055,83 @@ static void f_and(typval_T *argvars, typval_T *rettv)
& get_tv_number_chk(&argvars[1], NULL);
}
+// "api_close(prog, argv)" function
+static void f_api_close(typval_T *argvars, typval_T *rettv)
+{
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = 0;
+
+ if (check_restricted() || check_secure()) {
+ return;
+ }
+
+ if (argvars[0].v_type != VAR_NUMBER) {
+ // Wrong argument types
+ EMSG(_(e_invarg));
+ return;
+ }
+
+ rettv->vval.v_number = channel_close(argvars[0].vval.v_number);
+}
+
+
+// "api_spawn(prog, argv)" function
+static void f_api_spawn(typval_T *argvars, typval_T *rettv)
+{
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = 0;
+
+ if (check_restricted() || check_secure()) {
+ return;
+ }
+
+ if (argvars[0].v_type != VAR_STRING
+ || (argvars[1].v_type != VAR_LIST && argvars[1].v_type != VAR_UNKNOWN)) {
+ // Wrong argument types
+ EMSG(_(e_invarg));
+ return;
+ }
+
+ list_T *args = NULL;
+ int argsl = 0;
+ if (argvars[1].v_type == VAR_LIST) {
+ args = argvars[1].vval.v_list;
+ argsl = args->lv_len;
+ // Assert that all list items are strings
+ for (listitem_T *arg = args->lv_first; arg != NULL; arg = arg->li_next) {
+ if (arg->li_tv.v_type != VAR_STRING) {
+ EMSG(_(e_invarg));
+ return;
+ }
+ }
+ }
+
+ // Allocate extra memory for the argument vector and the NULL pointer
+ int argvl = argsl + 2;
+ char **argv = xmalloc(sizeof(char_u *) * argvl);
+
+ // Copy program name
+ argv[0] = xstrdup((char *)argvars[0].vval.v_string);
+
+ int i = 1;
+ // Copy arguments to the vector
+ if (argsl > 0) {
+ for (listitem_T *arg = args->lv_first; arg != NULL; arg = arg->li_next) {
+ argv[i++] = xstrdup((char *)arg->li_tv.vval.v_string);
+ }
+ }
+
+ // The last item of argv must be NULL
+ argv[i] = NULL;
+ uint64_t channel_id = channel_from_job(argv);
+
+ if (!channel_id) {
+ EMSG(_(e_api_spawn_failed));
+ }
+
+ rettv->vval.v_number = (varnumber_T)channel_id;
+}
+
/*
* "append(lnum, string/list)" function
*/
@@ -12718,14 +12796,18 @@ static void f_send_call(typval_T *argvars, typval_T *rettv)
return;
}
+ if (errored) {
+ vim_report_error(result.data.string);
+ goto end;
+ }
+
Error conversion_error = {.set = false};
- if (errored || !object_to_vim(result, rettv, &conversion_error)) {
- EMSG(errored ?
- result.data.string.data :
- _("Error converting the call result"));
+ if (!object_to_vim(result, rettv, &conversion_error)) {
+ EMSG(_("Error converting the call result"));
}
- msgpack_rpc_free_object(result);
+end:
+ api_free_object(result);
}
// "send_event()" function
@@ -19239,7 +19321,7 @@ static void script_host_eval(char *method, typval_T *argvars, typval_T *rettv)
Error err = {.set = false};
object_to_vim(result, rettv, &err);
- msgpack_rpc_free_object(result);
+ api_free_object(result);
if (err.set) {
EMSG("Error converting value back to vim");