I want to add a motion:

:onoremap <silent> f( :<C-U>normal! f)vF(b<CR>

If I have this line, where the asterisk is my current position:

int a = fo*o(4, 5, 99);

I want to type vf( and select foo(4, 5, 99). Later on I want to add the equivalents for [, {, and <.

However the above sadly doesn't work. This is an altered version of something I found under :help omap-info.

EDIT: Actually, it work with c and d, but not with v. Why is that?

  • You want to select a word and arguments next to it, right? Are you okay with some other mappings then?
    – SibiCoder
    Jun 11 '16 at 9:26
  • Well, yes, show me.
    – hgiesel
    Jun 11 '16 at 9:28
  • How about :nmap \sf bvf(f)?
    – SibiCoder
    Jun 11 '16 at 9:34

Operator pending mode has to be used only when waiting for a motion. You have used f, which waits for a character and moves there. Since you have given both f and ( together, f has got a character to find and move to. Hence, there isn't any operator 'pending'!

So, you can map in normal mode itself, like

 :noremap <silent> f( :<C-U>normal! f)vF(b<CR>

(This works in my vim.)

Or, you can use a simple mapping like

 :nmap \sf bvf(f)

(s - select, f - function)

EDIT: You can put [,{,< instead of ( in the above mappings to use with [,{,<.

You can create your own text objects as well as use plugins like easy motions for that.


You (also) need to address the visual mode map (onoremap doesn't do that):

:xnoremap <silent> f( :<C-U>normal! f)vF(b<CR>

See also: http://vim.wikia.com/wiki/Creating_new_text_objects
(where the omap is made based on the vnoremap).


:onoremap <silent> f( :<C-U>normal! f)vF(b<CR>

works well for

int a = foo(4, 5, 99);

but if you are using fo*o you need you b three times

BTW, you can use

:onoremap <silent> f( :<C-U>normal! f)vF(F l<cr>

  • 1
    * in f*oo is the cursor.
    – SibiCoder
    Jun 11 '16 at 15:03

I accomplished what I wanted to do initially and it works quite nicely. I didn't use (, { and etc. because I made it behave similiar to tpope's vim-surround.

function s:StatementOperator(opennext, closenext)
    let current_col = col(".")
    execute 'normal! m"f' . a:closenext
    let last_col = col(".")
    execute 'normal! vF' . a:opennext . 'b'
    let first_col = col(".")

    if first_col > current_col || current_col > last_col
        normal! v`"

onoremap <silent> pb :<c-u>call <sid>StatementOperator('(',')')<cr>
onoremap <silent> pB :<c-u>call <sid>StatementOperator('{','}')<cr>
onoremap <silent> pr :<c-u>call <sid>StatementOperator('[',']')<cr>
onoremap <silent> pa :<c-u>call <sid>StatementOperator('<','>')<cr>
vnoremap <silent> pb :<c-u>call <sid>StatementOperator('(',')')<cr>
vnoremap <silent> pB :<c-u>call <sid>StatementOperator('{','}')<cr>
vnoremap <silent> pr :<c-u>call <sid>StatementOperator('[',']')<cr>
vnoremap <silent> pa :<c-u>call <sid>StatementOperator('<','>')<cr>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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