Reputation: 60107
What's the best way to do triple state toggling in vim? Can I do something like? (C):
void toggle(void)
{
static int var = 3-1;
var=(var+1)%3;
printf("%d\n", var);
}
int main()
{
toggle(); //0
toggle(); //1
toggle(); //2
toggle(); //0
toggle(); //1
toggle(); //2
}
I tried
fun! Toggle()
let l:var=0
let l:var+=1
echom l:var
endfun
But this always prints 1.
Upvotes: 1
Views: 59
Reputation: 32966
The closest equivalent to C static variables are the script local s:variables. As the name suggests, they are not local to functions but to scripts.
On a side note, I provide a function for this purpose in my library plugin: lh#menu#def_toggle_item()
.
My associated unit tests are over there.
What it does:
:Toggle MenuSubmenuVariable [value]
-- completion is supportedFor instance, this is a complex example which triggers events:
let Data4 = {
\ "variable": "yesno",
\ "values": [ 1, 2, 3 ],
\ "text": [ "No", "Yes", "Perhaps" ],
\ "actions": [ function("s:No"), function("s:Yes"), function('s:Perhaps') ],
\ "menu": { "priority": '42.50.20', "name": '&LH-Tests.&TogMenu.&yesno'}
\}
call lh#menu#def_toggle_item(Data4)
which permits to toggle/cycle with:
:Toggle LHTestsTogMenuyesno " to go to the next state
:Toggle LHTestsTogMenuyesno no " to force a value
:echo g:yesno " -> 1 (associated to "no")
Upvotes: 0
Reputation: 8618
Your variable is local (hence the l
in l:var
) and so every time you call Toggle()
it "resets itself" to zero. You can use a global variable by using the prefix g
.
let g:var=0
fun! Toggle()
let g:var = (g:var + 1) % 3
echom g:var
endfun
And then inside vim:
:call Toggle()
0
:call Toggle()
1
:call Toggle()
2
:call Toggle()
0
I'd recommend prefixing your global variable with some identifier (e.g. let g:pskocik_toggle_count
) to prevent collisions with plugins and other scripts.
Upvotes: 2