3

I want to add some text before each return For example we have :

void* foo (){
   if (something){ 
   return A;
   }
do_something;
// That return word may be ignored, because it's comment
do_something;
returns(); //It may ignored to
return ;
}

I need :

void* foo (){
   if (something){
   END;
   return A;
   }
do_something;
// That return word may be ignored, becouse it's comment
do_something;
returns(); //It may ignored to
END;
return ;
}

I can't build regex for search request. It may looks like "

return"< some text here started with space symbol, or nothing >;<endline>

How I can make it in VIM?

4
  • 4
    What do you mean by "I can't build regex for search request." What did you try that didn't work? Commented Jul 18, 2013 at 18:31
  • You can substitute patterns in vim by first getting to the command mode. That is done by typing ':'. Then you can substitute patterns in the whole file by '%s///'. If you had a file with the text 'test' then '%s/test/two\rlines/' will replace the word 'test' with 'two', then a newline, then 'line'. For you '%s/returns();/returns();\rEND;/' may be what you are going for, but I'm not 100% on what you are intending. Commented Jul 18, 2013 at 18:59
  • A tutorial on and reference for Vim regular expressions: vimregex.com Commented Jul 18, 2013 at 22:35
  • Thanks for tutorial. I don't understand how can i missed it when googled. About search requests..... Before it I made macroses with simple logic: /return^MOEND;^[<80>kd (search "return" and add "END;" before it), and run it 1000 times (with set nowrapscan). Main problem was that /return search word "return" in coments. The main question was "What regex (for "return ;" "return var;" but not "// return") i need write after / to search what i whant? " Commented Jul 21, 2013 at 12:45

5 Answers 5

7

Using hold registers is an easy way to do this:

%s/^\(\s*\)\(return\>.*\)/\1END;\r\1\2/g

The meanings:

%s - global substitute
/  - field separator
^  - start of line
\( - start hold pattern
\s - match whitespace
*  - 0 or more times
\) - end hold pattern
\> - end of word boundary (prevent returns matching return)
.  - match any character
\1 - recall hold pattern number 1
\2 - recall hold pattern number 2
\r - <CR>
g  - Replace all occurrences in the line
Sign up to request clarification or add additional context in comments.

Comments

2

You may use the global command as follows:

:g/^\s*return\>/normal OEND;

It searches for lines having any number of whitespace and the word return, executes the command O and adds the "END;"

Bonus feature the END; is 'auto indented'.

1 Comment

Thanks. Now I know about multiple repeats. I take macros, set nowrap scan and repeat macros about 1000 times before that day. But now i'll do same work easier. Thank you.
0

Use a substitution:

:%s/\(return\)/END;\r\1/g

The substitution searches for occurrences of return, remembers such occurrences and places END; followed by a newline in front of those occurrences. You may want to read up on regular expressions in vim's substitution. Note that \(\) groups characters such that a group can be referenced in the substitution again.

Edit

Lets make that example more specific (I hope I hit your corner cases):

:%s/\(return\(\((\|\s\)[^;]\)*;\)/END\r\1/g

The regular expression matches every occurrence of return which is followed by whitespace or opening parenthesis and subsequent characters until ; is encountered. Such an occurrence is substituted with itself and a prepended END.

1 Comment

I think it's a little more complicated than that. The poster has some cases in the code that he wants ignored and your regex will hit all of them. return appears multiple times like in returns(); and in the comment.
0

:%s/.*\(\/\/.*\)\@<!\<return\>.*/END\r&/g

This basically says "find any line with a return statement that's not in a comment and replace it with END, newline, then the original line". The key to this is the lookbehind (\(\/\/.*\)\@<!) which essentially ignores any instances of return in a comment. The \<return\> makes sure you only search for return and not something like returns.

I tested using:

//return here
return; // return as mentioned
if (cornerCase) { return 1; }
returns();
return 0;

Which became this after the replace:

//return here
END
return; // return as mentioned
END
if (cornerCase) { return 1; }
returns();
END
return 0;

Comments

0
:%s/^\(\s*\)\<return\>/\1END;\r&/

Use & to return what was matched. Similar to \0 in Perl.

Comments

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.