0

I'm trying to do the following:

let b:toggleThisAlso = 1
let b:toggleThis = 1
function! Toggle(Toggle)
    if !exists('Toggle')
        let Toggle=1
    endif
    if Toggle == 1
        let Toggle = 0
        return Toggle
    else
        let Toggle = 1
        return Toggle
    endif
endfunction
function! ToggleOne()
    call Toggle(b:toggleThis)
endfunction

function! ToggleTwo()
    call Toggle(b:toggleThisAlso)
endfunction

and it's not working. Of course, there's some more stuff happening, but that's not what's affecting the functionality. I'm just executing a different norm (either norm xppi or norm xpa) command based on the value of, in this case, b:toggleThis or b:toggleThisAlso. What's going on here?

2
  • I didn't look further but your use of quotes is backward: do call Toggle('b:toggleThis') and if !exists(Toggle). Commented Nov 21, 2014 at 21:40
  • If I swap the quotes as you suggested vim yells at me for an invalid function argument on exists() and a couple related errors. Commented Nov 21, 2014 at 21:49

2 Answers 2

1

The issue is vim's variables have scope. Just like there is a buffer scope, b:, there are other scopes : global(g:), window(w:), script(s:), vim(v:), and argument(a:).

Lets start by fixing your "toggle" function:

function! Toggle(name)
  let b:{a:name} = !get(b:, a:name, 0)
  return b:{a:name}
endfunction

So what is going on here:

  • use a:name to refer to the function argument
  • a:name is the name of the buffer variable
  • vim's variables are basically Dictionaries. b: is the entire Dictionary for the buffer
  • {...} syntax inside of the variable will run an expression as part of the name (See :h curly-braces-names)
  • use get() function to get the variable and return a default value
  • Maybe consider using s: scope for your function: function! s:toggle(...)

Now you can do your other toggle functions: ToggleOne and ToggleTwo like so:

function! ToggleOne()
  execute "normal! " . (Toggle('toggleThis') ? 'xa' : 'xppi')
endfunction

Warning: This Toggle function causes side-effects so make sure you document your code well.

I do not know what the norm! xa and norm! xppi commands are supposed to be doing. a or i in a function like this will basically just move the cursor not leave you in insert mode. It may be worth describing what you are actually trying to accomplish instead of how you are trying to accomplish something.

For more help see the following:

:h variables
:h E121
:h get(
:h curly-braces-names
:h :funciton
:h a:var
:h local-variables
Sign up to request clarification or add additional context in comments.

3 Comments

Cool, but now how do I incorporate the other commands? The curly brace syntax is cool, and really useful, but I don't know if I made the problem clear. I solved the problem as well, but not as elegantly. If Stackoverflow will let me, I'll post my solution as an answer and you can critique it, if you feel like it.
@Jonathan 1) how do I incorporate the other commands? I gave you an example of your new ToggleOne function. 2) Your question seem to me is "Why is my Toggle function not working?". If this is no longer your question or you have a different one then create a new post with your actual question.
I just posted my solution. I edited my original code a bit and I think that made the big picture a bit muddy.
0

It turns out that Peter Rinckler had a solution, and the root cause of my problem is the same as what he said. This is the solution I came up with. I wasn't scoping my variables correctly. Since I'm new to Vim scripting, this is more clear, but it may not be the best, so I'll leave it un-accepted for a while and see if a better one comes along.

function! Toggle(Toggle)
    if a:Toggle == 1
        norm xppi
        let l:T = a:Toggle
        let l:T = 0
        return l:T
    else
        norm xa
        let l:T = a:Toggle
        let l:T = 1
        return l:T
    endif
endfunction
function! ToggleThis()
    if !exists('b:toggleThis')
        let b:toggleThis=1
    endif
    let b:toggleThis = Toggle(b:toggleThis)
    return b:toggleThis
endfunction

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.