Emacs编辑JSON的模式

78

有没有人知道一个好的 Emacs 模式来编辑 JSON?我正在开发的应用使用基于 JSON 的通信协议,将数据进行美观缩进并进行语法高亮处理将有助于我更好地理解它。


我使用js2-mode来验证JSON。请参见http://emacs.stackexchange.com/questions/24855/is-there-a-way-to-check-whether-or-not-a-string-is-valid-json/ - chen bin
12个回答

36

+1表示支持Josh的json-mode -- 对我来说很有效。我添加了

(defun beautify-json ()
  (interactive)
  (let ((b (if mark-active (min (point) (mark)) (point-min)))
        (e (if mark-active (max (point) (mark)) (point-max))))
    (shell-command-on-region b e
     "python -m json.tool" (current-buffer) t)))

并且

(define-key json-mode-map (kbd "C-c C-f") 'beautify-json)

将json-mode.el修改,使得调用shell命令更加方便。
更新:对于需要/希望使用unicode的用户,请查看我的问题here。要点是,不要使用:
python -m json.tool

你会想要使用

python -c 'import sys,json; data=json.loads(sys.stdin.read()); print json.dumps(data,sort_keys=True,indent=4).decode("unicode_escape").encode("utf8","replace")'

这既美化了JSON,又保留了原始的Unicode内容。


顺便说一句,我fork了Josh的json-mode,并在https://github.com/chad3814/json-mode上添加了jstevenco的补充。 - chad
我已经在 https://github.com/joshwnj/json-mode/issues/5 请求修复非ASCII更新。 - Jarl
json-mode 的最新版本已经修复了 utf-8 问题:请参见 https://github.com/joshwnj/json-mode/issues/5 - Jarl
1
安装最新的 json-mode 包melpa 上,它都可以直接使用。做得好! - TooTone
请将以下与编程有关的内容从英语翻译成中文。仅返回翻译后的文本:不要使用“unicode_escape”转义json内容,改用ensure_ascii=False代替。 - jfs

30

js-mode支持JSON文件的语法高亮和缩进。

自Emacs 23.2起,espresso-mode被并入Emacs并改名为js-mode。

请查看: http://www.nongnu.org/espresso/


6
不错!我在我的.emacs文件中加入了(setq auto-mode-alist (cons '("\\.json\\'" . js-mode) auto-mode-alist)) - Marvin
1
(add-to-list 'auto-mode-alist '("\\.json$" . js-mode)) 是同样的意思,但稍微更短些。 - ksrb

15

16
虽然 js2-mode 不是真正支持 JSON 的,但你可以参考 http://code.google.com/p/js2-mode/issues/detail?id=50。 - viam0Zah
1
@Török Gábor:你知道更好的替代方案吗? - jfs

15
如果你想要一个轻量级的编辑模式,可以尝试我捣鼓出来的这个主模式:https://github.com/joshwnj/json-mode。实际上,它只是在javascript-mode的基础上添加了一些额外的语法高亮,但对于我的用途,我发现它工作得非常好。
另一个常见的用例是自动格式化JSON文件(例如,如果它被压缩成一行且你想让它更易读)。为了做到这一点,我只需通过命令行脚本将缓冲区传输:C-u M-| 。

2
顺便说一句,我fork了这个repo并添加了jstevenco的beautify-json函数,它在https://github.com/chad3814/json-mode - 我也发送了一个pull请求。 - chad
就我所知,Josh已经接受了Chad的拉取请求,以包括jstevenco的添加(你都明白了吗?)。因此,截至本文撰写时,Josh在Github上的json-mode仓库是最新的源代码。 - Steven Collins
请应用非ASCII修复。 - Jarl
这是一个错误还是我做错了什么?http://emacs.stackexchange.com/q/17319/4003(我在我的.emacs中加载了json-mode) - Marcus Junius Brutus

9
我已经为js2-mode准备了一个解决方法,可以在不出错的情况下解析json文件。您可以在我的评论中找到它:http://code.google.com/p/js2-mode/issues/detail?id=50#c7
(我本想将其作为对J.F. Sebastian解决方案的评论发布,但似乎我没有权限这样做(没有“添加评论”链接))

6

json.el是Edward O'Connor开发的一个自GNU Emacs 23.1(2008年)起就成为其一部分的工具。

虽然它不是一个语法高亮器,但它有一个有用的功能可以对JSON进行格式化:

M-x json-pretty-print-buffer RET

因此,如果您使用的是最新版本的Emacs,则无需使用jq或python -m json.tool。

1
使用GNU Emacs 24.5.1附带的json-pretty-print-buffer,我发现它可以很好地格式化我的JSON,但它也会颠倒其内容。幸运的是,我还发现在我的JSON上第二次运行它可以将其恢复到原始顺序。 - DavidRR

3

由于JSON是YAML的子集,因此yaml-mode也可以使用(虽然我不知道它与js-modejson-mode相比如何)。

安装(从emacs):M-x package-install yaml-mode

yaml-mode与YAML和JSON文件关联,在~/.emacs.d/init.el中:

(add-to-list 'auto-mode-alist '("\\.yaml$" . yaml-mode))
(add-to-list 'auto-mode-alist '("\\.json$" . yaml-mode))

0

我对Mariusz Nowak的解决方法进行了扩展,使其可以作为自己的主要模式使用。除了简单地派生模式之外,几乎不需要进行任何修改;Nowak的工作实际上唯一需要的更改是能够识别与文件无关或文件名不以.json结尾的缓冲区作为JSON,我们通过一个缓冲区本地变量来实现这一点。

以下是增强版的解决方法:

(make-variable-buffer-local 'js2-parse-as-json)

(defadvice js2-reparse (before json)
    (setq js2-buffer-file-name buffer-file-name))
(ad-activate 'js2-reparse)

(defadvice js2-parse-statement (around json)
    (if (and (= tt js2-LC)
           js2-buffer-file-name
           (or js2-parse-as-json
               (string-equal (substring js2-buffer-file-name -5) ".json"))
           (eq (+ (save-excursion
                    (goto-char (point-min))
                    (back-to-indentation)
                    (while (eolp)
                      (next-line)
                      (back-to-indentation))
                    (point)) 1) js2-ts-cursor))
      (setq ad-return-value (js2-parse-assign-expr))
        ad-do-it))
(ad-activate 'js2-parse-statement)

(define-derived-mode json-mode js2-mode "JSON"
  "Major mode for editing JSON data."
  :group 'json
  (setq js2-parse-as-json t)
  (js2-reparse t))

(add-to-list 'auto-mode-alist '("\\.json$" . json-mode))

如果您已经使用js2-mode,那么它可能比js-mode加上flymake-json更好,因为您不需要安装任何新工具(js2-mode已经进行语法检查,不需要外部工具);而且该模式会继承您的js2-mode配置,而js-mode不会。

0

我也赞同Josh的json-mode,并推荐作为补充使用flymake-json。它有助于突出语法错误。

我不喜欢使用python -mjson.tool,因为它会重新排列JSON对象中的项目。 我发现(prog-indent-sexp)可以很好地重新缩进,并且在beautify-json中使用jsonlint 而不是python -mjson.tool适用于漂亮的打印/重新格式化。

(eval-after-load "json-mode"
  '(progn
     (require 'flymake-json)
     ;; flymake-cursor displays error in minibuffer message area instead of requiring hover
     (require 'flymake-cursor)

     (add-hook 'json-mode-hook 'flymake-json-load)
     (define-key json-mode-map "\C-c\C-n" (function flymake-goto-next-error))
  )
)

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接