Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to have window navigation wrap around in VIM

I would like it so that typing Ctrl-Wk from the right most window would focus the left most window in VIM. Obviously it would be handy for this to work in all directions.

My main motivation is for use with NERDTree. I typically have the following setup:

|----------|----------|-----------|
|          |          |           |
| NERDTree |   File1  |   File2   |
|          |          |           |
|          |----------|-----------|
|          |          |           |
|          |   File3  |   File4   |
|          |          |           |
|----------|----------|-----------|

If I want to open a new file in the same window as File4 I currently have to type 2Ctrl-Wj and it would be quite nice to achieve the same result with Ctrl-Wk.

Thanks.

like image 219
Wes Avatar asked Dec 12 '12 20:12

Wes


2 Answers

You'd have to override the default commands in your $HOME/.vimrc with your own mappings that include this extra logic. When the normal move doesn't change the window any more (i.e. we're at the border already), jump to the other side.

"
" Wrap window-move-cursor
"
function! s:GotoNextWindow( direction, count )
  let l:prevWinNr = winnr()
  execute a:count . 'wincmd' a:direction
  return winnr() != l:prevWinNr
endfunction

function! s:JumpWithWrap( direction, opposite )
  if ! s:GotoNextWindow(a:direction, v:count1)
    call s:GotoNextWindow(a:opposite, 999)
  endif
endfunction

nnoremap <silent> <C-w>h :<C-u>call <SID>JumpWithWrap('h', 'l')<CR>
nnoremap <silent> <C-w>j :<C-u>call <SID>JumpWithWrap('j', 'k')<CR>
nnoremap <silent> <C-w>k :<C-u>call <SID>JumpWithWrap('k', 'j')<CR>
nnoremap <silent> <C-w>l :<C-u>call <SID>JumpWithWrap('l', 'h')<CR>
nnoremap <silent> <C-w><Left> :<C-u>call <SID>JumpWithWrap('h', 'l')<CR>
nnoremap <silent> <C-w><Down> :<C-u>call <SID>JumpWithWrap('j', 'k')<CR>
nnoremap <silent> <C-w><Up> :<C-u>call <SID>JumpWithWrap('k', 'j')<CR>
nnoremap <silent> <C-w><Right> :<C-u>call <SID>JumpWithWrap('l', 'h')<CR>
like image 118
Ingo Karkat Avatar answered Sep 22 '22 09:09

Ingo Karkat


One can use

<C-w>w

and

<C-w>W

to cycle through all the windows to the right/down and left/up, respectively. Both commands wrap around, so <C-w>w will end up top left at some point and <C-w>W is going to end up bottom right at some point.

See :h window-move-cursor.

Or simply use <C-w>b which goes directly to your target window.

like image 30
romainl Avatar answered Sep 22 '22 09:09

romainl