diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2024-04-22 04:28:16 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-22 04:28:16 -0700 |
commit | fb5e2db4c72251ac8f59a7b80fc6d6b40dbec1d8 (patch) | |
tree | 99f8e8ddae86681814a47bb2ab4d7ccbe9ead8d3 /src/nvim/api/deprecated.c | |
parent | 013afc6863b0bed401e1d9e70cb861ee347b158f (diff) | |
download | rneovim-fb5e2db4c72251ac8f59a7b80fc6d6b40dbec1d8.tar.gz rneovim-fb5e2db4c72251ac8f59a7b80fc6d6b40dbec1d8.tar.bz2 rneovim-fb5e2db4c72251ac8f59a7b80fc6d6b40dbec1d8.zip |
refactor(api): deprecate nvim_call_atomic #28433
TODO:
FUNC_API_REMOTE_ONLY APIs such as `nvim_ui_*` cannot (yet) be used in
`nvim_exec_lua`. We can change FUNC_API_REMOTE_ONLY to allow
Vimscript/Lua to pass an explicit `channel_id`. #28437
Diffstat (limited to 'src/nvim/api/deprecated.c')
-rw-r--r-- | src/nvim/api/deprecated.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index 6254e9fbd8..d63b8411e8 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -20,6 +20,9 @@ #include "nvim/lua/executor.h" #include "nvim/memory.h" #include "nvim/memory_defs.h" +#include "nvim/msgpack_rpc/channel.h" +#include "nvim/msgpack_rpc/channel_defs.h" +#include "nvim/msgpack_rpc/unpacker.h" #include "nvim/option.h" #include "nvim/option_defs.h" #include "nvim/pos_defs.h" @@ -697,3 +700,89 @@ static void set_option_to(uint64_t channel_id, void *to, OptReqScope req_scope, set_option_value_for(name.data, opt_idx, optval, opt_flags, req_scope, to, err); }); } + +/// @deprecated Use nvim_exec_lua() instead. +/// +/// Calls many API methods atomically. +/// +/// This has two main usages: +/// 1. To perform several requests from an async context atomically, i.e. +/// without interleaving redraws, RPC requests from other clients, or user +/// interactions (however API methods may trigger autocommands or event +/// processing which have such side effects, e.g. |:sleep| may wake timers). +/// 2. To minimize RPC overhead (roundtrips) of a sequence of many requests. +/// +/// @param channel_id +/// @param calls an array of calls, where each call is described by an array +/// with two elements: the request name, and an array of arguments. +/// @param[out] err Validation error details (malformed `calls` parameter), +/// if any. Errors from batched calls are given in the return value. +/// +/// @return Array of two elements. The first is an array of return +/// values. The second is NIL if all calls succeeded. If a call resulted in +/// an error, it is a three-element array with the zero-based index of the call +/// which resulted in an error, the error type and the error message. If an +/// error occurred, the values from all preceding calls will still be returned. +Array nvim_call_atomic(uint64_t channel_id, Array calls, Arena *arena, Error *err) + FUNC_API_SINCE(1) FUNC_API_DEPRECATED_SINCE(12) FUNC_API_REMOTE_ONLY +{ + Array rv = arena_array(arena, 2); + Array results = arena_array(arena, calls.size); + Error nested_error = ERROR_INIT; + + size_t i; // also used for freeing the variables + for (i = 0; i < calls.size; i++) { + VALIDATE_T("'calls' item", kObjectTypeArray, calls.items[i].type, { + goto theend; + }); + Array call = calls.items[i].data.array; + VALIDATE_EXP((call.size == 2), "'calls' item", "2-item Array", NULL, { + goto theend; + }); + VALIDATE_T("name", kObjectTypeString, call.items[0].type, { + goto theend; + }); + String name = call.items[0].data.string; + VALIDATE_T("call args", kObjectTypeArray, call.items[1].type, { + goto theend; + }); + Array args = call.items[1].data.array; + + MsgpackRpcRequestHandler handler = + msgpack_rpc_get_handler_for(name.data, + name.size, + &nested_error); + + if (ERROR_SET(&nested_error)) { + break; + } + + Object result = handler.fn(channel_id, args, arena, &nested_error); + if (ERROR_SET(&nested_error)) { + // error handled after loop + break; + } + // TODO(bfredl): wasteful copy. It could be avoided to encoding to msgpack + // directly here. But `result` might become invalid when next api function + // is called in the loop. + ADD_C(results, copy_object(result, arena)); + if (handler.ret_alloc) { + api_free_object(result); + } + } + + ADD_C(rv, ARRAY_OBJ(results)); + if (ERROR_SET(&nested_error)) { + Array errval = arena_array(arena, 3); + ADD_C(errval, INTEGER_OBJ((Integer)i)); + ADD_C(errval, INTEGER_OBJ(nested_error.type)); + ADD_C(errval, STRING_OBJ(copy_string(cstr_as_string(nested_error.msg), arena))); + ADD_C(rv, ARRAY_OBJ(errval)); + } else { + ADD_C(rv, NIL); + } + +theend: + api_clear_error(&nested_error); + return rv; +} |