changeset 27645:1712b102d642 v8.2.4348

patch 8.2.4348: "legacy exe cmd" does not do what one would expect Commit: https://github.com/vim/vim/commit/5b1d6e98c6610553fe3946086cdba77718bd69d5 Author: Bram Moolenaar <Bram@vim.org> Date: Fri Feb 11 20:33:48 2022 +0000 patch 8.2.4348: "legacy exe cmd" does not do what one would expect Problem: "legacy exe cmd" does not do what one would expect. Solution: Apply the "legacy" and "vim9script" command modifiers to the argument of ":execute".
author Bram Moolenaar <Bram@vim.org>
date Fri, 11 Feb 2022 21:45:03 +0100
parents 666f8cbb90dd
children 9438620628e3
files runtime/doc/vim9.txt src/eval.c src/ex_docmd.c src/globals.h src/testdir/test_vim9_cmd.vim src/version.c
diffstat 6 files changed, 42 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/vim9.txt
+++ b/runtime/doc/vim9.txt
@@ -57,13 +57,13 @@ rewrite old scripts, they keep working a
 `:def` functions for code that needs to be fast.
 
 :vim9[cmd] {cmd}				*:vim9* *:vim9cmd* *E1164*
-		Execute {cmd} using Vim9 script syntax and semantics.
-		Useful when typing a command and in a legacy script or
-		function.
+		Evaluate and 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* *E1189* *E1234*
-		Execute {cmd} using legacy script syntax and semantics.  Only
-		useful in a Vim9 script or a :def function.
+		Evaluate and 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.
 
--- a/src/eval.c
+++ b/src/eval.c
@@ -6491,8 +6491,16 @@ ex_execute(exarg_T *eap)
 		did_emsg = save_did_emsg;
 	}
 	else if (eap->cmdidx == CMD_execute)
+	{
+	    int save_sticky_cmdmod_flags = sticky_cmdmod_flags;
+
+	    // "legacy exe cmd" and "vim9cmd exe cmd" applies to "cmd".
+	    sticky_cmdmod_flags = cmdmod.cmod_flags
+						& (CMOD_LEGACY | CMOD_VIM9CMD);
 	    do_cmdline((char_u *)ga.ga_data,
 		       eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE);
+	    sticky_cmdmod_flags = save_sticky_cmdmod_flags;
+	}
     }
 
     ga_clear(&ga);
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -2786,6 +2786,7 @@ parse_command_modifiers(
     int	    starts_with_colon = FALSE;
 
     CLEAR_POINTER(cmod);
+    cmod->cmod_flags = sticky_cmdmod_flags;
 
     // Repeat until no more command modifiers are found.
     for (;;)
--- a/src/globals.h
+++ b/src/globals.h
@@ -1156,6 +1156,7 @@ EXTERN int	mapped_ctrl_c INIT(= FALSE); 
 EXTERN int	ctrl_c_interrupts INIT(= TRUE);	// CTRL-C sets got_int
 
 EXTERN cmdmod_T	cmdmod;			// Ex command modifiers
+EXTERN int	sticky_cmdmod_flags INIT(= 0); // used by :execute
 
 #ifdef FEAT_EVAL
 EXTERN int	is_export INIT(= FALSE);    // :export {cmd}
--- a/src/testdir/test_vim9_cmd.vim
+++ b/src/testdir/test_vim9_cmd.vim
@@ -83,6 +83,31 @@ def Test_vim9cmd()
   v9.CheckScriptSuccess(lines)
 enddef
 
+def Test_cmdmod_execute()
+  # "legacy" applies not only to the "exe" argument but also to the commands
+  var lines =<< trim END
+      vim9script
+
+      b:undo = 'let g:undone = 1 | let g:undtwo = 2'
+      legacy exe b:undo
+      assert_equal(1, g:undone)
+      assert_equal(2, g:undtwo)
+  END
+  v9.CheckScriptSuccess(lines)
+
+  # same for "vim9cmd" modifier
+  lines =<< trim END
+      let b:undo = 'g:undone = 11 | g:undtwo = 22'
+      vim9cmd exe b:undo
+      call assert_equal(11, g:undone)
+      call assert_equal(22, g:undtwo)
+  END
+  v9.CheckScriptSuccess(lines)
+  unlet b:undo
+  unlet g:undone
+  unlet g:undtwo
+enddef
+
 def Test_edit_wildcards()
   var filename = 'Xtest'
   edit `=filename`
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    4348,
+/**/
     4347,
 /**/
     4346,