Chaining global commands
Global commands can be chained in Vim. That means the Ex command you pass to a :global invocation can be another :global invocation. This sounds a bit crazy, but think about the following examples:
:g/test/g/run— prints all of the lines matching bothtestandrun:g/foo/v/bar— prints all lines containingfoo, but notbar:g/foo/v/bar/g/baz— prints all lines containingfooandbaz, but notbar
To give you some ideas, I’ve used this is the past to:
- delete all debugging print statements that I’ve not explicitly marked with the string
KEEPME(hint::g/print/v/KEEPME/d) - list all of the type definitions in a file that don’t contain
GETin their name (hint::g/^type/v/GET/) - slowly whittle down what I’m grepping for in a file by chaining more global commands — I think this is a bit easier to cognitively manage than writing a more complex regex
The only limitation with using the global command recursively is that you can only specify a range for the first invocation of :global. As in, you can’t do this:
:g/foo/-10,+10g/bar/d
Thankfully the situations where you’d ever need this are extremely rare.
Let’s give this a try in the editor. Try deleting all of the lines that contain foo, but not bar, using a chained global command in the editor.