0

Let's say I have some code:

divide(int x) {
int a = 0;
a += x;
}

subtract(int x) {
int b = 0;
b += x;
}

multiply(int x) {
int c = 0;
c += x;
}

I'm using VIM and I'd like to be able to search and replace each instance of += with {'/=', '-=', '*='} in that order, using the vim command line. I'd like to use :%s/+=/..., but I'm not sure how.

I also thought about using python in vim like this, but I would prefer a simpler solution entirely in VIM, if possible.

1

2 Answers 2

2

If all of your += occur on different lines:

:let c=0 | g/\m+=/ s!\m+=!\=['/=', '-=', '*='][c%3]! | let c+=1

If there might be more than one += on the same line:

:fu! Cycle() | let c+=1 | return ['/=', '-=', '*='][c%3] | endf
:let c=-1 | %s/\m+=/\=Cycle()/g

References:

  • :h :global
  • :h s/\=
Sign up to request clarification or add additional context in comments.

1 Comment

Ok, thanks for the answer! Could you explain a bit in detail about why this works?
1

Here is a shorter variant of @SatoKatsura's answer. It first defines a List of replacements, then uses a :help sub-replace-expression to remove the first element of the list.

:let replacements = ['/=', '-=', '*='] | %s#+=#\=remove(replacements, 0)#

If there are more than 3 replacements, and you want repeating of the replacements, use this:

:let replacements = ['/=', '-=', '*='] | %s#+=#\=add(replacements, remove(replacements, 0))[-1]#

2 Comments

Ok, so then why does this work exactly? I understand everything up to the first # after %s.
remove() returns the element that is removed from the pre-populated list. So, each substitution removes (and uses) one element from the list. The second variant prevents that the list gets empty by re-adding each element again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.