]> granicus.if.org Git - vim/commitdiff
patch 8.2.0815: maparg() does not provide enough information for mapset() v8.2.0815
authorBram Moolenaar <Bram@vim.org>
Sun, 24 May 2020 11:10:18 +0000 (13:10 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 24 May 2020 11:10:18 +0000 (13:10 +0200)
Problem:    maparg() does not provide enough information for mapset().
Solution:   Add "lhsraw" and "lhsrawalt" items.  Drop "simplified"

runtime/doc/eval.txt
src/map.c
src/testdir/test_maparg.vim
src/version.c

index afda3505b1e5778c18a5d73bb8c2b43560efba70..1e0760fea278f636717603a135c56be259467316 100644 (file)
@@ -2586,7 +2586,7 @@ maparg({name} [, {mode} [, {abbr} [, {dict}]]])
                                        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} [, {dict}]]])                  *maparg()*
                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} [, {dict}]]])                   *maparg()*
                  "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}]])                  *mapcheck()*
                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})                           *mapset()*
                        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
index 4a9849d334ca5ac918e1b6bdfea1a3eb76ad20f3..6c926336c1c3c50cf511d25dcf1573fdd76c1895 100644 (file)
--- 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 *rettv, int exact)
 
     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 *rettv, int exact)
        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 *rettv, int exact)
        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 *rettv, int exact)
     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 *rettv UNUSED)
     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 *rettv UNUSED)
     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 *rettv UNUSED)
 
     // 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;
@@ -2324,7 +2342,6 @@ f_mapset(typval_T *argvars, typval_T *rettv UNUSED)
     }
     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 *rettv UNUSED)
     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);
 }
index b971be46f0595382be5013a26e7ed26d0858270f..81e057adcae14f6c1ced3a0cff252493cdd52cbb 100644 (file)
@@ -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\16<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
index 34852c3699bfff88c64e2ba617ca9df915695967..543f5a8eea21276681d7a21d07f5c2afd7285941 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    815,
 /**/
     814,
 /**/