I'd like to have a mapping that separates words, like this:

noremap RJ :s/\>\s*\</\r/g<CR>=''

I can do 3RJ with that.

I can also create opfunc, so I can do RJ}:

noremap RJ :set opfunc=splitline#splitline<CR>g@

function! splitline#splitline(type) range abort
    execute line("'[") . ',' . line("']") . 's/\>\s*\</\r/g'
    let @/ = @"
    normal =''

But how do I combine those two approaches together?


1 Answer 1


Usually you would have a separate mapping for an operator that would work on the current line and take a count to work on a set of lines. For example, you could have RJ{motion} to act on a motion or text object, and RJJ to act on the current line or on a set of lines if given a count.

Having said that, you can have your mapping behave differently and act on a set of lines (possibly only one) when given a count, and expect a motion when not given one.

All you have to do is make it an <expr> mapping and then check whether v:count is larger than 0 to implement the first case.

You could duplicate the logic of :s/\>\s*\</\r/g to implement the case where a count is given, but perhaps easier is to set 'opfunc' unconditionally and then use g@_ for the case where you want to consider only the current line, or "n" lines when given a count.

(See :help _ for more information on the _ motion. The _ motion is typically equivalent to the double letter commands, e.g. yy is the same as y_, dd same as d_, cc same as c_ and so on. It's very useful to refer to the current line and work for "n" lines when given a count.)

Putting it all together:

function! splitline#setup_splitline()
    set opfunc=splitline#splitline
    if v:count > 0
        return 'g@' . v:count . '_'
        return 'g@'

nnoremap <expr> RJ splitline#setup_splitline()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.