mirror of
https://github.com/vim/vim
synced 2025-07-16 09:12:00 +00:00
related: #11426 Signed-off-by: Maxim Kim <habamax@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
@ -23,6 +23,7 @@ runtime/autoload/tar.vim @cecamp
|
||||
runtime/autoload/vimball.vim @cecamp
|
||||
runtime/autoload/xmlformat.vim @chrisbra
|
||||
runtime/autoload/zip.vim @cecamp
|
||||
runtime/autoload/dist/json.vim @habamax
|
||||
runtime/colors/blue.vim @habamax @romainl @neutaaaaan
|
||||
runtime/colors/darkblue.vim @habamax @romainl @neutaaaaan
|
||||
runtime/colors/default.vim @habamax @romainl @neutaaaaan
|
||||
|
182
runtime/autoload/dist/json.vim
vendored
Normal file
182
runtime/autoload/dist/json.vim
vendored
Normal file
@ -0,0 +1,182 @@
|
||||
vim9script
|
||||
|
||||
# Maintainer: Maxim Kim <habamax@gmail.com>
|
||||
# Last update: 2023-12-10
|
||||
#
|
||||
# Set of functions to format/beautify JSON data structures.
|
||||
#
|
||||
# Could be used to reformat a minified json in a buffer (put it into ~/.vim/ftplugin/json.vim):
|
||||
# import autoload 'dist/json.vim'
|
||||
# setl formatexpr=json.FormatExpr()
|
||||
#
|
||||
# Or to get a formatted string out of vim's dict/list/string:
|
||||
# vim9script
|
||||
# import autoload 'dist/json.vim'
|
||||
# echo json.Format({
|
||||
# "widget": { "debug": "on", "window": { "title": "Sample \"Konfabulator\" Widget",
|
||||
# "name": "main_window", "width": 500, "height": 500
|
||||
# },
|
||||
# "image": { "src": "Images/Sun.png", "name": "sun1", "hOffset": 250,
|
||||
# "vOffset": 250, "alignment": "center" },
|
||||
# "text": { "data": "Click Here", "size": 36, "style": "bold", "name": "text1",
|
||||
# "hOffset": 250, "vOffset": 100, "alignment": "center",
|
||||
# "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" } }
|
||||
# })
|
||||
#
|
||||
# Should output:
|
||||
# {
|
||||
# "widget": {
|
||||
# "debug": "on",
|
||||
# "window": {
|
||||
# "title": "Sample \"Konfabulator\" Widget",
|
||||
# "name": "main_window",
|
||||
# "width": 500,
|
||||
# "height": 500
|
||||
# },
|
||||
# "image": {
|
||||
# "src": "Images/Sun.png",
|
||||
# "name": "sun1",
|
||||
# "hOffset": 250,
|
||||
# "vOffset": 250,
|
||||
# "alignment": "center"
|
||||
# },
|
||||
# "text": {
|
||||
# "data": "Click Here",
|
||||
# "size": 36,
|
||||
# "style": "bold",
|
||||
# "name": "text1",
|
||||
# "hOffset": 250,
|
||||
# "vOffset": 100,
|
||||
# "alignment": "center",
|
||||
# "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# NOTE: order of `key: value` pairs is not kept.
|
||||
#
|
||||
# You can also use a JSON string instead of vim's dict/list to maintain order:
|
||||
# echo json.Format('{"hello": 1, "world": 2}')
|
||||
# {
|
||||
# "hello": 1,
|
||||
# "world": 2
|
||||
# }
|
||||
|
||||
|
||||
# To be able to reformat with `gq` add following to `~/.vim/ftplugin/json.vim`:
|
||||
# import autoload 'dist/json.vim'
|
||||
# setl formatexpr=json.FormatExpr()
|
||||
export def FormatExpr(): number
|
||||
FormatRange(v:lnum, v:lnum + v:count - 1)
|
||||
return 0
|
||||
enddef
|
||||
|
||||
|
||||
# import autoload 'dist/json.vim'
|
||||
# command -range=% JSONFormat json.FormatRange(<line1>, <line2>)
|
||||
export def FormatRange(line1: number, line2: number)
|
||||
var indent_base = matchstr(getline(line1), '^\s*')
|
||||
var indent = &expandtab ? repeat(' ', &shiftwidth) : "\t"
|
||||
|
||||
var [l1, l2] = line1 > line2 ? [line2, line1] : [line1, line2]
|
||||
|
||||
var json_src = getline(l1, l2)->join()
|
||||
var json_fmt = Format(json_src, {use_tabs: !&et, indent: &sw, indent_base: indent_base})->split("\n")
|
||||
|
||||
exe $":{l1},{l2}d"
|
||||
|
||||
if line('$') == 1 && getline(1) == ''
|
||||
setline(l1, json_fmt[0])
|
||||
append(l1, json_fmt[1 : ])
|
||||
else
|
||||
append(l1 - 1, json_fmt)
|
||||
endif
|
||||
enddef
|
||||
|
||||
|
||||
# Format JSON string or dict/list as JSON
|
||||
# import autoload 'dist/json.vim'
|
||||
# echo json.FormatStr('{"hello": "world"}', {use_tabs: false, indent: 2, indent_base: 0})
|
||||
|
||||
# {
|
||||
# "hello": "world"
|
||||
# }
|
||||
|
||||
# echo json.FormatStr({'hello': 'world'}, {use_tabs: false, indent: 2, indent_base: 0})
|
||||
# {
|
||||
# "hello": "world"
|
||||
# }
|
||||
#
|
||||
# Note, when `obj` is dict, order of the `key: value` pairs might be different:
|
||||
# echo json.FormatStr({'hello': 1, 'world': 2})
|
||||
# {
|
||||
# "world": 2,
|
||||
# "hello": 1
|
||||
# }
|
||||
export def Format(obj: any, params: dict<any> = {}): string
|
||||
var obj_str = ''
|
||||
if type(obj) == v:t_string
|
||||
obj_str = obj
|
||||
else
|
||||
obj_str = json_encode(obj)
|
||||
endif
|
||||
|
||||
var indent_lvl = 0
|
||||
var indent_base = get(params, "indent_base", "")
|
||||
var indent = get(params, "use_tabs", false) ? "\t" : repeat(' ', get(params, "indent", 2))
|
||||
var json_line = indent_base
|
||||
var json = ""
|
||||
var state = ""
|
||||
for char in obj_str
|
||||
if state == ""
|
||||
if char =~ '[{\[]'
|
||||
json_line ..= char
|
||||
json ..= json_line .. "\n"
|
||||
indent_lvl += 1
|
||||
json_line = indent_base .. repeat(indent, indent_lvl)
|
||||
elseif char =~ '[}\]]'
|
||||
if json_line !~ '^\s*$'
|
||||
json ..= json_line .. "\n"
|
||||
indent_lvl -= 1
|
||||
if indent_lvl < 0
|
||||
json_line = strpart(indent_base, -indent_lvl * len(indent))
|
||||
else
|
||||
json_line = indent_base .. repeat(indent, indent_lvl)
|
||||
endif
|
||||
elseif json =~ '[{\[]\n$'
|
||||
json = json[ : -2]
|
||||
json_line = substitute(json_line, '^\s*', '', '')
|
||||
indent_lvl -= 1
|
||||
endif
|
||||
json_line ..= char
|
||||
elseif char == ':'
|
||||
json_line ..= char .. ' '
|
||||
elseif char == '"'
|
||||
json_line ..= char
|
||||
state = 'QUOTE'
|
||||
elseif char == ','
|
||||
json_line ..= char
|
||||
json ..= json_line .. "\n"
|
||||
json_line = indent_base .. repeat(indent, indent_lvl)
|
||||
elseif char !~ '\s'
|
||||
json_line ..= char
|
||||
endif
|
||||
elseif state == "QUOTE"
|
||||
json_line ..= char
|
||||
if char == '\'
|
||||
state = "ESCAPE"
|
||||
elseif char == '"'
|
||||
state = ""
|
||||
endif
|
||||
elseif state == "ESCAPE"
|
||||
state = "QUOTE"
|
||||
json_line ..= char
|
||||
else
|
||||
json_line ..= char
|
||||
endif
|
||||
endfor
|
||||
if json_line !~ '^\s*$'
|
||||
json ..= json_line .. "\n"
|
||||
endif
|
||||
return json
|
||||
enddef
|
@ -610,6 +610,18 @@ The mapping can be disabled with: >
|
||||
let g:no_gprof_maps = 1
|
||||
|
||||
|
||||
JSON-FORMAT *ft-json-plugin*
|
||||
|
||||
JSON filetype can be extended to use 'formatexpr' and "json.FormatExpr()"
|
||||
function for json formatting (using |gq|).
|
||||
|
||||
Add following lines to $HOME/.vim/ftplugin/json.vim: >
|
||||
|
||||
vim9script
|
||||
import autoload 'dist/json.vim'
|
||||
setl formatexpr=json.FormatExpr()
|
||||
|
||||
|
||||
MAIL *ft-mail-plugin*
|
||||
|
||||
Options:
|
||||
|
Reference in New Issue
Block a user