The problem with the often used
noremap j gj
noremap k gk
option is, that it breaks the <vcount>
functionality, if you have lines in your text, which span across multiple lines.
Example: you want 10k
(go UP 10 lines), because you use relative numbers in the sidebar, but theres a multiline with 4 lines height. Therefore you end up effectively at 6 lines (6k
) above your desired line, which you read from your relative numbers. You'd have to calculate manually! Annoying... Especially if you have multiple multiline between your current position and your desired position - not Vim-istic!
I like my <vcount>
function together with my :relativenumber
, which is why I wrote the following functions & mapping to solve all problems related to this.
These functions let you use commands like 10j
or 10k
as expected, despite the presence of multilines with all the advantages of using gj
and gk
as your default movement mappings:
Edit:
I just found the following on reddit, which is so much better then my own solution. This is shortest possible version:
nnoremap <expr> j v:count ? 'j' : 'gj'
nnoremap <expr> k v:count ? 'k' : 'gk'
(If you use noremap
instead of nnoremap
, then this works in both visual and normal modes)
"Longer" version for better understanding and completeness:
nnoremap <expr> k (v:count == 0 ? 'gk' : 'k')
nnoremap <expr> j (v:count == 0 ? 'gj' : 'j')
source: http://www.reddit.com/r/vim/comments/2k4cbr/problem_with_gj_and_gk/
My old solution:
nnoremap <silent> j :<C-U>call Down(v:count)<CR>
vnoremap <silent> j gj
nnoremap <silent> k :<C-U>call Up(v:count)<CR>
vnoremap <silent> k gk
function! Down(vcount)
if a:vcount == 0
exe "normal! gj"
else
exe "normal! ". a:vcount ."j"
endif
endfunction
function! Up(vcount)
if a:vcount == 0
exe "normal! gk"
else
exe "normal! ". a:vcount ."k"
endif
endfunction