Function: dcl-calc-command-indent

dcl-calc-command-indent is a byte-compiled function defined in dcl-mode.el.gz.

Signature

(dcl-calc-command-indent)

Documentation

Calculate how much the current line shall be indented.

The line is known to be a command line.

Find the indentation of the preceding line and analyze its contents to see if the current lines should be indented. Analyze the current line to see if it should be outdented.

Calculate the indentation of the current line, either with the default method or by calling dcl-calc-command-indent-function if it is non-nil.

If the current line should be outdented, calculate its indentation, either with the default method or by calling dcl-calc-command-indent-function if it is non-nil.

Rules for default indentation:

If it is the first line in the buffer, indent dcl-margin-offset.

Go to the previous command line with a command on it. Find out how much it is indented (cur-indent). Look at the first word on the line to see if the indentation should be adjusted. Skip margin-label, continuations and comments while looking for the first word. Save this buffer position as last-point. If the first word after a label is SUBROUTINE, set extra-indent to dcl-margin-offset.

First word extra-indent
THEN +dcl-basic-offset
ELSE +dcl-basic-offset
block-begin +dcl-basic-offset

Then return to the current line and look at the first word to see if the indentation should be adjusted again. Save this buffer position as this-point.

First word extra-indent
ELSE -dcl-basic-offset
ENDIF -dcl-basic-offset
block-end -dcl-basic-offset


If dcl-calc-command-indent-function is nil or returns nil set cur-indent to cur-indent+extra-indent.

If an extra adjustment is necessary and if dcl-calc-command-indent-function is nil or returns nil set cur-indent to cur-indent+extra-indent.

See also documentation for dcl-calc-command-indent-function. The indent-type classification could probably be expanded upon.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/dcl-mode.el.gz
;;;---------------------------------------------------------------------------
(defun dcl-calc-command-indent ()
  "Calculate how much the current line shall be indented.
The line is known to be a command line.

Find the indentation of the preceding line and analyze its contents to
see if the current lines should be indented.
Analyze the current line to see if it should be `outdented'.

Calculate the indentation of the current line, either with the default
method or by calling `dcl-calc-command-indent-function' if it is
non-nil.

If the current line should be outdented, calculate its indentation,
either with the default method or by calling
`dcl-calc-command-indent-function' if it is non-nil.


Rules for default indentation:

If it is the first line in the buffer, indent `dcl-margin-offset'.

Go to the previous command line with a command on it.
Find out how much it is indented (cur-indent).
Look at the first word on the line to see if the indentation should be
adjusted.  Skip margin-label, continuations and comments while looking for
the first word.  Save this buffer position as `last-point'.
If the first word after a label is SUBROUTINE, set extra-indent to
`dcl-margin-offset'.

First word  extra-indent
THEN        +dcl-basic-offset
ELSE        +dcl-basic-offset
block-begin +dcl-basic-offset

Then return to the current line and look at the first word to see if the
indentation should be adjusted again.  Save this buffer position as
`this-point'.

First word  extra-indent
ELSE        -dcl-basic-offset
ENDIF       -dcl-basic-offset
block-end   -dcl-basic-offset


If dcl-calc-command-indent-function is nil or returns nil set
cur-indent to cur-indent+extra-indent.

If an extra adjustment is necessary and if
dcl-calc-command-indent-function is nil or returns nil set cur-indent
to cur-indent+extra-indent.

See also documentation for dcl-calc-command-indent-function.
The indent-type classification could probably be expanded upon."
  ()
  (save-excursion
    (beginning-of-line)
    (let ((is-block nil)
	  (case-fold-search t)
	  cur-indent
	  (extra-indent 0)
	  indent-type last-point this-point extra-indent2 cur-indent2
	  indent-type2)
      (if (bobp)			; first line in buffer
	  (setq cur-indent 0 extra-indent dcl-margin-offset
		indent-type 'first-line
		this-point (dcl-indentation-point))
        (save-excursion
          (let (done)
	    ;; Find first non-empty command line
            (while (not done)
	      ;; back up one statement and look at the command
              (if (dcl-beginning-of-statement)
                  (cond
                   ((and dcl-block-begin-regexp ; might be nil
                         (looking-at (concat "^\\$" dcl-ws-r
                                             dcl-block-begin-regexp)))
                    (setq done t) (setq is-block t))
                   ((and dcl-block-end-regexp ; might be nil
                         (looking-at (concat "^\\$" dcl-ws-r
                                             dcl-block-end-regexp)))
                    (setq done t) (setq is-block t))
                   ((looking-at dcl-comment-line-regexp)
                    t) ; comment line, one more loop
                   ((looking-at "^\\$[ \t]*$")
                    t) ; empty line, one more loop
                   ((not (looking-at
                          (concat "^\\$" dcl-ws-r dcl-label-r dcl-ws-r "$")))
                    (setq done t))) ; not a label-only line, exit the loop
                ;; We couldn't go further back, so this must have been the
		;; first line.
                (setq cur-indent dcl-margin-offset
		      last-point (dcl-indentation-point))
                (setq done t)))
	    ;; Examine the line to get current indentation and possibly a
	    ;; reason to indent.
            (cond
             (cur-indent)
             ((looking-at (concat "^\\$[ \t]*" dcl-label-r dcl-ws-r
                                  "\\(subroutine\\b\\)"))
              (setq cur-indent dcl-margin-offset
		    last-point (1+ (match-beginning 1))))
             (t
              ;; Find out how much this line is indented.
              ;; Look at comment, continuation character, command but not label
              ;; unless it's a block.
              (if is-block
                  (re-search-forward "^\\$[ \t]*")
                (re-search-forward (concat "^\\$[ \t]*\\(" dcl-label-r
                                           "\\)*[ \t]*")))
              (setq cur-indent (current-column))
              ;; Look for a reason to indent: Find first word on this line
              (re-search-forward dcl-ws-r)
	      (setq last-point (point))
              (cond
               ((looking-at "\\bthen\\b")
                (setq extra-indent dcl-basic-offset indent-type 'indent))
               ((looking-at "\\belse\\b")
                (setq extra-indent dcl-basic-offset indent-type 'indent))
               ((and dcl-block-begin-regexp ; might be nil
                     (looking-at dcl-block-begin-regexp))
                (setq extra-indent dcl-basic-offset indent-type 'indent))
               ))))))
	(setq extra-indent2 0)
        ;; We're back at the beginning of the original line.
        ;; Look for a reason to outdent: Find first word on this line
        (re-search-forward (concat "^\\$" dcl-ws-r))
	(setq this-point (dcl-indentation-point))
        (cond
         ((looking-at "\\belse\\b")
          (setq extra-indent2 (- dcl-basic-offset) indent-type2 'outdent))
         ((looking-at "\\bendif\\b")
          (setq extra-indent2 (- dcl-basic-offset) indent-type2 'outdent))
         ((and dcl-block-end-regexp ; might be nil
               (looking-at dcl-block-end-regexp))
          (setq extra-indent2 (- dcl-basic-offset) indent-type2 'outdent))
         ((looking-at (concat dcl-label-r dcl-ws-r "\\(subroutine\\b\\)"))
          (setq cur-indent2 0 extra-indent2 dcl-margin-offset
		indent-type2 'first-line
		this-point (1+ (match-beginning 1)))))
	;; Calculate indent
	(setq cur-indent
	      (or (and dcl-calc-command-indent-function
		       (funcall dcl-calc-command-indent-function
				indent-type cur-indent extra-indent
				last-point this-point))
		  (+ cur-indent extra-indent)))
	;; Calculate outdent
	(if indent-type2
	    (progn
	      (or cur-indent2 (setq cur-indent2 cur-indent))
	      (setq cur-indent
		    (or (and dcl-calc-command-indent-function
			     (funcall dcl-calc-command-indent-function
				      indent-type2 cur-indent2 extra-indent2
				      last-point this-point))
			(+ cur-indent2 extra-indent2)))))
	cur-indent
        )))