\f
* 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'.
(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.
'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
(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
(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))))))
(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")