Function: tcl-calculate-indent
tcl-calculate-indent is a byte-compiled function defined in tcl.el.gz.
Signature
(tcl-calculate-indent &optional PARSE-START)
Documentation
Return appropriate indentation for current line as Tcl code.
In usual case returns an integer: the column to indent to. Returns nil if line starts inside a string, t if in a comment.
Aliases
calculate-tcl-indent (obsolete since 28.1)
Source Code
;; Defined in /usr/src/emacs/lisp/progmodes/tcl.el.gz
(defun tcl-calculate-indent (&optional parse-start)
"Return appropriate indentation for current line as Tcl code.
In usual case returns an integer: the column to indent to.
Returns nil if line starts inside a string, t if in a comment."
(save-excursion
(beginning-of-line)
(let* ((indent-point (point))
(case-fold-search nil)
(continued-line
(save-excursion
(if (bobp)
nil
(backward-char)
(= ?\\ (preceding-char)))))
(continued-indent-value (if continued-line
tcl-continued-indent-level
0))
state
containing-sexp
found-next-line)
(if parse-start
(goto-char parse-start))
(beginning-of-defun)
(while (< (point) indent-point)
(setq parse-start (point))
(setq state (parse-partial-sexp (point) indent-point 0))
(setq containing-sexp (car (cdr state))))
(cond ((or (nth 3 state) (nth 4 state))
;; Inside comment or string. Return nil or t if should
;; not change this line
(nth 4 state))
((null containing-sexp)
;; Line is at top level.
continued-indent-value)
(t
;; Set expr-p if we are looking at the expression part of
;; an "if", "expr", etc statement. Set commands-p if we
;; are looking at the body part of an if, while, etc
;; statement. FIXME Should check for "for" loops here.
(goto-char containing-sexp)
(let* ((sexpr-type (tcl-figure-type))
(expr-p (eq sexpr-type 'tcl-expr))
(commands-p (eq sexpr-type 'tcl-commands))
(expr-start (point)))
;; Find the first statement in the block and indent
;; like it. The first statement in the block might be
;; on the same line, so what we do is skip all
;; "virtually blank" lines, looking for a non-blank
;; one. A line is virtually blank if it only contains
;; a comment and whitespace. FIXME continued comments
;; aren't supported. They are a wart on Tcl anyway.
;; We do it this funky way because we want to know if
;; we've found a statement on some line _after_ the
;; line holding the sexp opener.
(goto-char containing-sexp)
(forward-char)
(if (and (< (point) indent-point)
(looking-at "[ \t]*\\(#.*\\)?$"))
(progn
(forward-line)
(while (and (< (point) indent-point)
(looking-at "[ \t]*\\(#.*\\)?$"))
(setq found-next-line t)
(forward-line))))
(if (or continued-line
(/= (char-after containing-sexp) ?{)
expr-p)
(progn
;; Line is continuation line, or the sexp opener
;; is not a curly brace, or we are looking at
;; an `expr' expression (which must be split
;; specially). So indentation is column of first
;; good spot after sexp opener (with some added
;; in the continued-line case). If there is no
;; nonempty line before the indentation point, we
;; use the column of the character after the sexp
;; opener.
(if (>= (point) indent-point)
(progn
(goto-char containing-sexp)
(forward-char))
(skip-chars-forward " \t"))
(+ (current-column) continued-indent-value))
;; After a curly brace, and not a continuation line.
;; So take indentation from first good line after
;; start of block, unless that line is on the same
;; line as the opening brace. In this case use the
;; indentation of the opening brace's line, plus
;; another indent step. If we are in the body part
;; of an "if" or "while" then the indentation is
;; taken from the line holding the start of the
;; statement.
(if (and (< (point) indent-point)
found-next-line)
(current-indentation)
(if commands-p
(goto-char expr-start)
(goto-char containing-sexp))
(+ (current-indentation) tcl-indent-level)))))))))