Dimitar Slavchev
Dimitar Slavchev

Reputation: 1667

Search and replace a multiline pattern inside Vim

I have a function like

myFunction (
  myStruct_1_Ptr *var1, /* commenty */
  myStruct_2_Ptr *var2, /* commenty */
  myStruct_3_Ptr *var3, /* commenty */
  int info1,
  int info2,
  int info3,
  int info4
)

Than I moved all those infos inside a wrapping struct and I want to make it look like

myFunction (
  myStruct_1_Ptr *var1, /* commenty */
  myStruct_2_Ptr *var2, /* commenty */
  myStruct_3_Ptr *var3, /* commenty */
  myStruct_4_Ptr *var4  /* This is where all infos went in */
)

The function is invoked by a similar syntax, by just removing the syntax in front.

myFunction (
  var1, /* commenty */
  var2, /* commenty */
  var3, /* commenty */
  var4  /* This is where all infos went in */
);

How can I do it with search and replace (or anything else)? I have written here only the declaration part that lives only in two places—in the corresponding .c and .h files, but I want to do it similarly with all the places I invoke the function. The variables' names that are given to the function are all the same.

An alternative way to S&R could probably be to execute a macro on all instances of the function across multiple files, but I am unsure how to do that.

Upvotes: 4

Views: 4359

Answers (1)

Tom Whittock
Tom Whittock

Reputation: 4220

If it's a simple function call with no nested parens, then you can do it with a substitute command, something like this:

:%s/\(myFunction\_s*(\(\_[^,]*,\)\{3}.*\_s*\)\_[^)]*/\1var4\r/

then you can do that across all open buffers with :bufdo, but this is really specific and comes with tons of caveats about no nested brackets, no commas is comments and I'm sure tons of other cases where it won't work right.

The key is \_ which extends character classes and . to match newlines.

Upvotes: 9

Related Questions