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.
This commit is contained in:
parent
9a05f0ac95
commit
6b66375133
3 changed files with 34 additions and 5 deletions
5
etc/NEWS
5
etc/NEWS
|
@ -314,6 +314,11 @@ standards.
|
|||
|
||||
* Changes in Specialized Modes and Packages in Emacs 25.1
|
||||
|
||||
** JSON
|
||||
---
|
||||
*** `json-pretty-print' and `json-pretty-print-buffer' now maintain
|
||||
the ordering of object keys by default.
|
||||
|
||||
** You can recompute the VC state of a file buffer with `M-x vc-refresh-state'
|
||||
** Prog mode has some support for multi-mode indentation.
|
||||
See `prog-indentation-context' and `prog-widen'.
|
||||
|
|
21
lisp/json.el
21
lisp/json.el
|
@ -57,7 +57,8 @@
|
|||
(defvar json-object-type 'alist
|
||||
"Type to convert JSON objects to.
|
||||
Must be one of `alist', `plist', or `hash-table'. Consider let-binding
|
||||
this around your call to `json-read' instead of `setq'ing it.")
|
||||
this around your call to `json-read' instead of `setq'ing it. Ordering
|
||||
is maintained for `alist' and `plist', but not for `hash-table'.")
|
||||
|
||||
(defvar json-array-type 'vector
|
||||
"Type to convert JSON arrays to.
|
||||
|
@ -136,6 +137,17 @@ without indentation.")
|
|||
'not-plist)))
|
||||
(null list))
|
||||
|
||||
(defun json--plist-reverse (plist)
|
||||
"Return a copy of PLIST in reverse order.
|
||||
Unlike `reverse', this keeps the property-value pairs intact."
|
||||
(let (res)
|
||||
(while plist
|
||||
(let ((prop (pop plist))
|
||||
(val (pop plist)))
|
||||
(push val res)
|
||||
(push prop res)))
|
||||
res))
|
||||
|
||||
(defmacro json--with-indentation (body)
|
||||
`(let ((json--encoding-current-indentation
|
||||
(if json-encoding-pretty-print
|
||||
|
@ -400,7 +412,10 @@ Please see the documentation of `json-object-type' and `json-key-type'."
|
|||
(signal 'json-object-format (list "," (json-peek))))))
|
||||
;; Skip over the "}"
|
||||
(json-advance)
|
||||
elements))
|
||||
(pcase json-object-type
|
||||
(`alist (nreverse elements))
|
||||
(`plist (json--plist-reverse elements))
|
||||
(_ elements))))
|
||||
|
||||
;; Hash table encoding
|
||||
|
||||
|
@ -602,6 +617,8 @@ Advances point just past JSON object."
|
|||
(interactive "r")
|
||||
(atomic-change-group
|
||||
(let ((json-encoding-pretty-print t)
|
||||
;; Ensure that ordering is maintained
|
||||
(json-object-type 'alist)
|
||||
(txt (delete-and-extract-region begin end)))
|
||||
(insert (json-encode (json-read-from-string txt))))))
|
||||
|
||||
|
|
|
@ -22,15 +22,22 @@
|
|||
(require 'ert)
|
||||
(require 'json)
|
||||
|
||||
(ert-deftest test-json-plist-reverse ()
|
||||
(should (equal (json--plist-reverse '()) '()))
|
||||
(should (equal (json--plist-reverse '(:a 1)) '(:a 1)))
|
||||
(should (equal (json--plist-reverse '(:a 1 :b 2 :c 3))
|
||||
'(:c 3 :b 2 :a 1))))
|
||||
|
||||
(ert-deftest json-encode-simple-alist ()
|
||||
(should (equal (json-encode '((a . 1)
|
||||
(b . 2)))
|
||||
"{\"a\":1,\"b\":2}")))
|
||||
|
||||
(ert-deftest json-read-simple-alist ()
|
||||
(should (equal (json-read-from-string "{\"a\": 1, \"b\": 2}")
|
||||
'((b . 2)
|
||||
(a . 1)))))
|
||||
(let ((json-object-type 'alist))
|
||||
(should (equal (json-read-from-string "{\"a\": 1, \"b\": 2}")
|
||||
'((a . 1)
|
||||
(b . 2))))))
|
||||
|
||||
(ert-deftest json-encode-string-with-special-chars ()
|
||||
(should (equal (json-encode-string "a\n\fb")
|
||||
|
|
Loading…
Add table
Reference in a new issue