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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.