[Modified the third solution]
On May 01, 2006, Yakov Lerner pointed out:
>On 5/2/06, Suresh Govindachar wrote:
>>
>> Yakov Lerner wondered:
>>
>>> But how do you remove #ifdef blocks? I mentioned piping
>>> because there is ready utility, 'unifdef', that removes some
>>> or all of #if blocks.
>>
>> Isn't there a way to do a multi-line substitution:
>>
>> :%s/^\s*#ifdef .*^\s*#endif//
>>
>> where the *s are multi-line and non-greedy, or maybe I should
>> say the *s are non-greedy and the . is multi-line? (I
>> haven't actually tried, but I am confident I can do it in
>> perl.)
>
> What if #if/#endif blocks are nested ?
[In the above pseudo :%s expression, replace ifdef by just if.]
I can think of three approaches, the second and third of which I
have tested successfully. While the third is elegant for deleting
#if/#endif blocks, the second is much more flexible.
1) Have . not match ^\s*#if -- so that we can get rid of
inner-most #if/#endif blocks. Repeat this in a while
loop till there are no more ^\s*#if in the buffer.
2) I successfully tested the following all-in-one-line command
(although it is written in multiple lines to make it easy
to read):
:perl my $skip=0; my @extract=();
foreach my $line ($curbuf->Get(1 .. VIM::Eval('line("$")')))
{
$line =~ /^\s*#if/ and $skip++;
$skip or push @extract, $line;
$line =~ /^\s*#endif/ and $skip--;
}
VIM::DoCommand('new');
$curbuf->Append(1, @extract);
VIM::DoCommand('1d');
with a file that looked like (note the nested, unaligned #if):
stay
stay, next blank too
#if
go away, previous blank too
go away, previous blank too
go away
#if
go away
go away, previous blank too
#endif
some more go away
#endif
stay, previous blank too
stay
stay, previous blank too
stay
very last stay
3) The following works on the above example
:%g/^\s*#if/normal d%dd
After seeing Tim Chase's post, noticed that the
preceding doesn't handle elses; I think the
following would do the job (only partially tested):
:exec 'normal G$' | while(search('^\s*#endif\s*', 'bce')) | exec 'normal
d%dd' | endwhile
(Of course, the perl solution can be translated to other
languages, including viml.)
--Suresh