Emacs mode to edit JSON
JsonEmacsUnicodeJson Problem Overview
Does anybody know a good Emacs mode to edit JSON? An app I am working on uses a JSON based communication protocol and having the data nicely indented and syntax-highlighted would help me a lot in the process of figuring it out.
Json Solutions
Solution 1 - Json
+1 for Josh's json-mode -- works well for me. I added
(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)))
and
(define-key json-mode-map (kbd "C-c C-f") 'beautify-json)
to json-mode.el to make the shell command invocation easier.
UPDATE: For those of you with a need/desire to do this with unicode, see my question here. The upshot is rather than using:
python -m json.tool
you will want to use
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")'
This both beautifies the JSON as well as preserving the original Unicode content.
Solution 2 - Json
js-mode supports syntax highlighting and indentation for json files.
This is as of Emacs 23.2, when espresso-mode was incorporated into Emacs and renamed js-mode.
Check it out: http://www.nongnu.org/espresso/
Solution 3 - Json
Have you tried Steve Yegge's js2-mode for Emacs?
Solution 4 - Json
If you want something lightweight try this major-mode I hacked together: https://github.com/joshwnj/json-mode
It's actually no more than some extra syntax highlighting on top of javascript-mode, but for my purposes I've found it to work quite well.
Another common use-case is auto-formatting a JSON file (eg. if it's whitespace-compressed and you want more readability). To do this I'm just piping the buffer through a command-line script: C-u M-|
Solution 5 - Json
I've prepared a workaround for js2-mode so it parses json files without errors. You can find it in my comment: http://code.google.com/p/js2-mode/issues/detail?id=50#c7
(I wanted to post it as a comment do J.F. Sebastian solution, but it seems I'm not allowed to do so (no 'add comment' link))
Solution 6 - Json
json.el
by Edward O'Connor is part of GNU Emacs since 23.1 (2008).
While it isn't a syntax highlighter, it has a useful function to format JSON:
M-x json-pretty-print-buffer RET
So, if you have a recent version of Emacs, there is no need for jq
or python -m json.tool
.
Solution 7 - Json
Since JSON is a subset of YAML, yaml-mode
works too (I don't know how it compares to js-mode
and json-mode
, though).
Install (from emacs): M-x package-install yaml-mode
.
Association of yaml-mode
with YAML and JSON files, in ~/.emacs.d/init.el
:
(add-to-list 'auto-mode-alist '("\\.yaml$" . yaml-mode))
(add-to-list 'auto-mode-alist '("\\.json$" . yaml-mode))
Solution 8 - Json
JSON is supported by espresso-mode
Solution 9 - Json
js3-mode:https://github.com/thomblake/js3-mode
js3-mode is an improved js2-mode
This package can be installed by package-list-packages command
Solution 10 - Json
I will also second Josh's json-mode, but also recommend flymake-json as an addition. It helps highlight syntax errors.
I don't like using python -mjson.tool
because it reorders items in JSON objects.
I find (prog-indent-sexp)
works just fine to reindent, and using jsonlint
instead of python -mjson.tool
works for pretty printing/reformatting in beautify-json
(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))
)
)
Solution 11 - Json
I've expanded on Mariusz Nowak's workaround, to make it usable as a major mode in its own right. Little modification was required beyond simply deriving the mode; the only change Nowak's work actually needed was the ability to recognize buffers not associated with files, or associated with files whose names don't end in .json
, as JSON, which we accomplish with a buffer-local variable.
Here's the augmented workaround:
(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))
If you already use js2-mode, this may be a better option than js-mode
plus flymake-json
because you need not install anything new (js2-mode already does syntax checking, no need for an external tool), and because this mode will inherit your js2-mode configuration, which js-mode will not.
Solution 12 - Json
I would also recommand js2-mode.
JSON stands for JavaScript Object Notation. It's not another language and it's even not a data container like yaml or xml are. JSON could be used as a data container if there's no function (or in this case we should say method) inside a JSON object, but it's not the primary goal of JSON :-)
var myJSObject = {
attr: {foo: "bar", baz: ["quux", "truc", "pouet"]},
fooAlert: function (num) {
alert(this.attr.foo+' '+num);
}
};
myJSObject.fooAlert(42);