Let me suggest an alternative implementation of the method you describe.
:?\\begin\>\zs\*\=?s//\='*'[submatch(0)!='']/|norm!``
The above command consists of two separate commands encoded with |
(see :help :bar
) in one line. The first is a replacement (see :help :s
) is performed for each line in the specified range,
?\\begin\>\zs\*\=?
According to the syntax of the range (see :help :range
), this range defines only the line, i.e. the previous line, where the pattern \\begin\>\zs\*\=
matches the word begin
, which is preceded by a backslash, and then optional star symbol. 1 The \zs
atom between the parts of the figure corresponds to \begin
and *
, sets the beginning of the match there. So, the match of the entire template is either empty or contains the symbol of one star. This is not required to specify a string in a range, it is useful to reuse the same pattern later in the command :substitute
, where only this star symbol or its empty space should be replaced. For more information on template syntax, see :help /\>
:help /\=
:help /\zs
.
Substitution itself
s//\='*'[submatch(0)!='']/
replaces the first occurrence of the last search pattern (which sets the reverse search in the range) with a string in which the expression '*'[submatch(0)!='']
is evaluated (see :help sub-replace-\=
). As the pattern matches only an empty string or a star symbol, the submatch(0)!=''
is evaluated to zero if there is no star after \begin
, or one else. The zero index from the string '*'
results in a substring containing the first character of this one-character string. The index is one equal to the length of the string, so the index results in an empty string. Thus, when there is a star after \begin
, it is replaced by an empty string, when there is no star, the zero interval immediately after \begin
is replaced by *
.
Second team
:norm!``
uses the fact that the :substitute
command stores the current cursor before it starts the replacement. The movement of the ``
command returns to the position until the last jump (which occurs in the aforementioned replacement command), restoring the cursor position. 2
1 Be careful with the search, as in ranges, as usual, it wraps around the end of the file when the wrapscan
option is wrapscan
(it is enabled by default).
2 Do not confuse ``
with a command ''
that moves the cursor to the first non-blank character in the location bar until the last jump.