尝试使用一个命令:
execute '%!python -m json.tool' | w
您可以添加自己的快捷键使其更加简单。当然,为了让这个方法起作用,您需要在您的机器上安装Python。
| w
是什么目的?为什么不直接写成 :%!python -m json.tool
?答:| w
的作用是将当前编辑的文本写入到磁盘中,即保存当前文件。如果你只使用 :%!python -m json.tool
命令,虽然会在 Vim 中将 JSON 进行格式化,但并不会将其写入文件,因此使用 | w
命令可以将格式化后的内容保存到文件中。 - jhrr|w
只是保存缓冲区,如果没有它,你会得到格式化后的 JSON,但更改不会被保存。我想这取决于你想要什么。 - Jose Bjq
工具:https://stedolan.github.io/jq/。然后在vim中执行:%!jq .
命令,它将用jq的输出替换当前缓冲区的内容。:%!jq "."
。需要先下载Windows版本的jq,并将其从jq-win64.exe
(32位版本类似)重命名为jq.exe
,同时确保它已被添加到环境变量的路径中。 - Jon V:%! jq .
对我有效,或者 :%! jq --indent 4 .
。 - Akavalljq
而不是python命令,因为Python可能会基于编码更改内容。例如:{"test":"ü"}
,其中"ü"
在执行:%!python - m json.tool
后变成了"\u00fc"
。 - Ken Jiiii%!python -m json.tool
或者
%!python -c "import json, sys, collections; print json.dumps(json.load(sys.stdin, object_pairs_hook=collections.OrderedDict), ensure_ascii=False, indent=4)"
你可以把这段添加到你的vimrc文件中:
com! FormatJSON %!python -m json.tool
然后你就可以使用:FormatJson
命令格式化json文件了。
ensure_ascii
或使用自己的 indent
,你可以使用 com! FormatJSON %!python -m json.tool --no-ensure-ascii --indent 4
。就像 python -m json.tool --help
所建议的那样。 - thetaprime感谢mMontu和Jose B,这就是我最终做的:
警告:这将覆盖您的缓冲区。因此,如果您打开一个已经存在语法错误的json文件,您将丢失整个文件(或可能会丢失文件)。
将此行添加到您的~/.vimrc
文件中。
" Ali: to indent json files on save
autocmd FileType json autocmd BufWritePre <buffer> %!python -m json.tool
当然,你需要在你的计算机上安装Python。
编辑:如果你的json出现错误,下面的代码不会覆盖你的缓冲区,这就是正确的答案。但由于我对Vim脚本或者说Shell命令不太熟悉,所以我把它作为一个实验性的东西呈现给你,如果你感觉幸运,可以试试。可能还取决于你的shell环境。请注意。
" Ali: to indent json files on save
autocmd FileType json autocmd BufWritePre <buffer> %!python -m json.tool 2>/dev/null || echo <buffer>
(%!python -m json.tool 2>/dev/null || echo <buffer>)
。 - Josh Peak如果它能格式化你期望的内容,那么你可以创建一个
gqaj
"pretty prints"(包装/缩进/排序关键字/清理其他)光标下的JSON结构。
autocmd BufWritePre
在保存时进行格式化。ggVG!jq '.'
这将突出显示整个JSON文档,然后通过 jq
运行它,该工具只会解析正确性,重新格式化(例如,修复任何缩进等),并将输出返回到Vim编辑器。
如果您只想解析文档的一部分,可以手动突出显示该部分,方法是按下v
或V
,然后运行相应命令。
!jq '.'
:%!jq '.'
- D. Ben KnobleVim自动格式化
https://github.com/Chiel92/vim-autoformat
这是一个Vim插件,支持多种自动格式化和缩进方案,并可针对每种文件类型扩展自定义格式化程序。
https://github.com/Chiel92/vim-autoformat#default-formatprograms
注意:
您需要安装nodejs
和js-beautify
,因为vim-autoformat
使用它们作为默认的外部工具。
npm install -g js-beautify
我做了一些整理(尽管其中有些与vim无关),并建议你自己在neovim上编写脚本!
Neovim允许通过将Python文件或包放置在rplugin/python3/
中的runtimepath
文件夹中来定义Python3插件。
在我的情况下
- init.vim
- rplugin/python3/[your_py_file_set].py
- rplugin/python3/fmt_file.py
fmt_file.py
文件:# rplugin/python3/fmt_file.py
import pynvim
import json
@pynvim.plugin
class Plugin:
__slots__ = ('vim',)
def __init__(self, vim):
self.vim = vim
@pynvim.command('FormatJson', nargs='*', range='')
def format_json(self, args, rg):
"""
USAGE::
:FormatJson
"""
try:
buf = self.vim.current.buffer
json_content: str = '\n'.join(buf[:])
dict_content: dict = json.loads(json_content)
new_content: str = json.dumps(dict_content, indent=4, sort_keys=True)
buf[:] = new_content.split('\n')
except Exception as e:
self.vim.current.line = str(e)
之后在Nvim
中运行:UpdateRemotePlugins
一次,以生成必要的Vimscript使您的插件可用。(最好重新启动neovim)
然后,打开您想要格式化的JSON文件并输入:FormatJson
命令即可完成所有操作。
不要忘记告诉 Vim 你的 Python 的位置
" init.vim
let g:python3_host_prog = '...\python.exe''
并且 pip install pynvim
tool.py
位于 Lib/json/tool.py
目录下。
:%!python -m json.tool
如果您已经安装了 Python,并且可以打开命令行:
python -m json.tool "test.json" >> "output.json"
我编写了一个简单的脚本来完成这些事情。
"""
USAGE::
python fmt_file.py fmt-json "C:\test\test.json"
python fmt_file.py fmt-json "C:\test\test.json" --out_path="abc.json"
python fmt_file.py fmt-json "test.json" --out_path="abc.json"
"""
import click # pip install click
from click.types import File
import json
from pathlib import Path
@click.group('json')
def gj():
...
@gj.command('fmt-json')
@click.argument('file_obj', type=click.File('r', encoding='utf-8'))
@click.option('--out_path', default=None, type=Path, help='output path')
def format_json(file_obj: File, out_path: Path):
new_content = ''
with file_obj as f:
buf_list = [_ for _ in f]
if buf_list:
json_content: str = '\n'.join(buf_list)
dict_content: dict = json.loads(json_content)
new_content: str = json.dumps(dict_content, indent=4, sort_keys=True)
if new_content:
with open(out_path if out_path else Path('./temp.temp_temp.json'),
'w', encoding='utf-8') as f:
f.write(new_content)
def main():
for register_group in (gj,):
register_group()
if __name__ == '__main__':
main()
let b:ale_fix_on_save = 1 " Fix files when they are saved.