Contents

Keyboard Macro Counters

Keyboard macros carry with them a counter that can be set, incremented, reset, and inserted as part of the macro. A common use of the counter is to create text that only varies by a numeric value. The macro counter is automatically incremented by one (the default) after each run of the macro.

A real-life example of the macro counter is in the answer to a question that was posed on the #emacs IRC channel: How can keyboard macros be used to build the followin case constructs for a switch statement in C++?

case 1:
case 2:
case 3:
case 4:
case 5:
case 6:

This can be easily done with a keyboard macro. The most obvious way is to start a macro with C-x ( or <F3>, type the case construct followed by the counter insertion command C-x C-k C-i or <F3> again, followed by the : and a newline and then end the macro with C-x ) or <F4>.

C-x C-k C-i Insert macro counter

Each time the macro counter is inserted, it is incremented by default by one. A prefix can be given to C-x C-k C-i to change the increment value.

An issue in this example is that the default start value for a macro counter is 0 and it needs to be changed to 1. The command for that is C-x C-k C-c with the starting value as its prefix (or entered at the prompt if there is no prefix.)

C-x C-k C-c Set macro counter

The macro counter needs to be set before executing the macro. If the command is used during macro definition, the counter will be set to the given value in each iteration.

As described in the first part of this post, macros can be executed directly at definition time. This means that the macro definition and execution can be combined:

C-u 1 C-x C-k C-c <F3> case <SPC> <F3> : <RET> C-u 6 <F4>

The use of <F3> here shows that it has two different meanings, depending on context. The first one starts the definition of the macro (equivalent to C-x () and the second one inserts the counter value (equivalent to C-x C-k C-i.)

Format Strings

The default format for inserting counters is an integer number. However, a different format string can be assigned either globally or within a macro definition at definition time. This can make sense if either the numbers need to be padded or if there is a repeated text pattern in which the counter should be embedded.

C-x C-k C-f Set format string

This presents an alternate approach to use a macro for the example above. If the counter should be right justified within three digits, the macro that uses the entire text as a format string is defined like this:

<F3> C-x C-k C-f case <SPC> %3d: <RET> <F3> <RET> <F4>

During macro execution, the counter can be incremented or decremented with the C-x C-k C-a command. The prefix determines the value by which to change the counter.

C-x C-k C-a Add to macro counter

Resetting The Counter

During macro execution, the counter can be reset to two different values:

C-u C-x C-k C-a Counter at the last insert
C-u C-x C-k C-c Counter at the beginning of current iteration

Additionally, using the prefix without a numeric value to the insert command inhibits the increment of the counter.

C-u C-x C-k C-i Insert previous counter and don’t increment

Let’s say the goal is to print a pattern like this:

112211
223322

First set the counter to 1 with C-u 1 C-x C-k C-c and then define the following macro with C-x ( or <f3>:

C-u 0 <f3> <f3> C-u 0 <f3> <f3> C-u C-x C-k C-c <f3> C-x C-k C-a <f3> RET

This can be broken down into the following pieces:

C-u 0 <f3> inserts the counter without increment
<f3> inserts and increments the counter
C-u 0 <f3> inserts the counter without increment
<f3> inserts and increments the counter
C-u C-x C-k C-c resets the counter to the beginning of the iteration
<f3> inserts and increments the counter
C-u C-x C-k C-a resets the counter to the last insert value
<f3> inserts and increments the counter
RET next line

In this example <f3> is used instead of C-x C-k C-i for brevity, but be aware that <f3> may not be available.

The pattern <f3> C-u C-x C-k C-a <f3> is used here for demonstration purposes only. It can be replaced with another C-u 0 <f3> <f3>.

This example presents an interesting challenge. The C-u C-x C-k C-c construct uses the macro counter from the most recent execution of a macro. What that means is that if the macro counter is reset between executions, the next execution still carries with it the previous one’s final counter value. The solution to this issue is to either decrement the counter back to the original value in the macro definition or to consider using a number register instead of the macro counter.

Querying During Macro Execution

A useful keyboard macro feature is the ability to stop and allow the user to prompt whether to continue. The macro query command is used for that.

C-x q Prompt user for confirmation

The possible responses are:

y/<SPC> Continue macro
n/<DEL> Skip the rest of the macro and start the next one
q/<RET> End macro execution

Going back to the example at the beginning of this post, a C-x q could be inserted after each line is finished to query the user whether to continue or not:

C-u 1 C-x C-k C-c <F3> case <SPC> <F3> : <RET> C-x q <F4>

Running this macro with a large number prefix and then simply holding the <SPC> key pressed would insert line after line until the user decides to stop and quit the macro.

An alternate use of the query function is the ability to enter recursive editing mode when pressing C-r at the prompt or prefixing the command during macro definition as C-u C-x q.

A common use for this is to allow for some manual editing in the middle of a macro execution because that change might be specific to each execution, e.g., different text and not just a counter.

Recursive Editing

Recursive editing is a feature that dates back to the earliest days of TECO EMACS. The command to enter the real-time (i.e., full-screen display) editing mode that became EMACS from TECO was C-r and the interactive editing commands were referred to as ^R commands. This real-time mode could be entered recursively; EMACS subsystems (like RMAIL for reading and editing mail) would call EMACS itself for editing functions.

In modern Emacs, recursive editing is a convenient feature when doing a query-replace (M-%). It is also implicitly used by a number of modes like Calc or Edebug. Brackets ([]) around the mode name on the Mode Line show that Emacs is currently in recursive edit mode. The number of brackets indicate the depth of levels of recursion.

After editing is completed, recursive editing is exited by C-M-c or the command that called it is aborted with C-]. This recursive edit exit command is already mentioned in an EMACS Introduction manual from 1978.

C-M-c Exit recursive editing
C-] Exit recursive editing and abort current command
M-x top-level Exit all recursive editing levels

Macro Step Edit

Macro editing has been discussed in the previous post. Step editing not only offers sophisticated debugging capabilities for keyboard macros, but can also be used to edit and modify macros. The command to start step editing for the most recent macro is C-x C-k <SPC>.

Step editing provides insight into the execution of a macro as the user single-steps through it. The help text in the minibuffer shows all the options that are available when requesting help with the ? key. The below is for the example at the beginning of this post.

Macro: case SPC <f3> : RET
--------------Step Edit Keyboard Macro  [?: help]---------------
 Step: y/SPC: execute next,  d/n/DEL: skip next,  f: skip but keep
       TAB: execute while same,  ?: toggle help
 Edit: i: insert,  r: replace,  a: append,  A: append at end,
       I/R: insert/replace with one sequence,
 End:  !/c: execute rest,  C-k: skip rest and save,  q/C-g: quit
----------------------------------------------------------------
Next command: kmacro-start-macro-or-insert-counter [yn iIaArR C-k kq!]

As always, the info manual is the definitive source of information. Step editing is powerful and can help the novice user better understand the construction and execution of keyboard macros.

Macros In Calc Mode

Calc mode, the advanced Emacs calculator, uses keyboard macros to implement programmability. Similar to how many scientific calculators record sequences of instructions by keystrokes, Calc takes advantage of the keyboard macro facility and extends it.

Defining a macro in Calc uses the standard key sequences. It integrates the macro editing facility with its own user-defined key naming approach to bind macros to a two-key sequence with the Z prefix.

Calc binds C-x * m to reading keyboard macro definition in a region and assigning it to the last macro. While it is a Calc keybinding, this command is independent of Calc and a useful way to quickly create macros from text instead of entering them one keystroke at a time.

Calc extends keyboard macros with its own commands to produce a programming language. It implements these features:

  • Loops
  • Conditionals
  • Local Variables
  • Prompts

Standard keyboard macros do not have these capabilities.

Conclusion

Keyboard macros have been in Emacs since well before GNU Emacs and are a fundamental tool to improve the ease and accuracy of repeated actions. At their most basic, they are a simple way to record and recall sequences of keystrokes. Counters and queries add to the power of macros and the different editing functions make them more manageable. Libraries of macros can be built up with named macros.

It is not necessary to master all keyboard macro features to take advantage of them. Even just the record and execute functions are enough to get value from macros. Locating and extracting data from multiple buffers, reformatting irregular text, or calling up a sequence of mode-specific commands are examples where keyboard macros shine.