HP-UX Admin Man: Time to Save Time in vi
It is very easy to get stuck in a rut, doing the same things the same ways, repeatedly. The purpose of this month's column is to help vi users get out of that rut.
It is very easy to get stuck in a rut, doing the same things the same ways, repeatedly. The purpose of this column is to help vi users get out of that rut. I received many e-mails about the vi columns we ran over the last few months (see "We Got Mail"). Most were to request more vi information. This column is a direct result of those requests, so please, keep any type of subject matter requests coming.
There are advantages and disadvantages to doing things by rote (amazing how close that sounds to "rut"). The advantages are that they are automatic, without thinking, and thus fast. The disadvantage is that you might be doing things in an inefficient manner, and you could be faster by training your fingers to rely on different commands.
We are going to look at some of the more common tasks in vi, and mention what might be time-saving ways of doing things. If you are a good vi user, you will probably be aware of them. Then again, just because you are aware does not mean that you are not out of the rut. Take, for example, simple cursor movement in vi. Most users know that h and l move the cursor left (h) and right (l) by one character. Lesser experienced people might use the arrow keys instead. More experienced people know that the space bar also moves the cursor right, and backspace moves the cursor left. If you want to move the cursor in either direction several places, and you keep tapping these movement keys, you are in a rut. There is probably a faster way, after all, vi was written for performing rapid simple edits in a file. The faster way is to remember that all movement commands in vi can be preceded by a repetition number.
For example, typing 7h will move the cursor 7 places left. The point is that it is usually faster to guess a number of characters, then jump to that location at once, rather than jumping up and down (so to speak) on the movement keys. A helpful part of commands like 22l or 10h is that they won’t wrap across a line. If you guess way too many characters, they just leave the cursor at the end or beginning of a line, instead of wrapping up or down a line, so you can guess away with impunity.
An even faster way to move on a line can be used when you need to move to either the end or beginning. The command ^ will move the cursor to the first non-blank character on the line. Hitting $ moves to the last character on the line. It is often faster to use one of those two as a coarse movement, then do final adjustments with the single character movements. Another little known line movement command set is 0 (that is a zero, not an oh). This moves to the true beginning of line, even if it starts with blanks. You could also use the column command. That is, 1| means the same thing (that is a one followed by a pipe character). The | command can be used to move to specific columns on a line. For example, 25| moves to column 25.
Another way to move efficiently is with the word movement commands. Most people who are familiar with vi knew these word movements when learning vi, but get stuck in the rut of banging on single character movement commands instead. Trust me, it is worth the time to stop and think of the proper command. vi was meant to be a fast editor, but it won’t be without training your fingers to use the commands that make it fast.
To move forward to the end of a word, use e or E. To move back to the beginning of a word, use b or B. To move forward to the beginning of a word, use w or W. All the capital versions of these word movement commands mean the same thing, including punctuation characters. This really makes a difference in efficiency when deleting or copying words, as well as when moving. For example, if the cursor were on the first character in this string: SX-R, and you wanted to change that word for another, you might issue the command cw (or ce). After either command, the string would show as: S$-X meaning that we are changing the "SX" part of the string, not the rest. If we had issued either cE or cW, we would be changing the entire string, so it would have changed to SX-$. If you are not familiar with the change (c) command, you can type in as much or as little as you want until you hit the escape key. All text up to the $ will disappear, either when you type over it, or when you hit escape.
If you are not doing it already, start remembering to precede movements by words with numbers. Again, just guessing that you want to move five words and hitting 5W, then using another word forward or back will probably be faster than banging on W. It does not take much practice to get so that you can guess accurately.
As far as speed when moving up and down in the file, remember to use numeric modifiers before the vertical movements, and you will be climbing out of that rut. For example, use 15j to move down 15 lines instead of hitting the j key 15 times. If you are moving more than a few lines, it is always faster to guess a number of lines, then zero in. You can also move vertically with the + and – commands. They move to the beginning of the target line, whereas the j and k commands try to maintain the column (if there are enough characters on the line). Control p and control j are the same as k and j, respectively.
Another shortcut that is often overlooked (or forgotten, or ignored) when moving around in a file is the move by sentence or paragraph commands. Parenthesis move the cursor forward to the end of a sentence or back to the beginning of a sentence. The ) obviously moves forward, the ( moves back. Using braces moves by paragraph. A paragraph is defined as ending with an empty line, so } will move you to the next blank line in the file. Another little-known movement command is useful only in certain files. If the file has any braces as the true first character on a line, you can jump to those locations using [[ or ]], depending on if you want to move up or down in the file.
The final time saver for this column is the "repeat last edit" command. I hope all you vi users are already using this, because if you are not, you are really wasting some time. If you need to make a deletion, insertion or change repeatedly in a file, you only need to do it once. Take, for example, if I want to add some text in several places in a file. Move the cursor to the first location, and use the appropriate command (a A i I o O) to insert (or append, or open a new line, whatever...) the text. Now just move the cursor to the next location (using some efficient method as mentioned above), and hit the period key (dot). Dot means redo the last edit, including whatever text you might have typed in.
So, get out of the rut. Start reaching out for forgotten, or unknown commands to make your editing faster.