34

Given a file with a large JSON object all on one line like

{"versions":[{"count":2,"version":""},{"count":1,"version":"1.1.1"},{"count":14,"version":"2.9"},{...

How can I format this to be human readable in Vim?

57

Or you can install jq which is faster (written in C) from your package manager (e.g. sudo apt install jq in Ubuntu/Debian, sudo dnf install jq on Fedora/RHEL/CentOS) or from source and then in vim, type:

:%!jq .
| improve this answer | |
  • 1
    :%!jq works just as well for me. – Micks Ketches Dec 27 '19 at 22:38
  • 4
    Hm... only works with the added . for me. I wonder why. – Costa Apr 15 at 23:02
  • 1
    on MacOS, I need the . as well – Thomas Jun 14 at 18:53
34

This one-liner works well to format JSON in Vim into a human readable form:

:%!python -m json.tool

| improve this answer | |
  • 1
    Do you memorize that and type it every time or do you use some kind of alias? – asedsami Dec 13 '19 at 17:05
  • I tend to use the :%!jq . answer these days, as I do less with Python and tend to have jq installed on my systems for any JSON work in CLI. I also get notifications for this SO question quite often, so it helps me not to forget :P I prefer vim with minimal customization, no plugins, etc, which is another reason the jq solution is now my preferred. – ljs.dev Dec 14 '19 at 7:37
  • (updated accepted answer to reflect this) – ljs.dev Dec 14 '19 at 7:37
  • 3
    Just a warning that this will escape some characters into ASCII only. So if you want UTF8 encoding jq is the better option. – AndrewHarvey Feb 5 at 3:01
5

To format in a deterministic way, we need to sort the hash. None of the other answers did that for me, so I created my own:

function! FormatJson()
python << EOF
import vim
import json
try:
    buf = vim.current.buffer
    json_content = '\n'.join(buf[:])
    content = json.loads(json_content)
    sorted_content = json.dumps(content, indent=4, sort_keys=True)
    buf[:] = sorted_content.split('\n')
except Exception, e:
    print e
EOF
endfunction

Usage:

:call FormatJson()
| improve this answer | |
  • Welcome to Vi and Vim! Nice first answer; it's interesting that you consider the sorting aspect! – D. Ben Knoble Nov 19 '19 at 15:26
  • About the sorting I'm pretty sure jq mentionned in SebMa answers has a --sort-keys option which would do the job. But it's cool to write your own implementation too :) – statox Nov 19 '19 at 16:23
1

If PHP is available, add the tool jf as a JSON Formatter by Composer:

$ composer global require codegear/json-formatter

Then Format current file:

:%!jf %

Or add a keymap in vimrc:

nnoremap <Leader>jf :%!jf %<CR>
| improve this answer | |
1

I use this :Jsonf command. It's can format unicode.

command! Jsonf :execute '%!python -c "import json,sys,collections,re; sys.stdout.write(re.sub(r\"\\\u[0-9a-f]{4}\", lambda m:m.group().decode(\"unicode_escape\").encode(\"utf-8\"),json.dumps(json.load(sys.stdin, object_pairs_hook=collections.OrderedDict), indent=2)))"'
| improve this answer | |

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.