aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortstsrt <41282711+tstsrt@users.noreply.github.com>2025-04-01 12:30:00 +0000
committerGitHub <noreply@github.com>2025-04-01 05:30:00 -0700
commitec18ebcb417bb9f2afc81d247db6993eaa48701f (patch)
treee48e5bedb7971c97589741705db18873b4fed2bd /src
parent0e7479bb7637a21121b990cc960262a0d60196da (diff)
downloadrneovim-ec18ebcb417bb9f2afc81d247db6993eaa48701f.tar.gz
rneovim-ec18ebcb417bb9f2afc81d247db6993eaa48701f.tar.bz2
rneovim-ec18ebcb417bb9f2afc81d247db6993eaa48701f.zip
fix(api): nvim_set_keymap() throws error even in pcall() #33228
Problem: When `nvim_set_keymap` tries to overwrite a `<unique>` mapping, it throws an error even when called in `pcall`. Solution: src/nvim/mapping.c:buf_do_map no longer calls `semsg`. Its callers now decide whether to ignore the error, or use `semsg` (not caught)/`api_set_error` (caught by `pcall`).
Diffstat (limited to 'src')
-rw-r--r--src/nvim/mapping.c56
1 files changed, 42 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;