How do I create a custom operator that works with motions and text objects?
Answer
:set operatorfunc=MyFunc<CR>g@
Explanation
Vim lets you define custom operators that behave like built-in ones (d, c, y) — they wait for a motion or text object, then act on the selected region. This is done by setting operatorfunc to your function and triggering it with g@.
How it works
operatorfuncis a Vim option that holds the name of a function to call wheng@is usedg@{motion}calls the function set inoperatorfunc, passing the motion type (line,char, orblock) as an argument- The function receives the region between
'[and']marks and can manipulate it however you want - You typically map
g@behind a custom key so it feels like a native operator
Example
Create an operator that wraps text in parentheses:
function! WrapInParens(type)
'[,']s/\%V.*\%V./(&)/
normal! `[
endfunction
nmap <silent> gw :set operatorfunc=WrapInParens<CR>g@
vmap <silent> gw :<C-u>call WrapInParens(visualmode())<CR>
Now gwiw wraps a word in parentheses, gw$ wraps to end of line, and visual selection with gw also works.
Tips
- The
typeargument is'line','char', or'block'— use it to handle different motion types - Always use the
'[and']marks to find the operated region - In Neovim, you can also use
vim.keymap.setwithopfuncfor Lua-based operators