Macros Containing Branches

The most common use of multi-line macros involves the Branch (b) command. This command was included in the editor to allow you to perform conditional execution of editor commands within macros. A simple example is the large + key on your keypad which performs one of two tasks. If you are in the text area it simply places you on the command line. If, however, you are already on the command line, it simulates your entering a carriage return to execute any command, then places you back on the command line. Hitting carriage return would normally execute any command then put you back in the text area. This key is defined as.

    t \a7 \ffoc?b2f\0a\0a\ffoc+\0a
       |     |         |    |
       |     |         |    +--  Return to command mode.
       |     |         +-------  Literal newline to execute
       |     |                   command line.
       |     +-----------------  Query and set condition
       |                         register if on command line.
       +-----------------------  Hexadecimal value generated
                                 by the large + key.

This macro is interesting for two reasons:

  1. It makes use of the Branch (b) command to conditionally execute editor commands. If you are in the text area it will skip two <newline> characters and only execute the "\ffoc+\0a" which will place you in command mode.
  2. It mixes literal text (which is entered at the current cursor) with command text (which is preceded by a \ff and is collected in an execute buffer). If you were already on the command line it will not branch, and therefore enter a <newline> on the command line which will cause it to be executed. You will then fall into the code which sets option command and goes to the command line.

Defining complex macros which contain several branches and several lines quickly becomes confusing when displayed as a single line with embedded <newline> character escapes. The macro for the F2 key illustrates this.

    t \82 \ffon?b3t\0a\ffi\0a\ffb4\0a\ffon-zch1\0a\ffb2t\0a\ffd\0a

This macro can be better understood when displayed as the multi-line sequence

t \82 \ffon?b3t
Check if option newline is on or off.
\ffi
If it is off, then do an insert command
\ffb4
and skip the rest of the macro.
\ffon-zch1
Else go to the beginning of the line and skip
\ffb2t
to the end of the macro if line isn't empty.
\ffd
Delete the empty line.

It should be remembered that the Zap Cursor Horizontal command (zch) will set the condition register false if you move to a position which does not contain a character. If there is no character in the first column then the line must be empty.

There is a macro which will allow you to type in a macro in your text buffer in the multi-line form above and convert it into a single string on the command line which you may type carriage return to enter. This macro is defined in your /usr/lib/ed.macros file, but has been commented out by a double quote. You may remove this quote and then execute the file

x /usr/lib/ed.macros

to define this macro as your Altm key. If you type the Altm key in the text area, it will compress your buffer into a single line and move it to the command line for execution. If you are on the command line, then it will take a macro which you have displayed via the

    t ? \hh

command and place it in your text buffer in a multi-line format.

For interest this macro is defined as:

t \84 \ffoc?b7f*da
\ffon-om+0zk1
\ffu1 s/\\\\\\\\/\\80/
\ffu1 s/\\\\0a/\\0a/
\ffu1 *s/\\80/\\\\\\\\/
\ff0zce255 1zch1b5
\ffom+                            -Start of code in the case
\ffu1 *s/$/\\\\0a/                 where you are in the text area.
\ffu40 1j
\ff1zk0zch1oc+

This macro uses Until (u) commands to prevent errors should a substitute fail.

In the case where you are on the command line, it deletes your buffer and places an empty line in it via the Append command. It then copies the command line to the empty line and splits the line at each \0a. Note that it is not tricked by a \\0a sequence.

The reverse process appends each line with a \0a sequence, joins all lines, then copies it to the command line. It leaves the joined line in your text buffer allowing you to save it with a write or write append command.