Sams Teach Yourself Emacs in 24 Hours


Hour 7: Searching for Text in a Buffer

Previous HourNext Hour

Sections in this Hour:


Search and Replace

Most editors have the capability to replace one string with another throughout a whole document. Emacs also has this feature, but it has another which is much more user-friendly. The difference between the ordinary search-and-replace mechanism and Emacs's query-replace is that each time it finds a match, it asks you what you want to do with it. Your choices include the following:

Replacing One String With Another

This task will show you how query-replace works, with text from the previous search example.

1. Press M-% to start query-replace. Emacs will ask for the string to replace in the minibuffer. Type alarm and press Enter (see Figure 7.10).

Figure 7.10
Press M-% to start query-replace. Emacs tells you in the minibuffer that it wants the string to search for.

2. Emacs now wants to know what this string should be replaced with. Type warn and press Enter (see Figure 7.11).

Figure 7.11
When you have told it the string to search for, Emacs asks for the string to replace these matches with.

3. Now Emacs searches for the string alarm and, when it finds the string, asks you what to do with it (see Figure 7.12).

Figure 7.12
Emacs asks, at each occurrence, for confirmation to replace.

4. If you have enabled highlighting of query-replace as suggested before, the string matched will be highlighted as shown in Figure 7.13.

Figure 7.13
This is what it looks like if you have enabled highlighting of query-replace.

5. You can now press y to replace the string ( y for yes) or n to skip this string and continue until the next one ( n for no). Press y (see Figure 7.14).

Figure 7.14
When you press y Emacs replaces the text, proceeds to the next occurrence, and asks for confirmation.

6. Emacs will continue until the next match. If you are certain that your replacement is okay, you can press ! (the exclamation mark) to replace all occurrences in the rest of the document (see Figure 7.15).

Figure 7.15
When you are finished replacing the text, Emacs informs you on the number of replacements.

If you want to do an unconditional search-and-replace, the easiest way is to do a query-replace and, when it asks for confirmation on the first occurrence, press !.

Caution - It is important to be aware that the search-and-replace operation works only from your current location in the buffer to the end of the buffer. Thus if you want to do search-and-replace on the whole buffer, you must go to the beginning of the buffer.

Tip - In the minibuffer M-p and M-n let you visit earlier strings used for search-and-replace.

Options when Replacing

For each occurrence of the search string, Emacs offers to do one of several actions. Previously, you saw two of them: Replace this occurrence and replace the rest of the occurrences.

The following choices exist:

  • Space or y--This replaces the current match and continues to the next one.

  • Delete or n--This skips the current match and continues to the next one. In other words, it doesn't replace the current match.

  • Enter or q--This terminates the query-replace operation and, therefore, doesn't replace any more matches. The matches already replaced will remain replaced.

  • !--This replaces the remaining occurrences in the rest of the buffer without asking for permission.

  • , (the comma character)--This replaces the current match but doesn't continue to the next one. That way, you can get the match replaced and see whether Emacs does it correctly. To continue on to the next match, press y. If you dislike the replacement, you can either abort the query-replace and undo, or use recursive editing to fix it. (Recursive editing is described in the following section)

  • C-g--This aborts the search-and-replace operation.

  • ^ (the caret character)--This moves the cursor back to the previous replacement. (You can go back as many steps as you want.) To continue your replacement press y. If you want to correct the previous replacement, (you must use recursive editing).

  • C-l--This centers the line with the match in the middle of the window. This enables you to see the text around the match.

  • C-r--This enters recursive editing, which is described in the following section.

Recursive Editing

When you use query-replace in your buffer, you might find that there is an error of some kind in the surrounding text of the word being replaced. You can do several things about that.

You can try to remember the location and go back to it, when you are finished with your search-and-replace. Unfortunately, this method works only if you have a superb brain like Einstein; otherwise, you will forget the location when you are finished with your search-and-replace. An alternative is to write the location down. This is better than the first solution, but if your document is large, you might end up with many such notes on your paper, and when you get back to the location, you will find that you have forgotten what the problem was.

The ultimate solution is to fix the problem immediately and continue your search-and-replace afterward.

Totally aborting your search-and-replace operation is not a good idea, because this means that you might have to tell Emacs to skip several replacements when you start search-and-replace again. What you really need is to tell Emacs to pause the search-and-replace operation, fix the problem, and ask Emacs to continue after you finish.

Fortunately, Emacs offers exactly that capability. It is called recursive editing .

To enter recursive editing from your search-and-replace operation, press C-r. When you finish that, you can work with Emacs as you normally do. (You can, in fact, start another search-and-replace operation while the first is pausing; watch out if you do, because things might get messy).

When you enter recursive editing, the modeline includes a pair of square brackets around the parentheses to indicate that you are in recursive editing.

To exit recursive editing and continue with your search-and-replace press C-M-c.

Caution - If you change the buffer while editing recursively, remember to get back to the one in which the search-and-replace operation was started.

Tip - If you find at some point that you have forgotten to finish a recursive edit, and you do not want to go back to your original operation, you can press C-] (abort-recursive-edit), which will exit the recursive editing without continuing the original task.

It might be easier to remember this key binding if you notice that the key is the same as the indication in the mode line (that is, the ending square bracket).

Tip - It might be a good idea to mark your book at this point so you can return to it later and refresh your knowledge of recursive editing. I have seen people forget about it all too often and instead use the solution of writing down the location to return to for editing when the operation is finished.

It might also be a good idea to insert the keybinding for exiting recursive editing into your database of tips.

Cases in Search-and-Replace Operations

Search-and-replace operations are made up of two parts. First Emacs searches for a match. Next it replaces the match. The use of cases in search operations is described in a previous section.

If the replacement string contains cases, no case conversion is done. Case conversion is also not done if the variable case-fold-search is set to nil, as described in the section "Cases in Search Operations." When the text string is in lowercase, Emacs tries to preserve case when replacing. Emacs can preserve case in three different situations:

  • When the match is in all lowercase, Emacs will insert the replacement in all lowercase. Thus foo will be replaced with bar.

  • When the match is in all uppercase, Emacs will insert the replacement in all upper case. Thus FOO will be replaced with BAR.

  • When the match is in mixed case, the case of the first letter in the replacement is preserved and the rest of the letters are made lowercase. Thus Foo, FoO, and FOo are all replaced by Bar; likewise, fOO, foO, and fOo are all replaced by bar.

Sams Teach Yourself Emacs in 24 Hours


Hour 7: Searching for Text in a Buffer

Previous HourNext Hour

Sections in this Hour: