Problem: maparg() does not provide enough information for mapset().
Solution: Add "lhsraw" and "lhsrawalt" items. Drop "simplified"
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}
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.
"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()|.
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: >
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
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;
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)
{
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
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);
}
/*
void
f_mapset(typval_T *argvars, typval_T *rettv UNUSED)
{
- char_u *keys;
char_u *keys_buf = NULL;
char_u *which;
int mode;
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;
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);
// Get the values in the same order as above in get_maparg().
lhs = dict_get_string(d, (char_u *)"lhs", FALSE);
- if (lhs == NULL)
- {
- emsg(_("E99: lhs entry missing in mapset() dict argument"));
- return;
- }
+ 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 (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;
}
orig_rhs = rhs;
}
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);
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);
}
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
call assert_equal('one<CR>two', getline(1))
iunmap K
- let &cpo = cpo_save
" Test literal <CR> using CTRL-V
inoremap K one\16<CR>two
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
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 815,
/**/
814,
/**/