Skip to content

Instantly share code, notes, and snippets.

@andymass
Last active July 14, 2018 00:22
Show Gist options
  • Save andymass/fa3934faf0695955ed3815d0ca6475a7 to your computer and use it in GitHub Desktop.
Save andymass/fa3934faf0695955ed3815d0ca6475a7 to your computer and use it in GitHub Desktop.
get window number in a particular direction hjkl
function! WinRect(winnr)
let l:pos = win_screenpos(a:winnr)
return { 'top': l:pos[0],
\ 'left': l:pos[1],
\ 'bottom': l:pos[0] + winheight(a:winnr) - 1,
\ 'right': l:pos[1] + winwidth(a:winnr) - 1,
\}
endfunction
function! Between(a, b, x)
return a:a <= a:x && a:x <= a:b
endfunction
function! WinIsInDir(winnr, dir)
if a:winnr == winnr()
return 0
endif
let l:this = WinRect(0)
let l:other = WinRect(a:winnr)
let l:curpos = [l:this.top + winline() - 1,
\ l:this.left + wincol() - 1]
let l:touches = 0
let l:cursor = 0
if a:dir ==# 'k'
let l:touches = l:this.top == l:other.bottom + 2
" extend one down for vertical separator
let l:cursor = Between(l:other.left, l:other.right + 1, l:curpos[1])
elseif a:dir ==# 'j'
let l:touches = l:this.bottom == l:other.top - 2
let l:cursor = Between(l:other.left, l:other.right, l:curpos[1])
elseif a:dir ==# 'h'
let l:touches = l:this.left == l:other.right + 2
let l:cursor = Between(l:other.top, l:other.bottom, l:curpos[0])
elseif a:dir ==# 'l'
let l:touches = l:this.right == l:other.left - 2
" extend one down for statusline
let l:cursor = Between(l:other.top, l:other.bottom + 1, l:curpos[0])
elseif a:dir ==# 'w'
return a:winnr == winnr() + 1 || winnr('$') == winnr() && a:winnr == 1
endif
return l:touches && l:cursor
endfunction
function! GetWinInDir(dir)
let l:w = filter(range(1,winnr('$')), 'WinIsInDir(v:val, a:dir)')
return len(l:w) ? l:w[0] : 0
endfunction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment