mirror of
https://github.com/neovim/neovim.git
synced 2024-12-31 17:13:26 -07:00
feat(api): add replace_keycodes to nvim_set_keymap (#19598)
This commit is contained in:
parent
9f5d5aa3da
commit
db6e93c48d
@ -1508,7 +1508,9 @@ nvim_set_keymap({mode}, {lhs}, {rhs}, {*opts}) *nvim_set_keymap()*
|
||||
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.
|
||||
is executed. "replace_keycodes" can be used with
|
||||
"expr" to replace keycodes, see
|
||||
|nvim_replace_termcodes()|.
|
||||
|
||||
nvim_set_var({name}, {value}) *nvim_set_var()*
|
||||
Sets a global (g:) variable.
|
||||
|
@ -2228,13 +2228,10 @@ set({mode}, {lhs}, {rhs}, {opts}) *vim.keymap.set()*
|
||||
• buffer: (number or boolean) Add a mapping to the
|
||||
given buffer. When "true" or 0, use the current
|
||||
buffer.
|
||||
• replace_keycodes: (boolean, default true) When
|
||||
both this and expr is "true",
|
||||
|nvim_replace_termcodes()| is applied to the
|
||||
result of Lua expr maps.
|
||||
• remap: (boolean) Make the mapping recursive.
|
||||
This is the inverse of the "noremap" option from
|
||||
|nvim_set_keymap()|. Default `false`.
|
||||
• replace_keycodes: (boolean) defaults to true.
|
||||
|
||||
See also: ~
|
||||
|nvim_set_keymap()|
|
||||
|
@ -42,11 +42,10 @@ local keymap = {}
|
||||
--- listed in |nvim_set_keymap()|, this table also accepts the following keys:
|
||||
--- - buffer: (number or boolean) Add a mapping to the given buffer. When "true"
|
||||
--- or 0, use the current buffer.
|
||||
--- - replace_keycodes: (boolean, default true) When both this and expr is "true",
|
||||
--- |nvim_replace_termcodes()| is applied to the result of Lua expr maps.
|
||||
--- - remap: (boolean) Make the mapping recursive. This is the
|
||||
--- inverse of the "noremap" option from |nvim_set_keymap()|.
|
||||
--- Default `false`.
|
||||
--- - replace_keycodes: (boolean) defaults to true.
|
||||
---@see |nvim_set_keymap()|
|
||||
function keymap.set(mode, lhs, rhs, opts)
|
||||
vim.validate({
|
||||
@ -60,22 +59,9 @@ function keymap.set(mode, lhs, rhs, opts)
|
||||
local is_rhs_luaref = type(rhs) == 'function'
|
||||
mode = type(mode) == 'string' and { mode } or mode
|
||||
|
||||
if is_rhs_luaref and opts.expr then
|
||||
local user_rhs = rhs
|
||||
rhs = function()
|
||||
local res = user_rhs()
|
||||
if res == nil then
|
||||
-- TODO(lewis6991): Handle this in C?
|
||||
return ''
|
||||
elseif opts.replace_keycodes ~= false then
|
||||
return vim.api.nvim_replace_termcodes(res, true, true, true)
|
||||
else
|
||||
return res
|
||||
end
|
||||
end
|
||||
if opts.expr and opts.replace_keycodes ~= false then
|
||||
opts.replace_keycodes = true
|
||||
end
|
||||
-- clear replace_keycodes from opts table
|
||||
opts.replace_keycodes = nil
|
||||
|
||||
if opts.remap == nil then
|
||||
-- default remap value is false
|
||||
|
@ -39,6 +39,7 @@ return {
|
||||
"unique";
|
||||
"callback";
|
||||
"desc";
|
||||
"replace_keycodes";
|
||||
};
|
||||
get_commands = {
|
||||
"builtin";
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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)) {
|
||||
|
@ -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
|
||||
|
@ -822,7 +822,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
|
||||
|
||||
it('can make lua expr mappings', function()
|
||||
exec_lua [[
|
||||
vim.api.nvim_set_keymap ('n', 'aa', '', {callback = function() return vim.api.nvim_replace_termcodes(':lua SomeValue = 99<cr>', true, false, true) end, expr = true })
|
||||
vim.api.nvim_set_keymap ('n', 'aa', '', {callback = function() return ':lua SomeValue = 99<cr>' end, expr = true, replace_keycodes = true })
|
||||
]]
|
||||
|
||||
feed('aa')
|
||||
@ -830,6 +830,16 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
|
||||
eq(99, exec_lua[[return SomeValue]])
|
||||
end)
|
||||
|
||||
it('can make lua expr mappings without replacing keycodes', function()
|
||||
exec_lua [[
|
||||
vim.api.nvim_set_keymap ('i', 'aa', '', {callback = function() return '<space>' end, expr = true })
|
||||
]]
|
||||
|
||||
feed('iaa<esc>')
|
||||
|
||||
eq({'<space>'}, meths.buf_get_lines(0, 0, -1, false))
|
||||
end)
|
||||
|
||||
it('does not reset pum in lua mapping', function()
|
||||
eq(0, exec_lua [[
|
||||
VisibleCount = 0
|
||||
@ -1020,7 +1030,7 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function()
|
||||
|
||||
it('can make lua expr mappings', function()
|
||||
exec_lua [[
|
||||
vim.api.nvim_buf_set_keymap (0, 'n', 'aa', '', {callback = function() return vim.api.nvim_replace_termcodes(':lua SomeValue = 99<cr>', true, false, true) end, expr = true })
|
||||
vim.api.nvim_buf_set_keymap (0, 'n', 'aa', '', {callback = function() return ':lua SomeValue = 99<cr>' end, expr = true, replace_keycodes = true })
|
||||
]]
|
||||
|
||||
feed('aa')
|
||||
@ -1028,6 +1038,17 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function()
|
||||
eq(99, exec_lua[[return SomeValue ]])
|
||||
end)
|
||||
|
||||
it('can make lua expr mappings without replacing keycodes', function()
|
||||
exec_lua [[
|
||||
vim.api.nvim_buf_set_keymap (0, 'i', 'aa', '', {callback = function() return '<space>' end, expr = true })
|
||||
]]
|
||||
|
||||
feed('iaa<esc>')
|
||||
|
||||
eq({'<space>'}, meths.buf_get_lines(0, 0, -1, false))
|
||||
end)
|
||||
|
||||
|
||||
it('can overwrite lua mappings', function()
|
||||
eq(0, exec_lua [[
|
||||
GlobalCount = 0
|
||||
|
Loading…
Reference in New Issue
Block a user