aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThiago de Arruda <tpadilha84@gmail.com>2014-08-07 12:03:36 -0300
committerThiago de Arruda <tpadilha84@gmail.com>2014-08-07 12:03:48 -0300
commit69497ad10a2b2231f2dc317b97124b9ec080a4d4 (patch)
tree06c30e6459f2b874a98a0147c41cad4804d59fd6 /src
parent4702b8a71636266cef8cc4fadc32f785d4eea962 (diff)
parent2875ad865b5c48103642a65728d984ceee75ed65 (diff)
downloadrneovim-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.c14
-rw-r--r--src/nvim/api/vim.c79
-rw-r--r--src/nvim/eval.c24
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));
}
}