Pablo Burgos
Pablo Burgos

Reputation: 1254

How to remove blocks of code that starts/ end with some specific pattern in vim?

I wonder whether there is some way within vim to remove all block of code whose first/last line match a specific pattern. For instance, I have a c++ code with a lot of #if #endif blocks I want to get rid of:

#if GGSDEBUG  ---|
somecode        Block to delete
#endif        ---|

//code

#if GGSDEBUG  ---|
somecode        Block to delete
#endif        ---|

//code

#if GGSDEBUG  ---|
somecode        Block to delete
#endif        ---|

Thanks,

Upvotes: 3

Views: 1018

Answers (4)

benjifisher
benjifisher

Reputation: 5112

For C code, you can use the built-in matching behavior:

:g/^#if\>/normal!V%d

This handles nesting properly. (At least, it should, and in my little test it does.) For other languages, use matchit and drop the !:

:runtime macros/matchit.vim
:e foo.html
:g/^<table>/normal Vh%d

 

:help :normal
:help %
:help matchit-install
:helptags $VIMRUNTIME/macros
:help matchit-%

Upvotes: 4

Jan
Jan

Reputation: 2490

Use this: It will automatically remove all occurrences in the file.

It makes use of a non-greedy search \{-} (in place of *) and uses \(.\|\n\) (in place of a simple ".") in the pattern to extend of multiple lines:

:%s/^#if GGSDEBUG\(.\|\n\)\{-}#endif//g

Note: If you have nested blocks that end with #endif, it will only delete until the first one. But this will be a limitation of all solutions here, I guess.

Upvotes: 1

romainl
romainl

Reputation: 196466

From within one of those blocks, you can use this variant of Ingo's answer:

:?^#if GGSDEBUG?,/^#endif/d

:?pattern before the cursor?,/pattern after the cursor/delete

Upvotes: 2

Ingo Karkat
Ingo Karkat

Reputation: 172510

Use the :global command to locate all start lines of your blocks, and execute a command there.

:g/^#if GGSDEBUG/ [...]

As the cursor is placed on that first line of the block, you can :delete the block by specifying a range that ends with a pattern describing your end of the block:

:.,/^#endif/delete

Put together:

:g/^#if GGSDEBUG/.,/^#endif/delete

You can adapt the patterns (e.g. by appending \n\zs$ to endif to also remove the following empty line).

Upvotes: 7

Related Questions