What I would like to do is issue a raiw where the current word would be replaced by an aaaaa word.


this is a w[o]rd <--- cursor on []
raiw             <--- command
this is a aaaa   <--- result.

Here iw is a motion, but it could be any motion.

a markdown recurring example:

|    -  [ ]  |   <--- cursor on []
rai|             <--- command
|------------|   <--- result
  • 5
    Why not simply v{text-object}ra? I'm sure you can afford one more character without any impact on your productivity.
    – romainl
    Aug 26, 2016 at 16:08
  • @romainl: because that it's not repeatable through usage of the . operator.
    – ninrod
    Aug 26, 2016 at 16:13

1 Answer 1


Like romainl said, the easiest way to that is with visual mode. However, if you absolutely want this to be an operator, you can define you own with operatorfunc. From :help opfunc

                        *'operatorfunc'* *'opfunc'*
'operatorfunc' 'opfunc' string  (default: empty)
            {not in Vi}
    This option specifies a function to be called by the |g@| operator.
    See |:map-operator| for more info and an example.

Basically, the way it works is you define a function like this:

function! Replace(type, ...) range

and :set opfunc=Replace, and now the g@ operator will call your function like an operator. From :help g@

g@{motion}  Call the function set by the 'operatorfunc' option.
            The '[ mark is positioned at the start of the text
            moved over by {motion}, the '] mark on the last
            character of the text.
            The function is called with one String argument:
                "line"  {motion} was |linewise|
                "char"  {motion} was |characterwise|
                "block" {motion} was |blockwise-visual|

When your function is called, it will set two marks: '[ and ']. The first one is the start of whatever motion your function was called with, and the second was the end. Then you check the string argument to see if the motion was linewise, characterwise, or blockwise. Then inside your function, you can use these marks to visually select whatever text you want to operate on. Putting this all together, we have the following:

function! Replace(type, ...) range
  if a:0
    silent exe "normal! gv"
  elseif a:type == 'line'
    silent exe "normal! '[V']"
    silent exe "normal! `[v`]"

  let r = nr2char(getchar())
  silent exe "normal! r".r

nnoremap r :set opfunc=Replace<cr>g@

It's worth noting that the order of keystrokes is reversed from what you described, e.g. rather than


you would have to press


I have tested this, and it sort of works with the dot operator, but you still have to enter the character you would like to replace the motion with. With some more hacking, and possibly with tpope/vim-repeat, you might be able to figure out the rest.

Hope that helps!


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.