Mode Emacs pour éditer JSON

Est-ce que quelqu’un connaît un bon mode Emacs pour éditer JSON? Une application sur laquelle je travaille utilise un protocole de communication basé sur JSON et le fait que les données soient bien mises en retrait et mises en évidence par la syntaxe m’aiderait beaucoup à résoudre ce problème.

Avez-vous essayé le mode js2 de Steve Yegge pour Emacs ?

+1 pour le mode json de Josh – fonctionne bien pour moi. J’ai ajouté

(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 be "python -mjson.tool" (current-buffer) t))) 

et

 (define-key json-mode-map (kbd "Cc Cf") 'beautify-json) 

à json-mode.el pour faciliter l’invocation de la commande shell.

MISE À JOUR: Pour ceux d’entre vous qui ont besoin / désir de faire cela avec unicode, voir ma question ici . Le résultat est plutôt que d’utiliser:

 python -mjson.tool 

vous voudrez utiliser

 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\")' 

Ceci à la fois embellit le JSON et préserve le contenu unicode original.

js-mode supporte la mise en évidence de la syntaxe et l’indentation pour les fichiers json.

C’est à partir d’Emacs 23.2 , quand le mode espresso a été incorporé dans Emacs et renommé js-mode.

Check it out: http://www.nongnu.org/espresso/

Si vous voulez quelque chose de léger, essayez ce mode majeur que j’ai piraté ensemble: https://github.com/joshwnj/json-mode

Ce n’est en fait rien de plus qu’une mise en évidence de la syntaxe supplémentaire en plus du mode javascript, mais pour ma part, je trouve que cela fonctionne assez bien.

Un autre cas d’usage courant est le formatage automatique d’un fichier JSON (par exemple, s’il est compressé en blanc et que vous souhaitez une meilleure lisibilité). Pour ce faire, je passe la mémoire tampon via un script de ligne de commande: Cu M- |

J’ai préparé une solution de contournement pour js2-mode afin qu’il parsing les fichiers json sans erreurs. Vous pouvez le trouver dans mon commentaire: http://code.google.com/p/js2-mode/issues/detail?id=50#c7

(Je voulais le poster en tant que commentaire dans la solution JF Sebastian, mais il semble que je ne suis pas autorisé à le faire (pas de lien “append un commentaire”))

Puisque JSON est un sous-ensemble de YAML, yaml-mode fonctionne aussi (je ne sais pas comment il se compare à js-mode et json-mode , cependant).

Installer (depuis emacs): Mx package-install yaml-mode .

Association de yaml-mode avec les fichiers YAML et JSON, dans ~/.emacs.d/init.el :

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

json.el par Edward O’Connor fait partie de GNU Emacs depuis 23.1 (2008).

Bien qu’il ne soit pas un surligneur syntaxique, il a une fonction utile pour formater JSON:

 Mx json-pretty-print-buffer RET 

Donc, si vous avez une version récente d’Emacs, il n’est pas nécessaire d’ jq ou python -m json.tool .

JSON est pris en charge par le mode espresso

js3-mode: https://github.com/thomblake/js3-mode

js3-mode est un mode js2 amélioré

Ce paquet peut être installé par la commande package-list-packages

Je vais également seconder le mode json de Josh, mais aussi recommander flymake-json comme un ajout. Il aide à mettre en évidence les erreurs de syntaxe.

Je n’aime pas utiliser python -mjson.tool car il réordonne les éléments dans les objects JSON. Je trouve que (prog-indent-sexp) fonctionne très bien pour réindexer, et utiliser jsonlint au lieu de python -mjson.tool fonctionne bien pour l’impression / reformatage dans 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 "\Cc\Cn" (function flymake-goto-next-error)) ) ) 

J’ai élargi la solution de contournement de Mariusz Nowak pour la rendre utilisable comme un mode majeur à part entière. Peu de modifications ont été nécessaires au-delà de la simple dérivation du mode; Le seul changement nécessaire au travail de Nowak était la capacité à reconnaître les tampons non associés à des fichiers, ou associés à des fichiers dont les noms ne se terminent pas par .json , comme JSON, avec une variable buffer-local.

Voici la solution de contournement améliorée:

 (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 (ssortingng-equal (subssortingng 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)) 

Si vous utilisez déjà js2-mode, cela peut être une meilleure option que js-mode plus flymake-json car vous n’avez pas besoin d’installer quoi que ce soit (js2-mode vérifie déjà la syntaxe, pas besoin d’un outil externe) héritera de votre configuration en mode js2, ce qui ne sera pas le cas avec js-mode.

Je recommanderais également js2-mode.

JSON signifie JavaScript Object Notation. Ce n’est pas un autre langage et ce n’est même pas un conteneur de données comme le yaml ou le xml. JSON pourrait être utilisé comme un conteneur de données s’il n’y a pas de fonction (ou dans ce cas, nous devrions dire méthode) dans un object JSON, mais ce n’est pas le but principal de JSON 🙂

 var myJSObject = { attr: {foo: "bar", baz: ["quux", "truc", "pouet"]}, fooAlert: function (num) { alert(this.attr.foo+' '+num); } }; myJSObject.fooAlert(42);