Mercurial > vim
changeset 20522:729853a754ea v8.2.0815
patch 8.2.0815: maparg() does not provide enough information for mapset()
Commit: https://github.com/vim/vim/commit/9c65253fe702ea010afec11aa971acd542c35de2
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun May 24 13:10:18 2020 +0200
patch 8.2.0815: maparg() does not provide enough information for mapset()
Problem: maparg() does not provide enough information for mapset().
Solution: Add "lhsraw" and "lhsrawalt" items. Drop "simplified"
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 24 May 2020 13:15:04 +0200 |
parents | fb1d6f728a72 |
children | 775e169d4cfc |
files | runtime/doc/eval.txt src/map.c src/testdir/test_maparg.vim src/version.c |
diffstat | 4 files changed, 93 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2586,7 +2586,7 @@ maparg({name} [, {mode} [, {abbr} [, {di rhs of mapping {name} in mode {mode} mapcheck({name} [, {mode} [, {abbr}]]) String check for mappings matching {name} -mapset({name}, {mode}, {abbr}, {dict} +mapset({mode}, {abbr}, {dict}) none restore mapping from |maparg()| result match({expr}, {pat} [, {start} [, {count}]]) Number position where {pat} matches in {expr} @@ -6829,7 +6829,10 @@ maparg({name} [, {mode} [, {abbr} [, {di When {dict} is there and it is |TRUE| return a dictionary containing all the information of the mapping with the following items: - "lhs" The {lhs} of the mapping. + "lhs" The {lhs} of the mapping as it would be typed + "lhsraw" The {lhs} of the mapping as raw bytes + "lhsrawalt" The {lhs} of the mapping as raw bytes, alternate + form, only present when it differs from "lhsraw" "rhs" The {rhs} of the mapping as typed. "silent" 1 for a |:map-silent| mapping, else 0. "noremap" 1 if the {rhs} of the mapping is not remappable. @@ -6847,7 +6850,6 @@ maparg({name} [, {mode} [, {abbr} [, {di "lnum" The line number in "sid", zero if unknown. "nowait" Do not wait for other, longer mappings. (|:map-<nowait>|). - "simplified" The dictionary can be used to restore a mapping with |mapset()|. @@ -6897,10 +6899,11 @@ mapcheck({name} [, {mode} [, {abbr}]]) Can also be used as a |method|: > GetKey()->mapcheck('n') + mapset({mode}, {abbr}, {dict}) *mapset()* Restore a mapping from a dictionary returned by |maparg()|. - {name}, {mode} and {abbr} should be the same as for the call - to |maparg()|. + {mode} and {abbr} should be the same as for the call to + |maparg()|. *E460* {mode} is used to define the mode in which the mapping is set, not the "mode" entry in {dict}. Example for saving and restoring a mapping: > @@ -6908,7 +6911,11 @@ mapset({mode}, {abbr}, {dict}) *mapse nnoremap K somethingelse ... call mapset('n', 0, save_map) -< +< Note that if you are going to replace a map in several modes, + e.g. with `:map!`, you need to save the mapping for all of + them, since they can differe. + + match({expr}, {pat} [, {start} [, {count}]]) *match()* When {expr} is a |List| then this returns the index of the first item where {pat} matches. Each item is used as a
--- a/src/map.c +++ b/src/map.c @@ -2176,15 +2176,20 @@ check_map( get_maparg(typval_T *argvars, typval_T *rettv, int exact) { char_u *keys; + char_u *keys_simplified; char_u *which; char_u buf[NUMBUFLEN]; char_u *keys_buf = NULL; + char_u *alt_keys_buf = NULL; + int did_simplify = FALSE; char_u *rhs; int mode; int abbr = FALSE; int get_dict = FALSE; mapblock_T *mp; + mapblock_T *mp_simplified; int buffer_local; + int flags = REPTERM_FROM_PART | REPTERM_DO_LT; // return empty string for failure rettv->v_type = VAR_STRING; @@ -2211,10 +2216,20 @@ get_maparg(typval_T *argvars, typval_T * mode = get_map_mode(&which, 0); - keys = replace_termcodes(keys, &keys_buf, - REPTERM_FROM_PART | REPTERM_DO_LT, NULL); - rhs = check_map(keys, mode, exact, FALSE, abbr, &mp, &buffer_local); - vim_free(keys_buf); + keys_simplified = replace_termcodes(keys, &keys_buf, flags, &did_simplify); + rhs = check_map(keys_simplified, mode, exact, FALSE, abbr, + &mp, &buffer_local); + if (did_simplify) + { + // When the lhs is being simplified the not-simplified keys are + // preferred for priting, like in do_map(). + // The "rhs" and "buffer_local" values are not expected to change. + mp_simplified = mp; + (void)replace_termcodes(keys, &alt_keys_buf, + flags | REPTERM_NO_SIMPLIFY, NULL); + rhs = check_map(alt_keys_buf, mode, exact, FALSE, abbr, &mp, + &buffer_local); + } if (!get_dict) { @@ -2236,6 +2251,11 @@ get_maparg(typval_T *argvars, typval_T * dict_T *dict = rettv->vval.v_dict; dict_add_string(dict, "lhs", lhs); + vim_free(lhs); + dict_add_string(dict, "lhsraw", mp->m_keys); + if (did_simplify) + // Also add the value for the simplified entry. + dict_add_string(dict, "lhsrawalt", mp_simplified->m_keys); dict_add_string(dict, "rhs", mp->m_orig_str); dict_add_number(dict, "noremap", mp->m_noremap ? 1L : 0L); dict_add_number(dict, "script", mp->m_noremap == REMAP_SCRIPT @@ -2247,11 +2267,12 @@ get_maparg(typval_T *argvars, typval_T * dict_add_number(dict, "buffer", (long)buffer_local); dict_add_number(dict, "nowait", mp->m_nowait ? 1L : 0L); dict_add_string(dict, "mode", mapmode); - dict_add_number(dict, "simplified", mp->m_simplified); - vim_free(lhs); vim_free(mapmode); } + + vim_free(keys_buf); + vim_free(alt_keys_buf); } /* @@ -2260,7 +2281,6 @@ get_maparg(typval_T *argvars, typval_T * void f_mapset(typval_T *argvars, typval_T *rettv UNUSED) { - char_u *keys; char_u *keys_buf = NULL; char_u *which; int mode; @@ -2268,6 +2288,8 @@ f_mapset(typval_T *argvars, typval_T *re int is_abbr; dict_T *d; char_u *lhs; + char_u *lhsraw; + char_u *lhsrawalt; char_u *rhs; char_u *orig_rhs; char_u *arg_buf = NULL; @@ -2279,7 +2301,6 @@ f_mapset(typval_T *argvars, typval_T *re mapblock_T **map_table = maphash; mapblock_T **abbr_table = &first_abbr; int nowait; - int simplified; char_u *arg; which = tv_get_string_buf_chk(&argvars[0], buf); @@ -2295,15 +2316,12 @@ f_mapset(typval_T *argvars, typval_T *re // Get the values in the same order as above in get_maparg(). lhs = dict_get_string(d, (char_u *)"lhs", FALSE); - if (lhs == NULL) + lhsraw = dict_get_string(d, (char_u *)"lhsraw", FALSE); + lhsrawalt = dict_get_string(d, (char_u *)"lhsrawalt", FALSE); + rhs = dict_get_string(d, (char_u *)"rhs", FALSE); + if (lhs == NULL || lhsraw == NULL || rhs == NULL) { - emsg(_("E99: lhs entry missing in mapset() dict argument")); - return; - } - rhs = dict_get_string(d, (char_u *)"rhs", FALSE); - if (rhs == NULL) - { - emsg(_("E99: rhs entry missing in mapset() dict argument")); + emsg(_("E460: entries missing in mapset() dict argument")); return; } orig_rhs = rhs; @@ -2324,7 +2342,6 @@ f_mapset(typval_T *argvars, typval_T *re } nowait = dict_get_number(d, (char_u *)"nowait") != 0; // mode from the dict is not used - simplified = dict_get_number(d, (char_u *)"simplified") != 0; // Delete any existing mapping for this lhs and mode. arg = vim_strsave(lhs); @@ -2333,10 +2350,11 @@ f_mapset(typval_T *argvars, typval_T *re do_map(1, arg, mode, is_abbr); vim_free(arg); - keys = replace_termcodes(lhs, &keys_buf, - REPTERM_FROM_PART | REPTERM_DO_LT, NULL); - (void)map_add(map_table, abbr_table, keys, rhs, orig_rhs, noremap, - nowait, silent, mode, is_abbr, expr, sid, lnum, simplified); + (void)map_add(map_table, abbr_table, lhsraw, rhs, orig_rhs, noremap, + nowait, silent, mode, is_abbr, expr, sid, lnum, 0); + if (lhsrawalt != NULL) + (void)map_add(map_table, abbr_table, lhsrawalt, rhs, orig_rhs, noremap, + nowait, silent, mode, is_abbr, expr, sid, lnum, 1); vim_free(keys_buf); vim_free(arg_buf); }
--- a/src/testdir/test_maparg.vim +++ b/src/testdir/test_maparg.vim @@ -17,24 +17,28 @@ func Test_maparg() vnoremap <script> <buffer> <expr> <silent> bar isbar call assert_equal("is<F4>foo", maparg('foo<C-V>')) call assert_equal({'silent': 0, 'noremap': 0, 'script': 0, 'lhs': 'foo<C-V>', + \ 'lhsraw': "foo\x80\xfc\x04V", 'lhsrawalt': "foo\x16", \ 'mode': ' ', 'nowait': 0, 'expr': 0, 'sid': sid, 'lnum': lnum + 1, - \ 'simplified': 1, 'rhs': 'is<F4>foo', 'buffer': 0}, + \ 'rhs': 'is<F4>foo', 'buffer': 0}, \ maparg('foo<C-V>', '', 0, 1)) - call assert_equal({'silent': 1, 'noremap': 1, 'script': 1, 'lhs': 'bar', 'mode': 'v', + call assert_equal({'silent': 1, 'noremap': 1, 'script': 1, 'lhs': 'bar', + \ 'lhsraw': 'bar', 'mode': 'v', \ 'nowait': 0, 'expr': 1, 'sid': sid, 'lnum': lnum + 2, - \ 'simplified': 0, 'rhs': 'isbar', 'buffer': 1}, + \ 'rhs': 'isbar', 'buffer': 1}, \ 'bar'->maparg('', 0, 1)) let lnum = expand('<sflnum>') map <buffer> <nowait> foo bar - call assert_equal({'silent': 0, 'noremap': 0, 'script': 0, 'lhs': 'foo', 'mode': ' ', + call assert_equal({'silent': 0, 'noremap': 0, 'script': 0, 'lhs': 'foo', + \ 'lhsraw': 'foo', 'mode': ' ', \ 'nowait': 1, 'expr': 0, 'sid': sid, 'lnum': lnum + 1, 'rhs': 'bar', - \ 'simplified': 0, 'buffer': 1}, + \ 'buffer': 1}, \ maparg('foo', '', 0, 1)) let lnum = expand('<sflnum>') tmap baz foo - call assert_equal({'silent': 0, 'noremap': 0, 'script': 0, 'lhs': 'baz', 'mode': 't', + call assert_equal({'silent': 0, 'noremap': 0, 'script': 0, 'lhs': 'baz', + \ 'lhsraw': 'baz', 'mode': 't', \ 'nowait': 0, 'expr': 0, 'sid': sid, 'lnum': lnum + 1, 'rhs': 'foo', - \ 'simplified': 0, 'buffer': 0}, + \ 'buffer': 0}, \ maparg('baz', 't', 0, 1)) map abc x<char-114>x @@ -199,7 +203,6 @@ func Test_mapset() call assert_equal('one<CR>two', getline(1)) iunmap K - let &cpo = cpo_save " Test literal <CR> using CTRL-V inoremap K one<CR>two @@ -221,8 +224,35 @@ func Test_mapset() iunmap K let &cpo = cpo_save - bwipe! endfunc +func Check_ctrlb_map(d, check_alt) + call assert_equal('<C-B>', a:d.lhs) + if a:check_alt + call assert_equal("\x80\xfc\x04B", a:d.lhsraw) + call assert_equal("\x02", a:d.lhsrawalt) + else + call assert_equal("\x02", a:d.lhsraw) + endif +endfunc + +func Test_map_restore() + " Test restoring map with alternate keycode + nmap <C-B> back + let d = maparg('<C-B>', 'n', 0, 1) + call Check_ctrlb_map(d, 1) + let dsimp = maparg("\x02", 'n', 0, 1) + call Check_ctrlb_map(dsimp, 0) + nunmap <C-B> + call mapset('n', 0, d) + let d = maparg('<C-B>', 'n', 0, 1) + call Check_ctrlb_map(d, 1) + let dsimp = maparg("\x02", 'n', 0, 1) + call Check_ctrlb_map(dsimp, 0) + + nunmap <C-B> + +endfunc + " vim: shiftwidth=2 sts=2 expandtab