Troy Daniel
Troy Daniel

Reputation: 1

vim: multiple conditions for different lines

Is there any way to act on a line when serveral conditions matches only. For exmaple, I have the text as

This is a blue coat
This is a red  coat
This is a purple coat
That is a coat

(PS: This text is borrowed from a nother similar question.) If the current line matches ^This and the following line matches red, and then do the normal command A some text to be appended{Esc}.

There is a simple way to achieve this like:

:%s/^This.*\ze\n.*red/&some text to be appended/e

However, when the conditions increase, the regex booms. Besides, this solution is not as elegant as I expected. Is there anyway to be accomplished with :gloabl command?

After some answers given, I've found my question isn't clear enough, thus I append the following pseudo command to show what I'm seeking for. The elegant way to achieve this for me is something like(but the following code won't work):

:g/^This\C/;.+1g/red/norm Asome text to be appended

The problem is, the first :g command won't pass lines but not block (I'm not sure if I'm correct), so it's unlikely to filter the biased condition (red, 1 line after).

If there exists a solution, thus I can easily handle the following actions: Print "the line and three lines following" on condition that "the line contains This and 100 lines later contains red".

I hope I've made myself clear.

Upvotes: 0

Views: 388

Answers (3)

Troy Daniel
Troy Daniel

Reputation: 1

Finally, I solved this problem by scripting. And I pushed the code to github in case any others need it. Please refer to EnhancedG.vim. For requirements:

  1. The current contains [a-z];
  2. 3 lines after contains \d;
  3. 2 lines before contains example;
  4. Perform appending Some text to the line before; will be a simple ex-command:
:G/[a-z]/+3/\d/-2/example/norm ASome text

And another example: For requirements:

  1. The current contains to delete;
  2. The next line does not matches ^$;
  3. Delete the current line;

would simple be:

:G/to delete/+!/^$/d

I hope it will be helpful.

Upvotes: 0

Dmitry
Dmitry

Reputation: 446

If I understand right, you want to append text at the end of each matched first line, but not with :subst command.

:global with :normal will help you achieve it:

:g/^This.*\ze\n.*red/normal Asome text to be appended

If you want to append to second line, just add "j" like this:

:g/^This.*\ze\n.*red/normal jAsome text to be appended

Upvotes: 1

SergioAraujo
SergioAraujo

Reputation: 11800

I would use \v which means "very magic search" so you can use regex groups like this:

/\v(red|blue|purple)

Then your regex matches each one of the above options you want. It would be better to show us the desired output, so we could understand better what you want as a result.

Upvotes: 0

Related Questions