Skip to content

Vim9: :def in legacy script can create a script variable - #21379

Open
h-east wants to merge 1 commit into
vim:masterfrom
h-east:vim9-def-legacy-unknown-script-var
Open

h-east wants to merge 1 commit into
vim:masterfrom
h-east:vim9-def-legacy-unknown-script-var

Conversation

@h-east

@h-east h-east commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor
Problem:  A :def function in a legacy script can create a script-local
          variable by assigning to it, while declaring one with "var"
          gives E1101.
Solution: Give E1089 for assigning to an unknown script-local variable
          in any :def function, not only in one defined in a Vim9
          script.  Remove uf_script_ctx_version, which was only used
          for this check.  Do not give it with ":source ++dryrun".

fixes: #21378

runtime/menu.vim created s:bmenu_short, s:bmenu_count, s:suglist,
s:fromword, s:changeitem, s:additem and s:ignoreitem this way, define
them at the script level.

":source ++dryrun" does not execute ":let" in a legacy script, thus
every script variable would be unknown when compiling. Document that
reading or calling such a variable without "s:" still gives an error,
and separate the paragraphs of ":source-dryrun" with blank lines.

Test_unlet() created s:somevar this way, define it at the script level
instead. Test_using_s_var_in_function() checks that assigning to
s:scriptlevel in a :def function of a legacy script gives E1089 when
the variable does not exist. Test_source_dryrun() checks that
assigning to a script variable with "s:" in a :def function of a
legacy script gives no error with ":source ++dryrun".

Problem:  A :def function in a legacy script can create a script-local
          variable by assigning to it, while declaring one with "var"
          gives E1101.
Solution: Give E1089 for assigning to an unknown script-local variable
          in any :def function, not only in one defined in a Vim9
          script.  Remove uf_script_ctx_version, which was only used
          for this check.  Do not give it with ":source ++dryrun".

runtime/menu.vim created s:bmenu_short, s:bmenu_count, s:suglist,
s:fromword, s:changeitem, s:additem and s:ignoreitem this way, define
them at the script level.

":source ++dryrun" does not execute ":let" in a legacy script, thus
every script variable would be unknown when compiling.  Document that
reading or calling such a variable without "s:" still gives an error,
and separate the paragraphs of ":source-dryrun" with blank lines.

Test_unlet() created s:somevar this way, define it at the script level
instead.  Test_using_s_var_in_function() checks that assigning to
s:scriptlevel in a :def function of a legacy script gives E1089 when
the variable does not exist.  Test_source_dryrun() checks that
assigning to a script variable with "s:" in a :def function of a
legacy script gives no error with ":source ++dryrun".

Assisted-by: Claude
Signed-off-by: Hirohito Higashi <[email protected]>
@h-east
h-east force-pushed the vim9-def-legacy-unknown-script-var branch from 6f8ec13 to 1d004b6 Compare September 27, 2026 18:40
@h-east
h-east marked this pull request as ready for review September 27, 2026 18:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Vim9: :def function in legacy script can create a script variable by assignment

1 participant