Vim Window Navigation Bindings

Note: This entry has been restored from old archives.

Today I finally got peeved enough at typing “:winc [hjkl]” to work out some new bindings. I don’t often work in multiple vim windows so have gotten by until now, but I’ve been using them a lot in the last couple of days. The problem is that the default mapping using <C-w> [hjkl] doesn’t seem to work for me, I can blame my WM for that I think.

So I tried to create mappings using the arrow keys, yes I know this is very “un-vi” and I should stick to [hjkl]. Blah, blah. Note that my arrow keys probably aren’t quite as inaccessible as yours though, I have a rather unusual keyboard layout. Here are the mappings:

noremap <silent> <S-Right> :winc l<CR>
inoremap <silent> <S-Right> <C-O>:winc l<CR>
noremap <silent> <S-Left> :winc h<CR>
inoremap <silent> <S-Left> <C-O>:winc h<CR>
noremap <silent> <S-Down> :winc j<CR>
inoremap <silent> <S-Down> <C-O>:winc j<CR>
noremap <silent> <S-Up> :winc k<CR>
inoremap <silent> <S-Up> <C-O>:winc k<CR>

This in its self wouldn’t be worth writing about. Where it gets a little more interesting is: the mapping doesn’t work! Argh! Through some hunting around I eventually found that the problem is vim (or the termcap, or something) not having the right definition for “Left”, “Right”, “Up”, and “Down” — a pain.

The good news is that you can re-define the definitions, stick this in above the mappings:

set <S-Up>=^[[a
set <S-Down>=^[[b
set <S-Right>=^[[c
set <S-Left>=^[[d

Note that that the initial “^[” is actually a literal escape byte (0x1b), so a copy-paste of this text will not work! To enter the lines above, taking Shift+Up for example, I type “set <S-Up>=” then (still in insert mode) Ctrl-v followed by Shift+Up. There’s probably a neater (printable) notation for the escape, but replacing it with the usual <ESC> doesn’t seem to do the trick. This works and I’m leaving it at that.

Now, a caveat! It turns out that this can change from terminal emulator to terminal emulator. For example, Shift+Up in good old xterm and gnome-terminal gives “^[[1;2A” and rxvt and urxvt (what I use) gives “^[[a“. However, my mappings seem to work in both xterm and rxvt so something somewhere seems to be accounting for this. That’s nice of it!

I wonder if a better fix would be to twiddle the termcap or XDefaults? No time! The mapping works!