Function: fortran-calculate-indent

fortran-calculate-indent is a byte-compiled function defined in fortran.el.gz.

Signature

(fortran-calculate-indent)

Documentation

Calculates the Fortran indent column based on previous lines.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/fortran.el.gz
(defun fortran-calculate-indent ()
  "Calculates the Fortran indent column based on previous lines."
  (let (icol first-statement (case-fold-search t)
             (fortran-minimum-statement-indent
              (if indent-tabs-mode
                  fortran-minimum-statement-indent-tab
                fortran-minimum-statement-indent-fixed)))
    (save-excursion
      (setq first-statement (fortran-previous-statement))
      (if first-statement
          (setq icol fortran-minimum-statement-indent)
        (if (= (point) (point-min))
            (setq icol fortran-minimum-statement-indent)
          (setq icol (fortran-current-line-indentation)))
        (skip-chars-forward " \t0-9")
        (cond ((looking-at "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?if[ \t]*(")
               (if (or (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t_$(=a-z0-9]")
                       (let (then-test) ; multi-line if-then
                         (while (and (zerop (forward-line 1))
                                     ;; Search forward for then.
                                     (looking-at " \\{5\\}[^ 0\n]\\|\t[1-9]")
                                     (not (setq then-test
                                                (looking-at
                                                 ".*then\\b[ \t]\
*[^ \t_$(=a-z0-9]")))))
                         then-test))
                   (setq icol (+ icol fortran-if-indent))))
              ((looking-at "else\\(if\\)?\\b")
               (setq icol (+ icol fortran-if-indent)))
              ((looking-at "select[ \t]*case[ \t](.*)")
               (setq icol (+ icol fortran-if-indent)))
              ((looking-at "case[ \t]*(.*)")
               (setq icol (+ icol fortran-if-indent)))
              ((looking-at "case[ \t]*default\\b")
               (setq icol (+ icol fortran-if-indent)))
              ((looking-at "\\(otherwise\\|else[ \t]*where\\)\\b")
               (setq icol (+ icol fortran-if-indent)))
              ((looking-at "where[ \t]*(.*)[ \t]*\n")
               (setq icol (+ icol fortran-if-indent)))
              ((looking-at "do\\b")
               (setq icol (+ icol fortran-do-indent)))
              ((looking-at
                "\\(structure\\|union\\|map\\|interface\\)\
\\b[ \t]*[^ \t=(a-z]")
               (setq icol (+ icol fortran-structure-indent)))
              ((and (looking-at fortran-end-prog-re1)
                    (fortran-check-end-prog-re))
               ;; Previous END resets indent to minimum.
               (setq icol fortran-minimum-statement-indent))
              ;; Previous statement was a numbered DO loop without a
              ;; closing CONTINUE or END DO, so we indented the
              ;; terminator like the loop body.
              ((and fortran-check-all-num-for-matching-do
                    (not (looking-at "\\(continue\\|end[ \t]*do\\)\\>"))
                    (progn
                      (beginning-of-line)
                      (and (looking-at "[ \t]*[0-9]+")
                           (fortran-check-for-matching-do))))
               (setq icol (- icol fortran-do-indent))))))
    (save-excursion
      (beginning-of-line)
      (cond ((looking-at "[ \t]*$"))
            ;; Check for directive before comment, so as not to indent.
            ((looking-at fortran-directive-re)
             (setq fortran-minimum-statement-indent 0 icol 0))
            ((looking-at fortran-comment-line-start-skip)
             (cond ((eq fortran-comment-indent-style 'relative)
                    (setq icol (+ icol fortran-comment-line-extra-indent)))
                   ((eq fortran-comment-indent-style 'fixed)
                    (setq icol (+ fortran-minimum-statement-indent
                                  fortran-comment-line-extra-indent))))
             (setq fortran-minimum-statement-indent 0))
            ((or (looking-at (concat "[ \t]*"
                                     (regexp-quote
                                      fortran-continuation-string)))
                 (looking-at " \\{5\\}[^ 0\n]\\|\t[1-9]"))
             (skip-chars-forward " \t")
             ;; Do not introduce extra whitespace into a broken string.
             (setq icol
                   (if (fortran-is-in-string-p (point))
                       6
                     (+ icol fortran-continuation-indent))))
            (first-statement)
            ;; The terminating statement is actually part of the
            ;; loop body, so unless it is a CONTINUE or END DO, we
            ;; indent it like the loop body (see above).
            ((and fortran-check-all-num-for-matching-do
                  (looking-at "[ \t]*[0-9]+[ \t]*\
\\(continue\\|end[ \t]*do\\)\\>")
                  (fortran-check-for-matching-do))
             (setq icol (- icol fortran-do-indent)))
            (t
             (skip-chars-forward " \t0-9")
             (cond ((looking-at "end[ \t]*\\(if\\|select\\|where\\)\\b")
                    (setq icol (- icol fortran-if-indent)))
                   ((looking-at "else\\(if\\)?\\b")
                    (setq icol (- icol fortran-if-indent)))
                   ((looking-at "case[ \t]*\\((.*)\\|default\\>\\)")
                    (setq icol (- icol fortran-if-indent)))
                   ((looking-at "\\(otherwise\\|else[ \t]*where\\)\\b")
                    (setq icol (- icol fortran-if-indent)))
                   ((and (looking-at "continue\\b")
                         (fortran-check-for-matching-do))
                    (setq icol (- icol fortran-do-indent)))
                   ((looking-at "end[ \t]*do\\b")
                    (setq icol (- icol fortran-do-indent)))
                   ((looking-at "end[ \t]*\
\\(structure\\|union\\|map\\|interface\\)\\b[ \t]*[^ \t=(a-z]")
                    (setq icol (- icol fortran-structure-indent)))
                   ((and (looking-at fortran-end-prog-re1)
                         (fortran-check-end-prog-re)
                         (not (= icol fortran-minimum-statement-indent)))
                    (message "Warning: `end' not in column %d.  Probably\
 an unclosed block." fortran-minimum-statement-indent))))))
    (max fortran-minimum-statement-indent icol)))