]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0767: legacy/vim9cmd modifiers do not set script version for options values v9.2.0767
authorIllia Bobyr <illia.bobyr@gmail.com>
Thu, 2 Jul 2026 18:40:03 +0000 (18:40 +0000)
committerChristian Brabandt <cb@256bit.org>
Thu, 2 Jul 2026 18:40:03 +0000 (18:40 +0000)
Problem:  legacy/vim9cmd modifiers do not set script version for options
          values
Solution: Set the correct script version depending on command modifier
          flags (Illia Bobyr)

When remembering script context for an option value we should consider
flags "CMOD_LEGACY" and "CMOD_VIM9CMD" set in "cmdmod.cmd_flags" by the
":legacy" and ":vim9cmd" command prefixes.  Otherwise, if an option
value is an expression, it might be evaluated in an incorrect context.

closes: #20683

Signed-off-by: Illia Bobyr <illia.bobyr@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/option.c
src/testdir/test_vim9_cmd.vim
src/version.c

index 9d291d1809b197dae92be33c59d4183bd6d47118..9a869fdb9b9525284b0d97fdfef2139f24ab0ac0 100644 (file)
@@ -3498,6 +3498,14 @@ set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
     if (!(opt_flags & OPT_MODELINE))
        new_script_ctx.sc_lnum += SOURCING_LNUM;
 
+    // ":legacy" and ":vim9cmd" change the execution context of an option.
+    if (cmdmod.cmod_flags & CMOD_VIM9CMD)
+       new_script_ctx.sc_version = SCRIPT_VERSION_VIM9;
+    if (cmdmod.cmod_flags & CMOD_LEGACY)
+       // It is a bit confusing, but "MAX" is actually the legacy Vim script
+       // version before Vim9.
+       new_script_ctx.sc_version = SCRIPT_VERSION_MAX;
+
     // Remember where the option was set.  For local options need to do that
     // in the buffer or window structure.
     if (both || (opt_flags & OPT_GLOBAL) || (indir & (PV_BUF|PV_WIN)) == 0)
index cec81f3ed636706458388b5ad46a8d5a1092b4fd..1f421e2a4c4783025da820196449e2bf79892baa 100644 (file)
@@ -97,6 +97,43 @@ def Test_vim9cmd()
   v9.CheckScriptFailure(lines, 'E1017:')
 enddef
 
+def Test_legacy_vim9cmd_preserved_by_options()
+  # Make sure that "legacy" and "vim9cmd" prefix affects value of an option that
+  # is a script expression.
+
+  var lines: list<string>
+
+  lines =<< trim END
+    vim9script
+    try
+      legacy set indentexpr='a'.'b'=='ab'
+      set debug=throw
+      normal O
+    finally
+      set debug& indentexpr&
+    endtry
+  END
+  # "'a'.'b'=='ab'" evaluated as a Vim9 expression produces:
+  #
+  # > E1030: Using a String as a Number: "a"
+  v9.CheckScriptSuccess(lines)
+
+  lines =<< trim END
+    try
+      vim9cmd set indentexpr=type((x)\ =>\ x)\ ==\ v:t_func\ ?\ 1\ :\ 0
+      set debug=throw
+      normal O
+    finally
+      set debug& indentexpr&
+    endtry
+  END
+  # "type((x) => x) == v:t_func ? 1 : 0" evaluated as a legacy expression
+  # produces:
+  #
+  # > E121: Undefined variable: x
+  v9.CheckScriptSuccess(lines)
+enddef
+
 def Test_defcompile_fails()
   assert_fails('defcompile NotExists', 'E1061:')
   assert_fails('defcompile debug debug Test_defcompile_fails', 'E488:')
index 2c531eb5bc45dd08989810238986f6f1a9ba260b..da6de93048431b5ce3e0168031369761d573df8c 100644 (file)
@@ -759,6 +759,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    767,
 /**/
     766,
 /**/