Function: perl-calculate-indent
perl-calculate-indent is a byte-compiled function defined in
perl-mode.el.gz.
Signature
(perl-calculate-indent)
Documentation
Return appropriate indentation for current line as Perl code.
In usual case returns an integer: the column to indent to. Returns (parse-state) if line starts inside a string.
Source Code
;; Defined in /usr/src/emacs/lisp/progmodes/perl-mode.el.gz
(defun perl-calculate-indent ()
"Return appropriate indentation for current line as Perl code.
In usual case returns an integer: the column to indent to.
Returns (parse-state) if line starts inside a string."
(save-excursion
(let* ((indent-point (point))
(case-fold-search nil)
(colon-line-end 0)
prev-char
(state (syntax-ppss))
(containing-sexp (nth 1 state))
;; Don't auto-indent in a quoted string or a here-document.
(unindentable (or (nth 3 state) (eq 2 (nth 7 state))))
(format (and (nth 3 state)
(char-equal (nth 3 state) ?\n))))
(when (and (eq t (nth 3 state))
(save-excursion
(goto-char (nth 8 state))
(looking-back "qw[ \t]*" (- (point) 4))))
;; qw(...) is a list of words so the spacing is not meaningful,
;; and makes indentation possible (and desirable).
(setq unindentable nil)
(setq containing-sexp (nth 8 state)))
(cond
(unindentable (if format 0 'noindent))
((null containing-sexp) ; Line is at top level.
(skip-chars-forward " \t\f")
(if (memq (following-char)
(if perl-indent-parens-as-block '(?\{ ?\( ?\[) '(?\{)))
0 ; move to beginning of line if it starts a function body
;; indent a little if this is a continuation line
(perl-backward-to-noncomment)
(if (or (bobp)
(memq (preceding-char) '(?\; ?\}))
(perl--end-of-format-p))
0 perl-continued-statement-offset)))
((/= (char-after containing-sexp) ?{)
;; line is expression, not statement:
;; indent to just after the surrounding open.
(goto-char (1+ containing-sexp))
(if (perl-hanging-paren-p)
;; We're indenting an arg of a call like:
;; $a = foobarlongnamefun (
;; arg1
;; arg2
;; );
(progn
;; Go just before the open paren (don't rely on the
;; skip-syntax-backward to jump over it, because it could
;; have string-fence syntax instead!).
(goto-char containing-sexp)
(skip-syntax-backward "(") ;FIXME: Not sure if still want this.
(condition-case nil
(while (save-excursion
(skip-syntax-backward " ") (not (bolp)))
(forward-sexp -1))
(scan-error nil))
(+ (current-column) perl-indent-level))
(if perl-indent-continued-arguments
(+ perl-indent-continued-arguments (current-indentation))
(skip-chars-forward " \t")
(current-column))))
;; Statement level. Is it a continuation or a new statement?
((setq prev-char (perl-continuation-line-p))
;; This line is continuation of preceding line's statement;
;; indent perl-continued-statement-offset more than the
;; previous line of the statement.
(perl-backward-to-start-of-continued-exp)
(+ (if (or (save-excursion
(perl-continuation-line-p))
(and (eq prev-char ?\,)
(looking-at "[[:alnum:]_]+[ \t\n]*=>")))
;; If the continued line is itself a continuation
;; line, then align, otherwise add an offset.
0 perl-continued-statement-offset)
(current-column)
(if (save-excursion (goto-char indent-point)
(looking-at
(if perl-indent-parens-as-block
"[ \t]*[{([]" "[ \t]*{")))
perl-continued-brace-offset 0)))
(t
;; This line starts a new statement.
;; Position at last unclosed open.
(goto-char containing-sexp)
(or
;; Is line first statement after an open-brace?
;; If no, find that first statement and indent like it.
(save-excursion
(forward-char 1)
;; Skip over comments and labels following openbrace.
(while (progn
(skip-chars-forward " \t\f\n")
(cond ((looking-at ";?#\\|^=\\w+")
(forward-comment 1) t)
((looking-at "\\(\\w\\|\\s_\\)+:[^:]")
(setq colon-line-end (line-end-position))
(search-forward ":")))))
;; The first following code counts
;; if it is before the line we want to indent.
(and (< (point) indent-point)
(if (> colon-line-end (point))
(- (current-indentation) perl-label-offset)
(current-column))))
;; If no previous statement,
;; indent it relative to line brace is on.
;; For open paren in column zero, don't let statement
;; start there too. If perl-indent-level is zero,
;; use perl-brace-offset + perl-continued-statement-offset
;; For open-braces not the first thing in a line,
;; add in perl-brace-imaginary-offset.
(+ (if (and (bolp) (zerop perl-indent-level))
(+ perl-brace-offset perl-continued-statement-offset)
perl-indent-level)
;; Move back over whitespace before the openbrace.
;; If openbrace is not first nonwhite thing on the line,
;; add the perl-brace-imaginary-offset.
(save-excursion (skip-chars-backward " \t")
(if (bolp) 0 perl-brace-imaginary-offset))
(perl-indent-new-calculate 'virtual))))))))