DavisDude
DavisDude

Reputation: 952

Vim - Map alternate key behavior depending on context

I have my column numbers set to relative mode because I like not counting. I also have nnoremapped j to gj so that it's easier to work with line wraps. The problem is that when I do a motion (say 2j) on a line that's wrapped, it doesn't move me up two rows, but two "lines".

In order to fix that, I would like to have j mapped to gj for regular movement, but act like regular j when given count. I have tried the following command in my vimrc:

"  Up and down now don't skip line-wraps unless given count
fun! MoveLines( lines, type )
    if ( a:lines == 1 )
        let a:str = 'g' . a:type
    else
        let a:str = a:lines . a:type
    endif
    call feedkeys( a:str )
endfun

nnoremap <silent> j :<C-U>call MoveLines( v:count1, 'j' )<CR>

This works fine when I just press j. The problem is when I try to give it a count: it calls itself recursively (as would be expected). I could try using cursor, but is it possible to do it without this way?

How can I conditionally map j to act as gj when not given a count, but act like normal when given a count?

Upvotes: 2

Views: 293

Answers (1)

Peter Rincker
Peter Rincker

Reputation: 45087

You can use v:count to get the current count given. If nothing is provided it is set to zero.

nnoremap <expr> j v:count == 0 ? 'gj' : 'j'

For more help see:

:h v:count
:h :map-<expr>

Upvotes: 2

Related Questions