3

I'm writing a plugin where I have several buffers open in split panes ( let's call them small panes ). The user can navigate between the small pane using the usual ctrl+w , wincmd etc ways. While I have another larger pane ( let's call it the large pane ), into which the buffer moved to should get automatically loaded. I have the following script to do this :

let g:current_buff=1
let g:loading_buffer=0

function! ActionOnWindowSwitch(...)
    if g:loading_buffer == 0
        let g:current_buff = bufnr("%")
        echo g:current_buff
        if g:current_buff != 1
            let g:loading_buffer=1
            :wincmd k
            :buffer g:current_buff
            :wincmd p
            let g:loading_buffer=0
        endif
    endif
endfunction

au BufEnter * call ActionOnWindowSwitch()

But when I run this, I get the error :

E94: No matching buffer for g:current_buff

I have verified by hardcoding the g:current_buff value that the script works in terms of loading the buffer etc. The problem seems mostly in variable substitution. Or that's what is my best guess. Any ideas how this can be fixed ?

1 Answer 1

7

You're correct in your diagnosis of the problem: no variable substitution is being performed. Try replacing the following line:

:buffer g:current_buf

with:

execute "buffer" g:current_buf

(As an aside, note also that the colon characters at the start of your :wincmd lines can also be removed.)

Generally, if you want the value of a variable to be used in a command-line command, you need to build the command as a string and then run it using :execute.

4
  • Thanks, that seems to work !. From wherever I've searched, this is how I've seen the usage of variables in vimscript to be. Would you mind adding some explanation why we had to use a different way in this case ?
    – Gautam
    Commented Feb 20, 2019 at 16:14
  • @Gautam The command :buffer g:current_buf attempts to switch to the buffer with the name "g:current_buf", not the buffer with the number corresponding to the current value of the g:current_buf variable. Does that (plus my edit above) help clarify things? If not, can you give me an example of where a variable is used in a different way so I can try to explain the difference better?
    – Rich
    Commented Feb 20, 2019 at 16:45
  • That clarifies it partially. Why wouldn't ( or shouldn't ) the substitution still occur after the buffer switch, given that I have defined the variable as global ? How is the "switch with the arg as string and not as variable" justified in case of buffer ?
    – Gautam
    Commented Feb 21, 2019 at 5:53
  • 1
    The answer is simple. Only very few vim script commands expect variables or vim like expressions. Most use the given variable literally, because that's how Vim commands work according to the old vi and POSIX. Therefore you have to use :exe and a like to build dynamic commands, that interpolate the given variables. Have a look at :h exe, it mentions it works with expressions, while most other commands use commands (and therefore cannot evaluate expressions) Commented Feb 21, 2019 at 10:01

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.