Next: , Previous: , Up: Top   [Contents][Index]


7 Indenting REDUCE code automatically

Indentation refers to the white space at the left of a line, which therefore determines the column in which the actual text of the line begins. Indentation is used in normal English text to indicate the beginning of paragraphs, quotations, lists, etc. and hence to indicate the logical structure of a document.

It is very important to use systematic indentation to indicate the logical structure of the source code of a computer program. Whilst the general principles of indentation are largely agreed, precise indentation conventions vary from author to author. The automatic indentation currently provided by REDUCE mode is very inflexible and reflects very much my own style of indentation. Future versions may provide more flexible and customizable indentation.

Currently all indentation is done in steps consisting of a fixed number of columns determined by the value of the variable reduce-indentation (see Customization of the REDUCE IDE), the default value of which is 3. This is the indentation recommended by A. C. Hearn (the principal author of REDUCE) for the indentation of the first line after a procedure (header) statement.

REDUCE mode provides fairly intelligent automatic indentation. The style used is as follows, where the indentation of a child statement is expressed relative to the parent statement. Each top-level statement is indented to the left margin. Procedure bodies are indented by one step. Bodies of multi-line compound and group statements are indented by one step and labels are exdented to match the beginning of the enclosing block. Lines that begin with end or >> are exdented to match the line containing the matching begin or <<. Bodies of control structures and lines that continue a previous statement are indented by one step. As parts of larger statements, compound and group statements themselves are generally not indented if they occupy multiple lines (because their bodies are indented) but they are indented if they occupy only a single line.

When a new line that is empty is being indented, the indentation can be based only on the preceding code, and not on the code that will appear in the line. Therefore, it is often necessary to re-indent a line in order to get consistent indentation. This seems a little strange, but it is unavoidable (given the syntax of REDUCE and the indentation style that I have chosen). It is for this reason that the key LFD runs the command reindent-then-newline-and-indent rather than just newline-and-indent. But see also below.

The command to indent, or re-indent, a line of text is reduce-indent-line, normally bound to the key TAB. If re-run immediately after itself (or run immediately after reindent-then-newline-and-indent (LFD) or newline-and-indent (M-x newline-and-indent)) then it indents by one further step. This is non-standard additional flexibility provided by REDUCE mode. To force a line back to its standard indentation after multiple use of the TAB key, simply execute any other command(s) and then press TAB once. The execution of reduce-indent-line is independent of the position of point within the line. It does not move point relative to the text around it unless point was within the indentation, in which case it is left before the first non-blank character (i.e. at the end of the indentation), or at the end of the line if it is empty. Normally, however, the most convenient way to use automatic indentation is to terminate each line of code with LFD rather than RET. See Miscellaneous minor features and bugs.

When called with any argument, reduce-indent-line will indent the current line correctly and then re-indent the rest of the logical statement containing point by the same amount that the current line was re-indented. This is not the same as correctly re-indenting the subsequent lines – it re-indents them rigidly, without changing their relative indentations at all, and is much faster.

TAB
M-x reduce-indent-line

Indent or re-indent the current line as REDUCE code. Indents to a fixed style determined by the current and previous non-blank lines. Subsequent consecutive calls indent additionally by reduce-indentation. With an interactive argument, indent any additional lines of the same statement rigidly together with this one.

LFD
M-x reindent-then-newline-and-indent

Re-indent the current line, insert a newline, then indent the new line. Indentation of both lines is done using reduce-indent-line, which is bound by default to TAB.

With the current indentation style, it is not possible in all cases to determine the correct indentation until after some text has been entered on a line. This applies to the terminal delimiter of a block end or group >> when it appears alone on a line and to an else clause. Therefore, REDUCE mode can automatically re-indent the current line once there is enough text to recognise that this is necessary. It does this only when it is otherwise idle and only when the relevant text has just been typed. It is not done if the cursor is later moved onto such a line since it is assumed that the desired indentation has been set by then. (The indentation of any text can, of course, be changed at any time, but it will never be automatically changed retrospectively!) This facility is turned on and off by the command reduce-auto-indent-mode, the length of idle time required before the facility will operate is controlled by the user option reduce-auto-indent-delay, and whether the current line is auto-indented by this facility is controlled by the regular expression that is the value of the user option reduce-auto-indent-regexp. Auto-indentation is on by default. See Customization of the REDUCE IDE.

M-x reduce-auto-indent-mode

Toggle REDUCE Auto Indent mode. With a prefix argument, turn the mode on if and only if the argument is positive. When REDUCE Auto Indent mode is enabled, after reduce-auto-indent-delay seconds of Emacs idle time re-indent the current line if the text just typed matches reduce-auto-indent-regexp.

A section of code can be re-indented using one command if it is first marked as the current region, or the whole buffer or a complete procedure definition can be re-indented by a single command. The latter command works by marking the procedure and then re-indenting the region; it currently leaves the procedure marked. Region (and hence procedure) indenting is currently implemented inefficiently by applying the single-line indentation algorithm line-by-line, and hence is very slow for a large region or procedure. In some future version it may be re-implemented more efficiently.

C-M-\
M-x reduce-indent-region

Indent or re-indent the region as REDUCE source code by applying reduce-indent-line to each line. With a prefix argument it indents the whole buffer.

C-M-q
M-x reduce-indent-procedure

Indent or re-indent the procedure (and trailing white space) ending after point by applying reduce-indent-line to each line.

An inverse of the extra-indentation facility is provided to decrease the indentation by one step. This command is bound to Shift-TAB (i.e. BACKTAB) if possible, but not all platforms support this (because it has no ASCII representation). It may be no different from TAB alone, or it may generate an obscure ASCII sequence, so just try Shift-TAB, or ask Emacs what function is bound to Shift-TAB (by using C-h k). A default key binding, which should work on all platforms, is provided as C-c TAB. (However, currently this is rebound by REDUCE run mode. See Run mode key bindings and menu.)

With an argument, reduce-unindent-line rigidly unindents by one step the current line and the rest of the logical statement as an inverse of extra applications of reduce-indent-line with an argument.

BACKTAB
Shift-TAB
C-c TAB
M-x reduce-unindent-line

Unindent the current line as REDUCE code by deleting reduce-indentation spaces from the beginning of the line. With an interactive argument, unindent any additional lines of the same statement rigidly along with this one.


Next: , Previous: , Up: Top   [Contents][Index]