Function: lisp-indent-calc-next

lisp-indent-calc-next is a byte-compiled function defined in lisp-mode.el.gz.

Signature

(lisp-indent-calc-next STATE)

Documentation

Move to next line and return calculated indent for it.

STATE is updated by side effect, the first state should be created by lisp-indent-initial-state. This function may move by more than one line to cross a string literal.

Source Code

;; Defined in /usr/src/emacs/lisp/emacs-lisp/lisp-mode.el.gz
(defun lisp-indent-calc-next (state)
  "Move to next line and return calculated indent for it.
STATE is updated by side effect, the first state should be
created by `lisp-indent-initial-state'.  This function may move
by more than one line to cross a string literal."
  (pcase-let* (((cl-struct lisp-indent-state
                           (stack indent-stack) ppss ppss-point)
                state)
               (indent-depth (car ppss)) ; Corresponding to indent-stack.
               (depth indent-depth))
    ;; Parse this line so we can learn the state to indent the
    ;; next line.
    (while (let ((last-sexp (nth 2 ppss)))
             (setq ppss (parse-partial-sexp
                         ppss-point (progn (end-of-line) (point))
                         nil nil ppss))
             ;; Preserve last sexp of state (position 2) for
             ;; `calculate-lisp-indent', if we're at the same depth.
             (if (and (not (nth 2 ppss)) (= depth (car ppss)))
                 (setf (nth 2 ppss) last-sexp)
               (setq last-sexp (nth 2 ppss)))
             (setq depth (car ppss))
             ;; Skip over newlines within strings.
             (and (not (eobp)) (nth 3 ppss)))
      (let ((string-start (nth 8 ppss)))
        (setq ppss (parse-partial-sexp (point) (point-max)
                                       nil nil ppss 'syntax-table))
        (setf (nth 2 ppss) string-start) ; Finished a complete string.
        (setq depth (car ppss)))
      (setq ppss-point (point)))
    (setq ppss-point (point))
    (let* ((depth-delta (- depth indent-depth)))
      (cond ((< depth-delta 0)
             (setq indent-stack (nthcdr (- depth-delta) indent-stack)))
            ((> depth-delta 0)
             (setq indent-stack (nconc (make-list depth-delta nil)
                                       indent-stack)))))
    (prog1
        (let (indent)
          (cond ((= (forward-line 1) 1)
                 ;; Can't move to the next line, apparently end of buffer.
                 nil)
                ((null indent-stack)
                 ;; Negative depth, probably some kind of syntax
                 ;; error.  Reset the state.
                 (setq ppss (parse-partial-sexp (point) (point))))
                ((car indent-stack))
                ((integerp (setq indent (calculate-lisp-indent ppss)))
                 (setf (car indent-stack) indent))
                ((consp indent)       ; (COLUMN CONTAINING-SEXP-START)
                 (car indent))
                ;; This only happens if we're in a string, but the
                ;; loop should always skip over strings (unless we hit
                ;; end of buffer, which is taken care of by the first
                ;; clause).
                (t (error "This shouldn't happen"))))
      (setf (lisp-indent-state-stack state) indent-stack)
      (setf (lisp-indent-state-ppss-point state) ppss-point)
      (setf (lisp-indent-state-ppss state) ppss))))