- (looking-at "sub\\>"))
- (setq old-indent
- (nth 1
- (parse-partial-sexp
- (save-excursion (beginning-of-line) (point))
- (point)))))
- (progn (goto-char (1+ old-indent))
- (skip-chars-forward " \t")
- (current-column))
- ;; Get initial indentation of the line we are on.
- ;; If line starts with label, calculate label indentation
- (if (save-excursion
- (beginning-of-line)
- (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*:[^:]"))
- (if (> (current-indentation) cperl-min-label-indent)
- (- (current-indentation) cperl-label-offset)
- ;; Do not move `parse-data', this should
- ;; be quick anyway:
- (cperl-calculate-indent))
- (current-indentation))))))))))))))
-
-;; (defvar cperl-indent-alist
-;; '((string nil)
-;; (comment nil)
-;; (toplevel 0)
-;; (toplevel-after-parenth 2)
-;; (toplevel-continued 2)
-;; (expression 1))
-;; "Alist of indentation rules for CPerl mode.
-;; The values mean:
-;; nil: do not indent;
-;; number: add this amount of indentation.
-
-;; Not finished, not used.")
-
-;; (defun cperl-where-am-i (&optional parse-start start-state)
-;; ;; Unfinished
-;; "Return a list of lists ((TYPE POS)...) of good points before the point.
-;; ;; POS may be nil if it is hard to find, say, when TYPE is `string' or `comment'.
-
-;; ;; Not finished, not used."
-;; (save-excursion
-;; (let* ((start-point (point))
-;; (s-s (cperl-get-state))
-;; (start (nth 0 s-s))
-;; (state (nth 1 s-s))
-;; (prestart (nth 3 s-s))
-;; (containing-sexp (car (cdr state)))
-;; (case-fold-search nil)
-;; (res (list (list 'parse-start start) (list 'parse-prestart prestart))))
-;; (cond ((nth 3 state) ; In string
-;; (setq res (cons (list 'string nil (nth 3 state)) res))) ; What started string
-;; ((nth 4 state) ; In comment
-;; (setq res (cons '(comment) res)))
-;; ((null containing-sexp)
-;; ;; Line is at top level.
-;; ;; Indent like the previous top level line
-;; ;; unless that ends in a closeparen without semicolon,
-;; ;; in which case this line is the first argument decl.
-;; (cperl-backward-to-noncomment (or parse-start (point-min)))
-;; ;;(skip-chars-backward " \t\f\n")
-;; (cond
-;; ((or (bobp)
-;; (memq (preceding-char) (append ";}" nil)))
-;; (setq res (cons (list 'toplevel start) res)))
-;; ((eq (preceding-char) ?\) )
-;; (setq res (cons (list 'toplevel-after-parenth start) res)))
-;; (t
-;; (setq res (cons (list 'toplevel-continued start) res)))))
-;; ((/= (char-after containing-sexp) ?{)
-;; ;; line is expression, not statement:
-;; ;; indent to just after the surrounding open.
-;; ;; skip blanks if we do not close the expression.
-;; (setq res (cons (list 'expression-blanks
-;; (progn
-;; (goto-char (1+ containing-sexp))
-;; (or (looking-at "[ \t]*\\(#\\|$\\)")
-;; (skip-chars-forward " \t"))
-;; (point)))
-;; (cons (list 'expression containing-sexp) res))))
-;; ((progn
-;; ;; Containing-expr starts with \{. Check whether it is a hash.
-;; (goto-char containing-sexp)
-;; (not (cperl-block-p)))
-;; (setq res (cons (list 'expression-blanks
-;; (progn
-;; (goto-char (1+ containing-sexp))
-;; (or (looking-at "[ \t]*\\(#\\|$\\)")
-;; (skip-chars-forward " \t"))
-;; (point)))
-;; (cons (list 'expression containing-sexp) res))))
-;; (t
-;; ;; Statement level.
-;; (setq res (cons (list 'in-block containing-sexp) res))
-;; ;; Is it a continuation or a new statement?
-;; ;; Find previous non-comment character.
-;; (cperl-backward-to-noncomment containing-sexp)
-;; ;; Back up over label lines, since they don't
-;; ;; affect whether our line is a continuation.
-;; ;; Back up comma-delimited lines too ?????
-;; (while (or (eq (preceding-char) ?\,)
-;; (save-excursion (cperl-after-label)))
-;; (if (eq (preceding-char) ?\,)
-;; ;; Will go to beginning of line, essentially
-;; ;; Will ignore embedded sexpr XXXX.
-;; (cperl-backward-to-start-of-continued-exp containing-sexp))
-;; (beginning-of-line)
-;; (cperl-backward-to-noncomment containing-sexp))
-;; ;; Now we get the answer.
-;; (if (not (memq (preceding-char) (append ";}{" '(nil)))) ; Was ?\,
-;; ;; This line is continuation of preceding line's statement.
-;; (list (list 'statement-continued containing-sexp))
-;; ;; This line starts a new statement.
-;; ;; Position following last unclosed open.
-;; (goto-char containing-sexp)
-;; ;; Is line first statement after an open-brace?
-;; (or
-;; ;; If no, find that first statement and indent like
-;; ;; it. If the first statement begins with label, do
-;; ;; not believe when the indentation of the label is too
-;; ;; small.
-;; (save-excursion
-;; (forward-char 1)
-;; (let ((colon-line-end 0))
-;; (while (progn (skip-chars-forward " \t\n" start-point)
-;; (and (< (point) start-point)
-;; (looking-at
-;; "#\\|[a-zA-Z_][a-zA-Z0-9_]*:[^:]")))
-;; ;; Skip over comments and labels following openbrace.
-;; (cond ((= (following-char) ?\#)
-;; ;;(forward-line 1)
-;; (end-of-line))
-;; ;; label:
-;; (t
-;; (save-excursion (end-of-line)
-;; (setq colon-line-end (point)))
-;; (search-forward ":"))))
-;; ;; Now at the point, after label, or at start
-;; ;; of first statement in the block.
-;; (and (< (point) start-point)
-;; (if (> colon-line-end (point))
-;; ;; Before statement after label
-;; (if (> (current-indentation)
-;; cperl-min-label-indent)
-;; (list (list 'label-in-block (point)))
-;; ;; Do not believe: `max' is involved
-;; (list
-;; (list 'label-in-block-min-indent (point))))
-;; ;; Before statement
-;; (list 'statement-in-block (point))))))
-;; ;; If no previous statement,
-;; ;; indent it relative to line brace is on.
-;; ;; For open brace in column zero, don't let statement
-;; ;; start there too. If cperl-indent-level is zero,
-;; ;; use cperl-brace-offset + cperl-continued-statement-offset instead.
-;; ;; For open-braces not the first thing in a line,
-;; ;; add in cperl-brace-imaginary-offset.
-
-;; ;; If first thing on a line: ?????
-;; (+ (if (and (bolp) (zerop cperl-indent-level))
-;; (+ cperl-brace-offset cperl-continued-statement-offset)
-;; cperl-indent-level)
-;; ;; Move back over whitespace before the openbrace.
-;; ;; If openbrace is not first nonwhite thing on the line,
-;; ;; add the cperl-brace-imaginary-offset.
-;; (progn (skip-chars-backward " \t")
-;; (if (bolp) 0 cperl-brace-imaginary-offset))
-;; ;; If the openbrace is preceded by a parenthesized exp,
-;; ;; move to the beginning of that;
-;; ;; possibly a different line
-;; (progn
-;; (if (eq (preceding-char) ?\))
-;; (forward-sexp -1))
-;; ;; Get initial indentation of the line we are on.
-;; ;; If line starts with label, calculate label indentation
-;; (if (save-excursion
-;; (beginning-of-line)
-;; (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*:[^:]"))
-;; (if (> (current-indentation) cperl-min-label-indent)
-;; (- (current-indentation) cperl-label-offset)
-;; (cperl-calculate-indent))
-;; (current-indentation))))))))
-;; res)))
+ (skip-chars-backward " \t")
+ (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*[ \t]*:")))
+ (get-text-property (point) 'first-format-line)))
+
+ ;; Look at previous line that's at column 0
+ ;; to determine whether we are in top-level decls
+ ;; or function's arg decls. Set basic-indent accordingly.
+ ;; Now add a little if this is a continuation line.
+ (and state
+ parse-data
+ (not (eq char-after ?\C-j))
+ (setcdr (cddr parse-data)
+ (list pre-indent-point)))
+ (vector 'toplevel start char-after state (nth 2 s-s)))
+ ((not
+ (or (setq is-block
+ (and (setq delim (= (char-after containing-sexp) ?{))
+ (save-excursion ; Is it a hash?
+ (goto-char containing-sexp)
+ (cperl-block-p))))
+ cperl-indent-parens-as-block))
+ ;; group is an expression, not a block:
+ ;; indent to just after the surrounding open parens,
+ ;; skip blanks if we do not close the expression.
+ (goto-char (1+ containing-sexp))
+ (or (memq char-after
+ (append (if delim "}" ")]}") nil))
+ (looking-at "[ \t]*\\(#\\|$\\)")
+ (skip-chars-forward " \t"))
+ (setq old-indent (point)) ; delim=is-brace
+ (vector 'in-parens char-after (point) delim containing-sexp))
+ (t
+ ;; Statement level. Is it a continuation or a new statement?
+ ;; Find previous non-comment character.
+ (goto-char pre-indent-point) ; Skip one level of POD/etc
+ (cperl-backward-to-noncomment containing-sexp)
+ ;; Back up over label lines, since they don't
+ ;; affect whether our line is a continuation.
+ ;; (Had \, too)
+ (while;;(or (eq (preceding-char) ?\,)
+ (and (eq (preceding-char) ?:)
+ (or;;(eq (char-after (- (point) 2)) ?\') ; ????
+ (memq (char-syntax (char-after (- (point) 2)))
+ '(?w ?_))))
+ ;;)
+ ;; This is always FALSE?
+ (if (eq (preceding-char) ?\,)
+ ;; Will go to beginning of line, essentially.
+ ;; Will ignore embedded sexpr XXXX.
+ (cperl-backward-to-start-of-continued-exp containing-sexp))
+ (beginning-of-line)
+ (cperl-backward-to-noncomment containing-sexp))
+ ;; Now we get non-label preceeding the indent point
+ (if (not (or (eq (1- (point)) containing-sexp)
+ (memq (preceding-char)
+ (append (if is-block " ;{" " ,;{") '(nil)))
+ (and (eq (preceding-char) ?\})
+ (cperl-after-block-and-statement-beg
+ containing-sexp))
+ (get-text-property (point) 'first-format-line)))
+ ;; This line is continuation of preceding line's statement;
+ ;; indent `cperl-continued-statement-offset' more than the
+ ;; previous line of the statement.
+ ;;
+ ;; There might be a label on this line, just
+ ;; consider it bad style and ignore it.
+ (progn
+ (cperl-backward-to-start-of-continued-exp containing-sexp)
+ (vector 'continuation (point) char-after is-block delim))
+ ;; This line starts a new statement.
+ ;; Position following last unclosed open brace
+ (goto-char containing-sexp)
+ ;; Is line first statement after an open-brace?
+ (or
+ ;; If no, find that first statement and indent like
+ ;; it. If the first statement begins with label, do
+ ;; not believe when the indentation of the label is too
+ ;; small.
+ (save-excursion
+ (forward-char 1)
+ (let ((colon-line-end 0))
+ (while
+ (progn (skip-chars-forward " \t\n")
+ (looking-at "#\\|[a-zA-Z0-9_$]*:[^:]\\|=[a-zA-Z]"))
+ ;; Skip over comments and labels following openbrace.
+ (cond ((= (following-char) ?\#)
+ (forward-line 1))
+ ((= (following-char) ?\=)
+ (goto-char
+ (or (next-single-property-change (point) 'in-pod)
+ (point-max)))) ; do not loop if no syntaxification
+ ;; label:
+ (t
+ (save-excursion (end-of-line)
+ (setq colon-line-end (point)))
+ (search-forward ":"))))
+ ;; We are at beginning of code (NOT label or comment)
+ ;; First, the following code counts
+ ;; if it is before the line we want to indent.
+ (and (< (point) indent-point)
+ (vector 'have-prev-sibling (point) colon-line-end
+ containing-sexp))))
+ (progn
+ ;; If no previous statement,
+ ;; indent it relative to line brace is on.
+
+ ;; For open-braces not the first thing in a line,
+ ;; add in cperl-brace-imaginary-offset.
+
+ ;; If first thing on a line: ?????
+ ;; Move back over whitespace before the openbrace.
+ (setq ; brace first thing on a line
+ old-indent (progn (skip-chars-backward " \t") (bolp)))
+ ;; Should we indent w.r.t. earlier than start?
+ ;; Move to start of control group, possibly on a different line
+ (or cperl-indent-wrt-brace
+ (cperl-backward-to-noncomment (point-min)))
+ ;; If the openbrace is preceded by a parenthesized exp,
+ ;; move to the beginning of that;
+ (if (eq (preceding-char) ?\))
+ (progn
+ (forward-sexp -1)
+ (cperl-backward-to-noncomment (point-min))))
+ ;; In the case it starts a subroutine, indent with
+ ;; respect to `sub', not with respect to the
+ ;; first thing on the line, say in the case of
+ ;; anonymous sub in a hash.
+ (if (and;; Is it a sub in group starting on this line?
+ (cond ((get-text-property (point) 'attrib-group)
+ (goto-char (cperl-beginning-of-property
+ (point) 'attrib-group)))
+ ((eq (preceding-char) ?b)
+ (forward-sexp -1)
+ (looking-at "sub\\>")))
+ (setq p (nth 1 ; start of innermost containing list
+ (parse-partial-sexp
+ (save-excursion (beginning-of-line)
+ (point))
+ (point)))))
+ (progn
+ (goto-char (1+ p)) ; enclosing block on the same line
+ (skip-chars-forward " \t")
+ (vector 'code-start-in-block containing-sexp char-after
+ (and delim (not is-block)) ; is a HASH
+ old-indent ; brace first thing on a line
+ t (point) ; have something before...
+ )
+ ;;(current-column)
+ )
+ ;; Get initial indentation of the line we are on.
+ ;; If line starts with label, calculate label indentation
+ (vector 'code-start-in-block containing-sexp char-after
+ (and delim (not is-block)) ; is a HASH
+ old-indent ; brace first thing on a line
+ nil (point) ; nothing interesting before
+ ))))))))))))))
+
+(defvar cperl-indent-rules-alist
+ '((pod nil) ; via `syntax-type' property
+ (here-doc nil) ; via `syntax-type' property
+ (here-doc-delim nil) ; via `syntax-type' property
+ (format nil) ; via `syntax-type' property
+ (in-pod nil) ; via `in-pod' property
+ (comment-special:at-beginning-of-line nil)
+ (string t)
+ (comment nil))
+ "Alist of indentation rules for CPerl mode.
+The values mean:
+ nil: do not indent;
+ number: add this amount of indentation.
+
+Not finished.")
+
+(defun cperl-calculate-indent (&optional parse-data) ; was parse-start
+ "Return appropriate indentation for current line as Perl 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.
+
+Will not correct the indentation for labels, but will correct it for braces
+and closing parentheses and brackets."
+ ;; This code is still a broken architecture: in some cases we need to
+ ;; compensate for some modifications which `cperl-indent-line' will add later
+ (save-excursion
+ (let ((i (cperl-sniff-for-indent parse-data)) what p)
+ (cond
+ ;;((or (null i) (eq i t) (numberp i))
+ ;; i)
+ ((vectorp i)
+ (setq what (assoc (elt i 0) cperl-indent-rules-alist))
+ (cond
+ (what (cadr what)) ; Load from table
+ ;;
+ ;; Indenters for regular expressions with //x and qw()
+ ;;
+ ((eq 'REx-part2 (elt i 0)) ;; [self start] start of /REP in s//REP/x
+ (goto-char (elt i 1))
+ (condition-case nil ; Use indentation of the 1st part
+ (forward-sexp -1))
+ (current-column))
+ ((eq 'indentable (elt i 0)) ; Indenter for REGEXP qw() etc
+ (cond ;;; [indentable terminator start-pos is-block]
+ ((eq 'terminator (elt i 1)) ; Lone terminator of "indentable string"
+ (goto-char (elt i 2)) ; After opening parens
+ (1- (current-column)))
+ ((eq 'first-line (elt i 1)); [indentable first-line start-pos]
+ (goto-char (elt i 2))
+ (+ (or cperl-regexp-indent-step cperl-indent-level)
+ -1
+ (current-column)))
+ ((eq 'cont-line (elt i 1)); [indentable cont-line pos prev-pos first-char start-pos]
+ ;; Indent as the level after closing parens
+ (goto-char (elt i 2)) ; indent line
+ (skip-chars-forward " \t)") ; Skip closing parens
+ (setq p (point))
+ (goto-char (elt i 3)) ; previous line
+ (skip-chars-forward " \t)") ; Skip closing parens
+ ;; Number of parens in between:
+ (setq p (nth 0 (parse-partial-sexp (point) p))
+ what (elt i 4)) ; First char on current line
+ (goto-char (elt i 3)) ; previous line
+ (+ (* p (or cperl-regexp-indent-step cperl-indent-level))
+ (cond ((eq what ?\) )
+ (- cperl-close-paren-offset)) ; compensate
+ ((eq what ?\| )
+ (- (or cperl-regexp-indent-step cperl-indent-level)))
+ (t 0))
+ (if (eq (following-char) ?\| )
+ (or cperl-regexp-indent-step cperl-indent-level)
+ 0)
+ (current-column)))
+ (t
+ (error "Unrecognized value of indent: %s" i))))
+ ;;
+ ;; Indenter for stuff at toplevel
+ ;;
+ ((eq 'toplevel (elt i 0)) ;; [toplevel start char-after state immed-after-block]
+ (+ (save-excursion ; To beg-of-defun, or end of last sexp
+ (goto-char (elt i 1)) ; start = Good place to start parsing
+ (- (current-indentation) ;
+ (if (elt i 4) cperl-indent-level 0))) ; immed-after-block
+ (if (eq (elt i 2) ?{) cperl-continued-brace-offset 0) ; char-after
+ ;; Look at previous line that's at column 0
+ ;; to determine whether we are in top-level decls
+ ;; or function's arg decls. Set basic-indent accordingly.
+ ;; Now add a little if this is a continuation line.
+ (if (elt i 3) ; state (XXX What is the semantic???)
+ 0
+ cperl-continued-statement-offset)))
+ ;;
+ ;; Indenter for stuff in "parentheses" (or brackets, braces-as-hash)
+ ;;
+ ((eq 'in-parens (elt i 0))
+ ;; in-parens char-after old-indent-point is-brace containing-sexp
+
+ ;; group is an expression, not a block:
+ ;; indent to just after the surrounding open parens,
+ ;; skip blanks if we do not close the expression.
+ (+ (progn
+ (goto-char (elt i 2)) ; old-indent-point
+ (current-column))
+ (if (and (elt i 3) ; is-brace
+ (eq (elt i 1) ?\})) ; char-after
+ ;; Correct indentation of trailing ?\}
+ (+ cperl-indent-level cperl-close-paren-offset)
+ 0)))
+ ;;
+ ;; Indenter for continuation lines
+ ;;
+ ((eq 'continuation (elt i 0))
+ ;; [continuation statement-start char-after is-block is-brace]
+ (goto-char (elt i 1)) ; statement-start
+ (+ (if (memq (elt i 2) (append "}])" nil)) ; char-after
+ 0 ; Closing parenth
+ cperl-continued-statement-offset)
+ (if (or (elt i 3) ; is-block
+ (not (elt i 4)) ; is-brace
+ (not (eq (elt i 2) ?\}))) ; char-after
+ 0
+ ;; Now it is a hash reference
+ (+ cperl-indent-level cperl-close-paren-offset))
+ ;; Labels do not take :: ...
+ (if (looking-at "\\(\\w\\|_\\)+[ \t]*:")
+ (if (> (current-indentation) cperl-min-label-indent)
+ (- (current-indentation) cperl-label-offset)
+ ;; Do not move `parse-data', this should
+ ;; be quick anyway (this comment comes
+ ;; from different location):
+ (cperl-calculate-indent))
+ (current-column))
+ (if (eq (elt i 2) ?\{) ; char-after
+ cperl-continued-brace-offset 0)))
+ ;;
+ ;; Indenter for lines in a block which are not leading lines
+ ;;
+ ((eq 'have-prev-sibling (elt i 0))
+ ;; [have-prev-sibling sibling-beg colon-line-end block-start]
+ (goto-char (elt i 1))
+ (if (> (elt i 2) (point)) ; colon-line-end; After-label, same line
+ (if (> (current-indentation)
+ cperl-min-label-indent)
+ (- (current-indentation) cperl-label-offset)
+ ;; Do not believe: `max' was involved in calculation of indent
+ (+ cperl-indent-level
+ (save-excursion
+ (goto-char (elt i 3)) ; block-start
+ (current-indentation))))
+ (current-column)))
+ ;;
+ ;; Indenter for the first line in a block
+ ;;
+ ((eq 'code-start-in-block (elt i 0))
+ ;;[code-start-in-block before-brace char-after
+ ;; is-a-HASH-ref brace-is-first-thing-on-a-line
+ ;; group-starts-before-start-of-sub start-of-control-group]
+ (goto-char (elt i 1))
+ ;; For open brace in column zero, don't let statement
+ ;; start there too. If cperl-indent-level=0,
+ ;; use cperl-brace-offset + cperl-continued-statement-offset instead.
+ (+ (if (and (bolp) (zerop cperl-indent-level))
+ (+ cperl-brace-offset cperl-continued-statement-offset)
+ cperl-indent-level)
+ (if (and (elt i 3) ; is-a-HASH-ref
+ (eq (elt i 2) ?\})) ; char-after: End of a hash reference
+ (+ cperl-indent-level cperl-close-paren-offset)
+ 0)
+ ;; Unless openbrace is the first nonwhite thing on the line,
+ ;; add the cperl-brace-imaginary-offset.
+ (if (elt i 4) 0 ; brace-is-first-thing-on-a-line
+ cperl-brace-imaginary-offset)
+ (progn
+ (goto-char (elt i 6)) ; start-of-control-group
+ (if (elt i 5) ; group-starts-before-start-of-sub
+ (current-column)
+ ;; Get initial indentation of the line we are on.
+ ;; If line starts with label, calculate label indentation
+ (if (save-excursion
+ (beginning-of-line)
+ (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*:[^:]"))
+ (if (> (current-indentation) cperl-min-label-indent)
+ (- (current-indentation) cperl-label-offset)
+ ;; Do not move `parse-data', this should
+ ;; be quick anyway:
+ (cperl-calculate-indent))
+ (current-indentation))))))
+ (t
+ (error "Unrecognized value of indent: %s" i))))
+ (t
+ (error "Got strange value of indent: %s" i))))))
+
+(defvar cperl-indent-alist
+ '((string nil)
+ (comment nil)
+ (toplevel 0)
+ (toplevel-after-parenth 2)
+ (toplevel-continued 2)
+ (expression 1))
+ "Alist of indentation rules for CPerl mode.
+The values mean:
+ nil: do not indent;
+ number: add this amount of indentation.
+
+Not finished, not used.")
+
+(defun cperl-where-am-i (&optional parse-start start-state)
+ ;; Unfinished
+ "Return a list of lists ((TYPE POS)...) of good points before the point.
+POS may be nil if it is hard to find, say, when TYPE is `string' or `comment'.
+
+Not finished, not used."
+ (save-excursion
+ (let* ((start-point (point)) unused
+ (s-s (cperl-get-state))
+ (start (nth 0 s-s))
+ (state (nth 1 s-s))
+ (prestart (nth 3 s-s))
+ (containing-sexp (car (cdr state)))
+ (case-fold-search nil)
+ (res (list (list 'parse-start start) (list 'parse-prestart prestart))))
+ (cond ((nth 3 state) ; In string
+ (setq res (cons (list 'string nil (nth 3 state)) res))) ; What started string
+ ((nth 4 state) ; In comment
+ (setq res (cons '(comment) res)))
+ ((null containing-sexp)
+ ;; Line is at top level.
+ ;; Indent like the previous top level line
+ ;; unless that ends in a closeparen without semicolon,
+ ;; in which case this line is the first argument decl.
+ (cperl-backward-to-noncomment (or parse-start (point-min)))
+ ;;(skip-chars-backward " \t\f\n")
+ (cond
+ ((or (bobp)
+ (memq (preceding-char) (append ";}" nil)))
+ (setq res (cons (list 'toplevel start) res)))
+ ((eq (preceding-char) ?\) )
+ (setq res (cons (list 'toplevel-after-parenth start) res)))
+ (t
+ (setq res (cons (list 'toplevel-continued start) res)))))
+ ((/= (char-after containing-sexp) ?{)
+ ;; line is expression, not statement:
+ ;; indent to just after the surrounding open.
+ ;; skip blanks if we do not close the expression.
+ (setq res (cons (list 'expression-blanks
+ (progn
+ (goto-char (1+ containing-sexp))
+ (or (looking-at "[ \t]*\\(#\\|$\\)")
+ (skip-chars-forward " \t"))
+ (point)))
+ (cons (list 'expression containing-sexp) res))))
+ ((progn
+ ;; Containing-expr starts with \{. Check whether it is a hash.
+ (goto-char containing-sexp)
+ (not (cperl-block-p)))
+ (setq res (cons (list 'expression-blanks
+ (progn
+ (goto-char (1+ containing-sexp))
+ (or (looking-at "[ \t]*\\(#\\|$\\)")
+ (skip-chars-forward " \t"))
+ (point)))
+ (cons (list 'expression containing-sexp) res))))
+ (t
+ ;; Statement level.
+ (setq res (cons (list 'in-block containing-sexp) res))
+ ;; Is it a continuation or a new statement?
+ ;; Find previous non-comment character.
+ (cperl-backward-to-noncomment containing-sexp)
+ ;; Back up over label lines, since they don't
+ ;; affect whether our line is a continuation.
+ ;; Back up comma-delimited lines too ?????
+ (while (or (eq (preceding-char) ?\,)
+ (save-excursion (cperl-after-label)))
+ (if (eq (preceding-char) ?\,)
+ ;; Will go to beginning of line, essentially
+ ;; Will ignore embedded sexpr XXXX.
+ (cperl-backward-to-start-of-continued-exp containing-sexp))
+ (beginning-of-line)
+ (cperl-backward-to-noncomment containing-sexp))
+ ;; Now we get the answer.
+ (if (not (memq (preceding-char) (append ";}{" '(nil)))) ; Was ?\,
+ ;; This line is continuation of preceding line's statement.
+ (list (list 'statement-continued containing-sexp))
+ ;; This line starts a new statement.
+ ;; Position following last unclosed open.
+ (goto-char containing-sexp)
+ ;; Is line first statement after an open-brace?
+ (or
+ ;; If no, find that first statement and indent like
+ ;; it. If the first statement begins with label, do
+ ;; not believe when the indentation of the label is too
+ ;; small.
+ (save-excursion
+ (forward-char 1)
+ (let ((colon-line-end 0))
+ (while (progn (skip-chars-forward " \t\n" start-point)
+ (and (< (point) start-point)
+ (looking-at
+ "#\\|[a-zA-Z_][a-zA-Z0-9_]*:[^:]")))
+ ;; Skip over comments and labels following openbrace.
+ (cond ((= (following-char) ?\#)
+ ;;(forward-line 1)
+ (end-of-line))
+ ;; label:
+ (t
+ (save-excursion (end-of-line)
+ (setq colon-line-end (point)))
+ (search-forward ":"))))
+ ;; Now at the point, after label, or at start
+ ;; of first statement in the block.
+ (and (< (point) start-point)
+ (if (> colon-line-end (point))
+ ;; Before statement after label
+ (if (> (current-indentation)
+ cperl-min-label-indent)
+ (list (list 'label-in-block (point)))
+ ;; Do not believe: `max' is involved
+ (list
+ (list 'label-in-block-min-indent (point))))
+ ;; Before statement
+ (list 'statement-in-block (point))))))
+ ;; If no previous statement,
+ ;; indent it relative to line brace is on.
+ ;; For open brace in column zero, don't let statement
+ ;; start there too. If cperl-indent-level is zero,
+ ;; use cperl-brace-offset + cperl-continued-statement-offset instead.
+ ;; For open-braces not the first thing in a line,
+ ;; add in cperl-brace-imaginary-offset.
+
+ ;; If first thing on a line: ?????
+ (setq unused ; This is not finished...
+ (+ (if (and (bolp) (zerop cperl-indent-level))
+ (+ cperl-brace-offset cperl-continued-statement-offset)
+ cperl-indent-level)
+ ;; Move back over whitespace before the openbrace.
+ ;; If openbrace is not first nonwhite thing on the line,
+ ;; add the cperl-brace-imaginary-offset.
+ (progn (skip-chars-backward " \t")
+ (if (bolp) 0 cperl-brace-imaginary-offset))
+ ;; If the openbrace is preceded by a parenthesized exp,
+ ;; move to the beginning of that;
+ ;; possibly a different line
+ (progn
+ (if (eq (preceding-char) ?\))
+ (forward-sexp -1))
+ ;; Get initial indentation of the line we are on.
+ ;; If line starts with label, calculate label indentation
+ (if (save-excursion
+ (beginning-of-line)
+ (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*:[^:]"))
+ (if (> (current-indentation) cperl-min-label-indent)
+ (- (current-indentation) cperl-label-offset)
+ (cperl-calculate-indent))
+ (current-indentation)))))))))
+ res)))