From: Illia Bobyr Date: Thu, 2 Jul 2026 18:40:03 +0000 (+0000) Subject: patch 9.2.0767: legacy/vim9cmd modifiers do not set script version for options values X-Git-Tag: v9.2.0767^0 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=02f2745e2757f8353e2e76db130682ed966f5544;p=thirdparty%2Fvim.git patch 9.2.0767: legacy/vim9cmd modifiers do not set script version for options values 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 Signed-off-by: Christian Brabandt --- diff --git a/src/option.c b/src/option.c index 9d291d1809..9a869fdb9b 100644 --- a/src/option.c +++ b/src/option.c @@ -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) diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim index cec81f3ed6..1f421e2a4c 100644 --- a/src/testdir/test_vim9_cmd.vim +++ b/src/testdir/test_vim9_cmd.vim @@ -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 + + 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:') diff --git a/src/version.c b/src/version.c index 2c531eb5bc..da6de93048 100644 --- a/src/version.c +++ b/src/version.c @@ -759,6 +759,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 767, /**/ 766, /**/