El_Mewo
El_Mewo

Reputation: 109

How does the range for inner contents of braces work in Vim?

From Drew Neil's fantastic book "Practical Vim" I learned what you can do with the :g command. However, there is one expression I don't get.

:g/{/ .+1,/}/-1 sort

This sorts all lines between braces in the file alphabetically. The general form of this command is

:global/{pattern}/[cmd]

, with [cmd] consisting of [range] [cmd]. I get that the search pattern is the starting point, so :g/{/is clear. Then follows the range .+1,/}/-1, with . being the current line (i.e. every line matching the pattern { ), +1 adding a one-line offset, , separating the start of the range from the end, /}/ saying "until the closing brace" and -1 subtracting one line to match only the inner contents of the braces. What I don't get is the /}/ part. What are the slashes needed for? Why is it not possible to just write }?

EDIT: From Vimhelp 10.3 I now know that /}/is the search pattern used for the upper range boundary. Which leaves me still confused about the second / here. So the updated question is: Why do I need the second / before -1?

Upvotes: 2

Views: 62

Answers (1)

Ingo Karkat
Ingo Karkat

Reputation: 172698

With ranges, the /.../ are always needed to tell Vim: this is a pattern, search for the next match and position the cursor there; that's where I want to start/end the range. If you look at :help :range, a literal } is not allowed there; Vim wants a line number, or a symbol representing such, a mark, or a search pattern. The only allowed variation is ?...? for an upwards search.

When you try out your suggested variant, you'll get

E492: Not an editor command: .+1,}-1 sort

Another way to motivate this is by abstracting from the concrete { ... } delimiters. Imagine how the range would look if you wanted a range inside foo ... bar. What if the range were 000 ... 999; Vim would not be able to differentiate between a literal number range (line 999) and the search (next line that contains 999).

Upvotes: 3

Related Questions