Function: json-pretty-print

json-pretty-print is an interactive and byte-compiled function defined in json.el.gz.

Signature

(json-pretty-print BEGIN END &optional MINIMIZE)

Documentation

Pretty-print selected region.

With prefix argument MINIMIZE, minimize it instead.

Probably introduced at or before Emacs version 25.1.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/json.el.gz
(defun json-pretty-print (begin end &optional minimize)
  "Pretty-print selected region.
With prefix argument MINIMIZE, minimize it instead."
  (interactive "r\nP")
  (let ((json-encoding-pretty-print (null minimize))
        ;; Distinguish an empty object from 'null'.
        (json-null :json-null)
        ;; Ensure that ordering is maintained.
        (json-object-type 'alist)
        ;; Ensure that keys survive roundtrip (bug#24252, bug#42545).
        (json-key-type 'string)
        (orig-buf (current-buffer))
        error)
    ;; Strategy: Repeatedly `json-read' from the original buffer and
    ;; write the pretty-printed snippet to a temporary buffer.  As
    ;; soon as we get an error from `json-read', simply append the
    ;; remainder which we couldn't pretty-print to the temporary
    ;; buffer as well (probably the region ends _inside_ a JSON
    ;; object).
    ;;
    ;; Finally, use `replace-region-contents' to swap the original
    ;; region with the contents of the temporary buffer so that point,
    ;; marks, etc. are kept.
    (with-temp-buffer
      (let ((tmp-buf (current-buffer)))
        (set-buffer orig-buf)
        (replace-region-contents
         begin end
         (lambda ()
           (let ((pos (point))
                 (keep-going t))
             (while keep-going
               (condition-case err
                   ;; We want to format only the JSON snippets in the
                   ;; region without modifying the whitespace between
                   ;; them.
                   (let ((space (buffer-substring
                                 (point)
                                 (+ (point) (skip-chars-forward " \t\n"))))
                         (json (json-read)))
                     (setq pos (point)) ; End of last good json-read.
                     (set-buffer tmp-buf)
                     (insert space (json-encode json))
                     (set-buffer orig-buf))
                 (t
                  (setq keep-going nil)
                  (set-buffer orig-buf)
                  ;; Rescue the remainder we couldn't pretty-print.
                  (append-to-buffer tmp-buf pos (point-max))
                  ;; EOF is expected because we json-read until we hit
                  ;; the end of the narrow region.
                  (unless (eq (car err) 'json-end-of-file)
                    (setq error err)))))
             tmp-buf))
         json-pretty-print-max-secs
         ;; FIXME: What's a good value here?  Can we use something better,
         ;; e.g., by deriving a value from the size of the region?
         64)))
    ;; If we got an error during JSON processing (possibly the region
    ;; starts or ends inside a JSON object), signal it to the user.
    ;; We did our best.
    (when error
      (signal (car error) (cdr error)))))