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
)))