diff options
-rw-r--r-- | scripts/msgpack-gen.lua | 11 | ||||
-rw-r--r-- | src/nvim/api/vim.c | 56 |
2 files changed, 62 insertions, 5 deletions
diff --git a/scripts/msgpack-gen.lua b/scripts/msgpack-gen.lua index 3d924fb239..d37a85abe8 100644 --- a/scripts/msgpack-gen.lua +++ b/scripts/msgpack-gen.lua @@ -132,11 +132,6 @@ for i = 1, #api.functions do output:write('static Object handle_'..fn.name..'(uint64_t channel_id, msgpack_object *req, Error *error)') output:write('\n{') - output:write('\n if (req->via.array.ptr[3].via.array.size != '..#fn.parameters..') {') - output:write('\n snprintf(error->msg, sizeof(error->msg), "Wrong number of arguments: expecting '..#fn.parameters..' but got %u", req->via.array.ptr[3].via.array.size);') - output:write('\n goto cleanup;') - output:write('\n }\n') - -- Declare/initialize variables that will hold converted arguments for j = 1, #fn.parameters do local param = fn.parameters[j] @@ -144,6 +139,12 @@ for i = 1, #api.functions do output:write('\n '..param[1]..' '..converted..' msgpack_rpc_init_'..string.lower(param[1])..';') end output:write('\n') + output:write('\n if (req->via.array.ptr[3].via.array.size != '..#fn.parameters..') {') + output:write('\n snprintf(error->msg, sizeof(error->msg), "Wrong number of arguments: expecting '..#fn.parameters..' but got %u", req->via.array.ptr[3].via.array.size);') + output:write('\n error->set = true;') + output:write('\n goto cleanup;') + output:write('\n }\n') + -- Validation/conversion for each argument for j = 1, #fn.parameters do local converted, convert_arg, param, arg diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index fbeb42cf4b..0a5dfdf337 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -19,6 +19,8 @@ #include "nvim/message.h" #include "nvim/eval.h" #include "nvim/misc2.h" +#include "nvim/term.h" +#include "nvim/getchar.h" #define LINE_BUFFER_SIZE 4096 @@ -47,6 +49,60 @@ void vim_command(String str, Error *err) try_end(err); } +/// Pass input keys to Neovim +/// +/// @param keys to be typed +/// @param replace_tcodes If true replace special keys such as <CR> or <Leader> +/// for compatibility with Vim --remote-send expressions +/// @param remap If True remap keys +/// @param typed Handle keys as if typed; otherwise they are handled as +/// if coming from a mapping. This matters for undo, +/// opening folds, etc. +void vim_feedkeys(String keys, Boolean replace_tcodes, Boolean remap, + Boolean typed, Error *err) +{ + char *ptr = NULL; + char *cpo_save = (char *)p_cpo; + + if (replace_tcodes) { + // Set 'cpoptions' the way we want it. + // B set - backslashes are *not* treated specially + // k set - keycodes are *not* reverse-engineered + // < unset - <Key> sequences *are* interpreted + // The last but one parameter of replace_termcodes() is TRUE so that the + // <lt> sequence is recognised - needed for a real backslash. + p_cpo = (char_u *)"Bk"; + replace_termcodes((char_u *)keys.data, (char_u **)&ptr, false, true, true); + p_cpo = (char_u *)cpo_save; + } else { + ptr = keys.data; + } + + if (ptr == NULL) { + set_api_error("Failed to eval expression", err); + } else { + // Add the string to the input stream. + // Can't use add_to_input_buf() here, we now have K_SPECIAL bytes. + // + // First clear typed characters from the typeahead buffer, there could + // be half a mapping there. Then append to the existing string, so + // that multiple commands from a client are concatenated. + if (typebuf.tb_maplen < typebuf.tb_len) { + del_typebuf(typebuf.tb_len - typebuf.tb_maplen, typebuf.tb_maplen); + } + (void)ins_typebuf((char_u *)ptr, (remap ? REMAP_YES : REMAP_NONE), + typebuf.tb_len, !typed, false); + + // Let input_available() know we inserted text in the typeahead + // buffer. */ + typebuf_was_filled = true; + + if (replace_tcodes) { + free(ptr); + } + } +} + /// Evaluates the expression str using the vim internal expression /// evaluator (see |expression|). /// Dictionaries and lists are recursively expanded. |