The commands we discussed in the first two chapters are enough to get you started, but they're certainly not enough to do any serious editing. If you're using Emacs for anything longer than a few paragraphs, you'll want the support this chapter describes. In this chapter, we cover the various ways that Emacs lets you search for and replace text. Emacs provides the traditional search and replace facilities you would expect in any editor; it also provides several important variants, including incremental searches, regular expression searches, and query-replace. We also cover spell-checking here, because it is a type of replacement (errors are sought and replaced with corrections). Finally, we cover word abbreviation mode; this feature is a type of automatic replacement that can be a real timesaver.
While you're editing, you frequently want to find something you've already typed. Rather than hunt through the file trying to find what you're looking for, virtually all editors provide some kind of search feature that lets you look for a particular text string. Emacs is no exception to the rule. It supplies a search command—in fact, it provides a dizzying array of search commands. Here's a quick summary of the different kinds of searches that are available:
Simple search
You give Emacs a search string, and it finds the next occurrence. You will find this search in almost any editor.
Incremental search
With incremental search, Emacs starts to search the file as soon as you type the first character of a search string. It continues to search as you type more characters.
Word search
A word search is like a simple search, except that Emacs searches only for full words and phrases. For example, if you are searching for the word hat, you don't have to worry about finding the word that. A word search is also useful when you need to find a phrase that is spread across two lines.
Regular expression search
To search for patterns, you can use a regular expression search. For example, if you wanted to find all instances of B1 and B2, you could search for them using the regular expression B[12]. However, regular expressions can be extremely complex. We'll give a brief introduction to this topic here; it is discussed more fully in Chapter 11.
Incremental regular expression search
This search procedure is a combination of an incremental search and a regular expression search.
You can search forward or backward. Searches can be either case-sensitive, meaning that Emacs considers upper- and lowercase letters to be different (i.e., the words This and this are different) or case-insensitive, in which upper- and lowercase are not differentiated (i.e., This and this are equivalent). By default, searches are case-insensitive, with upper- and lowercase letters considered to be the same. One exception: if you type any uppercase letters, Emacs makes the whole search string case-sensitive; it assumes you are looking for something precise since you've made the extra effort to type some letters in uppercase.
Replacement operations are closely related to searches. As with searches, Emacs offers you several different flavors:
Simple search and replace
In this procedure, Emacs replaces all occurrences of one string with another. Usually, this is too radical a solution and can have unintended results. Try query-replace instead.
Query-replace
With query-replace, Emacs conditionally replaces a string throughout a file. Emacs finds all occurrences of the search string, and for each one it asks you whether or not to perform the replacement. This type of replacement is useful if you need to change some, but not all, instances of a word or phrase throughout a file.
Regular expression replace
Regular expression replacement uses the powerful pattern matching facility of the same name to find strings and replace them.
So now you know what you'll be looking at. Don't be intimidated by the wealth of searches that are available. In practice, you'll probably settle on one search command and one replace command and use these for 99 percent of your work. For example, we use incremental search and query-replace most of the time. If you're a writer, you may use word search all the time; if you're a programmer, you might want a regular expression search. If you're just beginning, you may want to learn incremental search and read the rest of this chapter later. However, if you know what's available, you'll be able to make use of the other search commands when they become useful.
Incremental search starts to work from the moment you type the first character of the search string. Many users like the efficiency of incremental searches, and they like the highlighting as well. Emacs highlights all occurrences of the search string in aqua blue (if your display supports it) and uses purple to highlight the string at the cursor position (the current match).
Type: C-s m
Emacs highlights all the words that start with m.
To start an incremental search, type C-s and then type the text you want to find. Emacs temporarily enters Isearch mode. Notice how this search works: Emacs looks for each character as soon as you type it. For example, if you are searching for the word meter, in an incremental search Emacs finds the next m as soon as you type the m; it finds the next me as soon as you type the e; it finds the met as soon as you type the t; and so on. Sooner or later, you either find what you want, or Emacs is unable to find anything. If you find what you want, press Enter; doing so stops the search at the current place in the file. If Emacs can't find anything that matches your search string, it prints the message
Search failed
at the bottom of your screen and then it beeps.
Here's what happens when we search for the word meter; the numbers show how the cursor moves with each new letter in the search string.
Type: C-s meter
Emacs moves the cursor from one position to another as you type the letters of the search string.
In this incremental search, Emacs moves the cursor from position 1 to 2, to 3, and so on, as you type the search string meter. Also, note that
Isearch
appears on the mode line.
What happens if you find the string you're looking for but not the right occurrence of the string? Let's say you're searching for the word eschatology and you find the word, but you're still not in the right place. Simply press C-s again to find the next occurrence of the current search string. Emacs uses the same search string; you don't have to retype it.
Remember to press Enter when you've found the text you want. Forgetting to stop the search (by pressing Enter or with any other cursor movement command) is a common mistake: you type a few things, and suddenly Emacs is off looking at some completely different part of the file. What has happened? Emacs thinks you're still searching, and it has just added the characters you've typed to the search string.
If you type a letter in your search string incorrectly, press Del: Emacs moves back to the first instance of the reduced string in the file. If you keep pressing Del to delete characters from the search string, you'll see Emacs cycle back through the file to previous matches.
To cancel a search (that is, to give up searching), type C-g. This command brings you back to the place where the search began.
To search backward through a file, use C-r, which works exactly like C-s except that it searches in the opposite direction. It puts the cursor at the beginning of the text you find. Just as you can do when repeating C-s, you can press C-r to make the search go in the other direction without retyping the search string.
To avoid typing your search string, you can copy text from the buffer into the search string. To copy text from the cursor position through the next space or punctuation mark into the search string, type C-s C-w (it may help to think of C-s C-w as "search a word"). To copy text from the cursor to the end of the line into the search string, type C-s C-y. Notice that the text that is yanked is always converted to lowercase; this conversion ensures that the search will be case-insensitive. You can also copy text from the kill ring to the search string by typing C-s M-y. After you've given this command, you can press M-p to see previous items from the kill ring. M-n takes you to the next item if you've gone back with M-p.
Once you're in an incremental search, certain keys (such as Enter and Del) have different functions than they normally do. This situation may sound confusing, but it's actually fairly easy to get used to. Table 3-1 shows a summary of key functions during incremental search.
Table 3-1. Incremental search commands
Keystrokes | Command name | Action |
---|---|---|
C-s Edit → Search → Incremental Search → Forward String | isearch-forward | Start incremental search forward; follow by search string. Also, find next occurrence (forward) of search string. |
C-r Edit → Search → Incremental Search → Backward String | isearch-backward | Start incremental search backward; follow by search string. Also, find next occurrence (backward) of search string. |
Enter | isearch-exit | In an incremental search , exit the search. |
C-g | keyboard-quit | In an incremental search , cancel the search. |
Del | isearch-delete-char | In an incremental search, delete character from search string. |
C-s C-w | isearch-yank-word | Start an incremental search with the word the cursor is on as the search string. |
C-s C-y | isearch-yank-line | Start an incremental search with the text from the cursor position to the end of the line as the search string. |
C-s M-y | isearch-yank-kill | Start an incremental search with text from the kill ring as the search string. |
C-s C-s | isearch-repeat-forward | Repeat previous search. |
C-r C-r | isearch-repeat-backward | Repeat previous search backward. |
Emacs also offers a simple, or nonincremental, search. To use a more straightforward search, type C-s Enter. Type the search string, press Enter, and Emacs begins the search. Simply press C-s again to repeat the search. To start a nonincremental search backwards through the file, press C-r Enter. Again, you type the search string and press Enter to begin the search.
The search icon on the toolbar (a magnifying glass over paper) and the Edit → Search → String Forward option run the same kind of a search. The prompt is slightly different. C-s Enter prompts you with
Search:
in the minibuffer while the toolbar icon and the menu option prompt with Search for string:
. This is a minor difference; the searches are virtually identical otherwise.
Table 3-2 summarizes the simple search commands.
Table 3-2. Simple search commands
Keystrokes | Action |
---|---|
C-s Enter Enter Edit → Search → String Forward |
Start nonincremental search forward. |
C-s | Repeat search forward. |
C-r Enter Enter Edit → Search → String Backwards |
Start nonincremental search backward. |
C-r | Repeat search backward. |
If you're searching for a phrase and you know it's in the file but you can't find it with incremental search, try word search. (You probably can't find your phrase with incremental search because the phrase has a line break in it.) Word search is a nonincremental search that ignores line breaks, spaces, and punctuation. It also requires that your search string match entire words in the file.
To do a word search, type C-s Enter C-w (for word-search-forward). The prompt
Word search
appears in the minibuffer. (Don't be put off by the prompts that appear along the way: you'll see an I-search
prompt after typing C-s and a Search
prompt after pressing Enter. Ignore these.) Type the search string and press Enter. Emacs searches for the given string. To do a word search backwards, type C-r Enter C-w instead. For example, assume that you have the following text, with the cursor at the beginning:
He said, "All good elephants are wise, aren't they?"
She answered, "Some are smarter than others, but we
think this is socially conditioned."
The command C-s Enter C-w they she Enter positions the cursor after the word She. This command looks complicated, but it's really nothing more than a word search (C-s Enter C-w) for the word they, followed by the word she. It ignores the punctuation (?") and the newline between they and she.
Assume that you're looking for the word the. You don't want to bother with thence, there, theater, thesis, blithe, or any other word that happens to contain the letters the. In this situation, neither an incremental search nor a simple search is very useful—you need a word search. If you're writing a paper, word search is often exactly what you need. It is the only one of the three basic search commands that allows you to find what you want even if the phrase is split between two lines.
Now that you've seen the three most commonly used searches, you might want to experiment and see which you find most useful.
Search and replace definitely go together, like coffee and cream. Let's say you're working on a new software application and at the last possible moment, the Marketing Department decides to change the product's name.
There's a press release for Whirligig, an email service that periodically reminds you to make healthy lifestyle changes like exercising, drinking water, and taking vitamins. The level of harassment or, as the marketing department says, encouragement, can be set by the user. Whirligig isn't really the most descriptive name, so at the last minute the Marketing Department changes it to HealthBug.
Assume you're in the situation we just described. You want to replace every occurrence of one string with another. You know that Whirligig is never correct, and there is 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 M-x replace-string Enter, then type the search string and press Enter. Now type the replacement string and press Enter again. Emacs replaces all occurrences in the file from the cursor position onward. If you want to search and replace throughout the file, press M-< to go to the beginning of the file before typing this command. Here's a quick example of using replace-string.
Initial state:
Whirligig appears four times, but the cursor is positioned after the first instance.
Now we'll do the replacement.
Type: M-x replace-string Enter Whirligig Enter HealthBug Enter
Emacs replaces all instances from the cursor position onward.
The replacement occurs only from the cursor position onward; Whirligig in the first sentence is still incorrect. We'll work with this example again in a moment.
Few search and replace situations are as straightforward as those we've described. Often you're not sure that you want to replace every appearance of your search string: a global replacement can be reckless. 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, 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 with 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.
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.
In the minibuffer, change Whirligig to Bug and HealthBug to Bot and press Enter.
Pressing Enter executes the command again with the modified search and replacement strings.
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 (see Chapter 6).
When you do a query-replace, you inevitably see something else you want to change in the file. Try it a few times—you'll see what we mean! We typically try to remember the problem until we're done, then get frustrated when we forget exactly what and where the problem was.
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 key bindings, 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 public relations piece. You've used query-replace to find the first Bug to change to Bot, and you are about to press Space to fix it, when you remember that the lawyers said that the "64 ounces of water" statement was too specific and could be construed as giving medical advice. A quick recursive edit saves the day.
Type: C-r
Notice the square brackets around
(Text Fill)
, indicating a recursive edit in progress.
Now do any editing you want to; you are in an editing mode just like standard Emacs. Move down to the third line and delete "64 ounces of." When you want to resume the query-replace, press C-M-c. This command tells Emacs to leave the recursive edit and reactivate the query-replace. Emacs moves back to the point where you were when you started the recursive edit. You can then continue making replacements just as if nothing had happened.
Delete "64 ounces of," then type C-M-c
Emacs goes back to query-replace and you press Space to fix the next Bug.
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 M-x top-level Enter rather than C-M-c.
In fact, you can start a recursive edit at any time, not just when you're in a query-replace. The command M-x recursive-edit Enter puts you into a recursive edit; C-M-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.
By default, Emacs searches are not case-sensitive. Look at the Options menu and you'll see that the option Case-Insensitive Search is the only option that is checked by default.
What does this mean in practical terms? 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. If you mix capitalization, the replacement string appears just as you type it. healthbug would be replaced with HealthBug if that was the case in the replacement string. In other words, 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, sometimes you need finer control.
The variable case-fold-search determines whether 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-sensitive searches, the Case-Insensitive Search option on the Options menu provides an easy way to experiment with this variable.
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, type M-x set-variable Enter case-replace Enter nil Enter (there's no menu option for this variable).
Both the menu option and the set-variable command change the behavior of Emacs only temporarily. If you start a new editing session, you'll be back to the default behavior. This is probably what you want, because searching separately for capitalized and lowercase words is inconvenient.
You can set the value for the Case-Insensitive Search option permanently by selecting Save Options from the Options menu or by adding this line to your .emacs file:
(setq-default case-fold-search nil) ; require exact matches
To set case-replace permanently, add the following line to your .emacs file. You'll need to restart Emacs to have the change take effect.
(setq-default case-replace nil) ; never change case when replacing
You could change these variables through Emacs's interactive customization facility, Custom, instead (see Chapter 10).
Sometimes none of the simpler searches described in this chapter are adequate. Regular expressions allow you to build searches with strings that contain various wildcards.
Table 3-4 shows some of the characters you can use in creating a regular expression.
Table 3-4. Characters for creating regular expressions
Character(s) | 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 (. matches any character and * matches zero or more of the previous character). |
\< | 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. |
\s, \S | Matches any whitespace character: space, a newline, a tab, a carriage return, a formfeed, or a backspace; \S matches any character except whitespace. |
\d, \D | Matches any single digit, 0-9; \D matches any character but a digit. |
\w, \W | Matches any "word" character (upper- and lowercase letters, digits, and the underscore character); \W matches any character but these. |
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 could use beg[a-z]*s as your regular expression. This would find the words begins, begets, and begonias, in addition to really odd words 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 \
To search for a ^, $, ., *, [, ], or any number of other special characters, 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
This is a barebones introduction to regular expressions; see Chapter 11 for more details and Mastering Regular Expressions by Jeffrey Friedl (O'Reilly) for a book-length treatment of this topic.
You can use regular expressions in incremental searches and in query-replace. Table 3-5 lists the commands you use for regular expression searches. Although they are initiated with slightly different commands, the searches are the same as those described earlier in this chapter.
Table 3-5. Regular expression search commands
Keystrokes | Command name | Action |
---|---|---|
C-M-s Enter Edit → Search → Regexp Forward | re-search-forward | Search for a regular expression forward. |
C-M-r Enter Edit → Search → Regexp Backwards | re-search-backward | Search for a regular expression backward. |
C-M-s Edit → Search → Incremental Search → Forward Regexp | isearch-forward-regexp | Search incrementally forward for a regular expression. |
C-M-r Edit → Search → Incremental Search → Backward Regexp | isearch-backward-regexp | Search incrementally backward for a regular expression. |
C-M-% Edit → Replace → Replace Regexp | query-replace-regexp | Query-replace a regular expression. |
(none) | replace-regexp | Globally replace a regular expression unconditionally (use with caution). |
Emacs includes two spell-checking interfaces: to the Unix spell checker,
spell
, and to Ispell, which many people, including us, prefer. We say "interfaces" because Emacs does not include the executables for either of these spell-checkers. Because Ispell is superior and runs on a variety of platforms, we'll cover only Ispell here. If you attempt to run Ispell and it is not available, you'll have to install it. Chapter 13 provides details on installing Ispell on Windows and on Mac OS X.
A further enhancement to Ispell is Flyspell, a command that highlights misspelled words on the fly. If you have Ispell installed, you'll have Flyspell support as well.
Ispell includes options to check a buffer, a region, the comments in a program, or a single word. After you type the command telling Ispell what area you want to check, it works the same way for all these options. We'll describe ispell-buffer here. If all the words are spelled correctly, Ispell displays the message,
Spell-checking done
. If Ispell finds a misspelled word, a screen like the following appears. Let's spell-check a hastily typed passage from Homer's Odyssey.
Type: Esc x ispell-buffer Enter
Ispell finds the first unrecognized word in the buffer.
Ispell moves to the first unrecognized word, in this case a proper name correctly spelled (except for the proper accent marks). At the top of the screen, Ispell opens a small window that displays alternative spellings, numbered starting with 0. The minibuffer says
C-h or ? for more options, SPC to leave unchanged, character to replace word
. In this case, we have a properly spelled name, so press i to ask Ispell to insert it into your private dictionary, which is kept in a file called .ispell_Press i:
Ispell moves to the next unrecognized word, another proper name.
We insert a few more proper names and move along to the first real misspelling, pwers.
Ispell finds pwers misspelled.
Ispell opens a window at the top of the screen listing choices for a replacement. Usually one of its top few choices is correct.
To select powers, press: 1
Ispell replaces the word and goes on to the next misspelling.
If one of the words that Ispell lists at the top of the screen is correct, you type the number, and Ispell makes the replacement. To replace a word yourself, press r. After you type the corrected word, Ispell replaces it. If you press R instead, Ispell starts a query-replace through which you can correct all cases of the misspelling in this buffer.
Instead of replacing the word, you may simply want Ispell to skip over it. To skip this occurrence of a misspelled word, press Space. To ignore a misspelled word for the rest of the session for all buffers, press a (for accept). Uppercase A has one subtle difference: it tells Ispell to accept the word for this session but only in this buffer.
If you can see that something more complicated is wrong, you can start a recursive edit by typing C-r. Fix the error and type C-M-c to exit the recursive edit and resume Ispell. (You may recall that we discussed recursive editing earlier in this chapter.)
Our passage repeatedly spells would incorrectly and typing the character beside the correct word only replaces a single incidence, so a better choice would be to type R to query-replace the word throughout the buffer.
Type: R
Ispell asks for the correction for wuld.
Change wuld to would and press Enter.
Ispell starts a query-replace.
We want to replace all occurrences of the misspelled word, so we'll type !, which, as you might recall, means "replace them all without asking."
Type ! then y when prompted about saving your personal dictionary.
Emacs moves to the "next" misspelling, crse.
Ispell replaces the words, then goes on to the next misspelling, crse. Note that this misspelling occurs before the second incorrect wuld. Because we already query-replaced wuld with would, Ispell had to move backward to find the next misspelling.
Remember that Ispell, like all spellcheckers, corrects only true misspellings. If a misspelling forms another word, Ispell will leave it alone. It's up to you to change fries to fires in this passage.
Different forms of the same word must be corrected separately. For example, if you misspell receive, receives, and receiving by reversing the i and the e, you must change each misspelled word.
Sometimes when you are typing, you'll say, "That doesn't look right." To check the word the cursor is on, type M-$ (for ispell-word). Ispell checks the spelling of the word and displays
if the word is spelled correctly. If the word is incorrect, Ispell displays a window with the options discussed earlier.word : ok
You might start typing a word and then wonder, "How is that spelled?" This is where ispell-complete-word comes in. You're typing a word and you get stuck. Type M-Tab (for ispell-complete-word) and you get a list of choices. After typing occur, you use this command to find out the answer.
Type: occur M-Tab
Ispell choices appear at the top of the screen.
To select occurrence, type: 2
Ispell completes the word for you.
This feature varies in its helpfulness. In this case the replacement needed was shown. It won't always work that way, but you can always simply spell it wrong and then use ispell-buffer to fix it.
Flyspell highlights misspelled words as you type. You can also use it to check existing text. The commands for doing this are different.
To check text as you type, enter Flyspell mode by typing M-x flyspell-mode Enter.
Fly
appears on the mode line. If you set up Emacs to enter Flyspell mode automatically, your text is always spell-checked "on the fly." An alternative to Flyspell mode is Flyspell prog mode. In this mode, designed for programmers, Emacs highlights misspellings only in comments or strings. To enter it, type M-x flyspell-prog-mode Enter.
To check existing text, you run M-x flyspell-buffer Enter. This command is like ispell-buffer; it spell-checks the entire buffer. Flyspell's interface is different; it underlines all the words it suspects are misspelled and gives you a pop-up menu of alternatives.
The best way to check out Flyspell mode is to turn it on and type some misspelled text to see it in action. No matter whether you enter Flyspell mode or run flyspell-buffer, you correct errors in the same way. We'll demonstrate flyspell-buffer on our misspelled odyssey file. Because it's an existing file (not a new file we're typing), we need to issue the flyspell-buffer command.
Type: Esc x flyspell-buffer Enter
Flyspell highlights misspelled words (Mac OS X).
Flyspell highlights misspelled words in red. Words that are repeatedly misspelled are highlighted in yellow. Note that it doesn't highlight the proper names we inserted in the dictionary earlier using Ispell; Flyspell checks to see whether words are in your personal dictionary before highlighting them as errors.
You move to a misspelled word and press the middle mouse button to display a pop-up menu of possible replacements. (This implies that you have a three-button mouse, and, to be honest, you need one to make Flyspell work properly.) You select a replacement using the mouse.
Move the cursor to crse and press the middle mouse button.
Flyspell displays a pop-up window of alternatives; you choose one with the mouse (Mac OS X).
Choose curse with the mouse.
Emacs inserts the correct replacement (Mac OS X).
Ispell inserts new words in the dictionary. Flyspell takes it a step further, creating word abbreviations for words that you misspell. In essence, a word abbreviation tells Emacs, in this case, that wrd is just an abbreviation for word, and that therefore Emacs should replace it automatically. If you turn on word abbreviation mode, described in the next section, chronic misspellings that Flyspell encounters will be automatically corrected.
How can you tell Flyspell is using word abbreviations? When you exit a session in which you've used Flyspell, you see a prompt that says,
Save abbrevs in ~/.abbrev_defs (y or n)
. This automatic correction won't occur without turning on word abbreviation mode, whether in your startup or manually. Read the section on this topic in this chapter for more details.
What do you do if you encounter a word that's spelled correctly but that Flyspell doesn't recognize? You could insert it in your Ispell dictionary if it's a word you use frequently. The Save word option on the Flyspell pop-up menu handles this. For a temporary fix, the options Accept buffer and Accept session tell Flyspell to accept a word for the current buffer or for all buffers in the current Emacs session automatically. Of course, if it's a word you use frequently, you may want to insert it in the Ispell dictionary to keep Flyspell from flagging it each time.
To enter flyspell mode automatically, add this line to your .emacs file:
(setq-default flyspell-mode t)
Table 3-6 summarizes the Ispell and Flyspell commands.
Table 3-6. Spell-checking commands
Keystrokes | Command name | Action |
---|---|---|
M-$ Tools → Spell Checking → Spell-Check Word | ispell-word | Check the word the cursor is on or the word following the cursor. |
(none)Tools → Spell Checking → Spell-Check Region | ispell-region | Check spelling of the region. |
(none)Tools → Spell Checking → Spell-Check Buffer | ispell-buffer | Check spelling of the buffer. |
(none)Tools → Spell Checking → Spell-Check Message | ispell-message | Check spelling of the body of a mail message. |
(none)Tools → Spell Checking → Spell-Check Comments | ispell-comments-and-strings | Check spelling of comments and strings in a program. |
C-u M-$ Tools → Spell Checking → Continue Spell-Checking | ispell-continue | Resume Ispell; it works only if stopped Ispell with C-g. |
(none) | ispell-kill-ispell | Kill the Ispell process, which continues to run in the background after it is invoked. |
M-Tab Tools → Spell Checking → Complete Word | ispell-complete-word | In text mode, list possible completions for the current word. |
(none)Tools → Spell Checking → Automatic Spell-Checking (Flyspell) | flyspell-mode | Enter the Flyspell minor mode, in which incorrectly spelled words are highlighted. |
(none) | flyspell-buffer | Spell-check the current buffer, underlining all misspelled words. Use middle mouse button to correct. |
Word abbreviation mode and dynamic abbreviations are two features that lazy typists will love. The authors proudly include themselves in that category, so you'll be in good company if you choose to explore these features. Dynamic abbreviations are less complex, so we'll discuss them first.
Let's say that you are a scientist writing a paper on invertebrates. You're likely to have many long technical words in your paper, and if you're like us, you get tired of typing long words.
Dynamic abbreviations come to the rescue. After you've typed a long word once, you can simply type a few letters and give the command M-/ (for dabbrev-expand). Emacs inserts the nearest word that starts with that string.
Type: In M-/
Emacs inserts the last word starting with in, in this case, interesting.
Interesting was not the word we were hoping for; it's invertebrates we wanted. Without moving the cursor, type M-/ again.
Type: M-/
Emacs inserts the word Invertebrates, which is what we wanted.
The word being expanded need not be earlier in the file to be considered nearest. Emacs looks behind and ahead of the cursor position to find words it can expand. If there are eligible words that are equidistant above and below the cursor position both, Emacs selects the word that is above as the expansion.
Earlier we talked about completing a word with Ispell. Dynamic abbreviations are a bit different. When you complete a word, the word probably isn't in the buffer (yet). When you use a dynamic abbreviation, you simply don't want to type a word you typed earlier and you're asking Emacs to do it for you.
Using dynamic abbreviations doesn't require entering a special minor mode, as standard word abbreviations do. They are simply an aid for the tired typist. Word abbreviation mode has some other advantages, though, such as the ability to create an abbreviation for a phrase or a habitual typo, as we will see next.
Word abbreviation mode lets you define abbreviations for special words and phrases. You can use it in many ways. Traditionally, abbreviation mode is used so that you don't have to type long words or phrases in their entirety. For example, let's say you are writing a contract that repeatedly references the National Institute of Standards and Technology, and you are not allowed to use an acronym. Rather than typing the full name, you can define the abbreviation nist. Once you have set up this definition, Emacs inserts the full name whenever you type the abbreviation nist, followed by a space, tab, or punctuation mark. Emacs watches for you to type an abbreviation, then expands it automatically for you.
Before showing you how to get into word abbreviation mode and define your abbreviation list, we'll start with an example. Our favorite nontraditional use for word abbreviation mode is to correct misspellings as you type.[21] Almost everyone has a dozen or so words that they habitually type incorrectly because of worn neural pathways. You can simply tell Emacs that these misspellings are "abbreviations" for the correct versions, and Emacs fixes the misspellings every time you type them; you may not even notice that you typed the word wrong before Emacs fixes it. So assume that you've entered word abbreviation mode, and that you've defined receive as an abbreviation for recieve; now, as you're typing, you make an innocent mistake.
Type: You will recieve
You type the offending word but haven't yet pressed Space, which will cue Emacs to correct it (Windows).
Type: Space the materials you requested shortly
Emacs corrects the word automatically after you press Space; you need not stop typing or even be aware that a mistake has been made and corrected (Windows).
Besides the convenience of being able to invent abbreviations for phrases that you frequently type, you can see that setting up a short list of abbreviations for common misspellings could reduce the time it takes to proofread files and reduce the number of common typing errors.
When you define abbreviations, never use abbreviations that are words in their own right or Emacs may expand the word when you don't want it to, because expansion takes place without asking. For example, if you frequently write about the World Association for Replicant Technology, don't define an abbreviation of wart, or you won't be able to write about the difficulties of handling toads. (If you use the word wart so infrequently that you think the convenience of the acronym warrants it, you can use C-_ to undo the abbreviation when you really want to type wart.)
Emacs knows the abbreviations exactly as you define them. If you define recieve as an abbreviation for receive, you must also define recieves, recieving, and recieved as abbreviations to cover all the forms of the word you might misspell.
Before you go ahead and define some abbreviations, here's one more basic fact you should know. Emacs classifies abbreviations according to which modes they work in. Global abbreviations work in all modes; local abbreviations work only in the mode in which they were defined. For example, if you want abbreviations to work only in text mode and not in C mode, define them as local while you are in text mode. If you want abbreviations to work in any mode, define them as global. Remember: abbreviations are local to modes, not to files or buffers.
Emacs also provides an inverse method for defining abbreviations. This method is called inverse because you type the abbreviation and then the definition. Some commands (which we won't discuss) let you type the definition and then the abbreviation, but they require some tricky key sequences to let Emacs know how many words preceding the cursor are part of the abbreviation. The inverse method is easier and it works whether the definition for the abbreviation is one word or ten words.
Usually, if you go to the trouble of defining a word abbreviation, you will use it in more than one Emacs session. But if you'd like to try out abbreviation mode to see if you want to incorporate it into your startup, use the following procedure.
To define word abbreviations for this buffer and session:
1. Enter word abbreviation mode by typing M-x abbrev-mode Enter.
Abbrev
appears on the mode line. For a global abbreviation, type the abbreviation you want to use and type C-x a i g or C-x a - (for add-inverse-global). (For a local abbreviation, type C-x a i l for add-inverse-local instead.) Emacs then asks you for the expansion.
2. Type the definition for the abbreviation and press Enter. Emacs then expands the abbreviation and will do so each time you type it followed by a space or punctuation mark.
3. When you exit Emacs. it asks if you want to save the abbreviations in .abbrev_defs. Type y if you want to save them.
4. The abbreviations you've defined will work only in buffers where you enter abbrev mode.
If you find that you like using word abbreviation mode, you may want to make it part of your startup, as described in the following section.
Once you become hooked on using abbreviation mode, it's easiest to incorporate it into your .emacs file. This procedure creates a permanent file of your word abbreviations that is loaded every time you start Emacs. You can also delete abbreviations from this file; we'll discuss how to do so in the next section.
To define word abbreviations and make them part of your startup:
1. Add these lines to your .emacs file:
(setq-default abbrev-mode t)
(read-abbrev-file "~/.abbrev_defs")
(setq save-abbrevs t)
2. Save the .emacs file and reenter Emacs.
Abbrev
appears on the mode line. You may get an error message saying Emacs can't load your abbrev file (understandable if you haven't created the file yet). Ignore this error message; it won't happen again.
3. Type an abbreviation and type C-x a i g or C-x a - following the abbreviation. These commands create a global abbreviation; if you want to create a local abbreviation instead, type C-x a i l. Emacs asks you for the expansion.
4. Type the definition for the abbreviation and press Enter. Emacs expands the abbreviation and will do so each time you type it followed by a space or punctuation mark. You can define as many abbreviations as you want to by repeating Steps 3 and 4.
5. Type C-x C-c to exit Emacs. Emacs asks if you want to save the abbreviations in .abbrev_defs.
6. Type y to save your abbreviations.
After you define some abbreviations and save them, Emacs loads the abbreviations file automatically. When you define word abbreviations in subsequent sessions, Emacs asks again whether you want to save the abbreviations file. Respond with a y to save the new abbreviations you've defined and have them take effect automatically.
If you use word abbreviations frequently, you may define an abbreviation and later change your mind. You can edit the word abbreviation list by typing M-x edit-abbrevs Enter. You can see (but not edit) the list by typing M-x list-abbrevs Enter.
After the list is displayed, use C-k (or any other editing commands) to delete the abbreviations you don't want to use. Because Emacs itself formats this list, don't try to edit lines or add new lines; deleting is about the only operation that's safe. Here's how the abbreviations look when you edit word abbreviations. The file is divided into different sections based on whether the abbreviations are global or local to a particular mode:
(text-mode-abbrev-table)
(lisp-mode-abbrev-table)
(fundamental-mode-abbrev-table)
(global-abbrev-table)
"iwthout" 1 "without"
"prhase" 1 "phrase"
"teh" 1 "the"
"fo" 1 "of"
"eamcs" 2 "Emacs"
"wrok" 1 "work"
"aslo" 1 "also"
"sotred" 1 "stored"
"inforamtion" 1 "information"
"esc" 6 "Esc"
"taht" 1 "that"
"chatper" 1 "chapter"
"adn" 1 "and"
"iwth" 1 "with"
"chpater" 1 "chapter"
"loaction" 1 "location"
"recieve" 1 "receive"
"wart" 1 "World Association for Replicant Technology"
The file is divided into sections by mode. We defined global abbreviations in this case; any abbreviations Flyspell (described earlier in this chapter) creates are local abbreviations and would be listed under the mode in which they were defined.
In this buffer, the first column lists the abbreviations (in this case, mostly misspellings). The second column is for internal record keeping; you don't need to concern yourself with it. The third column provides the definitions of the abbreviations, the word or phrase that Emacs substitutes whenever it sees the abbreviation.
To delete any abbreviation, delete the line for that abbreviation and save the file by typing M-x write-abbrev-file. You can move back to the buffer you were editing before by typing C-x b (a command for working with multiple buffers, discussed in Chapter 4).
You can get rid of word abbreviations completely in one of two ways. First, you can type M-x kill-all-abbrevs Enter. This command disables word abbreviations for the current session.
Second, you can delete the file the abbreviations are in. If you made word abbreviations part of your startup, delete the read-abbrev-file line from your .emacs file.
Usually, Emacs capitalizes abbreviations exactly the way you want. If you run into special situations with abbreviations and capitalization, however, you may wantl to know what's going on behind the scenes. Here are the rules:
• If the abbreviation's definition contains any uppercase letters, Emacs always inserts the definition without changing anything. For example, if you define ora as an abbreviation for O'Reilly Media, O'Reilly will always be capitalized exactly as shown.
• If the abbreviation's definition is all lowercase, Emacs capitalizes according to the following rules:
- If you type all of the letters of the abbreviation in lowercase, Emacs inserts the definition in lowercase.
- If you type any of the letters of the abbreviation in uppercase, Emacs capitalizes the first letter of the first word.
- If you type all of the letters of the abbreviation in uppercase, Emacs capitalizes the first letter of every word, unless the variable abbrev-all-caps is set to t; in this case, it capitalizes all letters.
Table 3-7 shows some examples.
Table 3-7. Word abbreviation capitalization
Abbreviation | Definition | You type: | Expands to: | Because: |
---|---|---|---|---|
lc | lamb chop | lc | lamb chop | lc is lowercase, so lamb chop is lowercase. |
lc | lamb chop | Lc | Lamb chop | There's one capital in Lc, so Lamb is capitalized. |
lc | lamb chop | lC | Lamb chop | There's one capital in lC, so Lamb is capitalized. |
lc | lamb chop | LC | Lamb Chop | LC is all capitals, so both words are capitalized. |
lc | Lamb Chop | lc | Lamb Chop | Capitals in the definition are always unchanged. |
lc | Lamb Chop | LC | Lamb Chop | Capitals in the definition are always unchanged. |
You don't need to remember the rules, but looking them over may help you out if you can't understand how Emacs is capitalizing. In our experience, defining abbreviations in lowercase circumvents most capitalization problems.
Table 3-8 summarizes word abbreviation commands.
Table 3-8. Word abbreviation commands
Keystrokes | Command name | Action |
---|---|---|
M-/ | dabbrev-expand | Complete this word based on the nearest word that starts with this string (press M-/ again if that's not the word you want). |
(none) | abbrev-mode | Enter (or exit) word abbreviation mode. |
C-x a - or C-x a i g | inverse-add-global-abbrev | After typing the global abbreviation, type the definition. |
C-x a i l | inverse-add-mode-abbrev | After typing the local abbreviation, type the definition. |
(none) | unexpand-abbrev | Undo the last word abbreviation. |
(none) | write-abbrev-file | Write the word abbreviation file. |
(none) | edit-abbrevs | Edit the word abbreviations. |
(none) | list-abbrevs | View the word abbreviations. |
(none) | kill-all-abbrevs | Kill abbreviations for this session. |
• You search for a string you can see on the screen, and Emacs can't find it. The most probable explanation is that Emacs is taking into account line breaks and punctuation, and you're not including these in the search string. Use word search, which ignores any line breaks or punctuation, to find the string.
• You get a message that says,
Searching for program: No such file or directory ispell
. You don't have Ispell installed. Ispell is external to Emacs; see Chapter 13 for details on installing Ispell on Mac OS X and Windows.
• You can't see the pop-up menu in Flyspell. You activate this pop-up menu by pointing the mouse at a given word and pressing the middle mouse button. Essentially, you need a three-button mouse to run Flyspell.