Function: clojure-indent-function

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

Signature

(clojure-indent-function INDENT-POINT STATE)

Documentation

When indenting a line within a function call, indent properly.

INDENT-POINT is the position where the user typed TAB, or equivalent. Point is located at the point to indent under (for default indentation); STATE is the parse-partial-sexp state for that position.

If the current line is in a call to a Clojure function with a non-nil property clojure-indent-function, that specifies how to do the indentation.

The property value can be

- :defn, meaning indent defn-style (body indentation);
- an integer N, meaning indent the first N arguments specially
  (further indented) and then indent any further arguments like
  a body;
- a function to call just as this function was called.
  If that function returns nil, that means it doesn't specify
  the indentation;
- a list, used for backtracking indentation of complex forms.
  Each element controls indentation at the corresponding argument
  position. Elements can be integers, :defn, :form, nil, or
  a nested list like ((:defn)) meaning "a list of :defn-style
  forms". See clojure--find-indent-spec-backtracking for
  details.

When no indent spec is found, forms starting with def or with- get body-style indentation, and forms starting with : use clojure-indent-keyword-style.

This function also returns nil meaning don't specify the indentation.

Source Code

;; Defined in ~/.emacs.d/elpa/clojure-mode-20260325.811/clojure-mode.el
;; Check the general context, and provide indentation for data structures and
;; special macros. If current form is a function (or non-special macro),
;; delegate indentation to `clojure--normal-indent'.
(defun clojure-indent-function (indent-point state)
  "When indenting a line within a function call, indent properly.

INDENT-POINT is the position where the user typed TAB, or equivalent.
Point is located at the point to indent under (for default indentation);
STATE is the `parse-partial-sexp' state for that position.

If the current line is in a call to a Clojure function with a
non-nil property `clojure-indent-function', that specifies how to do
the indentation.

The property value can be

- `:defn', meaning indent `defn'-style (body indentation);
- an integer N, meaning indent the first N arguments specially
  (further indented) and then indent any further arguments like
  a body;
- a function to call just as this function was called.
  If that function returns nil, that means it doesn't specify
  the indentation;
- a list, used for backtracking indentation of complex forms.
  Each element controls indentation at the corresponding argument
  position.  Elements can be integers, `:defn', `:form', nil, or
  a nested list like ((:defn)) meaning \"a list of :defn-style
  forms\".  See `clojure--find-indent-spec-backtracking' for
  details.

When no indent spec is found, forms starting with `def' or `with-'
get body-style indentation, and forms starting with `:' use
`clojure-indent-keyword-style'.

This function also returns nil meaning don't specify the indentation."
  ;; Goto to the open-paren.
  (goto-char (elt state 1))
  ;; Maps, sets, vectors and reader conditionals.
  (if (clojure--not-function-form-p)
      (1+ (current-column))
    ;; Function or macro call.
    (forward-char 1)
    (let* ((function (thing-at-point 'symbol))
           (method (and clojure-enable-indent-specs
                        (clojure--find-indent-spec function)))
           (last-sexp calculate-lisp-indent-last-sexp)
           (containing-form-column (1- (current-column))))
      (pcase method
        ((or (and (pred integerp) method) `(,method))
         (let ((pos -1))
           (condition-case nil
               (while (and (<= (point) indent-point)
                           (not (eobp)))
                 (clojure-forward-logical-sexp 1)
                 (cl-incf pos))
             ;; If indent-point is _after_ the last sexp in the
             ;; current sexp, we detect that by catching the
             ;; `scan-error'. In that case, we should return the
             ;; indentation as if there were an extra sexp at point.
             (scan-error (cl-incf pos)))
           (cond
            ;; The first non-special arg. Rigidly reduce indentation.
            ((= pos (1+ method))
             (+ lisp-body-indent containing-form-column))
            ;; Further non-special args, align with the arg above.
            ((> pos (1+ method))
             (clojure--normal-indent last-sexp 'always-align))
            ;; Special arg. Rigidly indent with a large indentation.
            (t
             (+ (* clojure-special-arg-indent-factor lisp-body-indent)
                containing-form-column)))))
        (`:defn
         (+ lisp-body-indent containing-form-column))
        ((pred functionp)
         (funcall method indent-point state))
        ;; No indent spec, do the default.
        (`nil
         (cond
          ;; Preserve useful alignment of :require (and friends) in `ns' forms.
          ((and function (string-match "^:" function))
           (clojure--normal-indent last-sexp clojure-indent-keyword-style))
          ;; This should be identical to the :defn above.
          ((and function
                (string-match "\\`\\(?:\\S +/\\)?\\(def[a-z]*\\|with-\\)"
                              function)
                (not (string-match "\\`default" (match-string 1 function))))
           (+ lisp-body-indent containing-form-column))
          ;; Finally, nothing special here, just respect the user's
          ;; preference.
          (t (clojure--normal-indent last-sexp clojure-indent-style))))))))