]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.1687: mapset() not properly handling script ID v9.0.1687
authorzeertzjq <zeertzjq@outlook.com>
Fri, 11 Aug 2023 21:15:38 +0000 (23:15 +0200)
committerChristian Brabandt <cb@256bit.org>
Fri, 11 Aug 2023 21:16:10 +0000 (23:16 +0200)
Problem: mapset() not properly handling script ID
Solution: replace_termcodes() may accept a script ID

closes: #12699
closes: #12697

Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
src/clientserver.c
src/if_ole.cpp
src/map.c
src/menu.c
src/optionstr.c
src/proto/term.pro
src/term.c
src/terminal.c
src/testdir/test_map_functions.vim
src/usercmd.c
src/version.c

index 400a4ad3eb32c5394aaed56c52b17ed22ef3d1ee..cfc0ab66132684d1d66aea6acfd29b6b8cca49cb 100644 (file)
@@ -34,7 +34,7 @@ server_to_input_buf(char_u *str)
     //  The last but one parameter of replace_termcodes() is TRUE so that the
     //  <lt> sequence is recognised - needed for a real backslash.
     p_cpo = (char_u *)"Bk";
-    str = replace_termcodes(str, &ptr, REPTERM_DO_LT, NULL);
+    str = replace_termcodes(str, &ptr, 0, REPTERM_DO_LT, NULL);
     p_cpo = cpo_save;
 
     if (*ptr != NUL)   // trailing CTRL-V results in nothing
index f347387a9015c46d4023ab1d9f9cb4b514ff1a9b..d191010cd03f4b821c55e56f8a0985ea124c2ee8 100644 (file)
@@ -323,7 +323,7 @@ CVim::SendKeys(BSTR keys)
     }
 
     /* Translate key codes like <Esc> */
-    str = replace_termcodes((char_u *)buffer, &ptr, REPTERM_DO_LT, NULL);
+    str = replace_termcodes((char_u *)buffer, &ptr, 0, REPTERM_DO_LT, NULL);
 
     /* If ptr was set, then a new buffer was allocated,
      * so we can free the old one.
index 6020f63d301b5e024eb1a26ad8b05d595ba34619..5988445bd1588bb40854a1597d8cbb23628d794e 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -590,9 +590,9 @@ do_map(
 
        if (special)
            flags |= REPTERM_SPECIAL;
-       new_keys = replace_termcodes(keys, &keys_buf, flags, &did_simplify);
+       new_keys = replace_termcodes(keys, &keys_buf, 0, flags, &did_simplify);
        if (did_simplify)
-           (void)replace_termcodes(keys, &alt_keys_buf,
+           (void)replace_termcodes(keys, &alt_keys_buf, 0,
                                            flags | REPTERM_NO_SIMPLIFY, NULL);
        keys = new_keys;
     }
@@ -602,7 +602,7 @@ do_map(
        if (STRICMP(rhs, "<nop>") == 0)     // "<Nop>" means nothing
            rhs = (char_u *)"";
        else
-           rhs = replace_termcodes(rhs, &arg_buf,
+           rhs = replace_termcodes(rhs, &arg_buf, 0,
                        REPTERM_DO_LT | (special ? REPTERM_SPECIAL : 0), NULL);
     }
 
@@ -1133,7 +1133,7 @@ map_to_exists(char_u *str, char_u *modechars, int abbr)
     char_u     *buf;
     int                retval;
 
-    rhs = replace_termcodes(str, &buf, REPTERM_DO_LT, NULL);
+    rhs = replace_termcodes(str, &buf, 0, REPTERM_DO_LT, NULL);
 
     retval = map_to_exists_mode(rhs, mode_str2flags(modechars), abbr);
     vim_free(buf);
@@ -2488,14 +2488,15 @@ get_maparg(typval_T *argvars, typval_T *rettv, int exact)
 
     mode = get_map_mode(&which, 0);
 
-    keys_simplified = replace_termcodes(keys, &keys_buf, flags, &did_simplify);
+    keys_simplified = replace_termcodes(keys, &keys_buf, 0, 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 printing, like in do_map().
-       (void)replace_termcodes(keys, &alt_keys_buf,
+       (void)replace_termcodes(keys, &alt_keys_buf, 0,
                                        flags | REPTERM_NO_SIMPLIFY, NULL);
        rhs = check_map(alt_keys_buf, mode, exact, FALSE, abbr, &mp,
                                                                &buffer_local);
@@ -2579,7 +2580,8 @@ f_maplist(typval_T *argvars UNUSED, typval_T *rettv)
                did_simplify = FALSE;
 
                lhs = str2special_save(mp->m_keys, TRUE, FALSE);
-               (void)replace_termcodes(lhs, &keys_buf, flags, &did_simplify);
+               (void)replace_termcodes(lhs, &keys_buf, 0, flags,
+                                                               &did_simplify);
                vim_free(lhs);
 
                mapblock2dict(mp, d,
@@ -2758,11 +2760,6 @@ f_mapset(typval_T *argvars, typval_T *rettv UNUSED)
        return;
     }
     orig_rhs = rhs;
-    if (STRICMP(rhs, "<nop>") == 0)    // "<Nop>" means nothing
-       rhs = (char_u *)"";
-    else
-       rhs = replace_termcodes(rhs, &arg_buf,
-                                       REPTERM_DO_LT | REPTERM_SPECIAL, NULL);
 
     noremap = dict_get_number(d, "noremap") ? REMAP_NONE: 0;
     if (dict_get_number(d, "script") != 0)
@@ -2776,6 +2773,12 @@ f_mapset(typval_T *argvars, typval_T *rettv UNUSED)
     nowait = dict_get_number(d, "nowait") != 0;
     // mode from the dict is not used
 
+    if (STRICMP(rhs, "<nop>") == 0)    // "<Nop>" means nothing
+       rhs = (char_u *)"";
+    else
+       rhs = replace_termcodes(rhs, &arg_buf, sid,
+                                       REPTERM_DO_LT | REPTERM_SPECIAL, NULL);
+
     if (buffer)
     {
        map_table = curbuf->b_maphash;
index 04cd5f103c5ef7a92d9dd4372c25a467f0bb085d..e4008baab43d293cd132e15d460ed52f40c326d3 100644 (file)
@@ -394,7 +394,7 @@ ex_menu(
        else if (modes & MENU_TIP_MODE)
            map_buf = NULL;     // Menu tips are plain text.
        else
-           map_to = replace_termcodes(map_to, &map_buf,
+           map_to = replace_termcodes(map_to, &map_buf, 0,
                        REPTERM_DO_LT | (special ? REPTERM_SPECIAL : 0), NULL);
        menuarg.modes = modes;
 #ifdef FEAT_TOOLBAR
index 06958aab2c76050327cb2987ee38f5a6d569e947..31e30e195beee3bda76d49d5a62e690d69025449 100644 (file)
@@ -2102,7 +2102,7 @@ did_set_pastetoggle(optset_T *args UNUSED)
     // translate key codes like in a mapping
     if (*p_pt)
     {
-       (void)replace_termcodes(p_pt, &p,
+       (void)replace_termcodes(p_pt, &p, 0,
                REPTERM_FROM_PART | REPTERM_DO_LT, NULL);
        if (p != NULL)
        {
index 4c93a8130675e143303fb0d3da96330eb830ddec..4150cbe000a804209387fc0308cfa3010d90e4a8 100644 (file)
@@ -85,7 +85,7 @@ int decode_modifiers(int n);
 int check_termcode(int max_offset, char_u *buf, int bufsize, int *buflen);
 void term_get_fg_color(char_u *r, char_u *g, char_u *b);
 void term_get_bg_color(char_u *r, char_u *g, char_u *b);
-char_u *replace_termcodes(char_u *from, char_u **bufp, int flags, int *did_simplify);
+char_u *replace_termcodes(char_u *from, char_u **bufp, scid_T sid_arg, int flags, int *did_simplify);
 void show_termcodes(int flags);
 int show_one_termcode(char_u *name, char_u *code, int printit);
 void update_tcap(int attr);
index 0416acc7057021ceb2820aab9a800e9e68220ee6..15420450e1a89043f2c4c0d7495ad5750ed2b88b 100644 (file)
@@ -6591,6 +6591,8 @@ term_get_bg_color(char_u *r, char_u *g, char_u *b)
 replace_termcodes(
     char_u     *from,
     char_u     **bufp,
+    scid_T     sid_arg UNUSED, // script ID to use for <SID>,
+                               // or 0 to use current_sctx
     int                flags,
     int                *did_simplify)
 {
@@ -6660,12 +6662,12 @@ replace_termcodes(
             */
            if (STRNICMP(src, "<SID>", 5) == 0)
            {
-               if (current_sctx.sc_sid <= 0)
+               if (sid_arg < 0 || (sid_arg == 0 && current_sctx.sc_sid <= 0))
                    emsg(_(e_using_sid_not_in_script_context));
                else
                {
                    char_u  *dot;
-                   long    sid = current_sctx.sc_sid;
+                   long    sid = sid_arg != 0 ? sid_arg : current_sctx.sc_sid;
 
                    src += 5;
                    if (in_vim9script()
index d235eb34c9c8d39841cf499dc689123739081ddc..cb889ae19a44b4bac650782eca9447adac67b60a 100644 (file)
@@ -867,7 +867,7 @@ ex_terminal(exarg_T *eap)
            vim_free(opt.jo_eof_chars);
            p = skiptowhite(cmd);
            *p = NUL;
-           keys = replace_termcodes(ep + 1, &buf,
+           keys = replace_termcodes(ep + 1, &buf, 0,
                    REPTERM_FROM_PART | REPTERM_DO_LT | REPTERM_SPECIAL, NULL);
            opt.jo_set2 |= JO2_EOF_CHARS;
            opt.jo_eof_chars = vim_strsave(keys);
index d76c79cb858d607edc749292f31a18f142522030..4c62f89ff5cf5f14d85e517c7ede9e29d1b0c35a 100644 (file)
@@ -494,8 +494,32 @@ func Test_map_restore()
   nunmap <C-B>
 endfunc
 
-" Test restoring the script context of a mapping
+" Test restoring an <SID> mapping
 func Test_map_restore_sid()
+  func RestoreMap()
+    const d = maparg('<CR>', 'i', v:false, v:true)
+    iunmap <buffer> <CR>
+    call mapset('i', v:false, d)
+  endfunc
+
+  let mapscript =<< trim [CODE]
+    inoremap <silent><buffer> <SID>Return <C-R>=42<CR>
+    inoremap <script><buffer> <CR> <CR><SID>Return
+  [CODE]
+  call writefile(mapscript, 'Xmapscript', 'D')
+
+  new
+  source Xmapscript
+  inoremap <buffer> <C-B> <Cmd>call RestoreMap()<CR>
+  call feedkeys("i\<CR>\<C-B>\<CR>", 'xt')
+  call assert_equal(['', '42', '42'], getline(1, '$'))
+
+  bwipe!
+  delfunc RestoreMap
+endfunc
+
+" Test restoring a mapping with a negative script ID
+func Test_map_restore_negative_sid()
   let after =<< trim [CODE]
     call assert_equal("\tLast set from --cmd argument",
           \ execute('verbose nmap ,n')->trim()->split("\n")[-1])
index 7d844620bdae78033f0cdc4e1f8276d38e6d149b..57435fafbc2a8870f82636ec8235332aa6d9ee57 100644 (file)
@@ -990,7 +990,7 @@ uc_add_command(
     char_u     *rep_buf = NULL;
     garray_T   *gap;
 
-    replace_termcodes(rep, &rep_buf, 0, NULL);
+    replace_termcodes(rep, &rep_buf, 0, 0, NULL);
     if (rep_buf == NULL)
     {
        // can't replace termcodes - try using the string as is
index f4c73e7991371d59d615fc15a994c6b1f126a1af..dc054dfd7a046529afab1b9c7e85823effe233cd 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1687,
 /**/
     1686,
 /**/