Function: clojure--read-form

clojure--read-form is a byte-compiled function defined in clojure-mode.el.

Signature

(clojure--read-form END)

Documentation

Read the form after point, move past it and return it.

Return nil at a closing bracket or at END. Discarded forms count, as discard forms, but comments and metadata don't.

Source Code

;; Defined in ~/.emacs.d/elpa/clojure-mode-20261103.1226/clojure-mode.el
(defun clojure--read-form (end)
  "Read the form after point, move past it and return it.
Return nil at a closing bracket or at END.  Discarded forms count, as
`discard' forms, but comments and metadata don't."
  (clojure--skip-whitespace-and-comments)
  (let ((start (point)))
    (when (and (< start end) (not (memq (char-after) '(?\) ?\] ?\}))))
      (cond
       ((looking-at-p "#_")
        (forward-char 2)
        (clojure--make-form :type 'discard :start start
                            :children (delq nil (list (clojure--read-form end)))
                            :end (point)))
       ((looking-at "#?\\^")
        (goto-char (match-end 0))
        (clojure--read-form end)
        (let ((form (clojure--read-form end)))
          ;; Like comments, discarded forms between the metadata and its
          ;; form go with the form.
          (while (and form (eq (clojure--form-type form) 'discard))
            (setq form (clojure--read-form end)))
          (when form
            (setf (clojure--form-meta-start form) start))
          form))
       ((looking-at "'\\|\\(`\\)\\|~@?\\|@\\|#'\\|#=")
        (let ((type (cond ((match-beginning 1) 'syntax-quote)
                          ((eq (char-after) ?') 'quote)
                          (t 'other))))
          (goto-char (match-end 0))
          (clojure--make-form :type type :start start
                              :children (delq nil (list (clojure--read-form end)))
                              :end (point))))
       ((looking-at-p "[([{]")
        (clojure--read-coll (pcase (char-after) (?\( 'list) (?\[ 'vector) (_ 'map))
                            start end))
       ((looking-at-p "#:")
        (clojure--read-coll 'ns-map start end 2))
       ((looking-at-p "#\\?@")
        (clojure--read-coll 'splice start end 1))
       ((looking-at-p "#[({?]")
        (clojure--read-coll 'other start end 1))
       ((looking-at-p "#?\"")
        (skip-chars-forward "#")
        (forward-sexp)
        (clojure--make-form :type 'atom :start start :end (point)))
       ((looking-at "#[^#]")
        ;; A tagged literal
        (forward-char)
        (clojure--read-form end)
        (clojure--make-form :type 'other :start start
                            :children (delq nil (list (clojure--read-form end)))
                            :end (point)))
       ((eq (char-after) ?\\)
        (forward-char 2)
        (when (memq (char-syntax (char-before)) '(?w ?_))
          (skip-chars-forward "a-zA-Z0-9"))
        (clojure--make-form :type 'atom :start start :end (point)))
       (t
        (skip-chars-forward "^ \t\n\r\f,\";@^`~()[]{}\\\\" end)
        (when (= (point) start)
          (forward-char))
        (let ((token (buffer-substring-no-properties start (point))))
          (cond
           ((string-match-p "\\`[+-]?[0-9]" token)
            (clojure--make-form :type 'atom :start start :end (point)))
           (t
            (let* ((keyword (string-match "\\`::?" token))
                   (token (if keyword (substring token (match-end 0)) token))
                   (qualified (string-match "\\`\\([^/]+\\)/\\(.+\\)\\'" token)))
              (clojure--make-form :type (if keyword 'keyword 'symbol)
                                  :start start :end (point)
                                  :name (if qualified (match-string 2 token) token)
                                  :namespace (and qualified (match-string 1 token))))))))))))