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

To use query-replace, go to the beginning of the buffer using M-< and then type M-%. The prompt Query replace: appears in the minibuffer. Type the search string and press Enter. Now this appears:

Query replace searchstring with:

Type the replacement string and press Enter. So far, this procedure is almost identical to a replace-string operation; only the prompts are different.

Emacs now searches for the first occurrence of the search string. When it finds one, a new prompt appears:

Query replacing searchstring with newstring

Before performing the replacement, Emacs waits for a response to tell it what to do. Table 3-3 lists the possible responses and their results.

Table 3-3. Responses during query-replace

Keystrokes Action
Space or y Replace searchstring with newstring and go to the next instance of the string.
Del or n Don't replace; move to next instance.
. Replace the current instance and quit.
, Replace and let me see the result before moving on. (Press Space or y to move on.)
! Replace all the rest and don't ask.
^ Back up to the previous instance.
Enter or q Exit query-replace.
E Modify the replacement string.
C-r Enter a recursive edit (discussed in detail later).
C-w Delete this instance and enter a recursive edit (so you can make a custom replacement).
C-M-c Exit recursive edit and resume query-replace.
C-] Exit recursive edit and exit query-replace.

This list seems like a lot of keystrokes to remember, but you can get away with knowing two or three. Most of the time you'll respond to the prompt by pressing Space, telling Emacs to perform the replacement and go on to the next instance, or n to skip this replacement and go on to the next instance. If you're not too sure what will happen, enter a comma (,); Emacs makes the replacement but doesn't go on until you press Space. After performing the first few replaces, you may realize that there's no need to inspect every change individually. Typing an exclamation mark (!) tells Emacs to go ahead and finish the job without bothering you anymore. If you remember these keystrokes, you're all set.

How does this work in practice? Let's revisit our previous example, assuming that we want to change Whirligig to HealthBug throughout (and that we didn't save the changes we made with replace-string).

Type: M-< M-% Whirligig Enter HealthBug Enter

You're ready to replace the first occurrence; press Space to go on.

Press: Space

When you press Space, Emacs replaces the first word; the query-replace operation then moves to the second word.

This procedure continues until you reach the end of the file. As we've said, typing ! fixes the rest of the file.

In Table 3-3, you might have noticed that several keys, such as Space, have specialized meanings while the replacement is in progress. In practice, using these keys for a different function is not confusing, though it might sound bad on paper. You might want to try a query-replace on a practice file to get the hang of using the different responses. If you are easily amused, you might enjoy opening the Emacs FAQ, saving it as another file, then replacing Emacs throughout.

3.2.3 Repeating Query-Replaces (and Other Complex Commands)

Now that you've learned the basics of query-replace, let's talk about a shortcut that applies not only in query-replace but anywhere in Emacs: repeating complex commands, with slight modifications. We often exit a query-replace by mistake or decide that the replacement we really wanted was just slightly different. Do we have to type it all again? No. Simply go the beginning of the file and press C-x Esc Esc. The last complex command you typed appears. If it's not the one you want, type M-p to see the previous command (do this as many times as necessary; M-n goes to the next command). For example, let's go to the beginning of the file and repeat the query-replace we just carried out.

Type: M-< followed by C-x Esc Esc

Emacs puts the last complex command in the minibuffer; in fact it looks more complex than we remember it.

When we press M-<, we move to the beginning of the file; when we press C-x Esc Esc, the last complex command is displayed. Emacs speaks to itself in dark words, but we can still see that this is the command that we want.

This is the right command, so we don't have to press M-p to see a previous command. If we wanted to, we could change the query-replace strings before pressing Enter. In this case, the Marketing Department has once again changed the product's name from HealthBug (since bug could be construed as pest) to HealthBot (neutral, but a bit less descriptive in our opinion). Our earlier query replace changed Whirligig to HealthBug. We need to modify this command so it replaces Bug with Bot.