Reputation: 9611
I have blocks of code that look like:
ICar car = new Car<int>(10);
var result = car.Start(100);
Assert.IsTrue(result.IsValid);
That I want to convert to this:
Assert.IsTrue((new Car<int>(10).Start(100)).IsValid);
I have about 20 of these types of snippets with the exact same format, could this be automated in vim?
Upvotes: 1
Views: 199
Reputation: 12603
Macros are the easiest, but another way to do it is with global commands - :g/
regular expression/
Ex command. For example(not your example - we will get to it later), you can use :g/^\s*ICar/delete
will delete all lines starting with ICar
(^
is for start of line, \s*
is for skipping the tabs and spaces used for indention).
The advantage of this method over macros is that you can use it on a range: go into visual mode, mark the part you want to refactor, and use the global command. Only matches in the marked block will be affected. If you use macros, you need to either press @@
over and over again until you clear the block, count the exact number of times you want the macro to run, or set a high number and make the no-match error stop the macro. While the third option is quite easy to execute, it's also quite dangerous - you need to make sure the pattern appears only in the parts you want to refactor - so it won't affects unrelated parts of the code - and that the refactoring removes it - otherwise the macro will run on the same lines over and over again.
The advantage of macros is that they are easier to record. In complex refactoring like yours, the global command you need to run can be very long and complex. A macro to do the same thing is just as long and complex as a global command - but you can see how it works while you record it - much easier than calculating the result in your head while designing the global command.
Luckily, you can enjoy both world!
First you record your macro like cdleonard explained in his answer, with two main differences.
The first one is that the first keystroke in the macro should be ^
or _
- to go to the first non-white-space character in the line(that means you start with qq_
and then record as usual). This will guarantee the macro starts from the right place in the line every time.
The second difference is that you don't need to go to the next snippet in the end of the macro. The global command will take care of that for you.
After you've recorded the macro(I'll assume you recorded it to q
) mark all the snippets using visual mode, and type :g/^\s*ICar/norm @q
- this will search the marked range for all lines that begin with ICar
(possibly with indentation before them) and performs the macro on them. This is assuming everything in the range that begins with ICar
- and only those places - are snippets you want to refactor. If you have lines that begin with ICar
and you don't want to refactor, or if you have lines that you do want to apply the macro to, but they don't begin with ICar
- you will have to modify the regex.
Upvotes: 3
Reputation: 51603
:%s:^.* = \([^;]\+\);\_.[^.]\+\([^;]\+\);\n\n\+\([^(]\+\)(.*\.\(.*$\):\3((\1\2).\4
Will do it with the exact same format (placement of .
s and =
, etc are important in the original pattern.
HTH
Upvotes: 3
Reputation: 7050
Crash course in macros:
You can then type @q to execute the q macro and reformat one snippet. If it works as expected then type 20@q to execute 20 times.
Upvotes: 5