Consider the following Vim ex command,
:let i=1 | \'<,\'>g/^/ s/^\\ *-/\\=i/ | let i+=1
It replaces the heading dash with ordered number
This is the general pattern of a :global command:
:g/foo/command
Because everything after the second separator is considered as one command, the counter is incremented each time the command is executed: one time for each matching line.
The pattern of a global command is:
:range g[lobal][!]/pattern/cmd
The global commands work by first scanning through the [range] of of the lines and marking each line where a match occurs. In a second scan the [cmd] is executed for each marked line with its line number prepended. If a line is changed or deleted its mark disappears. The default for the [range] is the whole file. (see http://vimregex.com/#global for more details)
Now let's analyse
:let i=1 | '<,'>g/^/ s/^\ *-/\=i/ | let i+=1
step by step.
let i=1 is a single command executed setting the basic number for the loop. We can just execute it alone at the very beginning. Then '<,'>g/^/ s/^\ *-/\=i/ | let i+=1 looks a little more like a global command.'<,'>g defines the range. '< represents the first line and '> represents the last line of the selected area. (:help '< for more details)^ of course matches every line in range.s/^\ *-/\=i/ | let i+=1 is the [cmd], the number of times it will be executed equals to the number of lines in the selected area, and this is the most important reason why the loop took place.| is a typical substitute command :range s[ubstitute]/pattern/string/ (see http://vimregex.com/#substitute for more details)^\ *- matches 0 or more whitespace followed by a dash at the beginning of a line. We substitute \=i for this pattern. (:help :s\= for more details)s/^\ *-/\=i/, let i+=1 is executed. Then the next line, ... , till the last line of selected area.s/^\ *-/\=i/ | let i+=1 is a [cmd] as a whole, we can change the order of the two [sub-cmd], obtaining let i+=1 | s/^\ *-/\=i/. But for the same effect, let i=0 at the very beginning is essential.