In a legacy script (no vim9script), a :def function can create a
new script-local variable just by assigning to it:
def s:F() s:ccc = 1 enddef call s:F() echo s:ccc
This echoes 1. Declaring the variable in the same place is rejected:
def s:F() var s:ccc = 1 # E1101: Cannot declare a script variable in a function enddef
and let s:ccc = 1 gives E1126, since :let cannot be used in a
:def function.
Patch 8.2.1373 (#6630) added an error for assigning to a script
variable that does not exist, but only for a function defined in a
Vim9 script ("Check that in Vim9 script the variable was defined").
The check in compile_lhs() still tests
uf_script_ctx_version == SCRIPT_VERSION_VIM9, so a :def function in
a legacy script was left out. (In a Vim9 script the s: prefix itself
has since become an error, E1268.) The help does not cover this case:
:help vim9-s:var only states that "s:" is optional in a :def
function in a legacy script.
This looks inconsistent to me. The body of a :def function follows
Vim9 rules, where a variable is declared before it is used, and
:help E1269 states that script-local variables must be declared at
the script level. Yet var s:ccc = 1 is an error while a plain
s:ccc = 1 creates the variable.
Making this an error (E1089, "Unknown variable") would break a legacy
script that relies on it. The error would only be given when the
variable does not exist yet at the time the function is compiled;
assigning to an existing script variable keeps working.
I went through the legacy scripts under runtime/ that contain a :def
function, and none of them creates a script variable this way. So I
would still like to change it. What do others think? If you know of
a plugin that depends on this, please let me know.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
One more data point. Without the "s:" prefix the same assignment is
rejected:
let s:aaa = 1 def Aaa() bbb = 2 # E476: Invalid command: bbb = 2 enddef call Aaa()
So in a :def function of a legacy script, of these three lines only the
last one works, and it creates s:bbb:
bbb = 2 # E476 var s:bbb = 2 # E1101 s:bbb = 2 # creates s:bbb
":help vim9-s:var" states that "s:" is optional there, yet adding it
changes an error into creating a new variable.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
fixed by #21379
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()