What do I need to read to understand g: and s: VIM variable prefixes?

1,043 views
Skip to first unread message

Dotan Cohen

unread,
Oct 30, 2012, 2:04:55 PM10/30/12
to vim use
What do I need to read to understand g: and s: VIM variable prefixes?
This one is hard to guess for the built in help, and Google isn't
helping.

The root of the issue is trying to figure out why g:someVariable can
be seen in SomeFunction() but cannot be seen in s:AnotherFunction().
What is the s: for that precedes the second function's name, and why
does it change scope (s for scope, perhaps)? Thanks.

--
Dotan Cohen

http://gibberish.co.il
http://what-is-what.com

herm...@free.fr

unread,
Oct 30, 2012, 2:09:54 PM10/30/12
to vim use
Hello,

> What do I need to read to understand g: and s: VIM variable prefixes?
> This one is hard to guess for the built in help, and Google isn't
> helping.

Have you tried
:h s:^D
?
which will give you :h s:var

> The root of the issue is trying to figure out why g:someVariable can
> be seen in SomeFunction() but cannot be seen in s:AnotherFunction().

someVariable in a function will be actually l:someVariable. When accessing global variables from functions, always prefix them with g:.


> What is the s: for that precedes the second function's name, and why
> does it change scope (s for scope, perhaps)? Thanks.

s: stands for script. The scope of the variable is the script. As file static variables in C.

HTH,
--
Luc Hermitte
http://lh-vim.googlecode.com/
http://hermitte.free.fr/vim/

Ben Fritz

unread,
Oct 30, 2012, 3:27:50 PM10/30/12
to vim...@googlegroups.com
On Tuesday, October 30, 2012 1:10:16 PM UTC-5, herm...@free.fr wrote:
>
> > What is the s: for that precedes the second function's name, and why
> > does it change scope (s for scope, perhaps)? Thanks.
>
> s: stands for script. The scope of the variable is the script. As file static variables in C.
>

Any of the [gvslawtb]: prefixed variables define the scope of the variable, as follows:

g: global variable, accessible anywhere
v: special variable predefined by Vim only useful in certain contexts, see the help entry for that variable
s: script-local variable, accessible anywhere within a given script file
l: function-local variable, only accessible with the defining function
a: function argument
w: window-local variable, global variable but with a separate copy for every single window
t: tab-local variable, global variable but with a separate copy for each tab page
b: buffer-local variable, global variable but with a separate copy for each buffer

Dotan Cohen

unread,
Oct 30, 2012, 3:35:30 PM10/30/12
to vim...@googlegroups.com
On Tue, Oct 30, 2012 at 8:09 PM, <herm...@free.fr> wrote:
> Hello,
>
>> What do I need to read to understand g: and s: VIM variable prefixes?
>> This one is hard to guess for the built in help, and Google isn't
>> helping.
>
> Have you tried
> :h s:^D
> ?
> which will give you :h s:var
>

I had no idea that ^D would complete in :h! That's it, I'll never have
to post to the list again! :)


>> The root of the issue is trying to figure out why g:someVariable can
>> be seen in SomeFunction() but cannot be seen in s:AnotherFunction().
>
> someVariable in a function will be actually l:someVariable. When accessing global variables from functions, always prefix them with g:.
>
>
>> What is the s: for that precedes the second function's name, and why
>> does it change scope (s for scope, perhaps)? Thanks.
>
> s: stands for script. The scope of the variable is the script. As file static variables in C.
>

Thanks. Actually, since my first post I see that I did have a bug in
the function: reducing it to a most-simple case revealed the flaw. In
any case, what I have is a function in .vimrc that begins with s:,
something that was suggested to me on SuperUser, so I'd like to know
what it's doing, not just how to do it.

Thank you.

Dotan Cohen

unread,
Oct 30, 2012, 3:36:21 PM10/30/12
to vim...@googlegroups.com
On Tue, Oct 30, 2012 at 9:27 PM, Ben Fritz <fritzo...@gmail.com> wrote:
> Any of the [gvslawtb]: prefixed variables define the scope of the variable, as follows:
>
> g: global variable, accessible anywhere
> v: special variable predefined by Vim only useful in certain contexts, see the help entry for that variable
> s: script-local variable, accessible anywhere within a given script file
> l: function-local variable, only accessible with the defining function
> a: function argument
> w: window-local variable, global variable but with a separate copy for every single window
> t: tab-local variable, global variable but with a separate copy for each tab page
> b: buffer-local variable, global variable but with a separate copy for each buffer
>

Great, thank you!

Tony Mechelynck

unread,
Oct 31, 2012, 6:55:14 AM10/31/12
to vim...@googlegroups.com
Yes, and in addition, if you don't use a scope prefix Vim implies l: if
you're inside a function and g: otherwise.

See :help internal-variables


Best regards,
Tony.
--
Question:
Man Invented Alcohol,
God Invented Grass.
Who do you trust?

Dotan Cohen

unread,
Oct 31, 2012, 7:05:19 AM10/31/12
to vim...@googlegroups.com
On Wed, Oct 31, 2012 at 12:55 PM, Tony Mechelynck
<antoine.m...@gmail.com> wrote:

> Yes, and in addition, if you don't use a scope prefix Vim implies l: if
> you're inside a function and g: otherwise.
>
> See :help internal-variables
>

Thank you, that is not consistent with other programming environments
that I am familiar with. Very good to know!


> Question:
> Man Invented Alcohol,
> God Invented Grass.
> Who do you trust?
>

I'm pretty sure that God invented alcohol too, actually. I know that
I've had pomegranate juice ferment into a type of wine just sitting
there in the container. Divine fermentation?

Tim Chase

unread,
Oct 31, 2012, 2:33:38 PM10/31/12
to vim...@googlegroups.com, Dotan Cohen
On 10/31/12 06:05, Dotan Cohen wrote:
> On Wed, Oct 31, 2012 at 12:55 PM, Tony Mechelynck wrote:
>> Yes, and in addition, if you don't use a scope prefix Vim
>> implies l: if you're inside a function and g: otherwise.
>>
>> See :help internal-variables
>
> Thank you, that is not consistent with other programming
> environments that I am familiar with. Very good to know!

Python happens to work this way:

x = 42
def foo():
x = 32
return x
print foo()
print x

prints 32 followed by 42 (the x remains local to the function).
I've noticed little bits of Python show up in VimScript--such as
array slicing, negative-indexing, and first-class(ish) functions.
Not that I mind, as Python is my preferred language. :-)

There may be others where this scope is the same (pascal comes to mind)

-tim


Dotan Cohen

unread,
Oct 31, 2012, 3:15:20 PM10/31/12
to Tim Chase, vim...@googlegroups.com
On Wed, Oct 31, 2012 at 8:33 PM, Tim Chase <v...@tim.thechases.com> wrote:
> On 10/31/12 06:05, Dotan Cohen wrote:
>> On Wed, Oct 31, 2012 at 12:55 PM, Tony Mechelynck wrote:
>>> Yes, and in addition, if you don't use a scope prefix Vim
>>> implies l: if you're inside a function and g: otherwise.
>>>
>>> See :help internal-variables
>>
>> Thank you, that is not consistent with other programming
>> environments that I am familiar with. Very good to know!
>
> Python happens to work this way:
>
> x = 42
> def foo():
> x = 32
> return x
> print foo()
> print x
>
> prints 32 followed by 42 (the x remains local to the function).

Right, this is how most C-based languages work. I don't know if Python
is C-based (I think so), but this is what I expect. What I don't
expect is that x would be recognized inside the foo() declaration if
it was only defined outside, as Tony mentions is the case with VIM.
Let's try:

>>> x = 42
>>> print x
42
>>> def foo():
... print x
...
>>> print x
42
>>> foo()
42

Wow! This would be at minimum a compiler warning at at worse a huge
security flaw in other languages. I happen to have PHP handy:

php > $x = 42;
php > echo $x . PHP_EOL;
42
php > function foo() {
php { echo $x . PHP_EOL;
php { return true;
php { }
php > echo $x . PHP_EOL;
42
php > foo();
PHP Notice: Undefined variable: x in php shell code on line 2

The variable $x was not declared in foo(), and is not valid there.
Now, to check my suspicions:

- neptune:c$ cat scopeTest.c
#include <stdio.h>
int foo();

int main() {
int x = 42;
printf("%d", x);
foo();
return 0;
}

int foo() {
printf("%d", x);
}
- neptune:c$ gcc scopeTest.c
scopeTest.c: In function ‘foo’:
scopeTest.c:15:15: error: ‘x’ undeclared (first use in this function)
scopeTest.c:15:15: note: each undeclared identifier is reported only
once for each function it appears in
- neptune:c$

Nope, C won't allow it either.

In both PHP and C there are ways to explicitly make x global, but it
is not implicit.


> I've noticed little bits of Python show up in VimScript--such as
> array slicing, negative-indexing, and first-class(ish) functions.
> Not that I mind, as Python is my preferred language. :-)
>
> There may be others where this scope is the same (pascal comes to mind)
>

I've actually never touched Pascal, nor Cobol or Fortran for that matter.

Thank you for the information regarding Python. I do dabble in Python
occasionally, and things like this I should know. I love Python, but
VIM is ill-equipped to handle bracketless languages out of the box!

donothing successfully

unread,
Oct 31, 2012, 3:52:41 PM10/31/12
to vim...@googlegroups.com
On 31 October 2012 19:15, Dotan Cohen <dotan...@gmail.com> wrote:
>[…]
> #include <stdio.h>
> int foo();
>
> int main() {
> int x = 42;
> printf("%d", x);
> foo();
> return 0;
> }
>
> int foo() {
> printf("%d", x);
> }
>[…]
Here x is a local variable of the function *main*.
I think the "global" keyword is more of a weirdism of PHP than
standard practise.
http://en.wikipedia.org/wiki/Global_variable#C_and_C.2B.2B

Dotan Cohen

unread,
Oct 31, 2012, 4:02:20 PM10/31/12
to vim...@googlegroups.com
Exactly. However, there is no flow control outside of main(), so I
don't account for variables declared outside of main(). If someone is
declaring a variable in an area of the program with no flow control,
then they are explicitly declaring their intentions that the variable
will be global. In other words, it is not a surprise or a gotcha when
the variable is available in a different scope.

Tony Mechelynck

unread,
Nov 1, 2012, 3:09:33 AM11/1/12
to vim...@googlegroups.com, Dotan Cohen
On 31/10/12 21:02, Dotan Cohen wrote:
> On Wed, Oct 31, 2012 at 9:52 PM, donothing successfully
> <donothings...@gmail.com> wrote:
>> On 31 October 2012 19:15, Dotan Cohen <dotan...@gmail.com> wrote:
>>> [�]
>>> #include <stdio.h>
>>> int foo();
>>>
>>> int main() {
>>> int x = 42;
>>> printf("%d", x);
>>> foo();
>>> return 0;
>>> }
>>>
>>> int foo() {
>>> printf("%d", x);
>>> }
>>> [�]
>> Here x is a local variable of the function *main*.
>> I think the "global" keyword is more of a weirdism of PHP than
>> standard practise.
>> http://en.wikipedia.org/wiki/Global_variable#C_and_C.2B.2B
>>
>
> Exactly. However, there is no flow control outside of main(), so I
> don't account for variables declared outside of main(). If someone is
> declaring a variable in an area of the program with no flow control,
> then they are explicitly declaring their intentions that the variable
> will be global. In other words, it is not a surprise or a gotcha when
> the variable is available in a different scope.
>
>

In Vimscript, an interpreted language, there are no "declarations": any
command needs to be "executed" in order to have an effect. It is when
flow control goes through the :au, :map, :abbrev, :function or :command
command, for instance, that the autocommand, mapping, abbreviation,
function definition or user-command definition are stored in interpreter
memory; before that, Vim doesn't "know" anything about them. Similarly,
the type of a variable is set by the latest :let command affecting that
variable, you cannot "declare" a variable except by giving that variable
a value (possibly an empty value such as "", [] or {}).


Best regards,
Tony.
--
Vote for ME -- I'm well-tapered, half-cocked, ill-conceived and
TAX-DEFERRED!

Ben Fritz

unread,
Nov 1, 2012, 10:38:00 AM11/1/12
to vim...@googlegroups.com
On Wednesday, October 31, 2012 3:02:30 PM UTC-5, dotancohen wrote:
>
> Exactly. However, there is no flow control outside of main(), so I
> don't account for variables declared outside of main(). If someone is
> declaring a variable in an area of the program with no flow control,
> then they are explicitly declaring their intentions that the variable
> will be global. In other words, it is not a surprise or a gotcha when
> the variable is available in a different scope.
>

If somebody declares a variable with a g: prefix in Vim, they are explicitly declaring their intentions that the variable will be global. In other words, it is not a surprise or gotcha when the variable is available in a different scope. Am I misunderstanding your complaint?

Dotan Cohen

unread,
Nov 4, 2012, 1:19:48 PM11/4/12
to Tony Mechelynck, vim...@googlegroups.com
On Thu, Nov 1, 2012 at 9:09 AM, Tony Mechelynck
<antoine.m...@gmail.com> wrote:
> In Vimscript, an interpreted language, there are no "declarations": any
> command needs to be "executed" in order to have an effect. It is when flow
> control goes through the :au, :map, :abbrev, :function or :command command,
> for instance, that the autocommand, mapping, abbreviation, function
> definition or user-command definition are stored in interpreter memory;
> before that, Vim doesn't "know" anything about them. Similarly, the type of
> a variable is set by the latest :let command affecting that variable, you
> cannot "declare" a variable except by giving that variable a value (possibly
> an empty value such as "", [] or {}).
>

I realize that. I just stated that Vimscript is different than other
environments that I am familiar with, and that it was good of you to
point out an important difference.

Dotan Cohen

unread,
Nov 4, 2012, 1:20:43 PM11/4/12
to vim...@googlegroups.com
On Thu, Nov 1, 2012 at 4:38 PM, Ben Fritz <fritzo...@gmail.com> wrote:
> If somebody declares a variable with a g: prefix in Vim, they are explicitly declaring their intentions that the variable will be global. In other words, it is not a surprise or gotcha when the variable is available in a different scope. Am I misunderstanding your complaint?
>

I have no complaint. I just mentioned that Vimscript differs from
other environments.
Reply all
Reply to author
Forward
0 new messages