Using a macro or a
:s command is probably the easiest way to get this task done...
But if you'd like to explore an alternative, then the
gn command is a good fit. This commands selects the next search match in a visual selection. You can use it as a text object, so you can have your
ys command act on the
gn block, which you can then simply repeat with a
., without the need for a motion to get to the next match.
The problem with using the
gn command here is that we need a fairly complex regular expression, since it needs to only match the text before the modification, but not match it after it. If the search pattern still matches the text after the modification, the
gn command will apply the modification again to the current block, rather than skip to the next one.
So let's come up with a search that will match sequences of non-whitespace characters, as long as they don't start with a single quote.
This search pattern should work:
If you have
'hlsearch' set, you'll see Vim highlighting each of the individual words,
four. If you surround any of them with
', it will stop being highlighted, which means it will no longer match.
This regex is fairly complex. I'm using "verymagic" mode to avoid having to backquote many metacharacters. Then I'm matching a start of line
^ or a space, but I'm using a zero-width match-behind
/\@<= to match it without including it into the pattern. This is to ensure we only match beginning of words. Then I'm using
[^' \t] to match a character other than the single quote, a space or a tab. So this is the start of a word (sequence of non-whitespace characters) that doesn't start with a single quote.
Having performed this search, we're ready to use the
gn magic. Set your cursor somewhere in the first word you want to change, in this case
one, and then use:
This will surround the
one in single quotes:
'one'. If you have
'hlsearch' enabled, you'll see that
'one' is no longer highlighted, since it's not a match anymore.
At this point, you can repeat the
ysgn' command with a single
.. Since the word under the cursor is not a match, Vim will jump forward to the next match and act on it, so you'll get
'one' 'two'. Repeat it one more time with
. and you'll get
'three', and finally one last
So this is probably overkill for this specific case, but when you're doing operations that modify the term enough that it's easy to match it before the change and not match it after the change, this technique is super useful. One great example is switching identifiers from
CamelCase or vice-versa.