5

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
  else 
    return 1
  endif

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}
4

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
        endif
    endfor
    return 0
endfunction

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.

3

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
    endif

    " 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
        endif
    endwhile
endfunction

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, privacy policy and cookie policy

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