Function: common-lisp-indent-function-1
common-lisp-indent-function-1 is a byte-compiled function defined in
cl-indent.el.gz.
Signature
(common-lisp-indent-function-1 INDENT-POINT STATE)
Source Code
;; Defined in /usr/src/emacs/lisp/emacs-lisp/cl-indent.el.gz
(defun common-lisp-indent-function-1 (indent-point state)
(let ((normal-indent (current-column)))
;; Walk up list levels until we see something
;; which does special things with subforms.
(let ((depth 0)
;; Path describes the position of point in terms of
;; list-structure with respect to containing lists.
;; `foo' has a path of (0 3 1) in `((a b c (d foo) f) g)'.
(path ())
;; set non-nil when somebody works out the indentation to use
calculated
;; If non-nil, this is an indentation to use
;; if nothing else specifies it more firmly.
tentative-calculated
;; the position of the open-paren of the innermost containing list
(containing-form-start (elt state 1))
;; the column of the above
sexp-column)
;; Move to start of innermost containing list
(goto-char containing-form-start)
(setq sexp-column (current-column))
;; Look over successively less-deep containing forms
(while (and (not calculated)
(< depth lisp-indent-maximum-backtracking))
(let ((containing-sexp (point)))
(forward-char 1)
(parse-partial-sexp (point) indent-point 1 t)
;; Move to the car of the relevant containing form
(let (tem function method tentative-defun)
(if (not (looking-at "\\sw\\|\\s_"))
;; This form doesn't seem to start with a symbol
(setq function nil method nil)
(setq tem (point))
(forward-sexp 1)
(setq function (downcase (buffer-substring-no-properties
tem (point))))
(goto-char tem)
;; Elisp generally provides CL functionality with a CL
;; prefix, so if we have a special indenter for the
;; unprefixed version, prefer it over whatever's defined
;; for the cl- version. Users can override this
;; heuristic by defining a
;; common-lisp-indent-function-for-elisp property on the
;; cl- version.
(when (and (derived-mode-p 'emacs-lisp-mode)
(not (lisp-indent-find-method
(intern-soft function) t))
(string-match "\\`cl-" function)
(setf tem (intern-soft
(substring function (match-end 0))))
(lisp-indent-find-method tem t))
(setf function (symbol-name tem)))
(setq tem (intern-soft function)
method (lisp-indent-find-method tem))
;; The pleblisp package feature
(when (and (null tem)
(string-match ":[^:]+" function))
(setq function (substring function (1+ (match-beginning 0)))
tem (intern-soft function)
method (lisp-indent-find-method tem))))
(let ((n 0))
;; How far into the containing form is the current form?
(if (< (point) indent-point)
(while (condition-case ()
(progn
(forward-sexp 1)
(if (>= (point) indent-point)
nil
(parse-partial-sexp (point)
indent-point 1 t)
(setq n (1+ n))
t))
(error nil))))
(setq path (cons n path)))
;; backwards compatibility.
(cond ((null function))
((null method)
(when (null (cdr path))
;; (package prefix was stripped off above)
(cond ((string-match "\\`def"
function)
(setq tentative-defun t))
((string-match
(concat "\\`\\("
(regexp-opt '("with" "without" "do"))
"\\)-")
function)
(setq method '(&lambda &body))))))
;; backwards compatibility. Bletch.
((eq method 'defun)
(setq method lisp-indent-defun-method)))
(cond ((and (or (eq (char-after (1- containing-sexp)) ?\')
(and (not lisp-backquote-indentation)
(eq (char-after (1- containing-sexp)) ?\`)))
(not (eq (char-after (- containing-sexp 2)) ?\#)))
;; No indentation for "'(...)" elements
(setq calculated (1+ sexp-column)))
((when
(or (eq (char-after (1- containing-sexp)) ?\,)
(and (eq (char-after (1- containing-sexp)) ?\@)
(eq (char-after (- containing-sexp 2)) ?\,)))
;; ",(...)" or ",@(...)"
(when (eq lisp-indent-backquote-substitution-mode
'corrected)
(cl-incf sexp-column -1)
(when (eq (char-after (1- containing-sexp)) ?\@)
(cl-incf sexp-column -1)))
(cond (lisp-indent-backquote-substitution-mode
(setf tentative-calculated normal-indent)
(setq depth lisp-indent-maximum-backtracking)
nil)
(t (setq calculated normal-indent)))))
((eq (char-after (1- containing-sexp)) ?\#)
;; "#(...)"
(setq calculated (1+ sexp-column)))
((null method)
;; If this looks like a call to a `def...' form,
;; think about indenting it as one, but do it
;; tentatively for cases like
;; (flet ((defunp ()
;; nil)))
;; Set both normal-indent and tentative-calculated.
;; The latter ensures this value gets used
;; if there are no relevant containing constructs.
;; The former ensures this value gets used
;; if there is a relevant containing construct
;; but we are nested within the structure levels
;; that it specifies indentation for.
(if tentative-defun
(setq tentative-calculated
(common-lisp-indent-call-method
function lisp-indent-defun-method
path state indent-point
sexp-column normal-indent)
normal-indent tentative-calculated)))
((integerp method)
;; convenient top-level hack.
;; (also compatible with lisp-indent-function)
;; The number specifies how many `distinguished'
;; forms there are before the body starts
;; Equivalent to (4 4 ... &body)
(setq calculated (cond ((cdr path)
normal-indent)
((<= (car path) method)
;; `distinguished' form
(list (+ sexp-column 4)
containing-form-start))
((= (car path) (1+ method))
;; first body form.
(+ sexp-column lisp-body-indent))
(t
;; other body form
normal-indent))))
(t
(setq calculated
(common-lisp-indent-call-method
function method path state indent-point
sexp-column normal-indent)))))
(goto-char containing-sexp)
(unless calculated
(condition-case ()
(progn (backward-up-list 1)
(setq depth (1+ depth)))
(error (setq depth lisp-indent-maximum-backtracking))))))
(or calculated tentative-calculated))))