aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorRyan Crum2012-12-14 09:57:37 -0500
committerStefan Monnier2012-12-14 09:57:37 -0500
commitd72e9e922fb914a946e104ad2128f57c983ab75d (patch)
tree28033212d18d659b1f7f16cee58dfd6482041bab /lisp
parent5c207910c4899af1c547b0e508692d846c145d48 (diff)
downloademacs-d72e9e922fb914a946e104ad2128f57c983ab75d.tar.gz
emacs-d72e9e922fb914a946e104ad2128f57c983ab75d.zip
* lisp/json.el: Add pretty-print option.
(json-encoding-separator, json-encoding-default-indentation) (json--encoding-current-indentation, json-encoding-pretty-print) (json-encoding-lisp-style-closings): New vars. (json--with-indentation): New macro. (json-encode-hash-table, json-encode-alist, json-encode-plist) (json-encode-array): Use it to obey json-encoding-pretty-print. (json-pretty-print-buffer, json-pretty-print): New commands. Fixes: debbugs:12634
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog11
-rw-r--r--lisp/json.el136
2 files changed, 122 insertions, 25 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 8df55eaa108..97b3a6608ad 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,14 @@
12012-12-14 Ryan Crum <ryan.crum@eleostech.com>
2
3 * json.el: Add pretty-print option (bug#12634).
4 (json-encoding-separator, json-encoding-default-indentation)
5 (json--encoding-current-indentation, json-encoding-pretty-print)
6 (json-encoding-lisp-style-closings): New vars.
7 (json--with-indentation): New macro.
8 (json-encode-hash-table, json-encode-alist, json-encode-plist)
9 (json-encode-array): Use it to obey json-encoding-pretty-print.
10 (json-pretty-print-buffer, json-pretty-print): New commands.
11
12012-12-14 Dmitry Gutov <dgutov@yandex.ru> 122012-12-14 Dmitry Gutov <dgutov@yandex.ru>
2 13
3 * progmodes/ruby-mode.el (ruby-syntax-propertize-function): 14 * progmodes/ruby-mode.el (ruby-syntax-propertize-function):
diff --git a/lisp/json.el b/lisp/json.el
index b1ea03120dc..0927625de9f 100644
--- a/lisp/json.el
+++ b/lisp/json.el
@@ -3,7 +3,7 @@
3;; Copyright (C) 2006-2012 Free Software Foundation, Inc. 3;; Copyright (C) 2006-2012 Free Software Foundation, Inc.
4 4
5;; Author: Edward O'Connor <ted@oconnor.cx> 5;; Author: Edward O'Connor <ted@oconnor.cx>
6;; Version: 1.3 6;; Version: 1.4
7;; Keywords: convenience 7;; Keywords: convenience
8 8
9;; This file is part of GNU Emacs. 9;; This file is part of GNU Emacs.
@@ -48,6 +48,7 @@
48;; 2006-12-29 - XEmacs support, from Aidan Kehoe <kehoea@parhasard.net>. 48;; 2006-12-29 - XEmacs support, from Aidan Kehoe <kehoea@parhasard.net>.
49;; 2008-02-21 - Installed in GNU Emacs. 49;; 2008-02-21 - Installed in GNU Emacs.
50;; 2011-10-17 - Patch `json-alist-p' and `json-plist-p' to avoid recursion -tzz 50;; 2011-10-17 - Patch `json-alist-p' and `json-plist-p' to avoid recursion -tzz
51;; 2012-10-25 - Added pretty-printed reformatting -Ryan Crum (ryan@ryancrum.org)
51 52
52;;; Code: 53;;; Code:
53 54
@@ -98,6 +99,24 @@ If this has the same value as `json-false', you might not be able to
98tell the difference between `false' and `null'. Consider let-binding 99tell the difference between `false' and `null'. Consider let-binding
99this around your call to `json-read' instead of `setq'ing it.") 100this around your call to `json-read' instead of `setq'ing it.")
100 101
102(defvar json-encoding-separator ","
103 "Value to use as an element seperator when encoding.")
104
105(defvar json-encoding-default-indentation " "
106 "The default indentation level for encoding.
107Used only when `json-encoding-pretty-print' is non-nil.")
108
109(defvar json--encoding-current-indentation "\n"
110 "Internally used to keep track of the current indentation level of encoding.
111Used only when `json-encoding-pretty-print' is non-nil.")
112
113(defvar json-encoding-pretty-print nil
114 "If non-nil, then the output of `json-encode' will be pretty-printed.")
115
116(defvar json-encoding-lisp-style-closings nil
117 "If non-nil, ] and } closings will be formatted lisp-style,
118without indentation.")
119
101 120
102 121
103;;; Utilities 122;;; Utilities
@@ -123,6 +142,14 @@ this around your call to `json-read' instead of `setq'ing it.")
123 'not-plist))) 142 'not-plist)))
124 (null list)) 143 (null list))
125 144
145(defmacro json--with-indentation (body)
146 `(let ((json--encoding-current-indentation
147 (if json-encoding-pretty-print
148 (concat json--encoding-current-indentation
149 json-encoding-default-indentation)
150 "")))
151 ,body))
152
126;; Reader utilities 153;; Reader utilities
127 154
128(defsubst json-advance (&optional n) 155(defsubst json-advance (&optional n)
@@ -401,41 +428,70 @@ Please see the documentation of `json-object-type' and `json-key-type'."
401 428
402(defun json-encode-hash-table (hash-table) 429(defun json-encode-hash-table (hash-table)
403 "Return a JSON representation of HASH-TABLE." 430 "Return a JSON representation of HASH-TABLE."
404 (format "{%s}" 431 (format "{%s%s}"
405 (json-join 432 (json-join
406 (let (r) 433 (let (r)
407 (maphash 434 (json--with-indentation
408 (lambda (k v) 435 (maphash
409 (push (format "%s:%s" 436 (lambda (k v)
410 (json-encode-key k) 437 (push (format
411 (json-encode v)) 438 (if json-encoding-pretty-print
412 r)) 439 "%s%s: %s"
413 hash-table) 440 "%s%s:%s")
441 json--encoding-current-indentation
442 (json-encode-key k)
443 (json-encode v))
444 r))
445 hash-table))
414 r) 446 r)
415 ", "))) 447 json-encoding-separator)
448 (if (or (not json-encoding-pretty-print)
449 json-encoding-lisp-style-closings)
450 ""
451 json--encoding-current-indentation)))
416 452
417;; List encoding (including alists and plists) 453;; List encoding (including alists and plists)
418 454
419(defun json-encode-alist (alist) 455(defun json-encode-alist (alist)
420 "Return a JSON representation of ALIST." 456 "Return a JSON representation of ALIST."
421 (format "{%s}" 457 (format "{%s%s}"
422 (json-join (mapcar (lambda (cons) 458 (json-join
423 (format "%s:%s" 459 (json--with-indentation
424 (json-encode-key (car cons)) 460 (mapcar (lambda (cons)
425 (json-encode (cdr cons)))) 461 (format (if json-encoding-pretty-print
426 alist) 462 "%s%s: %s"
427 ", "))) 463 "%s%s:%s")
464 json--encoding-current-indentation
465 (json-encode-key (car cons))
466 (json-encode (cdr cons))))
467 alist))
468 json-encoding-separator)
469 (if (or (not json-encoding-pretty-print)
470 json-encoding-lisp-style-closings)
471 ""
472 json--encoding-current-indentation)))
428 473
429(defun json-encode-plist (plist) 474(defun json-encode-plist (plist)
430 "Return a JSON representation of PLIST." 475 "Return a JSON representation of PLIST."
431 (let (result) 476 (let (result)
432 (while plist 477 (json--with-indentation
433 (push (concat (json-encode-key (car plist)) 478 (while plist
434 ":" 479 (push (concat
435 (json-encode (cadr plist))) 480 json--encoding-current-indentation
436 result) 481 (json-encode-key (car plist))
437 (setq plist (cddr plist))) 482 (if json-encoding-pretty-print
438 (concat "{" (json-join (nreverse result) ", ") "}"))) 483 ": "
484 ":")
485 (json-encode (cadr plist)))
486 result)
487 (setq plist (cddr plist))))
488 (concat "{"
489 (json-join (nreverse result) json-encoding-separator)
490 (if (and json-encoding-pretty-print
491 (not json-encoding-lisp-style-closings))
492 json--encoding-current-indentation
493 "")
494 "}")))
439 495
440(defun json-encode-list (list) 496(defun json-encode-list (list)
441 "Return a JSON representation of LIST. 497 "Return a JSON representation of LIST.
@@ -474,7 +530,22 @@ become JSON objects."
474 530
475(defun json-encode-array (array) 531(defun json-encode-array (array)
476 "Return a JSON representation of ARRAY." 532 "Return a JSON representation of ARRAY."
477 (concat "[" (mapconcat 'json-encode array ", ") "]")) 533 (if (and json-encoding-pretty-print
534 (> (length array) 0))
535 (concat
536 (json--with-indentation
537 (concat (format "[%s" json--encoding-current-indentation)
538 (json-join (mapcar 'json-encode array)
539 (format "%s%s"
540 json-encoding-separator
541 json--encoding-current-indentation))))
542 (format "%s]"
543 (if json-encoding-lisp-style-closings
544 ""
545 json--encoding-current-indentation)))
546 (concat "["
547 (mapconcat 'json-encode array json-encoding-separator)
548 "]")))
478 549
479 550
480 551
@@ -541,6 +612,21 @@ Advances point just past JSON object."
541 ((listp object) (json-encode-list object)) 612 ((listp object) (json-encode-list object))
542 (t (signal 'json-error (list object))))) 613 (t (signal 'json-error (list object)))))
543 614
615;; Pretty printing
616
617(defun json-pretty-print-buffer ()
618 "Pretty-print current buffer."
619 (interactive)
620 (json-pretty-print (point-min) (point-max)))
621
622(defun json-pretty-print (begin end)
623 "Pretty-print selected region."
624 (interactive "r")
625 (atomic-change-group
626 (let ((json-encoding-pretty-print t)
627 (txt (delete-and-extract-region begin end)))
628 (insert (json-encode (json-read-from-string txt))))))
629
544(provide 'json) 630(provide 'json)
545 631
546;;; json.el ends here 632;;; json.el ends here