Unix for Mac OS X 10.4 Tiger: Visual QuickPro Guide (2nd Edition)
Besides the basics of entering text, saving, and quitting, you often use vi to change text that has already been saved. Sometimes you will simply want to delete text; other times you will want to alter existing text.
Deleting text is simpler, so we'll look at that first.
Deleting text
You can delete text from either edit mode or command mode.
The basic rule for deleting text in edit mode is: You can delete text by pressing
The version of vi in Mac OS X 10.3 and later allows you to use edit mode to delete any text in the file, and it will "word-wrap" backward past the start of the line to the previous line.
From command mode, you may delete any text in the file. Any text deleted while in command mode is saved temporarily in memory (similarly to the way the traditional Mac concept of the Clipboard works) and is available for pasting. See the section "Copy and paste," later in this chapter.
To delete text from edit mode:
- Press
It's that simple. No need to press
.
To delete one character from command mode:
- x
The x command (for excise ) deletes the character under the cursor. You do not press
, just type the x . There are many ways to delete text from command mode. Table 6.3 summarizes the most important methods .
Table 6.3. Deleting Text from Command Mode in vi
T O D ELETE T HIS
T YPE T HIS
Character under the cursor
x
Two characters
2x
From here to end of line
d$
This whole line
dd
Five lines (including this one)
d5
From this line to end of file
dG
From this line to line 27
d27G
From here forward to string
d/string
From here back to string
d?string
From cursor to end of word
dw
To delete one line of text from command mode:
- dd
The dd command deletes the current line (the line the cursor is on). Do not press
.
Notice how most of the methods shown in Table 6.3 follow a pattern consisting of the d command followed by something that indicates how much text to delete. You do not press
Changing text
You can change text in either command or edit mode.
To change text in edit mode, press
Changing text from command mode is usually a matter of selecting a range of text with a command that switches you into edit mode; then what you type after switching replaces the selected text. This is very much like selecting text with the mouse in a GUI word processor: As soon as you type something after making the selection, the selected text disappears.
It is important to note that many of the text changing examples below combine the change-text command ( c ) with one of the navigation techniques we talked about earlier in this chapter. For example, c24G actually does the following:
| 1. | Deletes all the text from the current cursor position through line 24 (inclusive).
|
| 2. | Switches you into edit mode.
|
So whatever you type next will replace the deleted text (which is available for pasting with the p command; see the section "Copy and paste").
To change from the cursor position to the end of the word:
| 1. | cw
Do not press
The word will disappear, and whatever you type next will be inserted where the word was.
Figure 6.14 shows the text before using the cw command, and Figure 6.15 shows what happens when you type cw . Basically, the word disappears and you are placed into insert mode. (In some versions of vi , the word does not disappear until you begin typing the replacement. Instead, the last character of the word changes to a $ when you type cw , to indicate that it is about to be replaced .)
Figure 6.14. Example of text before typing the cw command to change one word in command mode.
Figure 6.15. After the cw command is typed, the word disappears.
|
| 2. | Enter the new text.
In Figure 6.16 we show what you would see if you typed George .
Figure 6.16. Whatever you type next replaces the selected text.
|
| 3. | Press
|
To change text from the cursor to the end of the line:
- c$
The c$ command means "change to end-of-line." This command removes the text from the current position to the end of the current line and puts you into edit mode. (Again, in some versions of vi, the text will not disappear until you start typing the replacement text.)
-
There is a shortcut for this command C (an uppercase C ).
To change text from the cursor to the next occurrence of a given string:
| 1. | c/ string
You must press
|
| 2. | Type the replacement text.
|
-
You can also search backward, so that c? string selects text from the current cursor position to the previous occurrence of string (toward the top of the file).
To change text from the current line to a specific line number:
| 1. | c5G
Of course, you replace 5 with whatever line number you want. This selects the text from the current line to the specified line numberall the lines are included. The screen updates as soon as you type the G , showing the selected lines deleted and leaving you in edit mode. Figures 6.17 and 6.18 show text before and after the c5G command.
Figure 6.17. Example of text before using the c5G command.
Figure 6.18. After you type c5G , the selected lines are removed.
|
| 2. | Type the replacement text.
Remember that you are still in edit mode when you are done.
|
Sometimes you want to change just one character. Here is an easy way to change one character without having to go into edit mode and back.
To change just the character under the cursor:
| 1. | r
The r command selects just the character under the cursor. Do not press
|
| 2. | Type the replacement character.
Unlike most other editing commands, r lets you stay in command mode as you do thisyou are not left in insert mode when done.
|
To flip the case of the character that is under the cursor:
- ~
Typing ~ (the tilde) switches the character under the cursor from upper- to lowercase, or vice versa. This command does not switch you into edit mode. Again, do not press
.
The version of vi in Mac OS X has multiple levels of undothat is, you can undo not only the last change you made, but each change going back to when you opened the file for editing.
To undo the last change:
- u
Do not press
. The u command undoes the last edit you made anywhere in the file, even if the cursor has moved since the change was made, and even if you have saved the change. You can use this command several times in a row to take advantage of multiple levels of undo.
To revert to the last saved version:
- :e!
Then press
. vi reloads the last saved version of the file.
Copy and paste
vi supports fairly easy copy-and-paste functions. Like the commands for changing text, the copy command ( y for yank ) may be combined with many of the movement commands to select ranges of text and copy them.
To copy the current line:
- y
Then press
. This yanks the current line into the vi equivalent of the Clipboard; it's called the buffer and is totally separate from the regular Mac Clipboard.
Once you have yanked text, you can paste it.
To paste the contents of the buffer:
- p
Do not press
. The p (for paste ) command inserts the contents of the buffer at the cursor. If the buffer's content is one or more lines, the text is inserted below the current line.
If the buffer's content is less than a full line, it is inserted into the current line to the right of the cursor.
-
The uppercase P command also pastes, but it pastes either above the current line or to the left of the cursor.
To paste multiple copies simultaneously :
- Precede the p command with a number.
For example, 10p pastes ten copies of the buffer's content.
To copy several lines into the buffer:
- Precede the y command with a number.
For example, to copy the current line plus four more lines (five lines total), type 4y .
To paste deleted text:
- Any deleted text may be pasted using the p and P commands.
There is no separate "cut" command in vi . All deleted text is "cut" and available for "pasting"this includes text deleted using d$ , dw (delete to the end of the word), 10d
Search and replace
Search and replace in vi is done in command mode using commands on the status line. Like the commands to save and quit, the search and replace commands all begin with a colon , which drops the cursor to the command line, and all end with pressing
(To simply search for a string of text without replacing it, see "Navigating by searching for text," earlier in this section.)
The general format of the search-and-replace command is
:[optional range of lines]s/Old/New/
You will always type the colon, the s , and the three slashes . Old and New may be patterns using a simple subset of the regular expressions you learned in Chapter 4, "Useful Unix Utilities."
To create a general search-and-replace command:
| 1. | Type a colon to drop to the vi command line.
|
| 2. | As an option, you can enter a range of lines to be affected. This is a pair of specifiers separated by a comma. For example, 23,57 indicates lines 23 through 57 (inclusive). Use the specifier . for "the current line" and $ for "the end of the file." For example, use .,23 to indicate the current line through line 23 (either up or down from the current line without wrapping around the top or bottom of the file). Using .,$ would mean "from the current line through the end of the file." If you do not specify a range, only the current line is affected (the same as a range of .,. ).
|
| 3. | Type s (for substitute ).
|
| 4. | Type a slash: /
|
| 5. | Enter the target (search) pattern.
|
| 6. | Type another slash.
|
| 7. | Enter the replacement pattern.
|
| 8. | Type a third slash.
|
| 9. | Enter any optional modifiers, such as g , for "global on each line."
|
| 10. | Press
|
Here is a series of increasingly complex search-and-replace commands.
To replace the first Foo with Bar on the current line:
- :s/Foo/Bar/
This is the simplest form of a search and replace in vi . Only the first occurrence of Foo on the current line will be replaced with Bar .
To replace every Foo with Bar on the current line:
- :s/Foo/Bar/g
In this case you are adding the g modifier so that the change affects the line "globally"; that is, every occurrence of the first string is replaced.
To replace every occurrence in the file:
- :1,$s/Foo/Bar/g
When you add a range of lines, the change affects more than the current line. In this case the range 1,$ means from the first line in the file through the end of the file. If you leave off the g modifier, only the first occurrence of Foo on each line will be changed.
-
The range need not start at line 1. A range of 55,$ would affect lines 55 through the end of the file.
To replace from one line to another line:
- :15,23s/Foo/Bar/g
Here the range is from line 15 through line 23.
To replace from the current line to the end of the file:
- :.,$s/Foo/Bar/g
Here the range begins with the . character, which means "the current line"that is, the line the cursor was on before you typed the colon.
To replace from the current line and five more lines below it:
- :.,+5s/Foo/Bar/g
The +5 in this range means "the current line plus five more below it."
To replace from the current line and seven more lines above it:
- :.,-7s/Foo/Bar/g
The -7 here means "the current line plus seven lines above."
To replace text only when it occurs at the start of a line:
- Put the ^ character at the beginning of the target string.
This command replaces Foo only when it occurs as the very first thing on a line:
:1,$s/^Foo/Bar/
(No need for the g , since you are only looking for Foo at the start of each line.)
To replace text only when it occurs at the end of a line:
- Append $ to the target string.
This command replaces Foo only when it occurs as the very last thing on a line:
:1,$s/Foo$/Bar/
To include a / in either the target or replacement string:
- You use the backslash ( \ ) to escape the / character. By escape we mean that you remove the special meaning of the following character. This is similar to how you learned to use backslashes in Chapter 2 to escape spaces in command-line arguments. (The term escape in this context has nothing to do with the
key.) If you wanted to replace every occurrence of /usr with /usr/local , you would use the following:
:1,$s/\/usr/\/usr\/local/g
There are three un-escaped slashes in that command: The first, third, and sixth (last) / characters are not escaped in this example.
vi has a great many more commands available. Table 6.4 shows a few of the most useful ones, and the sidebar " vi Cheat Sheets" tells you where to find some handy guides to keep near your keyboard.
Table 6.4. More vi Commands
| C OMMAND | W HAT I T D OES |
|---|---|
| J | Joins the next line to this one. |
| % | Finds the matching closing parenthesis or brace . Position cursor on a (){}[] first. |
| :set ruler | Displays row#,column#. |
| :set all | Shows current settings. |
| :set ai | Turns on auto-indentation. |
| :set noai | Turns off auto-indentation. |
| :set number | Shows line numbers on left. |
| :set nonumber | Turns off line numbers. |
| :set wm=5 | Sets wrap margin to five characters from right edge. |
-
All of the above :set commands may be placed (without the : ) in your ~/.exrc file to be executed every time you start vi . For example, you might have the following in your ~/.exrc file:
set ai set ruler set wm=7
To repeat the last editing command:
- .
The . command (that's just a period without pressing
) repeats the last direct command that changed text. A direct command is one that did not use the : to drop to the status line.