]> granicus.if.org Git - vim/commitdiff
patch 8.2.2805: Vim9: cannot use legacy syntax in Vim9 script v8.2.2805
authorBram Moolenaar <Bram@vim.org>
Sat, 24 Apr 2021 12:15:41 +0000 (14:15 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 24 Apr 2021 12:15:41 +0000 (14:15 +0200)
Problem:    Vim9: cannot use legacy syntax in Vim9 script.
Solution:   Add the :legacy command.

runtime/doc/index.txt
runtime/doc/vim9.txt
src/ex_cmdidxs.h
src/ex_cmds.h
src/ex_docmd.c
src/structs.h
src/testdir/test_vim9_assign.vim
src/testdir/test_vim9_func.vim
src/version.c
src/vim9compile.c
src/vim9script.c

index 7da806691e1b1fe0e1936142511a583b23ba31e7..f0e8f30fae44895988a13234b23863d22e3f21e1 100644 (file)
@@ -1396,6 +1396,7 @@ tag               command         action ~
 |:lfdo|                :lfd[o]         execute command in each file in location list
 |:left|                :le[ft]         left align lines
 |:leftabove|   :lefta[bove]    make split window appear left or above
+|:legacy|      :leg[acy]       make following command use legacy script syntax
 |:let|         :let            assign a value to a variable or option
 |:lexpr|       :lex[pr]        read locations from expr and jump to first
 |:lfile|       :lf[ile]        read file with locations and jump to first
index 0fc7bf5278eab90e43ea304660412debc2baf639..0a2ea629523fd4e5d9f765b440865addbd76a8bc 100644 (file)
@@ -61,12 +61,17 @@ Vim9 script and legacy Vim script can be mixed.  There is no requirement to
 rewrite old scripts, they keep working as before.  You may want to use a few
 `:def` functions for code that needs to be fast.
 
-                                               *:vim9* *:vim9cmd*
-:vim9[cmd] {cmd}
+:vim9[cmd] {cmd}                               *:vim9* *:vim9cmd*
                Execute {cmd} using Vim9 script syntax and semantics.
                Useful when typing a command and in a legacy script or
                function.
 
+:leg[acy] {cmd}                                        *:leg* *:legacy*
+               Execute {cmd} using legacy script syntax and semantics.  Only
+               useful in a Vim9 script or a :def function.
+               Note that {cmd} cannot use local variables, since it is parsed
+               with legacy expression syntax.
+
 ==============================================================================
 
 2. Differences from legacy Vim script                  *vim9-differences*
index 70fb71a79423dfdab1a29994dd117a752e45d499..0d148d7d44695656ccba3e9107cd58f4110d6a5d 100644 (file)
@@ -17,20 +17,20 @@ static const unsigned short cmdidxs1[26] =
   /* j */ 209,
   /* k */ 211,
   /* l */ 216,
-  /* m */ 278,
-  /* n */ 296,
-  /* o */ 316,
-  /* p */ 328,
-  /* q */ 367,
-  /* r */ 370,
-  /* s */ 390,
-  /* t */ 459,
-  /* u */ 504,
-  /* v */ 515,
-  /* w */ 536,
-  /* x */ 550,
-  /* y */ 560,
-  /* z */ 561
+  /* m */ 279,
+  /* n */ 297,
+  /* o */ 317,
+  /* p */ 329,
+  /* q */ 368,
+  /* r */ 371,
+  /* s */ 391,
+  /* t */ 460,
+  /* u */ 505,
+  /* v */ 516,
+  /* w */ 537,
+  /* x */ 551,
+  /* y */ 561,
+  /* z */ 562
 };
 
 /*
@@ -52,7 +52,7 @@ static const unsigned char cmdidxs2[26][26] =
   /* i */ {  1,  0,  0,  0,  0,  3,  0,  0,  0,  4,  0,  5,  6,  0,  0,  0,  0,  0, 14,  0, 16,  0,  0,  0,  0,  0 },
   /* j */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0 },
   /* k */ {  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },
-  /* l */ {  3, 11, 15, 19, 20, 24, 27, 32,  0,  0,  0, 34, 37, 40, 44, 50,  0, 52, 61, 53, 54, 58, 60,  0,  0,  0 },
+  /* l */ {  3, 11, 15, 19, 20, 25, 28, 33,  0,  0,  0, 35, 38, 41, 45, 51,  0, 53, 62, 54, 55, 59, 61,  0,  0,  0 },
   /* m */ {  1,  0,  0,  0,  7,  0,  0,  0,  0,  0, 10,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16 },
   /* n */ {  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  8, 10,  0,  0,  0,  0,  0, 17,  0,  0,  0,  0,  0 },
   /* o */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  5,  0,  0,  0,  0,  0,  0,  9,  0, 11,  0,  0,  0 },
@@ -69,4 +69,4 @@ static const unsigned char cmdidxs2[26][26] =
   /* z */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }
 };
 
-static const int command_count = 576;
+static const int command_count = 577;
index aa41ab3a28f1549a8bcab124cb7a47ce3cf34912..819cf732c8ac3ef8771f5884eb7c0701a9e86312 100644 (file)
@@ -830,6 +830,9 @@ EXCMD(CMD_let,              "let",          ex_let,
 EXCMD(CMD_lexpr,       "lexpr",        ex_cexpr,
        EX_NEEDARG|EX_WORD1|EX_NOTRLCOM|EX_BANG,
        ADDR_NONE),
+EXCMD(CMD_legacy,      "legacy",       ex_wrongmodifier,
+       EX_NEEDARG|EX_EXTRA|EX_NOTRLCOM|EX_CMDWIN|EX_LOCK_OK,
+       ADDR_NONE),
 EXCMD(CMD_lfile,       "lfile",        ex_cfile,
        EX_TRLBAR|EX_FILE1|EX_BANG,
        ADDR_NONE),
index db7bb931f8fc412b43c0cc481c4e7bba9e3cdc36..0d87a894404485d92c7eddb6b8427e94409e2ff5 100644 (file)
@@ -2925,6 +2925,17 @@ parse_command_modifiers(
                            cmod->cmod_flags |= CMOD_LOCKMARKS;
                            continue;
                        }
+                       if (checkforcmd_noparen(&eap->cmd, "legacy", 3))
+                       {
+                           if (ends_excmd2(p, eap->cmd))
+                           {
+                               *errormsg =
+                                     _(e_vim9cmd_must_be_followed_by_command);
+                               return FAIL;
+                           }
+                           cmod->cmod_flags |= CMOD_LEGACY;
+                           continue;
+                       }
 
                        if (!checkforcmd_noparen(&eap->cmd, "leftabove", 5))
                            break;
index 6c8ef48c0b6c6e6020e4d34b6d4585120c7e3cd5..8da7c7b0cff597b9e9357820d6abc95c387b3965 100644 (file)
@@ -645,6 +645,7 @@ typedef struct
 #define CMOD_KEEPPATTERNS   0x1000     // ":keeppatterns"
 #define CMOD_NOSWAPFILE            0x2000      // ":noswapfile"
 #define CMOD_VIM9CMD       0x4000      // ":vim9cmd"
+#define CMOD_LEGACY        0x8000      // ":legacy"
 
     int                cmod_split;             // flags for win_split()
     int                cmod_tab;               // > 0 when ":tab" was used
index ad942a8f17780ed0f772e86eef34fd66278ac139..a0175cd281f9fca666a6ba18bb6b25e418aa14db 100644 (file)
@@ -1500,33 +1500,33 @@ def Test_script_local_in_legacy()
   # OK to define script-local later when prefixed with s:
   var lines =<< trim END
     def SetLater()
-      s:legacy = 'two'
+      s:legvar = 'two'
     enddef
     defcompile
-    let s:legacy = 'one'
+    let s:legvar = 'one'
     call SetLater()
-    call assert_equal('two', s:legacy)
+    call assert_equal('two', s:legvar)
   END
   CheckScriptSuccess(lines)
 
   # OK to leave out s: prefix when script-local already defined
   lines =<< trim END
-    let s:legacy = 'one'
+    let s:legvar = 'one'
     def SetNoPrefix()
-      legacy = 'two'
+      legvar = 'two'
     enddef
     call SetNoPrefix()
-    call assert_equal('two', s:legacy)
+    call assert_equal('two', s:legvar)
   END
   CheckScriptSuccess(lines)
 
   # Not OK to leave out s: prefix when script-local defined later
   lines =<< trim END
     def SetLaterNoPrefix()
-      legacy = 'two'
+      legvar = 'two'
     enddef
     defcompile
-    let s:legacy = 'one'
+    let s:legvar = 'one'
   END
   CheckScriptFailure(lines, 'E476:', 1)
 enddef
index 8cfb16099dac9f5679b1b6c4ac10fd214837b75e..230de20e376c7768ff26206ddc0a732c41df09f8 100644 (file)
@@ -2165,6 +2165,14 @@ def Test_list_lambda()
   assert_match('def <lambda>\d\+(_: any): number\n1  return 0\n   enddef', body)
 enddef
 
+def Test_legacy_lambda()
+  legacy echo {x -> 'hello ' .. x}('foo')
+  var lines =<< trim END
+      echo {x -> 'hello ' .. x}('foo')
+  END
+  CheckDefAndScriptFailure(lines, 'E720:')
+enddef
+
 def DoFilterThis(a: string): list<string>
   # closure nested inside another closure using argument
   var Filter = (l) => filter(l, (_, v) => stridx(v, a) == 0)
index c5c3feeb3e8bd289d9573549dea3f058c3e1e540..4c266eff6c2cf3298c3c69b6ff2a05cc71eeae82 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2805,
 /**/
     2804,
 /**/
index c74bb6e5cd41f74ef6575de6ebdb652a5e4633fa..c65f1c37c6f4b4784a3a9b0df4845b6f04d5d0f4 100644 (file)
@@ -9052,6 +9052,10 @@ compile_def_function(
            goto erret;
        }
 
+       // When using ":legacy cmd" always use compile_exec().
+       if (local_cmdmod.cmod_flags & CMOD_LEGACY)
+           ea.cmdidx = CMD_legacy;
+
        if (p == ea.cmd && ea.cmdidx != CMD_SIZE)
        {
            if (cctx.ctx_skip == SKIP_YES)
index 583a8d4c5976ba11b779f30d2968b5a126009809..ddbae781c612bc3177c8270fea3f4d1d0246b50f 100644 (file)
@@ -27,8 +27,9 @@ in_vim9script(void)
 {
     // "sc_version" is also set when compiling a ":def" function in legacy
     // script.
-    return current_sctx.sc_version == SCRIPT_VERSION_VIM9
-               || (cmdmod.cmod_flags & CMOD_VIM9CMD);
+    return (current_sctx.sc_version == SCRIPT_VERSION_VIM9
+                                        || (cmdmod.cmod_flags & CMOD_VIM9CMD))
+               && !(cmdmod.cmod_flags & CMOD_LEGACY);
 }
 
 #if defined(FEAT_EVAL) || defined(PROTO)