Reputation: 1254
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
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
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
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
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