diff options
author | tstsrt <41282711+tstsrt@users.noreply.github.com> | 2025-04-01 12:30:00 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-01 05:30:00 -0700 |
commit | ec18ebcb417bb9f2afc81d247db6993eaa48701f (patch) | |
tree | e48e5bedb7971c97589741705db18873b4fed2bd /src/nvim/mapping.c | |
parent | 0e7479bb7637a21121b990cc960262a0d60196da (diff) | |
download | rneovim-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/nvim/mapping.c')
-rw-r--r-- | src/nvim/mapping.c | 56 |
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; |