JSON is a common format that is used when coding backend apis. Would be good if vim had first class support for formatting JSON so that we don't have to use external tool or website.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
I have a json http response and need to format so I can inspect it. It could contain sensitive (customer) data and would like to avoid using random external tools to inspect it. Inspecting minified JSON is hard.
I'm looking for an equivalent for this :%!python -m json.tool by :JsonFormat and JSON.stringify() by json_format() but without me install python (it is pain to use in Windows).
In Javascript this is what one could do.
var obj = { 'name': 'prabir' }; JSON.stringify(obj, null, 4); // Indented 4 spaces JSON.stringify(obj, null, "\t"); // Indented with tab
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
can't you filter your buffer through e.g. jq ?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
Here is proof of concept:
https://asciinema.org/a/OIpGQplEKpjF9xbaxNZB5Bayn
def JSONFormat(line1: number, line2: number)
var json_src = getline(line1, line2)->join()
var json = []
var indent_lvl = 0
var indent_base = matchstr(getline(line1), '^\s*')
var indent = &expandtab ? repeat(' ', &shiftwidth) : "\t"
var json_line = indent_base
var state = ""
for char in json_src
if state == ""
if char =~ '{\|\['
json_line ..= char
json->add(json_line)
indent_lvl += 1
json_line = indent_base .. repeat(indent, indent_lvl)
elseif char =~ '}\|\]'
json->add(json_line)
indent_lvl -= 1
json_line = indent_base .. repeat(indent, indent_lvl)
json_line ..= char
elseif char == ':'
json_line ..= char .. ' '
elseif char == '"'
json_line ..= char
state = 'ATTR'
elseif char == ','
json_line ..= char
json->add(json_line)
json_line = indent_base .. repeat(indent, indent_lvl)
elseif char !~ '\s'
json_line ..= char
endif
elseif state == "ATTR"
json_line ..= char
if char == '"'
state = ""
endif
else
json_line ..= char
endif
endfor
if !empty(json_line)
json->add(json_line)
endif
exe $":{line1},{line2}d"
if line('$') == 1
setline(line1, json[0])
append(line1, json[1 : ])
else
append(line1 - 1, json)
endif
enddef
command! -range=% JSONFormat JSONFormat(<line1>, <line2>)
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
Hmm, I have tried to make it work with 'formatexpr' but failed :(
This is in after/json.vim
import autoload 'json.vim'
setl formatexpr=json.FormatExpr()
In autoload/json.vim I have
vim9script
export def FormatExpr()
Format(v:lnum, v:lnum + v:count)
enddef
export def Format(line1: number, line2: number)
.... as in previous message
And it formats it into garbage.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
Oh, formatexpr can't speak vim9script!
setl formatexpr=json#FormatExpr()
Works!
@brammool I can create a PR if needed.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
This is the latest thing I have that works with gq in normal mode.
Unfortunately I couldn't make it work for a {visual}gq.
vim9script
# in after/json.vim
# setl formatexpr=json#FormatExpr()
export def FormatExpr(): number
Format(v:lnum, v:lnum + v:count - 1)
return 0
enddef
export def Format(line1: number, line2: number)
var json_src = getline(line1, line2)->join()
var json = []
var indent_lvl = 0
var indent_base = matchstr(getline(line1), '^\s*')
var indent = &expandtab ? repeat(' ', &shiftwidth) : "\t"
var json_line = indent_base
var state = ""
for char in json_src
if state == ""
if char =~ '{\|\['
json_line ..= char
json->add(json_line)
indent_lvl += 1
json_line = indent_base .. repeat(indent, indent_lvl)
elseif char =~ '}\|\]'
json->add(json_line)
indent_lvl -= 1
json_line = indent_base .. repeat(indent, indent_lvl)
json_line ..= char
elseif char == ':'
json_line ..= char .. ' '
elseif char == '"'
json_line ..= char
state = 'ATTR'
elseif char == ','
json_line ..= char
json->add(json_line)
json_line = indent_base .. repeat(indent, indent_lvl)
elseif char !~ '\s'
json_line ..= char
endif
elseif state == "ATTR"
json_line ..= char
if char == '"'
state = ""
endif
else
json_line ..= char
endif
endfor
if json_line !~ '^\s*$'
json->add(json_line)
endif
exe $":{line1},{line2}d"
if line('$') == 1
setline(line1, json[0])
append(line1, json[1 : ])
else
append(line1 - 1, json)
endif
enddef
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
let me close this in favor of #11506
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()
Closed #11426 as completed.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you commented.![]()