6

I am writing a plugin which needs to have two windows displayed at the same time:

 _______ | | | | A | B | |___|___| 

I need to keep in memory a reference to those windows as I execute my plugin. This is because I need to be able to jump between the two windows automaticaly.

I use the winnr() function that returns the current window number, which I can use later like so:

let s:winA = winnr() new let s:winB = winnr() " stuff " go to window A execute s:winA . "wincmd w" 

But in this case, both variables will have the value 1, this is because the winnr() return the position of the current window in the tab display.

I tried to use the bufnr('%') which return the buffer number for the current buffer. This is great, but when I do:

let s:bufA = bufnr('%') new let s:bufB = bufnr('%') " stuff " go to buffer A execute 'buffer '. s:bufA 

The current window load the buffer, and the cursor will not jump to the existing window containing the buffer.


Here is my question:

How to store permanent information about windows so the cursor can jump on it later?

2 Answers 2

7

I think what you are looking for is the function win_getid() combined to the function win_gotoid().

:h win_getid() says:

win_getid([{win} [, {tab}]])

Get the window ID for the specified window.
When {win} is missing use the current window.
With {win} this is the window number. The top window has number 1.

The advantage of these functions is that ID is linked to a window and does not change when the position of the window is changed

Your script would become something like:

let s:winA = win_getid() new let s:winB = win_getid() " stuff " go to window A call win_gotoid(s:winA) 
3

You can't store a window number reliably because it changes every time a window is created and destroyed. You can use winbufnr() if you know the buffer's ID.

When the buffer doesn't matter, I use a window variable to keep track of the windows I open:

new let w:_plugin_variable = 1 

The variable above is just a boolean, but you could use your own identifier if you want to keep windows paired to each other. For example:

let w:_plugin_variable = ['parent', 123] new let w:_plugin_variable = ['child', 123] 

The first item being the relationship and the second as some special identifier. This way is useful if both windows might contain the same buffer but have different settings/purposes.

To find the windows, you just iterate over all window numbers to get the variable you're looking for:

for i in range(1, winnr('$')) let id = getwinvar(i, '_plugin_variable', -1) if id != -1 " Do something with the information. break endif endfor 

In the loop above, i is the window's number. You can get settings from the window with getwinvar(i, '&textwidth') or switch to it with execute i 'wincmd w'.

The same thing can be done with tabs using tabpagenr(), tabpagewinnr(), gettabvar(), gettabwinvar(), etc.

3
  • Nice! Do you think there's performance drawback from doing this? Commented Jul 10, 2016 at 15:40
  • 1
    @nobe4 I'm pretty sure that any performance impact would be unnoticeable since you'd be dealing with dozens of windows at most (per tab) in realistic scenarios. Commented Jul 10, 2016 at 15:57
  • 1
    See also this answer (useful in a wider context). Commented Jul 10, 2016 at 19:17

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.