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?
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?
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 .
brew install jq I could also just type :%!jq without a dot at the end
– olik79
Apr 20 '21 at 19:01
jq as a command line tool) and how it's being used by vim in this particular case.
– Alexandre
Apr 11 '23 at 18:32
% stands for a range equal to 1,$ (the entire file) and ! filters the range of line to the external program jq.
– SebMa
Apr 11 '23 at 21:11
jq as a chocolatey package
– Michael Dandini
Jun 20 '23 at 19:25
. is the identity filter, meaning "give me back exactly what I gave you." Without a filter, some versions or invocations of jq will not assume which part of the JSON you want it to process, so it's best to always include the dot. See man jq. Use :%!jq . --tab to get indentation with tabs.
– Walf
Feb 15 '24 at 01:19
This one-liner works well to format JSON in Vim into a human readable form:
:%!python -m json.tool
:%!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 07:37
jq
– Anurag A S
Jul 20 '22 at 15:11
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()
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
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)))"'
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>
If nodejs and xargs are available on your system you can add the following command to your .vimrc
command! -range FormatJson <line1>,<line2>!xargs -0 -I {} node -e 'console.log(JSON.stringify({}, null, 2));'
After that you can visual select the JSON text in the buffer and run
:'<,'>FormatJson
to pretty print it. Works with Unicode too.
Another solution is to use coc-format-json.
I wanted to open jq with vim. However i didn't manage to find a way to do it in one command.
I wrote a shell script, and it worked for me (linux version : redhat 7.6):
# Don't miss the dot after jq
cat input.json | jq . > output.json
vim output.json
- to read from stdin: jq input.json . | vim - (maybe you need to reverse the input.json and . in that jq command). Another option would be to use -c or + to run a command when Vim opens: vim +':%!jq .' input.json
– Martin Tournoij
May 03 '21 at 07:41
Use ALE to help you with linting/formatting
Install ALE into .vim/vimfiles/pack/*/opt/ale
add the following line to your vimrc:
packadd ale
if exists("b:my_ftplugin") | finish | endif
let b:my_ftplugin = 1
if !exists('g:loaded_ale') | finish | endif
" Pick from available fixers :help ale-fix
" E.g., use prettier if it is installed:
let b:ale_fixers = ['prettier']
If no fixers are available at your disposal, python is always an option:
if !executable('python') | finish | endif
let b:ale_fixers = [{ -> {'command': 'python -m json.tool --indent 2 -'}}]
:ALEFix
Set all values at a new line with substitute commands (they must fit your file!):
:%s/","/",\r"/g:%s/null,"/null,\r"/g:%s/(\d),"/\1,\r"/g},{, [{{
"versions":[
{
"count":2,"version":""
},
{"count":1,
"version":"1.1.1"
},
{
"count":14,
"version":"2.9"
}]
}
Then go to the first { and type =%.
The JSON will be rudimentary formatted. Not perfect but readable.