The Ultimate Vim j/k Binding
As a user of relativenumber, I get a bit more mileage out of j and k than many Vim users. It enables me to quickly see how far away I am from a line, making jumps like 28j easy and practical. However, relativenumber works with lines delimited by newline characters, not the lines you see on the screen. And if a line wraps, j and k will move by text lines, not visual lines, causing awkward jumps. Because of this, may users have this in their .vimrcs:
nnoremap j gj
nnoremap k gk
But, since j and k no longer act on text lines, 23j may no longer go the the line marked 23 in the gutter. If there is a wrapped line between the cursor and the target, it will actually take multiple presses of j to pass that line, meaning that the cursor's end position will be too high. A good way to get around this would be to have single presses of j and k act as gj and gk while j and k with a count would act normally.
The other issue that bothered me was that large j and k jumps didn't get added to the jumplist, meaning that there was no easy way to undo and redo them. That can be fixed by automatically setting the ' mark if j or k is executed with a count.
So, without further ado, this is what I've come up with:
nnoremap <silent> k :<C-U>execute 'normal!' (v:count > 1 ? "m'" . v:count : 'g') . 'k'<CR>
nnoremap <silent> j :<C-U>execute 'normal!' (v:count > 1 ? "m'" . v:count : 'g') . 'j'<CR>
This does the following:
- For an n
jcommand,m'njis instead executed - For a
jcommand without a count,gjis instead executed
It's not perfect - in visual mode, j and k revert to their normal definitions, but I'm really enjoying its more intuitive behaviour in normal mode.