0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

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"
This commit is contained in:
Bram Moolenaar 2020-05-24 13:10:18 +02:00
parent 3718427ba3
commit 9c65253fe7
4 changed files with 92 additions and 35 deletions

View File

@ -2586,7 +2586,7 @@ maparg({name} [, {mode} [, {abbr} [, {dict}]]])
rhs of mapping {name} in mode {mode} rhs of mapping {name} in mode {mode}
mapcheck({name} [, {mode} [, {abbr}]]) mapcheck({name} [, {mode} [, {abbr}]])
String check for mappings matching {name} String check for mappings matching {name}
mapset({name}, {mode}, {abbr}, {dict} mapset({mode}, {abbr}, {dict})
none restore mapping from |maparg()| result none restore mapping from |maparg()| result
match({expr}, {pat} [, {start} [, {count}]]) match({expr}, {pat} [, {start} [, {count}]])
Number position where {pat} matches in {expr} Number position where {pat} matches in {expr}
@ -6829,7 +6829,10 @@ maparg({name} [, {mode} [, {abbr} [, {dict}]]]) *maparg()*
When {dict} is there and it is |TRUE| return a dictionary When {dict} is there and it is |TRUE| return a dictionary
containing all the information of the mapping with the containing all the information of the mapping with the
following items: 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. "rhs" The {rhs} of the mapping as typed.
"silent" 1 for a |:map-silent| mapping, else 0. "silent" 1 for a |:map-silent| mapping, else 0.
"noremap" 1 if the {rhs} of the mapping is not remappable. "noremap" 1 if the {rhs} of the mapping is not remappable.
@ -6847,7 +6850,6 @@ maparg({name} [, {mode} [, {abbr} [, {dict}]]]) *maparg()*
"lnum" The line number in "sid", zero if unknown. "lnum" The line number in "sid", zero if unknown.
"nowait" Do not wait for other, longer mappings. "nowait" Do not wait for other, longer mappings.
(|:map-<nowait>|). (|:map-<nowait>|).
"simplified"
The dictionary can be used to restore a mapping with The dictionary can be used to restore a mapping with
|mapset()|. |mapset()|.
@ -6897,10 +6899,11 @@ mapcheck({name} [, {mode} [, {abbr}]]) *mapcheck()*
Can also be used as a |method|: > Can also be used as a |method|: >
GetKey()->mapcheck('n') GetKey()->mapcheck('n')
mapset({mode}, {abbr}, {dict}) *mapset()* mapset({mode}, {abbr}, {dict}) *mapset()*
Restore a mapping from a dictionary returned by |maparg()|. Restore a mapping from a dictionary returned by |maparg()|.
{name}, {mode} and {abbr} should be the same as for the call {mode} and {abbr} should be the same as for the call to
to |maparg()|. |maparg()|. *E460*
{mode} is used to define the mode in which the mapping is set, {mode} is used to define the mode in which the mapping is set,
not the "mode" entry in {dict}. not the "mode" entry in {dict}.
Example for saving and restoring a mapping: > Example for saving and restoring a mapping: >
@ -6908,7 +6911,11 @@ mapset({mode}, {abbr}, {dict}) *mapset()*
nnoremap K somethingelse nnoremap K somethingelse
... ...
call mapset('n', 0, save_map) 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()* match({expr}, {pat} [, {start} [, {count}]]) *match()*
When {expr} is a |List| then this returns the index of the When {expr} is a |List| then this returns the index of the
first item where {pat} matches. Each item is used as a first item where {pat} matches. Each item is used as a

View File

@ -2176,15 +2176,20 @@ check_map(
get_maparg(typval_T *argvars, typval_T *rettv, int exact) get_maparg(typval_T *argvars, typval_T *rettv, int exact)
{ {
char_u *keys; char_u *keys;
char_u *keys_simplified;
char_u *which; char_u *which;
char_u buf[NUMBUFLEN]; char_u buf[NUMBUFLEN];
char_u *keys_buf = NULL; char_u *keys_buf = NULL;
char_u *alt_keys_buf = NULL;
int did_simplify = FALSE;
char_u *rhs; char_u *rhs;
int mode; int mode;
int abbr = FALSE; int abbr = FALSE;
int get_dict = FALSE; int get_dict = FALSE;
mapblock_T *mp; mapblock_T *mp;
mapblock_T *mp_simplified;
int buffer_local; int buffer_local;
int flags = REPTERM_FROM_PART | REPTERM_DO_LT;
// return empty string for failure // return empty string for failure
rettv->v_type = VAR_STRING; rettv->v_type = VAR_STRING;
@ -2211,10 +2216,20 @@ get_maparg(typval_T *argvars, typval_T *rettv, int exact)
mode = get_map_mode(&which, 0); mode = get_map_mode(&which, 0);
keys = replace_termcodes(keys, &keys_buf, keys_simplified = replace_termcodes(keys, &keys_buf, flags, &did_simplify);
REPTERM_FROM_PART | REPTERM_DO_LT, NULL); rhs = check_map(keys_simplified, mode, exact, FALSE, abbr,
rhs = check_map(keys, mode, exact, FALSE, abbr, &mp, &buffer_local); &mp, &buffer_local);
vim_free(keys_buf); 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) if (!get_dict)
{ {
@ -2236,6 +2251,11 @@ get_maparg(typval_T *argvars, typval_T *rettv, int exact)
dict_T *dict = rettv->vval.v_dict; dict_T *dict = rettv->vval.v_dict;
dict_add_string(dict, "lhs", lhs); 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_string(dict, "rhs", mp->m_orig_str);
dict_add_number(dict, "noremap", mp->m_noremap ? 1L : 0L); dict_add_number(dict, "noremap", mp->m_noremap ? 1L : 0L);
dict_add_number(dict, "script", mp->m_noremap == REMAP_SCRIPT dict_add_number(dict, "script", mp->m_noremap == REMAP_SCRIPT
@ -2247,11 +2267,12 @@ get_maparg(typval_T *argvars, typval_T *rettv, int exact)
dict_add_number(dict, "buffer", (long)buffer_local); dict_add_number(dict, "buffer", (long)buffer_local);
dict_add_number(dict, "nowait", mp->m_nowait ? 1L : 0L); dict_add_number(dict, "nowait", mp->m_nowait ? 1L : 0L);
dict_add_string(dict, "mode", mapmode); dict_add_string(dict, "mode", mapmode);
dict_add_number(dict, "simplified", mp->m_simplified);
vim_free(lhs);
vim_free(mapmode); vim_free(mapmode);
} }
vim_free(keys_buf);
vim_free(alt_keys_buf);
} }
/* /*
@ -2260,7 +2281,6 @@ get_maparg(typval_T *argvars, typval_T *rettv, int exact)
void void
f_mapset(typval_T *argvars, typval_T *rettv UNUSED) f_mapset(typval_T *argvars, typval_T *rettv UNUSED)
{ {
char_u *keys;
char_u *keys_buf = NULL; char_u *keys_buf = NULL;
char_u *which; char_u *which;
int mode; int mode;
@ -2268,6 +2288,8 @@ f_mapset(typval_T *argvars, typval_T *rettv UNUSED)
int is_abbr; int is_abbr;
dict_T *d; dict_T *d;
char_u *lhs; char_u *lhs;
char_u *lhsraw;
char_u *lhsrawalt;
char_u *rhs; char_u *rhs;
char_u *orig_rhs; char_u *orig_rhs;
char_u *arg_buf = NULL; char_u *arg_buf = NULL;
@ -2279,7 +2301,6 @@ f_mapset(typval_T *argvars, typval_T *rettv UNUSED)
mapblock_T **map_table = maphash; mapblock_T **map_table = maphash;
mapblock_T **abbr_table = &first_abbr; mapblock_T **abbr_table = &first_abbr;
int nowait; int nowait;
int simplified;
char_u *arg; char_u *arg;
which = tv_get_string_buf_chk(&argvars[0], buf); which = tv_get_string_buf_chk(&argvars[0], buf);
@ -2295,15 +2316,12 @@ f_mapset(typval_T *argvars, typval_T *rettv UNUSED)
// Get the values in the same order as above in get_maparg(). // Get the values in the same order as above in get_maparg().
lhs = dict_get_string(d, (char_u *)"lhs", FALSE); 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);
emsg(_("E99: lhs entry missing in mapset() dict argument"));
return;
}
rhs = dict_get_string(d, (char_u *)"rhs", FALSE); rhs = dict_get_string(d, (char_u *)"rhs", FALSE);
if (rhs == NULL) if (lhs == NULL || lhsraw == NULL || rhs == NULL)
{ {
emsg(_("E99: rhs entry missing in mapset() dict argument")); emsg(_("E460: entries missing in mapset() dict argument"));
return; return;
} }
orig_rhs = rhs; orig_rhs = rhs;
@ -2324,7 +2342,6 @@ f_mapset(typval_T *argvars, typval_T *rettv UNUSED)
} }
nowait = dict_get_number(d, (char_u *)"nowait") != 0; nowait = dict_get_number(d, (char_u *)"nowait") != 0;
// mode from the dict is not used // 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. // Delete any existing mapping for this lhs and mode.
arg = vim_strsave(lhs); arg = vim_strsave(lhs);
@ -2333,10 +2350,11 @@ f_mapset(typval_T *argvars, typval_T *rettv UNUSED)
do_map(1, arg, mode, is_abbr); do_map(1, arg, mode, is_abbr);
vim_free(arg); vim_free(arg);
keys = replace_termcodes(lhs, &keys_buf, (void)map_add(map_table, abbr_table, lhsraw, rhs, orig_rhs, noremap,
REPTERM_FROM_PART | REPTERM_DO_LT, NULL); nowait, silent, mode, is_abbr, expr, sid, lnum, 0);
(void)map_add(map_table, abbr_table, keys, rhs, orig_rhs, noremap, if (lhsrawalt != NULL)
nowait, silent, mode, is_abbr, expr, sid, lnum, simplified); (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(keys_buf);
vim_free(arg_buf); vim_free(arg_buf);
} }

View File

@ -17,24 +17,28 @@ func Test_maparg()
vnoremap <script> <buffer> <expr> <silent> bar isbar vnoremap <script> <buffer> <expr> <silent> bar isbar
call assert_equal("is<F4>foo", maparg('foo<C-V>')) call assert_equal("is<F4>foo", maparg('foo<C-V>'))
call assert_equal({'silent': 0, 'noremap': 0, 'script': 0, 'lhs': '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, \ '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)) \ 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, \ 'nowait': 0, 'expr': 1, 'sid': sid, 'lnum': lnum + 2,
\ 'simplified': 0, 'rhs': 'isbar', 'buffer': 1}, \ 'rhs': 'isbar', 'buffer': 1},
\ 'bar'->maparg('', 0, 1)) \ 'bar'->maparg('', 0, 1))
let lnum = expand('<sflnum>') let lnum = expand('<sflnum>')
map <buffer> <nowait> foo bar 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', \ 'nowait': 1, 'expr': 0, 'sid': sid, 'lnum': lnum + 1, 'rhs': 'bar',
\ 'simplified': 0, 'buffer': 1}, \ 'buffer': 1},
\ maparg('foo', '', 0, 1)) \ maparg('foo', '', 0, 1))
let lnum = expand('<sflnum>') let lnum = expand('<sflnum>')
tmap baz foo 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', \ 'nowait': 0, 'expr': 0, 'sid': sid, 'lnum': lnum + 1, 'rhs': 'foo',
\ 'simplified': 0, 'buffer': 0}, \ 'buffer': 0},
\ maparg('baz', 't', 0, 1)) \ maparg('baz', 't', 0, 1))
map abc x<char-114>x map abc x<char-114>x
@ -199,7 +203,6 @@ func Test_mapset()
call assert_equal('one<CR>two', getline(1)) call assert_equal('one<CR>two', getline(1))
iunmap K iunmap K
let &cpo = cpo_save
" Test literal <CR> using CTRL-V " Test literal <CR> using CTRL-V
inoremap K one<CR>two inoremap K one<CR>two
@ -221,8 +224,35 @@ func Test_mapset()
iunmap K iunmap K
let &cpo = cpo_save let &cpo = cpo_save
bwipe! bwipe!
endfunc 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 " vim: shiftwidth=2 sts=2 expandtab

View File

@ -746,6 +746,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
815,
/**/ /**/
814, 814,
/**/ /**/