Emacs mode to edit JSON - json

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.

+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.

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/

Have you tried Steve Yegge's js2-mode for Emacs?

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-|

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))

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.

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))

JSON is supported by espresso-mode

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

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))
)
)

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.

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);

Related

Having trouble compiling scribble document with `#lang scribble/html`

I'm trying to use Scribble (Racket v8.0 [cs]) to generate some HTML using #lang scribble/html and I've reduced my source file to only the lang statement (to isolate other issues):
#lang scribble/html
To run the code I'm using terminal:
% scribble test.scrbl
However, I'm running into the following error during compilation:
dynamic-require: name is not provided
name: 'doc
module: #<resolved-module-path:"/Users/josh/Desktop/blog architecture/00001 article name/test.scrbl">
context...:
.../private/map.rkt:40:19: loop
.../racket/cmdline.rkt:191:51
body of "/Applications/Racket v8.0/share/pkgs/scribble-lib/scribble/run.rkt"
Obviously something is missing - perhaps a require statement? I'm not sure. If you have a better approach to using #lang scribble/html I'm open to that as long as I can use the html tags.
Thank you!
Hello person from 6 months ago! I hope you have solved your problem, but for other travelers here's what worked for me:
Don't use the scribble binary, but directly use the racket executable.
So, instead of:
$ scribble test.scrbl
Do
$ racket test.scrbl
This seemed to work for me with scribble/text, and outputted exactly what I wanted (nothing weirdly processed, nothing "helpfully" escaped - just my text + my racket code executed)

How to auto indent multiple files?

Currently, I generate static files and those files aren't indented properly. Emacs' auto indent works great with c-x h tab, but that's per file. I want to auto indent multiple files (Like 50 or so, thus it's not feasible to do it manually).
Is there any way to accomplish this? Whether it be using a different text editor or a script or etc. If it helps, most of the files are .html.
I tested the code below with some HTML files, it works well.
(defun indent-file (file-name)
(save-window-excursion
(find-file file-name)
(indent-region (point-min) (point-max))
(write-region nil nil file-name)))
;; argv is a list stores command line option. In this case, it will be ("/your/directory/path").
;; directory-files-recursively will find files recursively, and it needs emacs 25.1 or later.
(let* ((target-dir (car argv))
(target-file-names (directory-files-recursively target-dir ".*.html$")))
(dolist (file-name target-file-names)
(indent-file file-name)))
Save the code above as 'indent-files.el'
Run emacs --script indent-files.el "/your/directory/path" in terminal
It will be tricky if you want to use emacs lisp as a common script language, although it actually could indeed. Here are some tips: https://swsnr.de/blog/2014/08/12/emacs-script-pitfalls/

Vim modeline in a JSON file

I'm trying to add the following vim modeline to my global .tern-config file:
// vim: set ft=json:
{
plugins: {
...
However, the Tern server fails to start, giving the following error:
Failed to start server:
Bad JSON in /Users/XXXXX/.tern-config: Unexpected token / in JSON at position 0
I suspect the reason for this error is JSON's lack of support for comments. I should note that the same modeline in my .eslintrc file works.
How do I include a vim modeline in my .tern-config file?
If one puts an object like this
"_vim_": { "modeline": "/* vim: set ft=json noet ts=4 sw=4: */" }
as first or last entry into the top-level object list of a json file it will be used as modeline by vim (as long as the line appears close enough at the beginning or end of the file, where "close enough" means: within the number of lines that vim scans for modelines according to its 'modelines' option which defaults to 5).
Also, the object's name ("_vim_") should be carefully chosen, so that -- at best -- it is ignored by the software that uses the file as input, or -- at least -- can be ignored by the software's users (i. e., it doesn't cause any side effect that would be considered as unwanted behaviour).
You won't able to do this in the file itself. JSON does not support comments, and it's a very unforgiving syntax.
This may work in some JSON files, like .eslintrc, but in others, you will be out of luck. The stricter JSON parsers will not allow it, so it depends on which parser the tool you're using at the moment is built on.
Rather than guessing which parsers are forgiving and which aren't, you are probably better off telling Vim how to do this using an autocmd.
autocmd BufNewFile,BufRead *.tern-config set filetype=json

No auto-complete on HTML and CSS files in VIM (YouCompleteMe)

For some reason, I get no autocomplete on html and css files. All works well with other languages, for example JS, Ruby or Python.
I've spent close to 2h today trying to fix it but to no avail. I use Vundle and YouCompleteMe to do all of this. You can have a look at my .vimrc file here https://gist.github.com/comatory/73aacac1b0249b8c1c55.
I'm on OS X 10.10.5 and my Vim version is 7.4 (installed via Homebrew). I also use Macvim but it doesn't matter, it doesn't work in either of them.
Check the value of the paste setting
:verbose set paste?
will show you the current value for this buffer as well as which plugin set it last.
In my experience, completion doesn't happen if paste is set. Disable with
:set nopaste
Maybe it is in your filepath blacklist as in default.
Quote from: https://github.com/ycm-core/YouCompleteMe/
The g:ycm_filepath_blacklist option
This option controls for which Vim filetypes (see :h filetype) should filepath completion be disabled. The option value should be a Vim dictionary with keys being filetype strings (like python, cpp, etc.) and values being unimportant (the dictionary is used like a hash set, meaning that only the keys matter).
let g:ycm_filepath_blacklist = {'*': 1}
The * key is special and matches all filetypes. Use this key if you want to completely disable filepath completion:
You can get the filetype of the current file in Vim with :set ft?.
Default: [see next line]
let g:ycm_filepath_blacklist = {
\ 'html': 1,
\ 'jsx': 1,
\ 'xml': 1,
\}
I would suggest you use NeoComplete. I tried YouCompleteMe on Vim8, but doesn't work for some reason. NeoComplete does the job for me.
After installing NeoComplete just add, let g:neocomplete#enable_at_startup = 1 to your .vimrrc

"info command rtExMath" in Tk with vtk

I am new for Tcl/Tk. I am using vtk with Tk command window for running vtk tcl/tk examples. Here is a code which include Tk expression as condition of if and I am not getting it.
if { [info command rtExMath] != "" } {
##Do something related VTK
}
I have explored info of Tk but there is a combination with keyword command and also no any good explanation I found for rtExMath.
Please explain me above.
The info commands command (info command is just an unambiguous prefix) returns a list of all commands, or a list of all commands that match the given glob pattern. In the case you're looking at, the glob pattern is actually going to be a string-equality check (and is even optimised to such internally); there's no glob metacharacters in it. The result of that is that [info command rtExMath] != "" is a condition that is true exactly when the command rtExMath exists.
Tcl itself does not define any command called rtExMath; I conclude that it must be part of some specialist extension or application. However, Googling makes me suspect that it is actually a somewhat-standard name for an instance of the vtkMath class in Vtk, but I don't really know for sure. (I'm guessing that the binding of that class to Tcl was done by SWIG…)