That is indeed a novel and potentially time-saving feature!
The way to do this in plain Vim would be using :substitute
for a range; the pattern can be easily set via *
when the cursor is on top of it:
*vip:s//hi/g<CR>
A mapping for the :s///g
part that puts the cursor right into the replacement part can save many keystrokes here.
In order to support arbitrary text objects (ip
covers entire lines, which plays well with the :{range}
, but objects like is
don't), the vis.vim plugin can help.
Plugin alternatives
I'm not aware of any plugin that implements this for Vim; however, my ChangeGlobally plugin offers something similar: Instead of having a fixed text (the cword with the operator modifier) applied over the specified {motion}
, it applies the change or delete of a specified {motion}
over a fixed range. I think the implementation could also support the other use case; I might add that to it ...
Update: I've added similar mappings to my plugin. Instead of the o
operator modifier, I went with the plugin's existing mapping scheme. (Also, the plugin only handles changes and deletions, and cannot be applied to other actions like gU
.)
These are the new mappings:
[N]["x]gc*{motion} Delete the current whole \<word\> [into register x]
and start inserting. After exiting insert mode, that
text substitution is applied to all / the first [N]
occurrences inside {motion} text.
[N]["x]gx*{motion} Delete the current whole \<word\> [into register x]
and apply the deletion to all / the first [N]
occurrences inside {motion} text.
[N]["x]gcg*{motion} Delete the current word [into register x] and
start inserting. After exiting insert mode, that text
substitution is applied to all / the first [N]
occurrences inside {motion} text.
[N]["x]gxg*{motion} Delete the current word [into register x] and
apply the deletion to all / the first [N] occurrences
inside {motion} text.
[N]["x]gc_ALT-8{motion} Delete the current whole \_sWORD\_s [into register x]
and ALT-8t inserting. After exiting insert mode, that
text substitution is applied to all / the first [N]
occurrences inside {motion} text.
[N]["x]gx_ALT-8{motion} Delete the current whole \_sWORD\_s [into register x]
and apply the deletion to all / the first [N]
occurrences inside {motion} text.
[N]["x]gcg_ALT-8{motion}Delete the current WORD [into register x] and
ALT-8t inserting. After exiting insert mode, that text
substitution is applied to all / the first [N]
occurrences inside {motion} text.
[N]["x]gxg_ALT-8{motion}Delete the current WORD [into register x] and
apply the deletion to all / the first [N] occurrences
inside {motion} text.
[N]["x]<Leader>gc{source-motion}{target-motion}
Delete {source-motion} text [into register x] and
start inserting. After exiting insert mode, that text
substitution is applied to all / the first [N]
occurrences inside {target-motion} text.
{Visual}[N]["x]<Leader>gc{motion}
Delete the selected text [into register x] and start
inserting. After exiting insert mode, that text
substitution is applied to all / the first [N]
occurrences inside {motion} text.
[N]["x]<Leader>gx{source-motion}{target-motion}
Delete the {source-motion} text [into register x] and
apply the deletion to all / the first [N] occurrences
inside {target-motion} text.
{Visual}[N]["x]<Leader>gx{motion}
Delete the selected text [into register x] and apply
the deletion to all / the first [N] occurrences inside
{motion} text.
:%s/hello/hi/g
or a:%s/hello/hi/gc
if you need to select which occurrences you want to change, but the closest of what you want is to use the dot command (explained in my other answer)word character
? e.g. cursor on;
ofvoid foo();
.