2

Situation

I have a large, hierarchical json file with many single entries, like so:

       {
          "tokens": [
            "payload, a string"
          ],
          "values": [
            {
              "value": "frong zshok blam flarb"
            }
          ]
        },
        {
          "tokens": [
            "another token"
          ],
          "values": [
            {
              "value": "another important string"
            }
          ]
        },

so there are lots of empty lines with brackets and parentheses.

Question:

How can I have json formatted to only use line breaks after : or ,?

What I'm hoping for is something like this:

{ "tokens": 
    [ "<foo.barbaz>" ],
  "values": 
    [ { "value": "<frong gronk shoop blurb>" } ] },
{ "tokens": 
    [ "<a string>" ],
      "values": 
    [ { "value": "<another string>" } ] },

Pretty indentation to have contents of [] {} () aligned would be a bonus.

Whether this is done via external tool or vim plugin, I wouldn't mind either.

5
  • 4
    if you know of a tool that formats a json like this, you can filter your buffer using this tool Commented Aug 29, 2019 at 15:40
  • Is your actual file as regularly structured/formatted as your example?
    – Rich
    Commented Aug 30, 2019 at 9:57
  • @Rich, yes, that's a copy/paste with replaced values Commented Aug 30, 2019 at 12:38
  • Not a solution, but a worthy alternative: I have found that I can use a json2yaml script and can now use a much more convenient format. [-2 urgency] Commented Aug 30, 2019 at 14:26
  • I wonder if using a racket-like formatter would work, since it sees all 3 types of brackets as parens.
    – D. Ben Knoble
    Commented May 21, 2021 at 20:07

2 Answers 2

0

Because the structure of your file is so regular, you can do this very quickly with a recursive macro.

Starting with your cursor at the top of the file (gg), type in the following:

qqqqq
Jf:aEnterSpaceSpaceSpaceSpaceEsc
JJ+f:aEnterSpaceSpaceEsc
6J+
@qq@q

How it works

  1. qqqqq This is recursive macro boilerplate. It clears out the "q register and then starts recording a macro into it.

  2. J Join the next line.

  3. f: Move the cursor to the colon.

  4. aEnterSpaceSpaceSpaceSpaceEsc Add a newline and some indent.

  5. JJ Join the next two lines.

  6. +f: Move the cursor to the next line and then to the colon.

  7. aEnterSpaceSpaceEsc Add another newline and indent.

  8. 6J Join the next 6 lines.

  9. + Move to the next line. We're now done formatting.

  10. @qq@q This is more recursive macro boilerplate. The first @q plays back the macro in register "q, but that register is currently empty because we cleared it in step 1. Then the q stops the recording and saves the macro. Finally, the @q plays back the recursive macro. The macro will continue playing back until it hits the bottom of the file.

0

This is pretty easy to do with a series of substitutions:

  1. First, add a newline after every : or ,:

    :%s/[:,]/&\r
    
  2. Then replace any newline that doesn't follow a : or , with a single space.

    :%s/[^:,]\zs\n\s*/ /
    
  3. Then, note that you don't actually want newlines between : and " characters, so replace these with single spaces too:

    :%s/:\_s*"/: "
    
  4. Finally, fix the indents, and remove any completely blank lines that have been introduced:

    =gg
    :g/^$/d
    

You could probably do all this with only two substitutions or perhaps even just one, but the regular expressions would be a lot more complicated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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