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! 😉