aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/mapping.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2022-08-03 00:08:17 -0600
committerJosh Rahm <joshuarahm@gmail.com>2022-08-03 00:08:17 -0600
commit9449e1b8d273ff78eb894c588110ffa0c17d6ee3 (patch)
tree9e4470c33bd4187d9f42f0b2c4aaa995310c5be8 /src/nvim/mapping.c
parent308e1940dcd64aa6c344c403d4f9e0dda58d9c5c (diff)
parentb8dcbcc732baf84fc48d6b272c3ade0bcb129b3b (diff)
downloadrneovim-9449e1b8d273ff78eb894c588110ffa0c17d6ee3.tar.gz
rneovim-9449e1b8d273ff78eb894c588110ffa0c17d6ee3.tar.bz2
rneovim-9449e1b8d273ff78eb894c588110ffa0c17d6ee3.zip
Merge remote-tracking branch 'upstream/master' into rahm
Diffstat (limited to 'src/nvim/mapping.c')
-rw-r--r--src/nvim/mapping.c318
1 files changed, 210 insertions, 108 deletions
diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c
index 5a11ac686e..1797bb0365 100644
--- a/src/nvim/mapping.c
+++ b/src/nvim/mapping.c
@@ -235,7 +235,7 @@ static void showmap(mapblock_T *mp, bool local)
/// @param[in] orig_lhs Original mapping LHS, with characters to replace.
/// @param[in] orig_lhs_len `strlen` of orig_lhs.
/// @param[in] orig_rhs Original mapping RHS, with characters to replace.
-/// @param[in] rhs_lua Lua reference for Lua maps.
+/// @param[in] rhs_lua Lua reference for Lua mappings.
/// @param[in] orig_rhs_len `strlen` of orig_rhs.
/// @param[in] cpo_flags See param docs for @ref replace_termcodes.
/// @param[out] mapargs MapArguments struct holding the replaced strings.
@@ -428,6 +428,66 @@ static int str_to_mapargs(const char_u *strargs, bool is_unmap, MapArguments *ma
return 0;
}
+/// @param args "rhs", "rhs_lua", "orig_rhs", "expr", "silent", "nowait", "replace_keycodes" and
+/// and "desc" fields are used.
+/// "rhs", "rhs_lua", "orig_rhs" fields are cleared if "simplified" is false.
+/// @param sid -1 to use current_sctx
+static void map_add(buf_T *buf, mapblock_T **map_table, mapblock_T **abbr_table, const char_u *keys,
+ MapArguments *args, int noremap, int mode, bool is_abbr, scid_T sid,
+ linenr_T lnum, bool simplified)
+{
+ mapblock_T *mp = xcalloc(1, sizeof(mapblock_T));
+
+ // If CTRL-C has been mapped, don't always use it for Interrupting.
+ if (*keys == Ctrl_C) {
+ if (map_table == buf->b_maphash) {
+ buf->b_mapped_ctrl_c |= mode;
+ } else {
+ mapped_ctrl_c |= mode;
+ }
+ }
+
+ mp->m_keys = vim_strsave(keys);
+ mp->m_str = args->rhs;
+ mp->m_orig_str = args->orig_rhs;
+ mp->m_luaref = args->rhs_lua;
+ if (!simplified) {
+ args->rhs = NULL;
+ args->orig_rhs = NULL;
+ args->rhs_lua = LUA_NOREF;
+ }
+ mp->m_keylen = (int)STRLEN(mp->m_keys);
+ mp->m_noremap = noremap;
+ mp->m_nowait = args->nowait;
+ mp->m_silent = args->silent;
+ mp->m_mode = mode;
+ mp->m_simplified = simplified;
+ mp->m_expr = args->expr;
+ mp->m_replace_keycodes = args->replace_keycodes;
+ if (sid >= 0) {
+ mp->m_script_ctx.sc_sid = sid;
+ mp->m_script_ctx.sc_lnum = lnum;
+ } else {
+ mp->m_script_ctx = current_sctx;
+ mp->m_script_ctx.sc_lnum += sourcing_lnum;
+ nlua_set_sctx(&mp->m_script_ctx);
+ }
+ mp->m_desc = NULL;
+ if (args->desc != NULL) {
+ mp->m_desc = xstrdup(args->desc);
+ }
+
+ // add the new entry in front of the abbrlist or maphash[] list
+ if (is_abbr) {
+ mp->m_next = *abbr_table;
+ *abbr_table = mp;
+ } else {
+ const int n = MAP_HASH(mp->m_mode, mp->m_keys[0]);
+ mp->m_next = map_table[n];
+ map_table[n] = mp;
+ }
+}
+
/// Sets or removes a mapping or abbreviation in buffer `buf`.
///
/// @param maptype @see do_map
@@ -452,7 +512,7 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
abbr_table = &first_abbr;
// For ":noremap" don't remap, otherwise do remap.
- if (maptype == 2) {
+ if (maptype == MAPTYPE_NOREMAP) {
noremap = REMAP_NONE;
} else {
noremap = REMAP_YES;
@@ -470,10 +530,10 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
const bool has_lhs = (args->lhs[0] != NUL);
const bool has_rhs = args->rhs_lua != LUA_NOREF || (args->rhs[0] != NUL) || args->rhs_is_noop;
- const bool do_print = !has_lhs || (maptype != 1 && !has_rhs);
+ const bool do_print = !has_lhs || (maptype != MAPTYPE_UNMAP && !has_rhs);
// check for :unmap without argument
- if (maptype == 1 && !has_lhs) {
+ if (maptype == MAPTYPE_UNMAP && !has_lhs) {
retval = 1;
goto theend;
}
@@ -507,13 +567,11 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
goto theend;
}
- if (is_abbrev && maptype != 1) {
- //
+ if (is_abbrev && maptype != MAPTYPE_UNMAP) {
// If an abbreviation ends in a keyword character, the
// rest must be all keyword-char or all non-keyword-char.
// Otherwise we won't be able to find the start of it in a
// vi-compatible way.
- //
int same = -1;
const int first = vim_iswordp(lhs);
@@ -551,7 +609,8 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
}
// Check if a new local mapping wasn't already defined globally.
- if (args->unique && map_table == buf->b_maphash && has_lhs && has_rhs && maptype != 1) {
+ if (args->unique && map_table == buf->b_maphash && has_lhs && has_rhs
+ && maptype != MAPTYPE_UNMAP) {
// need to loop over all global hash lists
for (int hash = 0; hash < 256 && !got_int; hash++) {
if (is_abbrev) {
@@ -581,7 +640,7 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
}
// When listing global mappings, also list buffer-local ones here.
- if (map_table != buf->b_maphash && !has_rhs && maptype != 1) {
+ if (map_table != buf->b_maphash && !has_rhs && maptype != MAPTYPE_UNMAP) {
// need to loop over all global hash lists
for (int hash = 0; hash < 256 && !got_int; hash++) {
if (is_abbrev) {
@@ -616,7 +675,7 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
// entry with a matching 'to' part. This was done to allow ":ab foo bar"
// to be unmapped by typing ":unab foo", where "foo" will be replaced by
// "bar" because of the abbreviation.
- for (int round = 0; (round == 0 || maptype == 1) && round <= 1
+ for (int round = 0; (round == 0 || maptype == MAPTYPE_UNMAP) && round <= 1
&& !did_it && !got_int; round++) {
int hash_start, hash_end;
if (has_lhs || is_abbrev) {
@@ -650,7 +709,7 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
p = mp->m_keys;
}
if (STRNCMP(p, lhs, (size_t)(n < len ? n : len)) == 0) {
- if (maptype == 1) {
+ if (maptype == MAPTYPE_UNMAP) {
// Delete entry.
// Only accept a full match. For abbreviations
// we ignore trailing space when matching with
@@ -715,6 +774,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);
@@ -745,7 +805,7 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
}
}
- if (maptype == 1) {
+ if (maptype == MAPTYPE_UNMAP) {
// delete entry
if (!did_it) {
if (!keyround1_simplified) {
@@ -779,50 +839,10 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
}
// Get here when adding a new entry to the maphash[] list or abbrlist.
- mp = xmalloc(sizeof(mapblock_T));
-
- // If CTRL-C has been mapped, don't always use it for Interrupting.
- if (*lhs == Ctrl_C) {
- if (map_table == buf->b_maphash) {
- buf->b_mapped_ctrl_c |= mode;
- } else {
- mapped_ctrl_c |= mode;
- }
- }
-
- mp->m_keys = vim_strsave(lhs);
- mp->m_str = args->rhs;
- mp->m_orig_str = args->orig_rhs;
- mp->m_luaref = args->rhs_lua;
- if (!keyround1_simplified) {
- args->rhs = NULL;
- args->orig_rhs = NULL;
- args->rhs_lua = LUA_NOREF;
- }
- mp->m_keylen = (int)STRLEN(mp->m_keys);
- mp->m_noremap = noremap;
- mp->m_nowait = args->nowait;
- mp->m_silent = args->silent;
- mp->m_mode = mode;
- mp->m_simplified = keyround1_simplified; // Notice this when porting patch 8.2.0807
- mp->m_expr = args->expr;
- mp->m_script_ctx = current_sctx;
- mp->m_script_ctx.sc_lnum += sourcing_lnum;
- nlua_set_sctx(&mp->m_script_ctx);
- mp->m_desc = NULL;
- if (args->desc != NULL) {
- mp->m_desc = xstrdup(args->desc);
- }
-
- // add the new entry in front of the abbrlist or maphash[] list
- if (is_abbrev) {
- mp->m_next = *abbr_table;
- *abbr_table = mp;
- } else {
- n = MAP_HASH(mp->m_mode, mp->m_keys[0]);
- mp->m_next = map_table[n];
- map_table[n] = mp;
- }
+ map_add(buf, map_table, abbr_table, lhs, args, noremap, mode, is_abbrev,
+ -1, // sid
+ 0, // lnum
+ keyround1_simplified);
}
theend:
@@ -861,7 +881,9 @@ theend:
/// for :cabbr mode is MODE_CMDLINE
/// ```
///
-/// @param maptype 0 for |:map|, 1 for |:unmap|, 2 for |noremap|.
+/// @param maptype MAPTYPE_MAP for |:map|
+/// MAPTYPE_UNMAP for |:unmap|
+/// MAPTYPE_NOREMAP for |noremap|.
/// @param arg C-string containing the arguments of the map/abbrev
/// command, i.e. everything except the initial `:[X][nore]map`.
/// - Cannot be a read-only string; it will be modified.
@@ -878,7 +900,7 @@ theend:
int do_map(int maptype, char_u *arg, int mode, bool is_abbrev)
{
MapArguments parsed_args;
- int result = str_to_mapargs(arg, maptype == 1, &parsed_args);
+ int result = str_to_mapargs(arg, maptype == MAPTYPE_UNMAP, &parsed_args);
switch (result) {
case 0:
break;
@@ -1230,7 +1252,7 @@ char_u *set_context_in_map_cmd(expand_T *xp, char_u *cmd, char_u *arg, bool forc
/// Find all mapping/abbreviation names that match regexp "regmatch".
/// For command line expansion of ":[un]map" and ":[un]abbrev" in all modes.
/// @return OK if matches found, FAIL otherwise.
-int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file)
+int ExpandMappings(regmatch_T *regmatch, int *num_file, char ***file)
{
mapblock_T *mp;
int hash;
@@ -1270,7 +1292,7 @@ int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file)
if (round == 1) {
count++;
} else {
- (*file)[count++] = vim_strsave(p);
+ (*file)[count++] = (char *)vim_strsave(p);
}
}
}
@@ -1293,7 +1315,7 @@ int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file)
if (round == 1) {
count++;
} else {
- (*file)[count++] = p;
+ (*file)[count++] = (char *)p;
p = NULL;
}
}
@@ -1307,22 +1329,18 @@ int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file)
}
if (round == 1) {
- *file = (char_u **)xmalloc((size_t)count * sizeof(char_u *));
+ *file = xmalloc((size_t)count * sizeof(char_u *));
}
} // for (round)
if (count > 1) {
- char_u **ptr1;
- char_u **ptr2;
- char_u **ptr3;
-
// Sort the matches
sort_strings(*file, count);
// Remove multiple entries
- ptr1 = *file;
- ptr2 = ptr1 + 1;
- ptr3 = ptr1 + count;
+ char **ptr1 = *file;
+ char **ptr2 = ptr1 + 1;
+ char **ptr3 = ptr1 + count;
while (ptr2 < ptr3) {
if (STRCMP(*ptr1, *ptr2)) {
@@ -1517,12 +1535,8 @@ 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;
- int save_msg_col;
- int save_msg_row;
// Remove escaping of K_SPECIAL, because "str" is in a format to be used as
// typeahead.
@@ -1536,9 +1550,9 @@ char_u *eval_map_expr(mapblock_T *mp, int c)
textlock++;
ex_normal_lock++;
set_vim_var_char(c); // set v:char to the typed character
- save_cursor = curwin->w_cursor;
- save_msg_col = msg_col;
- save_msg_row = msg_row;
+ const pos_T save_cursor = curwin->w_cursor;
+ const int save_msg_col = msg_col;
+ const int save_msg_row = msg_row;
if (mp->m_luaref != LUA_NOREF) {
Error err = ERROR_INIT;
Array args = ARRAY_DICT_INIT;
@@ -1564,8 +1578,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;
@@ -1612,7 +1633,7 @@ int makemap(FILE *fd, buf_T *buf)
continue;
}
- // skip lua mappings and mappings that contain a <SNR> (script-local thing),
+ // skip Lua mappings and mappings that contain a <SNR> (script-local thing),
// they probably don't work when loaded again
if (mp->m_luaref != LUA_NOREF) {
continue;
@@ -1973,9 +1994,9 @@ void f_hasmapto(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// @param mp The maphash that contains the mapping information
/// @param buffer_value The "buffer" value
/// @param compatible True for compatible with old maparg() dict
-static void mapblock_fill_dict(dict_T *const dict, const mapblock_T *const mp, long buffer_value,
- bool compatible)
- FUNC_ATTR_NONNULL_ALL
+static void mapblock_fill_dict(dict_T *const dict, const mapblock_T *const mp,
+ const char *lhsrawalt, long buffer_value, bool compatible)
+ FUNC_ATTR_NONNULL_ARG(1, 2)
{
char *const lhs = str2special_save((const char *)mp->m_keys,
compatible, !compatible);
@@ -2007,6 +2028,11 @@ static void mapblock_fill_dict(dict_T *const dict, const mapblock_T *const mp, l
tv_dict_add_allocated_str(dict, S_LEN("desc"), xstrdup(mp->m_desc));
}
tv_dict_add_allocated_str(dict, S_LEN("lhs"), lhs);
+ tv_dict_add_str(dict, S_LEN("lhsraw"), (const char *)mp->m_keys);
+ if (lhsrawalt != NULL) {
+ // Also add the value for the simplified entry.
+ tv_dict_add_str(dict, S_LEN("lhsrawalt"), lhsrawalt);
+ }
tv_dict_add_nr(dict, S_LEN("noremap"), noremap_value);
tv_dict_add_nr(dict, S_LEN("script"), mp->m_noremap == REMAP_SCRIPT ? 1 : 0);
tv_dict_add_nr(dict, S_LEN("expr"), mp->m_expr ? 1 : 0);
@@ -2015,23 +2041,14 @@ 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);
}
static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
{
- char *keys_buf = NULL;
- char_u *alt_keys_buf = NULL;
- bool did_simplify = false;
- char_u *rhs;
- LuaRef rhs_lua;
- int mode;
- bool abbr = false;
- bool get_dict = false;
- mapblock_T *mp;
- int buffer_local;
- int flags = REPTERM_FROM_PART | REPTERM_DO_LT;
-
// Return empty string for failure.
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
@@ -2041,8 +2058,11 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
return;
}
- char buf[NUMBUFLEN];
const char *which;
+ char buf[NUMBUFLEN];
+ bool abbr = false;
+ bool get_dict = false;
+
if (argvars[1].v_type != VAR_UNKNOWN) {
which = tv_get_string_buf_chk(&argvars[1], buf);
if (argvars[2].v_type != VAR_UNKNOWN) {
@@ -2058,13 +2078,19 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
return;
}
- mode = get_map_mode((char **)&which, 0);
+ char *keys_buf = NULL;
+ char_u *alt_keys_buf = NULL;
+ bool did_simplify = false;
+ const int flags = REPTERM_FROM_PART | REPTERM_DO_LT;
+ const int mode = get_map_mode((char **)&which, 0);
char_u *keys_simplified
- = (char_u *)replace_termcodes(keys,
- STRLEN(keys), &keys_buf, flags, &did_simplify,
+ = (char_u *)replace_termcodes(keys, STRLEN(keys), &keys_buf, flags, &did_simplify,
CPO_TO_CPO_FLAGS);
- rhs = check_map(keys_simplified, mode, exact, false, abbr, &mp, &buffer_local, &rhs_lua);
+ mapblock_T *mp = NULL;
+ int buffer_local;
+ LuaRef rhs_lua;
+ char_u *rhs = check_map(keys_simplified, mode, exact, false, abbr, &mp, &buffer_local, &rhs_lua);
if (did_simplify) {
// When the lhs is being simplified the not-simplified keys are
// preferred for printing, like in do_map().
@@ -2093,7 +2119,8 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
tv_dict_alloc_ret(rettv);
if (mp != NULL && (rhs != NULL || rhs_lua != LUA_NOREF)) {
// Return a dictionary.
- mapblock_fill_dict(rettv->vval.v_dict, mp, buffer_local, true);
+ mapblock_fill_dict(rettv->vval.v_dict, mp, did_simplify ? (char *)keys_simplified : NULL,
+ buffer_local, true);
}
}
@@ -2101,6 +2128,74 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
xfree(alt_keys_buf);
}
+/// "mapset()" function
+void f_mapset(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ char buf[NUMBUFLEN];
+ const char *which = tv_get_string_buf_chk(&argvars[0], buf);
+ if (which == NULL) {
+ return;
+ }
+ const int mode = get_map_mode((char **)&which, 0);
+ const bool is_abbr = tv_get_number(&argvars[1]) != 0;
+
+ if (argvars[2].v_type != VAR_DICT) {
+ emsg(_(e_dictreq));
+ return;
+ }
+ dict_T *d = argvars[2].vval.v_dict;
+
+ // Get the values in the same order as above in get_maparg().
+ char *lhs = tv_dict_get_string(d, "lhs", false);
+ char *lhsraw = tv_dict_get_string(d, "lhsraw", false);
+ char *lhsrawalt = tv_dict_get_string(d, "lhsrawalt", false);
+ char *rhs = tv_dict_get_string(d, "rhs", false);
+ if (lhs == NULL || lhsraw == NULL || rhs == NULL) {
+ emsg(_("E460: entries missing in mapset() dict argument"));
+ return;
+ }
+ char *orig_rhs = rhs;
+ char *arg_buf = NULL;
+ rhs = replace_termcodes(rhs, STRLEN(rhs), &arg_buf, REPTERM_DO_LT, NULL, CPO_TO_CPO_FLAGS);
+
+ int noremap = tv_dict_get_number(d, "noremap") ? REMAP_NONE : 0;
+ if (tv_dict_get_number(d, "script") != 0) {
+ noremap = REMAP_SCRIPT;
+ }
+ MapArguments args = { // TODO(zeertzjq): support restoring "callback"?
+ .rhs = (char_u *)rhs,
+ .rhs_lua = LUA_NOREF,
+ .orig_rhs = vim_strsave((char_u *)orig_rhs),
+ .expr = tv_dict_get_number(d, "expr") != 0,
+ .silent = tv_dict_get_number(d, "silent") != 0,
+ .nowait = tv_dict_get_number(d, "nowait") != 0,
+ .replace_keycodes = tv_dict_get_number(d, "replace_keycodes") != 0,
+ .desc = tv_dict_get_string(d, "desc", false),
+ };
+ scid_T sid = (scid_T)tv_dict_get_number(d, "sid");
+ linenr_T lnum = (linenr_T)tv_dict_get_number(d, "lnum");
+ bool buffer = tv_dict_get_number(d, "buffer") != 0;
+ // mode from the dict is not used
+
+ mapblock_T **map_table = buffer ? curbuf->b_maphash : maphash;
+ mapblock_T **abbr_table = buffer ? &curbuf->b_first_abbr : &first_abbr;
+
+ // Delete any existing mapping for this lhs and mode.
+ MapArguments unmap_args = MAP_ARGUMENTS_INIT;
+ set_maparg_lhs_rhs(lhs, strlen(lhs), rhs, strlen(rhs), LUA_NOREF, 0, &unmap_args);
+ unmap_args.buffer = buffer;
+ buf_do_map(MAPTYPE_UNMAP, &unmap_args, mode, false, curbuf);
+ xfree(unmap_args.rhs);
+ xfree(unmap_args.orig_rhs);
+
+ if (lhsrawalt != NULL) {
+ map_add(curbuf, map_table, abbr_table, (char_u *)lhsrawalt, &args, noremap, mode, is_abbr,
+ sid, lnum, true);
+ }
+ map_add(curbuf, map_table, abbr_table, (char_u *)lhsraw, &args, noremap, mode, is_abbr,
+ sid, lnum, false);
+}
+
/// "maparg()" function
void f_maparg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -2123,11 +2218,11 @@ void f_mapcheck(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// @param buffer If true, make a buffer-local mapping for curbuf
void add_map(char *lhs, char *rhs, int mode, bool buffer)
{
- MapArguments args = { 0 };
+ MapArguments args = MAP_ARGUMENTS_INIT;
set_maparg_lhs_rhs(lhs, strlen(lhs), rhs, strlen(rhs), LUA_NOREF, 0, &args);
args.buffer = buffer;
- buf_do_map(2, &args, mode, false, curbuf);
+ buf_do_map(MAPTYPE_NOREMAP, &args, mode, false, curbuf);
xfree(args.rhs);
xfree(args.orig_rhs);
}
@@ -2307,7 +2402,8 @@ static void do_exmap(exarg_T *eap, int isabbrev)
char *cmdp = eap->cmd;
mode = get_map_mode(&cmdp, eap->forceit || isabbrev);
- switch (do_map((*cmdp == 'n') ? 2 : (*cmdp == 'u'),
+ switch (do_map((*cmdp == 'n') ? MAPTYPE_NOREMAP
+ : (*cmdp == 'u') ? MAPTYPE_UNMAP : MAPTYPE_MAP,
(char_u *)eap->arg, mode, isabbrev)) {
case 1:
emsg(_(e_invarg));
@@ -2396,10 +2492,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)) {
@@ -2461,11 +2563,11 @@ void modify_keymap(uint64_t channel_id, Buffer buffer, bool is_unmap, String mod
}
// buf_do_map() reads noremap/unmap as its own argument.
- int maptype_val = 0;
+ int maptype_val = MAPTYPE_MAP;
if (is_unmap) {
- maptype_val = 1;
+ maptype_val = MAPTYPE_UNMAP;
} else if (is_noremap) {
- maptype_val = 2;
+ maptype_val = MAPTYPE_NOREMAP;
}
switch (buf_do_map(maptype_val, &parsed_args, mode_val, 0, target_buf)) {
@@ -2499,7 +2601,7 @@ fail_and_free:
///
/// @param mode The abbreviation for the mode
/// @param buf The buffer to get the mapping array. NULL for global
-/// @param from_lua Whether it is called from internal lua api.
+/// @param from_lua Whether it is called from internal Lua api.
/// @returns Array of maparg()-like dictionaries describing mappings
ArrayOf(Dictionary) keymap_array(String mode, buf_T *buf, bool from_lua)
{
@@ -2523,7 +2625,7 @@ ArrayOf(Dictionary) keymap_array(String mode, buf_T *buf, bool from_lua)
}
// Check for correct mode
if (int_mode & current_maphash->m_mode) {
- mapblock_fill_dict(dict, current_maphash, buffer_value, false);
+ mapblock_fill_dict(dict, current_maphash, NULL, buffer_value, false);
Object api_dict = vim_to_object((typval_T[]) { { .v_type = VAR_DICT,
.vval.v_dict = dict } });
if (from_lua) {