O'Reilly logo

Learning GNU Emacs, Second Edition by Eric S. Raymond, Bill Rosenblatt, Debra Cameron

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Search and Replace

You often want to combine a search operation with a replace operation. For example, if you spell poorly, you may want to replace every occurrence of recieve with receive. The hard way to do it is to search for recieve and, whenever you find it, make your change by hand. Emacs provides a search and replace operation that lets you fix every occurrence of the word recieve with a single command.

Simple Search and Replace Operations

First, let’s assume you’re in the situation we just described. You want to replace every occurrence of one string with another. There is no conceivable way that recieve could be correct, and absolutely no ambiguity about how you want to replace it. When you want to replace every instance of a given string, you can use a simple command that tells Emacs to do just that. Type ESC x replace-string RETURN, then type the search string and press RETURN. Now type the replacement string and press RETURN again. Emacs replaces all occurrences in the file from the cursor position onward. If you want to search and replace throughout the file, press ESC < or HOME to go to the beginning of the file before typing this command. Here’s a quick example of using replace-string.

Initial state:

Simple Search and Replace Operations

Receive is misspelled as recieve three times on this screen, but the cursor is positioned after the first instance.

Now we’ll fix them.

Type: ESC x replace-string RETURN recieve RETURN receive RETURN

Simple Search and Replace Operations

The misspelling was corrected only from the cursor position onward; the word recieve in the first sentence is still incorrect. Note how replace-string changes recieved as well as recieve.

What if you’re not sure about capitalization? The word recieve might begin a sentence, in which case it is capitalized. Do you need two separate searches? No. We’ll describe what actually happens a little later—but for now, let’s just say that Emacs does its best to match capitalization when doing a replacement.

Query-Replace

Often you’re not sure that you want to replace every appearance of your search string; a global replacement can be reckless if the file is longer than five lines. If you want to decide whether to replace the string on a case-by-case basis, use a query-replace, which allows you to change a string conditionally throughout a file. After Emacs finds an occurrence of the search string, it asks whether it should replace it, and you respond accordingly.

To use query-replace, type ESC % or select Query Replace from the Search menu. The prompt Query replace: appears in the minibuffer. Type the search string and press RETURN. Now

Query replace searchstring with:

appears. Type the replacement string and press RETURN. 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 4-3. Responses During Query-Replace

Keystrokes

Action

ESC %

Start query-replace.

SearchQuery Replace

 

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.

RETURN or q

Exit query-replace.

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).

ESC C-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, press 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 receive is misspelled throughout.

Type: ESC % recieve RETURN receive RETURN

Responses During Query-Replace

You’re ready to replace the first word; type a SPACE to go on.

Press: SPACE

Responses During Query-Replace

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.

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. In our case, we didn’t start the query-replace at the beginning of the file. 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 ESC p to see the previous command (do this as many times as necessary; ESC 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: ESC < followed by C-x ESC ESC

Repeating Query-Replaces (and Other Complex Commands)

When we press ESC <, we move to the beginning of the file; when we press C-x ESC ESC, the last complex command is displayed.

Since this is the command we want, we don’t have to press ESC p to see a previous command. If we wanted to, we could change the query-replace strings before pressing RETURN.

Press: RETURN

Repeating Query-Replaces (and Other Complex Commands)

Pressing RETURN executes the command again.

As we mentioned, C-x ESC ESC works for any command involving input in the minibuffer, not just query-replace. But we use this feature most frequently in query-replace. (It is also good for repeating keyboard macros, which are discussed in Chapter 10s.)

Recursive Editing

When you do a query-replace, you almost inevitably see something else you want to change in the file. Try it a few times—you’ll see what we mean! Your first reaction will be to try to remember your error until you’re done; your second reaction will be anger and frustration when you’ve finished the replacement and realize that you’ve forgotten what was wrong.

Fortunately, Emacs provides an easier way. It allows you to start a recursive edit while you’re in the middle of a query-replace. By starting a recursive edit, you effectively put query-replace on hold while you make any other desired edits. When you exit the recursive edit, the query-replace resumes where you left off.

To start a recursive edit while in query-replace, press C-r. (Note that like many other keystrokes, C-r has a different meaning in query-replace than it does in standard Emacs.) When you start a recursive edit, square brackets ([ ]) appear on the mode line. Let’s go back, one more time, to our order memo. You’ve used query-replace to find the first recieve, and you are about to type a SPACE to fix it, when you notice that you inadvertently omitted the apostrophe in we’ve. A quick recursive edit saves the day.

Type: C-r

Recursive Editing

When you enter a recursive edit, notice the square brackets around (Text Fill).

Now do any editing you want to; you are in an editing mode just like standard Emacs. Move back a few characters and fix we’ve. When you want to resume the query-replace, press ESC C-c (to do this, press and release ESC, then press C-c). This command tells Emacs to leave the recursive edit and reactivate the query-replace. Emacs moves back to the point at which you left off. You can then continue making replacements just as if nothing had happened.

Put an apostrophe in we’ve, then type ESC C-c

Recursive Editing

When you’re done with the recursive edit, go back to query-replace and type a SPACE to fix recieve.

If you decide to exit the recursive edit and cancel the query-replace in one fell swoop, you can type C-] (for abort-recursive-edit) or ESC x top-level RETURN rather than ESC C-c.

For more advanced users: Note that you can start a recursive edit at any time, not just when you’re in a query-replace. The command ESC x recursive-edit RETURN puts you into a recursive edit; ESC C-c takes you out of the recursive edit and brings you back to what you were doing before. You can even have recursive edits within recursive edits, although the possibility for confusion increases with each new level.

Are Emacs Searches Case-Sensitive?

By default, Emacs searches are not case-sensitive. If you search for the word random, the search finds random, Random, and RANDOM, as well as oddities like RanDoM and rANdOM. When doing replacements, Emacs pays attention to the form of the word being replaced and replaces it with the same case. If you replaced random with tandem, Random would be replaced with Tandem, and RANDOM would be replaced with TANDEM.

Therefore, the default search and replacement operations usually do what you want: they find a search string regardless of its case, and adjust the replacement appropriately for its context. However, there are times when you need finer control. The variable case-fold-search determines whether or not searches are case-sensitive. It applies to all searches: incremental searches, word searches, searches within search-and-replace operations, and so on. By default, case-fold-search is set to t, which means “ignore case unless the user types in mixed or uppercase.” This sensible default is usually just what you want. But if you need case-specific searches, set case-fold-search to nil by giving the command ESC x set-variable RETURN. Emacs prompts you for a variable name; type case-fold-search RETURN. Emacs then asks you for the new value; type nil RETURN.

Likewise, if you don’t want Emacs to adjust the case of your replacement strings, you can set the variable case-replace. Again, its value is t (for “true”) by default, which means “adjust the case of a replacement string to match the original text”—that is, capitalize the replacement if the original word was capitalized and so on. Setting this variable to nil means “never adjust the case of the replacement string; always put it in exactly as I typed it.” To change the value of case-replace, use the set-variable command we described earlier. We feel that leaving case replacement “on” is useful, particularly if you use case-insensitive searches; but you should spend some time experimenting with it, just so you’re sure you understand what it does.

The set-variable command only changes the behavior of Emacs temporarily. If you start a new editing session or even if you edit another file within the same Emacs session, you’ll be back to the default behavior. This is probably what you want, since searching separately for capitalized and noncapitalized words is inconvenient. However, you can set these variables permanently by adding the following lines to your .emacs file:

(setq-default case-fold-search nil)  ; require exact matches
(setq-default case-replace nil)      ; never change case when replacing

To have these lines take effect, save the .emacs file and restart Emacs.

Regular Expressions for Search and Replacement Operations

Sometimes none of the simpler searches described in this chapter are adequate. Regular expressions are a standard UNIX feature that has been incorporated into Emacs. Often used by programmers and UNIX hackers, regular expressions allow you to build searches with strings that contain various wildcards. Regular expressions in general are discussed in more detail in Chapter 13; here we outline the basics of using regular expression search, teaching you most of what you need to know to build and use regular expressions for searching. For even more information about regular expressions, see the O’Reilly book, sed & awk by Dale Dougherty and Arnold Robbins.

Table 3-4 shows some of the characters that you can use in creating a regular expression.

Table 4-4. Characters for Creating Regular Expressions

Character

Match

^

Matches the beginning of a line

$

Matches the end of a line

.

Matches any single character (like ? in filenames)

.*

Matches any group of zero or more characters (i.e., it’s a real wildcard, like * in filenames)

\<

Matches the beginning of a word

\>

Matches the end of a word

[ ]

Matches any character specified within the brackets; for example, [a-z] matches any alphabetic character

If you do a regular expression search for ^word$, you would find instances of word on a line by itself. The ^ says that the w must be the first character on the line, the $ says that the d must be the last character.

If you wanted to find all words starting with beg and ending with the letter s, you would use beg[a-z]*s as your regular expression. This would find the words begins, begets, and begonias, in addition to mutants like: shibegrees and altbegaslia. If you don’t want these mutants—that is, if you really want words that begin with beg and end with s, use \<beg[a-z]*s\>. The \< is a special sequence that matches the beginning of a word; \> matches the end of a word. If you wanted to find the words beg, big, and bag; but not begonias, and certainly not any strange words with beg on the inside, you would use \<b[a-z]g\> as the regular expression.

To search for a ^, $, ., *, [, ], or any number of other special things, you obviously can’t use the character itself. Put a backslash (\) first—i.e., to search for a period, search for \. For example, to search for the electronic mail address

howie@mcds.com

the regular expression would be

howie@mcds\.com

You can use regular expressions in incremental searches and in query-replace. Table 3-5 lists the commands you use for regular expression searches. Except that they are initiated with slightly different commands, the searches are the same as those described earlier in this chapter.

Table 4-5. Regular Expression Search Commands

Keystrokes

Command Name

Action

ESC C-s RETURN

re-search-forward

Search for a regular expression forward.

SearchRegexp Search

  

ESC C-r RETURN

re-search-backward

Search for a regular expression backward.

Search

  

Regexp Search Backwards

  

ESC C-s

isearch-forward-regexp

Search incrementally forward for a regular expression.

ESC C-r

isearch-backward-regexp

Search incrementally backward for a regular expression.

(none)

query-replace-regexp

Query-replace a regular expression.

Search

  

Query Replace Regexp

  

(none)

replace-regexp

Globally replace a regular expression unconditionally (use with caution).

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required