3

I was looking at a global command that I saved from long time ago. I did not understand how it was a valid syntax, but apparently the syntax was valid because the command worked.

The command: :g/\v\{/+1,/\v}/-1 sort

If you run it against a file with content like this:

const something = {
   c:  'x',
   b:  'x',
   a:  'x',
   d:  'x',
}

const else = {
   d: 'x',
   c: 'x',
   a: 'x',
   b: 'x',
}

const c = 'bar'    
const a = 'hello'
const b = 'foo'

It worked. It sorted all keys inside something and else objects only.

When I looked at :h :global, it says

:[range]g[lobal]/{pattern}/[cmd]

I had trouble distinguishing range and pattern in this command. However, I am inclined to think this part (/\v\{/+1,/\v}/-1) was a range and not a pattern, because:

  1. It had comma, like most ranges.
  2. There was no delimiter (/) right before sort command.

So I am made to assume that it was a range. But if it was a range, I am left with more questions.

Shouldn't range always go before global command? If range always goes before g, how did this script still work? And where was the pattern?

My question for this post is, can someone clarify how does the syntax of that command work, even though it looks contrary to what :h :g gives?

0
3

Add space between pattern, cmd:

g /\v\{/ +1,/\v}/-1 sort
        ^------------------separation between pattern and command

It's a good habit to leave space between pattern and cmd if your cmd takes a range.

+1,/\v}/-1 is a range from the line after the { found by the :g command to the line preceding the next occurrence of }. Check :h :range If you have doubts. This range is used for cmd, not for global. range for global must appears before global.

1
  • 1
    I think I got it. The syntax follows: :g /pattern/ {cmd}, whereas /pattern/ is /\v\{/ and command is +1,/\v}/-1 sort. The command part was the confusing part, because apparently vim allows you to give {cmd} its own range, even though it was used within g context. So it reads: Do global, very magic, and find each line that matches { pattern. When you find that line, do sort starting on the line after it and ends a line before the first } match. Makes sense! – Iggy Mar 20 '20 at 12:43
1

@dedowsdi's answer is complete. But the question's subject is syntax clarification and I have something relevant to that that hasn't been mentioned:

The "very magic mode" \vs in the command are totally unnecessary and just make it that much less readable.

This command does the same thing as the original but it has five fewer characters:

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

Two things are noteworthy here:

  1. Regarding the first \v we've gone from \v\{ to just {. That's because (unescaped) curly braces don't have special meaning in default ("magic") mode. Normally, "very magic" is used to reduce the amount of escaping one needs to do but in this case it required adding characters!
  2. Looking at the second \v we have an even more wasteful use of "very magic". Right curly braces never require escaping whether they're being used in a quantifier like a\{3} or \va{3} (both indicate three consecutive 'a' characters) or just acting as themselves: } or \v}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.