diff options
author | Thiago de Arruda <tpadilha84@gmail.com> | 2014-08-07 12:03:36 -0300 |
---|---|---|
committer | Thiago de Arruda <tpadilha84@gmail.com> | 2014-08-07 12:03:48 -0300 |
commit | 69497ad10a2b2231f2dc317b97124b9ec080a4d4 (patch) | |
tree | 06c30e6459f2b874a98a0147c41cad4804d59fd6 /src | |
parent | 4702b8a71636266cef8cc4fadc32f785d4eea962 (diff) | |
parent | 2875ad865b5c48103642a65728d984ceee75ed65 (diff) | |
download | rneovim-69497ad10a2b2231f2dc317b97124b9ec080a4d4.tar.gz rneovim-69497ad10a2b2231f2dc317b97124b9ec080a4d4.tar.bz2 rneovim-69497ad10a2b2231f2dc317b97124b9ec080a4d4.zip |
Merge pull request #920 'Add `feedkeys` API function part 2'
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/private/helpers.c | 14 | ||||
-rw-r--r-- | src/nvim/api/vim.c | 79 | ||||
-rw-r--r-- | src/nvim/eval.c | 24 |
3 files changed, 56 insertions, 61 deletions
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 354a74d19a..f6fb46e1d1 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -343,6 +343,20 @@ String cstr_to_string(const char *str) }; } +/// Creates a String using the given C string. Unlike +/// cstr_to_string this function DOES NOT copy the C string. +/// +/// @param str the C string to use +/// @return The resulting String, or an empty String if +/// str was NULL +String cstr_as_string(char *str) FUNC_ATTR_PURE +{ + if (str == NULL) { + return (String) STRING_INIT; + } + return (String) {.data = str, .size = strlen(str)}; +} + bool object_to_vim(Object obj, typval_T *tv, Error *err) { tv->v_type = VAR_UNKNOWN; diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 6c793cbc54..a2c50b4c81 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -54,55 +54,52 @@ void vim_command(String str, Error *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) +/// @param mode specifies the mapping options +/// @see feedkeys() +void vim_feedkeys(String keys, String mode) { - 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; + bool remap = true; + bool typed = false; + + if (keys.size == 0) { + return; } - 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); + for (size_t i = 0; i < mode.size; ++i) { + switch (mode.data[i]) { + case 'n': remap = false; break; + case 'm': remap = true; break; + case 't': typed = true; break; } - (void)ins_typebuf((char_u *)ptr, (remap ? REMAP_YES : REMAP_NONE), - typebuf.tb_len, !typed, false); + } + + /* Need to escape K_SPECIAL and CSI before putting the string in the + * typeahead buffer. */ + char *keys_esc = (char *)vim_strsave_escape_csi((char_u *)keys.data); + ins_typebuf((char_u *)keys_esc, (remap ? REMAP_YES : REMAP_NONE), + typebuf.tb_len, !typed, false); + free(keys_esc); - // Let input_available() know we inserted text in the typeahead - // buffer. */ + if (vgetc_busy) typebuf_was_filled = true; +} - if (replace_tcodes) { - free(ptr); - } +/// Replace any terminal codes with the internal representation +/// +/// @see replace_termcodes +/// @see cpoptions +String vim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, + Boolean special) +{ + if (str.size == 0) { + // Empty string + return str; } + + char *ptr = NULL; + replace_termcodes((char_u *)str.data, (char_u **)&ptr, + from_part, do_lt, special); + return cstr_as_string(ptr); } /// Evaluates the expression str using the vim internal expression diff --git a/src/nvim/eval.c b/src/nvim/eval.c index f7b65d1476..af41893035 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -83,7 +83,7 @@ #include "nvim/os/time.h" #include "nvim/os/channel.h" #include "nvim/api/private/helpers.h" -#include "nvim/api/private/defs.h" +#include "nvim/api/vim.h" #include "nvim/os/msgpack_rpc_helpers.h" #include "nvim/os/dl.h" #include "nvim/os/provider.h" @@ -8280,11 +8280,8 @@ static void f_extend(typval_T *argvars, typval_T *rettv) */ static void f_feedkeys(typval_T *argvars, typval_T *rettv) { - int remap = TRUE; - char_u *keys, *flags; + char_u *keys, *flags = NULL; char_u nbuf[NUMBUFLEN]; - int typed = FALSE; - char_u *keys_esc; /* This is not allowed in the sandbox. If the commands would still be * executed in the sandbox it would be OK, but it probably happens later, @@ -8296,23 +8293,10 @@ static void f_feedkeys(typval_T *argvars, typval_T *rettv) if (*keys != NUL) { if (argvars[1].v_type != VAR_UNKNOWN) { flags = get_tv_string_buf(&argvars[1], nbuf); - for (; *flags != NUL; ++flags) { - switch (*flags) { - case 'n': remap = FALSE; break; - case 'm': remap = TRUE; break; - case 't': typed = TRUE; break; - } - } } - /* Need to escape K_SPECIAL and CSI before putting the string in the - * typeahead buffer. */ - keys_esc = vim_strsave_escape_csi(keys); - ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE), - typebuf.tb_len, !typed, FALSE); - free(keys_esc); - if (vgetc_busy) - typebuf_was_filled = TRUE; + vim_feedkeys(cstr_as_string((char *)keys), + cstr_as_string((char *)flags)); } } |