Function: cider--indent-spec-to-legacy

cider--indent-spec-to-legacy is a byte-compiled function defined in cider-util.el.

Signature

(cider--indent-spec-to-legacy SPEC)

Documentation

Convert a modern indent SPEC to legacy format for older clojure-mode.

Returns SPEC unchanged if it is not in modern format.

Modern format uses ((:block N)), ((:inner D)), ((:inner D I)). Legacy format uses integers, :defn, and positional lists, where the first element is the spec of the form itself and the rest are the specs of its arguments, the last one also covering the arguments after it. Only the shallowest of several :inner rules without a position is kept, and a rule with a position replaces the others for that argument. Like in cljfmt, (:inner 0) does nothing next to a :block rule. Rules with negative numbers are ignored.

This ensures compatibility with clojure-mode versions that don't understand the modern format.

Source Code

;; Defined in ~/.emacs.d/elpa/cider-20261106.1225/cider-util.el
(defun cider--indent-spec-to-legacy (spec)
  "Convert a modern indent SPEC to legacy format for older clojure-mode.
Returns SPEC unchanged if it is not in modern format.

Modern format uses ((:block N)), ((:inner D)), ((:inner D I)).
Legacy format uses integers, :defn, and positional lists, where the
first element is the spec of the form itself and the rest are the specs
of its arguments, the last one also covering the arguments after it.
Only the shallowest of several :inner rules without a position is kept,
and a rule with a position replaces the others for that argument.  Like
in cljfmt, (:inner 0) does nothing next to a :block rule.  Rules with
negative numbers are ignored.

This ensures compatibility with clojure-mode versions that don't
understand the modern format."
  (if (not (cider--modern-indent-spec-p spec))
      spec
    (let* ((wrap-defn (lambda (depth)
                        (let ((s :defn))
                          (dotimes (_ depth)
                            (setq s (list s)))
                          s)))
           (block (let ((n (cadr (assq :block spec)))) (and (natnump n) n)))
           (inner (seq-filter (lambda (rule) (eq (car rule) :inner)) spec))
           (own (or block (and (member '(:inner 0) inner) :defn)))
           (depths (sort (seq-filter (lambda (depth) (> depth 0))
                                     (mapcar #'cadr (seq-remove #'cddr inner)))
                         #'<))
           (tail (and depths (funcall wrap-defn (car depths))))
           (indexed (seq-filter (lambda (rule)
                                  (and (natnump (caddr rule)) (> (cadr rule) 0)))
                                inner)))
      (if (not (or tail indexed))
          own
        ;; The spec of the form itself, then those of its arguments.
        (let* ((args (if indexed (+ 2 (apply #'max (mapcar #'caddr indexed))) 1))
               (result (cons own (make-list args tail))))
          (pcase-dolist (`(:inner ,depth ,idx) indexed)
            (setf (nth (1+ idx) result) (funcall wrap-defn depth)))
          result)))))