Step 7 of 10

19. The Global Command

Acting on the surrounding lines

The Ex command given to Vim’s global command works in the exact same way as if you had specified it on Vim’s command line. :global will execute the command verbatim. If you specify an address or a range, it’ll be accounted for.

This means that the global command is not limited to just acting on the matching line. It can act on the surrounding range of lines, or even a completely different line/region entirely. This is where the power of this command really shines, and not many Vim users are aware that this is possible.

We know the core mechanics of :global by now, so let us learn by example.

Delete all paragraphs containing the word foo

Here’s how you do it:

:g/foo/'{+,'}d

Here, the :g/foo part is saying ‘find all of the lines that contain foo’. The command part is using two of Vim’s special marks, '{ and '}, which specify the start and the end of the current paragraph respectively. '{+,'} is specifying the surrounding paragraph as range, then the d is deleting it. So the above command is deleting all paragraphs that contain the word foo.

Here’s how you do it:

:g/^func/,/^}$/p

Here, the :g/^func part is saying ‘find all of the lines that start with func’. The ,/}$/ part is specifying a range that captures from the current line to the next line that contains only a } — this range is approximating a function definition in a language like Go. The p part is just saying ‘print this range’ (and is optional, as we know).

Here’s how you do it:

:g/var/?^func?;p

Here, the :g/var part is saying ‘find all of the lines that contain var’. The ?^func?; part is saying ‘from those lines, search backwards for the nearest line that starts with func and change to it’. The p part is just saying ‘print that line’. Note that if a function contains the string ‘var’ multiple times, you’ll get multiple entries in your output.

Let’s try. The editor holds a list of request definitions. Work through the checklist below to print the path of every GET request — twice, using two different addressing tricks. First with ?path?p, which searches backwards from each GET line to the nearest line containing path and prints it; then with -1p, where -1 simply means ‘the line just above the match’. The path always sits on the line above its type, which is why both tricks land on the same lines.

  1. Print each GET's path with :g/GET/?path?p Type :g/GET/?path?p and hit Enter — the paths will print. Hit Enter again to put the output away.
  2. Get the same paths with :g/GET/-1p Type :g/GET/-1p and hit Enter — the same paths will print. Hit Enter again to put the output away.
Print each GET's path with :g/GET/?path?p Type :g/GET/?path?p and hit Enter — the paths will print. Hit Enter again to put the output away.

Next: Get the same paths with :g/GET/-1p

Loading editor…