10

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.

Wes
  • 101
  • 3
  • You'll most certainly have to write some code to get that accomplished and map it to desired key-combo. Check `:h window-move-cursor`; movement commands are listed there. – plesiv Dec 12 '12 at 21:11
  • That was my thought. Unfortunately I'm not that familiar with vim scripting just yet :) – Wes Dec 13 '12 at 02:36

3 Answers3

7

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>
mcandre
  • 22,868
  • 20
  • 88
  • 147
Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
4

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.

romainl
  • 186,200
  • 21
  • 280
  • 313
0

Here is a Lua version of the other answer if you use Neovim:

local function try_jump_window(direction, count)
  local prev_win_nr = vim.fn.winnr()
  vim.cmd(count .. "wincmd " .. direction)
  return vim.fn.winnr() ~= prev_win_nr
end

local function jump_window_with_wrap(direction, opposite)
  return function ()
    if not try_jump_window(direction, vim.v.count1) then
      try_jump_window(opposite, 999)
    end
  end
end
local opts = { silent = true, noremap = true }
vim.keymap.set("n", "<C-w><C-h>", jump_window_with_wrap("h", "l"), opts)
vim.keymap.set("n", "<C-w><C-l>", jump_window_with_wrap("l", "h"), opts)
vim.keymap.set("n", "<C-w><C-j>", jump_window_with_wrap("j", "k"), opts)
vim.keymap.set("n", "<C-w><C-k>", jump_window_with_wrap("k", "j"), opts)
XiaoChuan Yu
  • 3,951
  • 1
  • 32
  • 44