[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

Reply via email to