diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/keysets.lua | 1 | ||||
-rw-r--r-- | src/nvim/api/vim.c | 3 | ||||
-rw-r--r-- | src/nvim/buffer_defs.h | 1 | ||||
-rw-r--r-- | src/nvim/mapping.c | 23 | ||||
-rw-r--r-- | src/nvim/mapping.h | 3 |
5 files changed, 26 insertions, 5 deletions
diff --git a/src/nvim/api/keysets.lua b/src/nvim/api/keysets.lua index 21319fb7a6..4f4ac40ce9 100644 --- a/src/nvim/api/keysets.lua +++ b/src/nvim/api/keysets.lua @@ -39,6 +39,7 @@ return { "unique"; "callback"; "desc"; + "replace_keycodes"; }; get_commands = { "builtin"; diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 256482fb38..dc57841b96 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1447,7 +1447,8 @@ ArrayOf(Dictionary) nvim_get_keymap(uint64_t channel_id, String mode) /// Unknown key is an error. "desc" can be used to give a /// description to the mapping. When called from Lua, also accepts a /// "callback" key that takes a Lua function to call when the -/// mapping is executed. +/// mapping is executed. "replace_keycodes" can be used with "expr" +/// to replace keycodes, see |nvim_replace_termcodes()|. /// @param[out] err Error details, if any. void nvim_set_keymap(uint64_t channel_id, String mode, String lhs, String rhs, Dict(keymap) *opts, Error *err) diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 174eb1cec9..aeba3acbc3 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -369,6 +369,7 @@ struct mapblock { char m_expr; // <expr> used, m_str is an expression sctx_T m_script_ctx; // SCTX where map was defined char *m_desc; // description of keymap + bool m_replace_keycodes; // replace termcodes in lua function }; /// Used for highlighting in the status line. diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c index 237586dc22..93374a41bd 100644 --- a/src/nvim/mapping.c +++ b/src/nvim/mapping.c @@ -715,6 +715,7 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, mp->m_mode = mode; mp->m_simplified = keyround1_simplified; mp->m_expr = args->expr; + mp->m_replace_keycodes = args->replace_keycodes; mp->m_script_ctx = current_sctx; mp->m_script_ctx.sc_lnum += sourcing_lnum; nlua_set_sctx(&mp->m_script_ctx); @@ -806,6 +807,7 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, mp->m_mode = mode; mp->m_simplified = keyround1_simplified; // Notice this when porting patch 8.2.0807 mp->m_expr = args->expr; + mp->m_replace_keycodes = args->replace_keycodes; mp->m_script_ctx = current_sctx; mp->m_script_ctx.sc_lnum += sourcing_lnum; nlua_set_sctx(&mp->m_script_ctx); @@ -1513,7 +1515,6 @@ bool check_abbr(int c, char_u *ptr, int col, int mincol) /// @param c NUL or typed character for abbreviation char_u *eval_map_expr(mapblock_T *mp, int c) { - char_u *res; char_u *p = NULL; char_u *expr = NULL; pos_T save_cursor; @@ -1560,8 +1561,15 @@ char_u *eval_map_expr(mapblock_T *mp, int c) if (p == NULL) { return NULL; } - // Escape K_SPECIAL in the result to be able to use the string as typeahead. - res = (char_u *)vim_strsave_escape_ks((char *)p); + + char_u *res = NULL; + + if (mp->m_replace_keycodes) { + replace_termcodes((char *)p, STRLEN(p), (char **)&res, REPTERM_DO_LT, NULL, CPO_TO_CPO_FLAGS); + } else { + // Escape K_SPECIAL in the result to be able to use the string as typeahead. + res = (char_u *)vim_strsave_escape_ks((char *)p); + } xfree(p); return res; @@ -2011,6 +2019,9 @@ static void mapblock_fill_dict(dict_T *const dict, const mapblock_T *const mp, l tv_dict_add_nr(dict, S_LEN("lnum"), (varnumber_T)mp->m_script_ctx.sc_lnum); tv_dict_add_nr(dict, S_LEN("buffer"), (varnumber_T)buffer_value); tv_dict_add_nr(dict, S_LEN("nowait"), mp->m_nowait ? 1 : 0); + if (mp->m_replace_keycodes) { + tv_dict_add_nr(dict, S_LEN("replace_keycodes"), 1); + } tv_dict_add_allocated_str(dict, S_LEN("mode"), mapmode); } @@ -2392,10 +2403,16 @@ void modify_keymap(uint64_t channel_id, Buffer buffer, bool is_unmap, String mod KEY_TO_BOOL(script); KEY_TO_BOOL(expr); KEY_TO_BOOL(unique); + KEY_TO_BOOL(replace_keycodes); #undef KEY_TO_BOOL } parsed_args.buffer = !global; + if (parsed_args.replace_keycodes && !parsed_args.expr) { + api_set_error(err, kErrorTypeValidation, "\"replace_keycodes\" requires \"expr\""); + goto fail_and_free; + } + if (!set_maparg_lhs_rhs(lhs.data, lhs.size, rhs.data, rhs.size, lua_funcref, CPO_TO_CPO_FLAGS, &parsed_args)) { diff --git a/src/nvim/mapping.h b/src/nvim/mapping.h index b19131a686..98d0074075 100644 --- a/src/nvim/mapping.h +++ b/src/nvim/mapping.h @@ -21,6 +21,7 @@ struct map_arguments { bool script; bool silent; bool unique; + bool replace_keycodes; /// The {lhs} of the mapping. /// @@ -44,7 +45,7 @@ struct map_arguments { char *desc; /// map description }; typedef struct map_arguments MapArguments; -#define MAP_ARGUMENTS_INIT { false, false, false, false, false, false, false, \ +#define MAP_ARGUMENTS_INIT { false, false, false, false, false, false, false, false, \ { 0 }, 0, { 0 }, 0, NULL, 0, LUA_NOREF, false, NULL, 0, NULL } #ifdef INCLUDE_GENERATED_DECLARATIONS |