Выбрать главу

The following screens show what the macro defined in Table 6-3 looks like when you run it.

Type: F4

The macro pauses so that you can type your address.

Type your address and press: C-M-c

The macro pauses so you can type the recipient's name and address.

Type the recipient's name and address and press: C-M-c

The macro pauses so you can type the date.

Type the date and press: C-M-c

The macro finishes by typing the opening for the letter.

Now the macro has finished editing; you can type the recipient's name and then the body of the letter, and of course you can go back and edit any of the information you've already filled in.

6.8.2 Adding a Query to a Macro

The more complex the task your macro performs, the more difficult it is to make the macro general enough to work in every case. Although macros can do a lot of things, they aren't programs: you can't have if statements, loops, and the other things you associate with a program. In particular, a macro can't get input from the user and then take some action on the basis of that input.

However, one feature lets a macro get input, in a limited way, from the user. You can create a macro that queries the user while it is running; it works much like a query-replace. To create this kind of a macro, type C-x q when you reach the point in the macro definition where you want the macro to query the user. Nothing happens immediately; go on defining the macro as you normally would.

Things get interesting later, when you execute the macro. When it gets to the point in the macro where you typed C-x q, Emacs prints a query in the minibuffer:

Proceed with macro? (y, n, RET, C-l, C-r)

The responses listed here are analogous to those in query-replace:

• Pressing y means to continue and go on to the next repetition, if any.

• Pressing n means to stop executing the macro but go on to the next repetition, if any.

• Pressing Enter means to stop executing the macro and cancel any repetitions.

• Pressing C-r starts a recursive edit, which lets you do any editing or moving around you may want to and then resume the macro when you exit the recursive edit. To exit a recursive edit, press C-M-c. Emacs again asks if you want to proceed with the macro, and you type y for yes or n or Enter for no.

• Pressing C-l puts the line the cursor is on in the middle of the screen (this is good for getting a feel for the context). Similar to C-r, Emacs again asks if you want to proceed with the macro, and you have to answer y, n, or Enter.

• Pressing C-g (although not listed as an option) cancels the query and the macro; it is similar to pressing Enter.

6.8.2.1 Example

Let's say that you write a macro that copies comments from a program to another buffer. The comments in our program are preceded by a slash, so you start the macro with a search for a slash. However, not all comments are worth copying. Following the search with a query lets you decide case by case whether the search has found a comment you want to copy. Table 6-4 shows a macro to copy comments to another buffer.

Table 6-4. Comment-copying macro with a query

Keystrokes Action
F3 Start the macro definition.
C-s / Search for a slash.
Enter Stop the search when it is successful.
C-x q Insert a query in the macro; Emacs asks you if you want to proceed at this point when you run the macro.
M-f Move forward one word.
M-b Move to the beginning of this word.
C-Space Set the mark.
C-e Move to the end of the line.
C-f Move forward one character.
M-w Copy the comment to the kill ring.
C-x b comments Move to a buffer called comments.
C-y Insert the comment in the buffer.
C-x b Move back to the original buffer.
F4 End the macro definition.