aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/mapping.c56
-rw-r--r--test/functional/api/keymap_spec.lua20
2 files changed, 62 insertions, 14 deletions
diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c
index 3dc66f7dba..36369e1e57 100644
--- a/src/nvim/mapping.c
+++ b/src/nvim/mapping.c
@@ -681,12 +681,7 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
if ((mp->m_mode & mode) != 0
&& mp->m_keylen == len
&& strncmp(mp->m_keys, lhs, (size_t)len) == 0) {
- if (is_abbrev) {
- semsg(_(e_global_abbreviation_already_exists_for_str), mp->m_keys);
- } else {
- semsg(_(e_global_mapping_already_exists_for_str), mp->m_keys);
- }
- retval = 5;
+ retval = 6;
goto theend;
}
}
@@ -799,11 +794,6 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
did_it = true;
break;
} else if (args->unique) {
- if (is_abbrev) {
- semsg(_(e_abbreviation_already_exists_for_str), p);
- } else {
- semsg(_(e_mapping_already_exists_for_str), p);
- }
retval = 5;
goto theend;
} else {
@@ -962,6 +952,7 @@ theend:
/// - 2 for no match
/// - 4 for out of mem (deprecated, WON'T HAPPEN)
/// - 5 for entry not unique
+/// - 6 for buflocal unique entry conflicts with global entry
///
int do_map(int maptype, char *arg, int mode, bool is_abbrev)
{
@@ -2637,16 +2628,47 @@ static void do_exmap(exarg_T *eap, int isabbrev)
char *cmdp = eap->cmd;
int mode = get_map_mode(&cmdp, eap->forceit || isabbrev);
- switch (do_map((*cmdp == 'n') ? MAPTYPE_NOREMAP
- : (*cmdp == 'u') ? MAPTYPE_UNMAP : MAPTYPE_MAP,
- eap->arg, mode, isabbrev)) {
+ int maptype;
+ if (*cmdp == 'n') {
+ maptype = MAPTYPE_NOREMAP;
+ } else if (*cmdp == 'u') {
+ maptype = MAPTYPE_UNMAP;
+ } else {
+ maptype = MAPTYPE_MAP;
+ }
+ MapArguments parsed_args;
+ int result = str_to_mapargs(eap->arg, maptype == MAPTYPE_UNMAP, &parsed_args);
+ switch (result) {
+ case 0:
+ break;
+ case 1:
+ emsg(_(e_invarg));
+ goto free_rhs;
+ break;
+ default:
+ assert(false && "Unknown return code from str_to_mapargs!");
+ goto free_rhs;
+ }
+ switch (buf_do_map(maptype, &parsed_args, mode, isabbrev, curbuf)) {
case 1:
emsg(_(e_invarg));
break;
case 2:
emsg(isabbrev ? _(e_noabbr) : _(e_nomap));
break;
+ case 5:
+ semsg(isabbrev ? _(e_abbreviation_already_exists_for_str)
+ : _(e_mapping_already_exists_for_str),
+ parsed_args.lhs);
+ break;
+ case 6:
+ semsg(isabbrev ? _(e_global_abbreviation_already_exists_for_str)
+ : _(e_global_mapping_already_exists_for_str),
+ parsed_args.lhs);
}
+free_rhs:
+ xfree(parsed_args.rhs);
+ xfree(parsed_args.orig_rhs);
}
/// ":abbreviate" and friends.
@@ -2808,6 +2830,12 @@ void modify_keymap(uint64_t channel_id, Buffer buffer, bool is_unmap, String mod
is_abbrev ? e_abbreviation_already_exists_for_str
: e_mapping_already_exists_for_str, lhs.data);
goto fail_and_free;
+ break;
+ case 6:
+ api_set_error(err, kErrorTypeException,
+ is_abbrev ? e_global_abbreviation_already_exists_for_str
+ : e_global_mapping_already_exists_for_str, lhs.data);
+ goto fail_and_free;
default:
assert(false && "Unrecognized return code!");
goto fail_and_free;
diff --git a/test/functional/api/keymap_spec.lua b/test/functional/api/keymap_spec.lua
index acaccee4e5..2c44905274 100644
--- a/test/functional/api/keymap_spec.lua
+++ b/test/functional/api/keymap_spec.lua
@@ -1465,4 +1465,24 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function()
eq(1, exec_lua [[return GlobalCount]])
eq('\nNo mapping found', n.exec_capture('nmap <C-I>'))
end)
+
+ it('does not overwrite in <unique> mappings', function()
+ api.nvim_buf_set_keymap(0, 'i', 'lhs', 'rhs', {})
+ eq(
+ 'E227: Mapping already exists for lhs',
+ pcall_err(api.nvim_buf_set_keymap, 0, 'i', 'lhs', 'rhs', { unique = true })
+ )
+
+ api.nvim_buf_set_keymap(0, 'ia', 'lhs2', 'rhs2', {})
+ eq(
+ 'E226: Abbreviation already exists for lhs2',
+ pcall_err(api.nvim_buf_set_keymap, 0, 'ia', 'lhs2', 'rhs2', { unique = true })
+ )
+
+ api.nvim_set_keymap('n', 'lhs', 'rhs', {})
+ eq(
+ 'E225: Global mapping already exists for lhs',
+ pcall_err(api.nvim_buf_set_keymap, 0, 'n', 'lhs', 'rhs', { unique = true })
+ )
+ end)
end)