aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimen Heggestøyl2015-10-03 23:52:36 +0200
committerSimen Heggestøyl2015-10-03 23:52:36 +0200
commit6b66375133a54ea37106b00786d3a85f7c6d658d (patch)
treec1430aec49e3610c6db7d6aa082988fbfc159b78
parent9a05f0ac953ce19395c7409aed6bdd8db83cebb0 (diff)
downloademacs-6b66375133a54ea37106b00786d3a85f7c6d658d.tar.gz
emacs-6b66375133a54ea37106b00786d3a85f7c6d658d.zip
Maintain ordering of JSON object keys by default
* lisp/json.el (json-object-type): Mention order handling in doc-string. (json--plist-reverse): New utility function. (json-read-object): Maintain ordering for alists and plists. (json-pretty-print): Ensure that ordering is maintained. * test/automated/json-tests.el (test-json-plist-reverse): New test for `json--plist-reverse'. (json-read-simple-alist): Update test to accommodate for changes in `json-read-object'. * etc/NEWS: Document the new behavior of the pretty printing functions.
-rw-r--r--etc/NEWS5
-rw-r--r--lisp/json.el21
-rw-r--r--test/automated/json-tests.el13
3 files changed, 34 insertions, 5 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 26c478eff73..dbe0de38db6 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -314,6 +314,11 @@ standards.
314 314
315* Changes in Specialized Modes and Packages in Emacs 25.1 315* Changes in Specialized Modes and Packages in Emacs 25.1
316 316
317** JSON
318---
319*** `json-pretty-print' and `json-pretty-print-buffer' now maintain
320the ordering of object keys by default.
321
317** You can recompute the VC state of a file buffer with `M-x vc-refresh-state' 322** You can recompute the VC state of a file buffer with `M-x vc-refresh-state'
318** Prog mode has some support for multi-mode indentation. 323** Prog mode has some support for multi-mode indentation.
319See `prog-indentation-context' and `prog-widen'. 324See `prog-indentation-context' and `prog-widen'.
diff --git a/lisp/json.el b/lisp/json.el
index daa0c94da28..e2c7cc77222 100644
--- a/lisp/json.el
+++ b/lisp/json.el
@@ -57,7 +57,8 @@
57(defvar json-object-type 'alist 57(defvar json-object-type 'alist
58 "Type to convert JSON objects to. 58 "Type to convert JSON objects to.
59Must be one of `alist', `plist', or `hash-table'. Consider let-binding 59Must be one of `alist', `plist', or `hash-table'. Consider let-binding
60this around your call to `json-read' instead of `setq'ing it.") 60this around your call to `json-read' instead of `setq'ing it. Ordering
61is maintained for `alist' and `plist', but not for `hash-table'.")
61 62
62(defvar json-array-type 'vector 63(defvar json-array-type 'vector
63 "Type to convert JSON arrays to. 64 "Type to convert JSON arrays to.
@@ -136,6 +137,17 @@ without indentation.")
136 'not-plist))) 137 'not-plist)))
137 (null list)) 138 (null list))
138 139
140(defun json--plist-reverse (plist)
141 "Return a copy of PLIST in reverse order.
142Unlike `reverse', this keeps the property-value pairs intact."
143 (let (res)
144 (while plist
145 (let ((prop (pop plist))
146 (val (pop plist)))
147 (push val res)
148 (push prop res)))
149 res))
150
139(defmacro json--with-indentation (body) 151(defmacro json--with-indentation (body)
140 `(let ((json--encoding-current-indentation 152 `(let ((json--encoding-current-indentation
141 (if json-encoding-pretty-print 153 (if json-encoding-pretty-print
@@ -400,7 +412,10 @@ Please see the documentation of `json-object-type' and `json-key-type'."
400 (signal 'json-object-format (list "," (json-peek)))))) 412 (signal 'json-object-format (list "," (json-peek))))))
401 ;; Skip over the "}" 413 ;; Skip over the "}"
402 (json-advance) 414 (json-advance)
403 elements)) 415 (pcase json-object-type
416 (`alist (nreverse elements))
417 (`plist (json--plist-reverse elements))
418 (_ elements))))
404 419
405;; Hash table encoding 420;; Hash table encoding
406 421
@@ -602,6 +617,8 @@ Advances point just past JSON object."
602 (interactive "r") 617 (interactive "r")
603 (atomic-change-group 618 (atomic-change-group
604 (let ((json-encoding-pretty-print t) 619 (let ((json-encoding-pretty-print t)
620 ;; Ensure that ordering is maintained
621 (json-object-type 'alist)
605 (txt (delete-and-extract-region begin end))) 622 (txt (delete-and-extract-region begin end)))
606 (insert (json-encode (json-read-from-string txt)))))) 623 (insert (json-encode (json-read-from-string txt))))))
607 624
diff --git a/test/automated/json-tests.el b/test/automated/json-tests.el
index fd89b7aa994..d1b7a2fa022 100644
--- a/test/automated/json-tests.el
+++ b/test/automated/json-tests.el
@@ -22,15 +22,22 @@
22(require 'ert) 22(require 'ert)
23(require 'json) 23(require 'json)
24 24
25(ert-deftest test-json-plist-reverse ()
26 (should (equal (json--plist-reverse '()) '()))
27 (should (equal (json--plist-reverse '(:a 1)) '(:a 1)))
28 (should (equal (json--plist-reverse '(:a 1 :b 2 :c 3))
29 '(:c 3 :b 2 :a 1))))
30
25(ert-deftest json-encode-simple-alist () 31(ert-deftest json-encode-simple-alist ()
26 (should (equal (json-encode '((a . 1) 32 (should (equal (json-encode '((a . 1)
27 (b . 2))) 33 (b . 2)))
28 "{\"a\":1,\"b\":2}"))) 34 "{\"a\":1,\"b\":2}")))
29 35
30(ert-deftest json-read-simple-alist () 36(ert-deftest json-read-simple-alist ()
31 (should (equal (json-read-from-string "{\"a\": 1, \"b\": 2}") 37 (let ((json-object-type 'alist))
32 '((b . 2) 38 (should (equal (json-read-from-string "{\"a\": 1, \"b\": 2}")
33 (a . 1))))) 39 '((a . 1)
40 (b . 2))))))
34 41
35(ert-deftest json-encode-string-with-special-chars () 42(ert-deftest json-encode-string-with-special-chars ()
36 (should (equal (json-encode-string "a\n\fb") 43 (should (equal (json-encode-string "a\n\fb")