Using VIm’s „Negative Lookahead“ to Delete All Lines NOT Containing a Pattern

UPDATE:

Please note that „bw1“ has notified me of a much simpler solution than what is described here; please see

Using VIm’s „:v“ Command to Delete All Lines NOT Containing a Pattern

Some statements have been struck through in the article below because they are false.

I want to delete all lines in the current file not containing the string foo:

:g/^.*?\@!foo/d

Explanation: Using the global command g („act on range or entire file“) like :g/pattern/d applies the command d („delete line“) to any line in the current file that matches pattern.

Since VIm generally does not support inverting RegExps (for example like sed does with the modifier !), I employ the „negative lookahead operator“ @! (that has to be escaped \@!) of VIm-RegExp-syntax.

Since, in VIm RegExp syntax, look-ahead must follow something (why? I don’t know) I precede it with ^.*, but this is not enough, since it renders the obscure error E62: Nested \@ (why? I don’t know).

But it works if I make the preceeding term optional using the ? modifier. It’s a horribly inefficient RegExp, but it’s shortest to write (which is what VI-commands are all about).

And now you know that, too. 😀

P.S.: If you know a shorter version let me know –  FYI, I already know

:%!sed /foo/\!d

and it does not count – VIm onboard stuff only! 😉