Is there a robust way to detect whether a window has a neighbour in a given direction? So far, the only solution I found uses wincmd,

  let winnum = winnr()
  noautocmd wincmd h
  if winnum != winnr()
    noautocmd wincmd l
    return 0
    return 1

but is it robust? Ideally, I would like to find a way that does not use wincmd; perhaps something similar to the following tmux command:

tmux display-message -p #{pane_at_left}

3 Answers 3


The winnr function was updated to take movement arguments as patch 8.1.1140 on April 8, 2019. If your version of Vim has this updated function, :echo has('patch-8.1.1140') will output 1.

The movement argument can be 'h', 'j', 'k', or 'l', optionally preceeded by a count. For example, winnr('h') will return the window number of the window to the left of the current window. If there is no window to the left, the current window's window number will be returned. This can be used to check whether the current window has a neighbor to the left, where winnr() !=# winnr('h').


You can do this by looking at the window positions. Take "right" as an example. If any window has a left column position greater than the current window's rightmost column, then the current window has some right neighbor. Think about this for a few minutes. Of course, you would need to write similar functions for the other cardinal directions.

function! HasWinToRight()
    let l:rightedge = win_screenpos(0)[1] + winwidth(0) - 1
    for l:win in range(1, winnr('$'))
        if l:win != winnr() && win_screenpos(l:win)[1] > l:rightedge
            return 1
    return 0

This solution is much more robust than any that switches windows, since window switching has unpredictable side-effects, even with noautocmd.

It will not tell you which window is to the immediate right, as defined by wincmd l. In general this would also depend on the cursor position and row positions of the other windows. That is, a window may have many right neighbors but wincmd l picks one.


I am a little late after @Mass but I tried to do a more generic function which takes the direction to test as argument:

" Values of the argument
"   1 : Top
"   2 : Right
"   3 : Bottom
"   4 : Left
function! HasNeighbour(direction)
    " Position of the current window
    let currentPosition = win_screenpos(winnr())

    if a:direction == 1
        " if we are looking for a top neigbour simply test if we are on the first line
        return currentPosition[0] != 1
    elseif a:direction == 4
        " if we are looking for a left neigbour simply test if we are on the first column
        return currentPosition[1] != 1

    " Number of windows on the screen
    let winNr = winnr('$')

    while winNr > 0
        " Get the position of each window
        let position = win_screenpos(winNr)
        let winNr = winNr - 1

        " Test for window on the right
        if ( a:direction == 2 && ( currentPosition[1] + winwidth(0) ) < position[1] )
            return 1
        " Test for windo on the bottom
        elseif ( a:direction == 3 && ( currentPosition[0] + winheight(0) ) < position[0] )
            return 1

This way if you want to know if the current window has a right neighbour you can use HasNeighbour(2), to test for neighbour on the left HasNeighbour(4) will do, etc...

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.