# Situation

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

       {
"tokens": [
],
"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.

• if you know of a tool that formats a json like this, you can filter your buffer using this tool – Christian Brabandt Aug 29 '19 at 15:40
• Is your actual file as regularly structured/formatted as your example? – Rich Aug 30 '19 at 9:57
• @Rich, yes, that's a copy/paste with replaced values – Richard Wonka Aug 30 '19 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] – Richard Wonka Aug 30 '19 at 14:26

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.

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.