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 spaces determined by the value of the variable reduce-indentation, the default value of which is 3; Options that control REDUCE IDE. 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 inserted 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 may seem 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 C-j runs the command reindent-then-newline-and-indent rather than just newline-and-indent.

The command to indent, or re-indent, a line of text is reduce-indent-line, normally bound (indirectly) to the key TAB. 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 contains only white space. Normally, however, the most convenient way to use automatic indentation is to terminate each line of code with C-j rather than RET. See Miscellaneous features.

When called with any argument, which is possible only via the direct key binding M-i, 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-i
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. With an interactive argument, indent any additional lines of the same statement rigidly together with this one.

C-j
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 (>>) 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 can be turned on and off by the command reduce-auto-indent-mode, and it is turned on automatically if the value of the option reduce-auto-indent-mode-on is non-nil, which it is by default. The length of idle time required before the facility will operate is controlled by the option reduce-auto-indent-delay, and whether the current line is re-indented by this facility is controlled by the regular expression that is the value of the 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. 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.

The command reduce-indent-line-always, bound to C-TAB, is analogous to reduce-indent-line but always indents by precisely one additional step consisting of reduce-indentation spaces. With an argument, it rigidly indents by one step the current line and the rest of the logical statement.

The command reduce-unindent-line, bound to S-TAB (i.e. BACKTAB), is an inverse of reduce-indent-line-always and decreases the indentation by one step. With an argument, it rigidly unindents by one step the current line and the rest of the logical statement.

C-TAB
M-x reduce-indent-line-always

Indent the current line as REDUCE code by adding reduce-indentation spaces at the beginning of the line. With an interactive argument, indent any additional lines of the same statement rigidly along with this one.

BACKTAB
S-TAB
M-x reduce-unindent-line

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