Vi IMproved - Vim - PDF Free Download (2024)

The CTRL-G command.

Sometimes you will see a split column number (for example, col 2–9).This indicates that the cursor is positioned on character 2. But because character one is a tab, the screen column is 9. Figure 2.8 shows the results of a typical CTRL-G command.

Scrolling Up and Down The CTRL-U command scrolls up half a screen of text. (Up in this case is backward in the file; the text moves down on the screen. Don’t worry if you have a little trouble remembering which end is up. Most programmers have the same problem.) The CTRL-D command scrolls you down half a screen. Figure 2.9 shows how these two commands work. A dozen, a gross, and a score, Plus three times the square root of four Divided by seven, Plus five time eleven, Equals nine squared plus zero, no more.

-----A dozen, a gross, and a score, Plus three times the square root of four Divided by seven, Plus five time eleven, Equals nine squared plus zero, no more.

-----A computer, to print out a fact, Will divide, multiply, and subtract.

A dozen, a gross, and a score, Plus three times the square root of four Divided by seven, Plus five time eleven, Equals nine squared plus zero, no more. -----A computer, to print out a fact, Will divide, multiply, and subtract.

If buckets of bits Take one down, short it to ground FE buckets of bits on the bus

-----A computer, to print out a fact, Will divide, multiply, and subtract. But this output can be No more than debris, If the input was short of exact. ------

Results of the CTRL-U and CTRL-D commands.

Deleting Text As you learned in Chapter 1, the dd command deletes a line.The dw command deletes a word.You may recognize the w command as the move word command. In fact, the d command may be followed by any motion command, and it deletes from the current

location to the place where the cursor winds up. (Therefore, we say the syntax of the d command is dmotion.) The 3w command, for example, moves the cursor over three words.The d3w command deletes three words, as seen in Figure 2.10. (You can write it as d3w or 3dw; both versions work the same.) To err is human, To really foul up you need a computer. d3w (three words) To err is human, To realyou need a computer.

The d3w command.

The $ command moves to the end of a line.The d$ command deletes from the cursor to the end of the line, as seen in Figure 2.11. A shortcut for this is the D command. To err is human, To really foul up you need a computer. d$ ($ _ go to the end of line) To err is human, To real

The d$ command.

Where to Put the Count (3dw or d3w) The commands 3dw and d3w delete three words. If you want to get really picky about things, the first command, 3dw, deletes one word three times; the command d3w deletes three words once.This is a difference without a distinction. You can actually put in two counts, however (for example, 3d2w).This command deletes two words, repeated three times, for a total of six words.

Changing Text The c command changes text. It acts just like the d command, except it leaves you in insert mode. For example, cw changes a word. Or more specifically, it deletes a word and then puts you in insert mode. Figure 2.12 illustrates how this command works. There is a saying that for every problem there is an answer that’s simple, clear, and wrong.That is the case with the example used here for the cw command.The cmotion command works just like the dmotion command, with one exception: the cw and dw commands.Whereas cw deletes the text up to the space following the word (and then enters insert mode), the dw command deletes the word and the space following it.

To err is human, To really foul up you need a computer.

) To err is human, To really foul up you need a computer.

cwscrew<Esc> c—Change command w—Change one word screw—The word we are inserting <Esc>—Ends insert mode

Figure 2.12

How cw works.

The cc command works on the entire line.That is, it deletes the line and then goes into insert mode. In other words, cc works on the current line just like dd. Likewise, c$ or C change from the cursor to the end of the line.

The . Command The . command is one of the most simple yet powerful commands in Vim. It repeats the last delete or change command. For instance, suppose you are editing an HTML file and want to delete all the tags.You position the cursor on the first < and delete the with the command df>.You then go to the < of the next and kill it using the . command.The . command executes the last change command (in this case, df>).To delete another tag, position the cursor on the < and press the . command. Figure 2.13 illustrates how this can work.

To generate a table of contents all the C program files in your current working directory, use the command:

 $ ctags *.c 

Figure 2.13

j

—down a line —start of line f< —find “<” of df>—delete to “>” f< —find “<” of “” . —repeat last change (df>) j> —down, start of line f> —find “<” of . —repeat last change (df>) f< —find “<” of “” . —repeat last change (df>)

Using the . command.

Replacing Characters

Joining Lines The J command joins the current line with the next one. A space is added to the end of the first line to separate the two pieces that are joined, as illustrated by Figure 2.14. If a count is specified, the count lines are joined (minimum of two). This is a test

This is a test

J

This is a test with two lines

This is a test with two lines

3J

Figure 2.14

The J command.

Replacing Characters The rx command replaces the character under the cursor with x. Figure 2.15 shows how you can use the r command to replace a z with an s. The r command can be preceded with a count, indicating the number of characters to be replaced. In Figure 2.16, we go to the beginning of line (the ^ command) and execute 5ra to replace the first five characters with a. This iz a test. rs

This is a test.

Figure 2.15

The replace (r) command.

This is a test. 5ra

aaaaais a test.

Figure 2.16

Replace (r) command with count.

Note

The r command treats <Enter> in a special way. No matter how big the count is, only one <Enter> is inserted. Therefore, 5ra inserts five a characters, whereas 5r<Enter> replaces five characters with one <Enter>.

23

24

Chapter 2 Editing a Little Faster

Be careful where you place the count.The 5rx command replaces five characters with the character x, whereas r5x replaces the character under the cursor with 5 (r5) and then deletes a character (x).

Changing Case The ~ command changes a character’s case. It changes uppercase to lowercase and vice versa. If a count is specified, the count characters are changed. Figure 2.17 contains examples. now is the time. . . .

“~”

NOW

IS the TIME. . . .

“14~” Now

is the time. . . .

Figure 2.17

Now is THE time. . . .

Use of the ~ command.

Keyboard Macros The . command repeats the preceding change. But what if you want to do something more complex than a single change? That’s where the keyboard macros come in.The qcharacter command records keystrokes into the register named character. (The character must be between a and z.) To finish recording, just type a q command.You can now execute the macro by typing the @character command. (This can be preceded by a count, which will cause the macro to be executed that number of times.) Take a look at how to use these commands in practice.You have a list of filenames that look like this: stdio.h fcntl.h unistd.h stdlib.h

And what you want is the following: #include “stdio.h” #include “fcntl.h” #include “unistd.h” #include “stdlib.h”

You start by moving to the first character of the first line. Next you execute the following commands: qa Start recording a macro in register a. ^

Move to the beginning of the line.

i#include “<Esc>

Insert the string #include " at the beginning of the line.

$

Move to the end of the line.

Digraphs

a”<Esc>

Append the character double quotation mark (“) to the end of the line.

j

Go to the next line.

q

Stop recording the macro.

Now that you have done the work once, you can repeat the change by typing the command @a. Alternatively, because you have three lines to go, you can change them using the command 3@a. Figure 2.18 shows how to define and then execute a macro. stdio.h fcntl.h unistd.h stdlib.h

Start

#include “stdio.h” fcntl.h unistd.h stdlib.h

qa-Record into register a -Go to the geginning of a line i#include ‘<Esc>-Insert text a“<Esc>-Insert more text j-Go to the next line q-Stop macro

#include “stdio.h” #include “fcntl.h” unistd.h stdlib.h

@a-Execute macro “a”

#include “stdio.h” #include “fcntl.h” #include “unistd.h” #include “stdlib.h”

2.18

2@a-Execute macro “a” twice

Defining and using a macro.

Digraphs Some characters are not on the keyboard—for example, the copyright character (©). To type these letters in Vim, you use digraphs, where two characters represent one.To enter a ©, for example, you type CTRL-Kc0. To find out what digraphs are available, use the following command: :digraphs

The Vim editor will display the digraph-mapping table, as seen in Figure 2.19. This shows, for example, that the digraph you get by typing CTRL-K~! is the character (¡).This is character number 161. Warning The digraphs are set up assuming that you have a standard ISO-646 character set. Although this is an international standard, your particular display or printing system might not use it.

25

26

Chapter 2 Editing a Little Faster

~ :digraphs ~! ¡ 161 c| ¢ 162 $$ £ 163 || | 166 pa § 167 "" ¯¯ 168 –, ¬ 172 –– – 173 rO ® 174 222 178 333 179 ´´ ´ 180 ,, ¸ 184 111 185 o– º 186 ~? ¿ 191 A` À 192 343/4 190 A" Ä 196 A@ Å 197 AA Å 197 E´ É 201 E^ Ê 202 E" Ë 203 N~ Ñ 209 I" I ¨ 207 D- D 208 /\ × 215 O~ Õ 213 O" Ö 214 U" Ü 220 U´ Ú 218 U^ Û 219 a´ á 225 a^ â 226 a` à 224 aa å 229 ae æ 230 c, ç 231 e" ë 235 i` ì 236 i´ í 237 o´ ó 243 n~ ñ 241 o` ò 242 o/ ø 248 :- ÷ 247 oe ÷ 247 y´ y´ 253 ip p 254 u" ü 252 Press RETURN or enter command to continue

Figure 2.19

ox ¤ 164 cO © 169 –= ¯ 175 ju µ 181 >> » 187 A´ Á 193 AE Æ 198 I` Ì 204 O` Ò 210 OE × 215 ´ 221 Y´ Y a~ ã 227 e` è 232 i^ î 238 o^ ô 244 u` ù 249 y" ÿ 255

e= ¤ 164 a- ª 170 ~o ° 176 pp ¶ 182 141/4 188 A^ Â 194 C, Ç 199 I´ I ´205 O´ Ó 211 O/ Ø 216 Ip p 222 a" ä 228 e´ é 233 i" ï 239 o~ õ 245 u´ ú 250

Digraph-mapping table.

Y– ¥ 165 << « 171 +– ± 177 ~. • 183 121/2 189 A~ Ã 195 E` È 200 I^ I ˆ206 O^ Ô 212 U` Ù 217 ss ß 223 a@ å 229 e^ ê 234 d- ∂ 240 o" ö 246 u^ û 251

Searching

T

HIS CHAPTER INTRODUCES YOU TO THE VARIOUS Vim

search commands.The basic

search commands in Vim are rather simple, which means that you can get started with searching fairly easily. In this chapter, you learn about the following: n

Simple forward searches

n

Search options

n

Incremental searches

n

Changing directions

n

Basic regular expressions

Simple Searches To search for a string, use the /string command.To find the word include, for example, use the command /include. An <Enter> is implied at the end of this command. (Any time the cursor jumps to the bottom of the screen and you type something, you must end it with <Enter>.) Note:The characters .*[]ˆ%/\?~$ have special meaning. If you want to use them in a search you must put a \ in front of them. Example: to find . use the search string\.. The cursor now moves to the i of include, as seen in Figure 3.1.

28

Chapter 3 Searching

/******************************************************** * cd-speed * Report the speed of a cd-rom * (Also works on hard drives and other * devices) * * Usage: * cd-speed <device> * ********************************************************/ #include

#include /include

Figure 3.1

* * * * * * * *

Searching for include.

To find the next include, use the command /<Enter>.The cursor now moves to the next occurrence of the string, as shown by Figure 3.2. /******************************************************** * cd-speed * Report the speed of a cd-rom * (Also works on hard drives and other * devices) * * Usage: * cd-speed <device> * ********************************************************/ #include

#include /include

Figure 3.2

* * * * * * * *

Search again, forward (/<Enter>).

Another way to find the next match is with the n command.This command does the same thing as /<Enter>, but does it with one less keystroke. Figure 3.3 shows the result of this search. * cd-speed * Report the speed of a cd-rom * (Also works on hard drives and other * devices) * * Usage: * cd-speed <device> * ********************************************************/ #include

#include #include

Figure 3.3

* * * * * * * *

Search again (n).

Both the /<Enter> and n commands can have a count specified. If there is a count, the command searches for the count number of matches from the current location.

Search History The search command has a history feature. Suppose, for example, that you do three searches: /one /two /three

Searching Options

Now let’s start searching by typing a simple / without pressing <Enter>. If you press

,Vim puts /three on the prompt line. Pressing <Enter> at this point searches for three. If you do not press <Enter>, but press instead, Vim changes the prompt to /two. Another command moves you to /one. In other words, after you do a number of searches, you can use the and keys to select one of your recent searches.

Searching Options Many different options control the way you perform a search.This section discusses a few of them.

Highlighting The following command causes Vim to highlight any strings found matching the search pattern: :set hlsearch

If you turn on this option and then search for include, for example, the results in all the include strings are highlighted, as seen in Figure 3.4. To turn off search highlighting, use this command: :set nohlsearch

To clear the current highlighting, use the following command: :nohlsearch

Search highlighting is now turned off; matched text will not be highlighted. However, the highlighting will return when you use a search command.

Incremental Searches By default, Vim uses the traditional search method:You specify the string, and then Vim performs the search.When you use the following command, the editor performs incremental searches: :set incsearch

* devices) * * Usage: * cd-speed <device> * ********************************************************/ #include

#include #include #include <stdlib.h> #include <stdio.h> #include <sys/ioctl.h>

Figure 3.4

The 'hlsearch' option.

* * * * *

29

30

Chapter 3 Searching

The editor starts searching as soon as you type the first character of the string. Each additional character further refines the search. Suppose, for example, that you want to search for ioctl.h, but this time you want to use an incremental search. First, you turn on incremental searching. Next, you start the search by typing the /i command. Figure 3.5 shows how the editor searches for the first i and positions the cursor on it. * Usage: * cd-speed <device> * ********************************************************/ #include

#include #include #include <stdlib.h> #include <stdio.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/mtio.h> /i

Figure 3.5

* * *

Results after /i.

You continue the search by typing an o.Your search now is /io, so the editor finds the first io, as seen in Figure 3.6. This is still not the place you want, so you add a c to the search, resulting in the /ioc command.The Vim editor advances, as illustrated in Figure 3.7, to the first match of ioc. This is what you want to find, so you press <Enter>, and you’re there. To turn off incremental searches, use the following command: :set noincsearch * Usage: * cd-speed <device> * ********************************************************/ #include

#include #include #include <stdlib.h> #include <stdio.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/mtio.h> /io

Figure 3.6

Incremental search after /io.

* Usage: * cd-speed <device> * ********************************************************/ #include

#include #include #include <stdlib.h> #include <stdio.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/mtio.h> /ioc

Figure 3.7

* * *

Incremental search after /ioc.

* * *

Changing Direction

Searching Backward The reverse search command (?) searches backward.The n command repeats the last search. If a reverse search was the last one used, the n command searches in the reverse direction. If the last search was a forward search, the n command searches forward. Figure 3.8 shows how the ? and n commands can work together. #include <sys/fcntl.h> #include <sys/time.h> #include <errno.h>

2) n 1) ?unsigned Start

// Read at most 10MB const unsigned int MAX_READ = (10 * 1024 * 1024); // Size of a buffer const unsigned int BUF_SIZE = (62 * 1024);

3) n

// Buffer to be written static unsigned char buffer [BUF_SIZE];

Figure 3.8

?

and n commands.

Changing Direction Suppose you start a forward search for unsigned using the /unsigned command.You can turn around and search in the reverse direction by using the ? command.The n command repeats the search in the same direction.The N command reverses the direction on the search and repeats it. To make things a little clearer, line numbering has been turned on using the following command: :set number

In this example, we use the following search commands: Command

Meaning

Result

/unsigned

Forward search for unsigned

Line 24

n

Repeat search in the same (forward) direction

Line 26

n

Search again

Line 29

?

Reverse search for the preceding

Line 26

string (unsigned) N

Reverse direction and repeat the search

Line 29

31

32

Chapter 3 Searching

Figure 3.9 shows the /unsigned command used to perform a search.The n command was used twice to go the next occurrences of the string.Then we reversed course with a ? command (which always goes backward.) Finally, we reverse course again with the N command. Figure 3.9 shows this tortured path. /unsigned

19 #include <sys/fcntl.h> 20 #include <sys/time.h> 21 #include <errno.h> 22 23 // Read at most 10MB 24 const unsigned int MAX_READ = (10 25 // Size of a buffer 26 const unsigned int BUF_SIZE = (62 27 28 // Buffer to be written 29 static unsigned char buffer[BUF_S

n n ? N

:set number

Figure 3.9

Different kinds of search commands.

Basic Regular Expressions The Vim editor uses regular expressions to specify what to search for. Regular expressions are an extremely powerful and compact way to specify a search pattern. Unfortunately, this power comes at a price because regular expressions are a bit tricky to specify. Let’s start with the simple stuff. In a regular expression, the normal letters match themselves. So the regular expression Steve will match Steve.

The Beginning (^) and End ($) of a Line The ^ character matches the beginning of a line. (It is no coincidence that this is also the command to move to the beginning of the line.) The expression include matches the word include anywhere on the line. But the expression ^include matches the word include only if it is at the beginning of a line. The $ character matches the end of a line.Therefore, was$ finds the word was only if it is at the end of a line. Figure 3.10, for example, shows a search for the pattern the with highlighting enabled.

Dumb user tricks At one university the computer center was experience trouble with a new type of computer terminal. Seems that the professors loved to put papers on top of the equipment, covering the ventilation holes. Many terminals broke down because they became so hot that the solder holding one of the chips melted and the chip fell out. The student technicians were used to this problem. One day a technician took the back off a terminal /the

Figure 3.10

Searching for the.

Basic Regular Expressions

Next you see what happens when searching for the regular expression ^the.The results, as seen in Figure 3.11, show that only two occurrences, both of which begin lines, are highlighted. Finally a search for the$. As you can see from Figure 3.12, only one the ends a line. If you want to search for a line consisting of just the word the, use the regular expression ^the$.To search for empty lines, use the regular expression ^$.

Dumb user tricks At one university the computer center was experience trouble with a new type of computer terminal. Seems that the professors loved to put papers on top of the equipment, covering the ventilation holes. Many terminals broke down because they became so hot that the solder holding one of the chips melted and the chip fell out. The student technicians were used to this problem. One day a technician took the back off a terminal /^the

Figure 3.11

Searching for ^the.

Dumb user tricks At one university the computer center was experience trouble with a new type of computer terminal. Seems that the professors loved to put papers on top of the equipment, covering the ventilation holes. Many terminals broke down because they became so hot that the solder holding one of the chips melted and the chip fell out. The student technicians were used to this problem. One day a technician took the back off a terminal /the$

Figure 3.12

Searching for the$.

Match Any Single Character (.) The character . matches any single character. For example, the expression c.m matches a string whose first character is a c, whose second character is anything, and whose the third character is m. Figure 3.13 shows that the pattern matched the com of computer and the cam of became.

At one university the computer center was experience trouble with a new type of computer terminal. Seems that the professors loved to put papers on top of the equipment, covering the ventilation holes. Many terminals broke down because they became so hot that the solder holding one of the chips melted and the chip fell out. The student technicians were used to this problem. One day a technician took the back off a terminal expecting to find a loose chip and instead found a /c.m

Figure 3.13

Special character ..

33

34

Chapter 3

Searching

Matching Special Characters Most symbols have a special meaning inside a regular expression.To match these special symbols, you need to precede them with a backslash (\).To find the. (period), for example, use the string the\..

Regular Expression Summary The following list assumes that the ‘magic’ option is on (the default). x

The literal character x

^

Start of line

$

End of line

.

A single character

\character

Turns off the special meaning of many characters, gives special meaning to a few others

Text Blocks and Multiple Files

T

HIS CHAPTER SHOWS YOU HOW TO DEAL

with larger text blocks.This includes the

commands that enable you to define a large text block as well as perform cut, paste, and copy operations. With most editors, you can just cut and paste. However, the Vim editor has the concept of a register.This enables you to hold data for multiple cut, copy, or paste operations. Most other editors are limited to a single cut/paste clipboard.With the Vim registers you get more than 26 clipboards. One of the strengths of UNIX is the number of text manipulation commands it provides.This chapter shows you how to use the filter command to take advantage of this power to use UNIX filters to edit text from within Vim. Up until now, you have worked with single files in this book.You will now start using multiple files.This will enable you to perform the same edits on a series of files, and to cut and paste between files. This chapter discusses the following topics: Simple cut-and-paste operations (in Vim terms, delete and put) Marking locations within the text Copying text into a register using the yank commands Filtering text Editing multiple files n

n

n

n

n

36

Chapter 4 Text Blocks and Multiple Files

Cut, Paste, and Copy When you delete something with the d, x, or another command, the text is saved.You can paste it back by using the p command. (The technical name for this is a put). Take a look at how this works. First you will delete an entire line with the dd command, by putting the cursor on the line you want to delete and pressing dd. Now you move the cursor to where you want to place the line and use the p (put) command. The line is inserted on the line following the cursor. Figure 4.1 shows the operation of these commands. Because you deleted an entire line, the p command placed the text on the line after the cursor. If you delete part of a line (a word with the dw command, for instance), the p command puts it just after the character under the cursor (see Figure 4.2). Line 1 Line 2 Line 3 ~ ~ <, 21C written

dd

Line 1 Line 3 ~ ~ ~

(Deletes line)

Figure 4.1

p

(Paste after cursor.)

Line 1 Line 3 Line 2 ~ ~

Deleting (cutting) and putting (pasting).

We will delete the word in the middle

dw (delete word and the space after it)

We will the word in the middle p

We will tdelete he word in the middle Deleted text “delete” inserted after cursor

Figure 4.2

Deleting a word and putting back again.

Marks

Character Twiddling Frequently when you are typing, your fingers get ahead of your brain.The result is a typo such as teh for the.The Vim editor makes it easy to correct such problems. Just put the cursor on the e of teh and execute the command xp. Figure 4.3 illustrates this command.This works as follows: x

Deletes the character ‘e’ and places it in a register.

p

Puts the text after the cursor, which is on the ‘h’. teh

x—delete the character

th

p—paste character after the cursor the

Figure 4.3

Character twiddling with xp.

More on “Putting” You can execute the p command multiple times. Each time, it inserts another copy of the text into the file. The p command places the text after the cursor.The P command places the text before the cursor. A count can be used with both commands and, if specified, the text will be inserted count times.

Marks The Vim editor enables you to place marks in your text.The command ma marks the place under the cursor as mark a.You can place 26 marks (a through z) in your text. (You can use a number of other marks as well.) To go to a mark, use the command `mark, where mark is the mark letter (and ` is the backtick or open single-quote character). The command ‘mark (single quotation mark, or apostrophe) moves you to the beginning of the line containing the mark.This differs from the `mark command, which moves you to the marked line and column. The ‘mark command can be very useful when deleting a long series of lines.To delete a long series of lines, follow these steps: 1. Move the cursor to the beginning of the text you want to delete. 2. Mark it using the command ma. (This marks it with mark a.) 3. Go to the end of the text to be removed. Delete to mark a using the command d’a. Note:There is nothing special about using the a mark. Any mark from a to z may be used.

37

38

Chapter 4 Text Blocks and Multiple Files

There is nothing special about doing the beginning first followed by the end.You could just as easily have marked the end, moved the cursor to the beginning, and deleted to the mark. One nice thing about marks is that they stay with the text even if the text moves (because you inserted or deleted text above the mark. Of course, if you delete the text containing the mark, the mark disappears.

Where Are the Marks? To list all the marks, use the following command: :marks

Figure 4.4 shows the typical results of such a command. The display shows the location of the marks a through d as well as the special marks: ‘, “, [, and ]. Marks a through d are located at lines 1, 8, 14, and 25 in the file. The special marks are as follows: '

The last place the cursor was at line 67 of the current file

"

Line 1 (we were at the top of the file when last closed it)

[

The start of the last insert (line 128)

]

The end of the insert (line 129)

To view specific marks, use this command: :marks args

Replace args with the characters representing the marks you want to view. * the data from an input * (.c) file. */ struct in_file_struct { :marks mark line col file/text ´ 67 0 *^I^I^I into the "bad" list^I^I* a 1 0 #undef USE_CC^I/* Use Sun's CC com b 8 1 * Usage:^I^I^I^I^I^I* c 14 1 *^I^I^I (default = proto_db)^I^I d 25 1 *^I––quote^I^I^I^I^I^I* " 1 0 #undef USE_CC^I/* Use Sun's CC com [ 128 42 * in_file_struct –– structure that ] 129 12 * the data from an input Press RETURN or enter command to continue

Figure 4.4

:marks.

Yanking For years, I used a simple method for copying a block of text from one place to another. I deleted it using the d command, restored the deleted text with the p command, and then went to where I wanted the copy and used the p to put it into the text.

Yanking

There is a better way. The y command “yanks” text into a register (without removing it from the file).The general form of the y command is ymotion. It works just like the delete (d) command except the text is not deleted. And the shorthand yy yanks the current line into the buffer. (Note: Most other editors call this a “copy” operation.) Take a look at how you can use this command to duplicate a block of text. First go to the top of the text to be copied and mark it with ma.Then go to the bottom and do a y’a (yank to mark a). Now go to where the copied text is to be inserted and put it there using the p command. Figure 4.5 shows these commands in action.

Yanking Lines The Y command yanks a single line. If preceded by a count, it yanks that number of lines into the register.You might have expected Y to yank until the end of the line, like D and C, but it really yanks the whole line. Line 1 Line 2 (ma line) Line 3 Line 4 (y'a done here) Line 5 Line 6 Line 7 ~ ~ ~ ~ ~

1) Place mark a (ma)

Line 1 Line 2 (ma line) Line 3 Line 4 (y'a done here) Line 5 Line 6 Line 7 ~ ~ ~ ~ ~ 4) Move to line 6

2) Go to line 4

Line 1 Line 2 (ma line) Line 3 Line 4 (y'a done here) Line 5 Line 6 Line 7 ~ ~ ~ ~ ~ 3 lines yanked 3) Yank to mark a (y'a)

Line 1 Line 2 (ma line) Line 3 Line 4 (y'a done here) Line 5 Line 6 Line 2 (ma line) Line 3 Line 4 (y’a done here) Line 7 ~ ~ 3 more lines 5) Put text in using the p command

Figure 4.5

Yank (copy) and put (paste).

39

40

Chapter 4

Text Blocks and Multiple Files

Filtering The !motion command takes a block of text and filters it through another program. In other words, it runs the system command represented by command, giving it the block of text represented by motion as input.The output of this command then replaces the selected block. Because this summarizes badly if you are unfamiliar with UNIX filters, take a look at an example.The sort command sorts a file. If you execute the following command, the unsorted file input.txt will be sorted and written to output.txt. (This works on both UNIX and Microsoft Windows.) $ sort

output.txt

Now do the same thing in Vim. You want to sort lines 1 through 10 of a file.You start by putting the cursor on line 1. Next you execute the following command: !10G

The ! tells Vim that you are performing a filter operation.The Vim editor expects a motion command to follow indicating which part of the file to filter.The 10G command tells Vim to go to line 10, so it now knows that it is to filter lines 1 (the current line) through 10 (10G). In anticipation of the filtering, the cursor drops to the bottom of the screen and a ! prompt displays.You can now type in the name of the filter program, in this case sort. Therefore, your full command is as follows: !10Gsort<Enter>

The result is that the sort program is run on the first 10 lines.The output of the program replaces these lines. The !! command runs the current line through a filter. (I have found this a good way to get the output of system commands into a file.) I’m editing a readme.txt file, for example, and want to include in it a list of the files in the current directory. I position the cursor on a blank line and type the following: !!ls

This puts the output of the ls command into my file. (Microsoft Windows users would use dir.) Another trick is to time stamp a change.To get the current date time (on UNIX), I use the following command: !!date

This proves extremely useful for change histories and such.

Note

Using !! like this is technically not filtering because commands like ls and date don’t read standard input.

Dealing With Multiple Files

Editing Another File Suppose that you have finished editing one file and want to edit another file.The simple way to switch to the other file is to exit Vim and start it up again on the other file. Another way to do so is to execute the following command: :vi file

This command automatically closes the current file and opens the new one. If the current file has unsaved changes, however, Vim displays a warning message and aborts the command: No write since last change (use ! to override)

At this point, you have a number of options.You can write the file using this command: :write

Or you can force Vim to discard your changes and edit the new file using the force (!) option, as follows: :vi! file.txt Note

The :e command can be used in place of :vi. The fact that these commands are equivalent has led to a flame war between Steve Oualline, who prefers :vi and Bram Moolenaar, who prefers :e. (Okay, it was limited to three slightly discordant emails, but it’s hard to

introduce real drama in a book like this.)

The :view Command The following command works just like the :vi command, except the new file is opened in read-only mode: :view file

If you attempt to change a read-only file, you receive a warning.You can still make the changes; you just can’t save them.When you attempt to save a changed read-only file, Vim issues an error message and refuses to save the file. (You can force the write with the :write! command, as described later in this chapter.)

Dealing with Multiple Files So far the examples in this book have dealt with commands that edit a single file.This section introduces you to some commands that can edit multiple files. Consider the initial Vim command, for example.You can specify multiple files on the command line, as follows: $ gvim one.c two.c three.c

41

42

Chapter 4 Text Blocks and Multiple Files

This command starts Vim and tells it that you will be editing three files. By default, Vim displays just the first file (see Figure 4.6). To edit the next file, you need to change files using the :next command. Figure 4.7 shows the results. Note that if you have unsaved changes in the current file and you try to do a :next, you will get a warning message and the :next will not work. You can solve this problem in many different ways.The first is to save the file using the following command: :write

In other words, you can perform a :write followed by a :next. The Vim editor has a shorthand command for this.The following command performs both operations: :wnext

/* File one.c */ ~ ~ ~ ~

Figure 4.6

Editing the first of multiple files.

/* File two.c */ ~ ~ ~ ~ “two.c” 1L, 17C

Figure 4.7

:next.

Or, you can force Vim to go the next file using the force (!) option. If you use the following command and your current file has changes, you will lose those changes: :next!

Finally, there is the ‘autowrite’ option. If this option is set, Vim will not issue any No Instead, it just writes the file for you and goes on.To turn this option on, use the following command:

write... messages. :set autowrite

To turn it off, use this command: :set noautowrite

Which File Am I On?

You can continue to go through the file list using the following command until you reach the last file: :next

Also, the :next command can take a repeat count. For example, if you execute the command :2 next

(or :2next), Vim acts like you issued a :next twice.

Which File Am I On? Suppose you are editing a number of files and want to see which one you are on.The following command displays the list of the files currently being edited: :args

The one that you are working on now is enclosed in square brackets. Figure 4.8 shows the output of the command. /* File two.c */

~ ~ ~ ~ one.c [two.c] three.c

Figure 4.8

Output of :args.

This figure shows three files being edited: one.c, two.c, and three.c.The file currently being editing is two.c.

Going Back a File To go back a file, you can execute either of the following commands: :previous

or :Next

These commands act just like the :next command, except that they go backward rather than forward. If you want to write the current file and go to the previous one, use either of the following commands: :wprevious :wNext

43

44

Chapter 4 Text Blocks and Multiple Files

Editing the First or Last File You might think that :first would put you at the first file and :last would edit the last file.This makes too much sense for use with computers.To start editing from the first file, no matter which file you are on, execute the following command: :rewind

To edit the last file, use this command: :last

Note: Bram has promised to add a :first command in the next release of Vim.

Editing Two Files Suppose that you edit two files by starting Vim with the following: $ gvim one.c two.c

You edit a little on the first file, and then go to the next file with the following: :wnext

At this point, the previous file, one.c, is considered the alternate file.This has special significance in Vim. For example, a special text register (#) contains the name of this file. By pressing CTRL-^, you can switch editing from the current file to the alternate file.Therefore, if you are editing two.c and press CTRL-^, you will switch to one.c (two.c becoming the alternate file). Pressing CTRL-^ one more time switches you back. Suppose that you are editing a bunch of files, as follows: $ gvim one.c two.c three.c

The command countCTRL-^ goes to the count file on the command line.The following list shows the results of several CTRL-^ commands: 1 CTRL-^ 2 CTRL-^ 3 CTRL-^ CTRL-^

one.c two.c three.c two.c

(previous file)

Note When you first start editing (file one.c) and press CTRL-^, you will get an error message: No alternate file. Remember the alternate file is the last file you just edited before this one (in this editing session). Because one.c is the only file edited, there is no previous file and therefore the message.

error

Windows

S

O FAR YOU HAVE BEEN USING A SINGLEwindow.

In this chapter, you split the

screen into multiple windows and edit more than one file simultaneously.This chapter also discusses the use of editing buffers. A buffer is a copy of a file that you edit along with the setting and marks that go with it. The topics discussed in this chapter include the following: n

How to open a new window

n

Window selection

n

Editing two files at once

n

Controlling the size of a window

n

Basic buffer usage

Opening a New Window The easiest way to open a new window is to use the following command: :split

46

Chapter 5 Windows

This command splits the screen into two windows (and leaves the cursor in the top one), as seen in Figure 5.1. /* File one.c */ ~ ~ one.c /* File one.c */ ~ one.c

Figure 5.1

Splitting a window.

Both are editing the same file, so you can view two different parts of a file simultaneously. If you are at the bottom window, the CTRL-Ww command moves the cursor to the top window (alternate command: CTRL-W CTRL-W). If you are at the top window, the editor jumps to the bottom one on the screen. To change windows, use CTRL-Wj to go down a window and CTRL-Wk to go up a window (see Figure 5.2). Or if you are using Vim with a mouse, you can just click in the window you want. To close a window, use ZZ or the following command: :q

does the same thing. Usually you would expect CTRL-W CTRL-C also to close a window. It would if all the CTRL-W commands were consistent. Because CTRL-C cancels any pending operation, however, CTRL-W CTRL-C does nothing. CTRL-Wc

Opening Another Window with Another File The following command opens a second window and starts editing the given file: :split file

Figure 5.3 shows what happens when you start editing one.c and then execute the following command :split two.c

CTRL-Ww

CTRL-Wj

/* File one.c */ ~ ~ one.c /* File one.c */ ~ one.c

Figure 5.2

CTRL-Wk

Window navigation.

Opening a New Window /* File two.c */ ~ ~ two.c /* File one.c */ ~ one.c "two.c" 1L, 17C

Figure 5.3

Results of :split two.c.

The :split command can also execute an initial command using the +command convention. Figure 5.4 shows what happens when you are editing one.c and execute the following command: :split +/printf three.c

{ printf(”%2d squared is %3d\n", i, i*i); } three.c /* File one.c */ ~ one.c "three.c" 11L, 160C

Figure 5.4

Result of :split with a + command

Controlling Window Size The :split command can take a number argument. If specified, this will be the number of lines in the new window. For example, the following opens a new window three lines high and starts editing the file alpha.c: :3 split alpha.c

A space appears here for clarity.You could have just as easily write the following: :3split alpha.c

Figure 5.5 shows the results. /* This is alpha.c */ ~ ~ alpha.c /* File one.c */ ~ ~ ~ ~ ~ ~ ~ ~ one.c "alpha.c" 1L, 22C

Figure 5.5

:3split.

47

48

Chapter 5 Windows

Split Summary The general form of the :split command is as follows: :count split +command file

count

The size of the new window in lines. (Default is to split the current window into two equal sizes.)

+command

An initial command.

file

The name of the file to edit. (Default is the current file.)

The :new Command The :new command works just like the :split command except that the :split command splits the current window and displays the current file in both windows. The following command splits the current window and starts a new file in the other window: :new

Split and View The :sview command acts like a combination of :split and :view.This command proves useful if you want to look at, but not edit, a file in another window.

Changing Window Size Changing window size when you are using gvim is easy.To change the size of a window, use the mouse to drag the separator up or down (see Figure 5.6). If you are using the terminal version of Vim, you need to type in some commands. The command countCTRL-W+ increases the window size by count (default = 1). Similarly countCTRL-W- decreases the window’s size by count (default = 1). The command CTRL-W= makes all the windows the same size (or as close as possible). /* File two.c */ ~ ~ ~ ~ ~ two.c /* File three.c */ #include <stdio.h> int i; int main () { for (i = 1; i <= 10; ++i) three.c :q Grab this bar with the mouse

Figure 5.6

/* File two.c */ ~ ~ ~ ~ ~ ~ ~ ~ two.c /* File three.c */ #include <stdio.h> int i; three.c :q and drag to here.

Adjusting the window size.

Buffers

The command countCTRL-W_ makes the current window count lines high. If no count is specified, the window is increased to its maximum size.

Buffers The Vim editor uses the term buffer to describe a file being edited. Actually, a buffer is a copy of the file that you edit.When you finish changing the buffer and exit, the contents of the buffer are written to the file. Buffers not only contain file contents, but also all the marks, settings, and other stuff that go with it. Normally it is pretty easy to tell what buffers you have: If it has a window on the screen, it is a buffer; if it is not on the screen, it is not a buffer. Now for a new concept thrown into the mix, that of the hidden buffer. Suppose you are editing a file named one.c and you need to do some work on two.c.You split the screen and create two windows, one for each file. But you do not like split-screen mode; you want to see one file at a time. One solution is to make the window for two.c as big as possible.This works, but there still is an annoying little bit of one.c showing. Another solution is to close the one.c window, but then you lose all the changes for that file. The Vim editor has another solution for you: the :hide command.This causes the current buffer to become “hidden.”This causes it to disappear from the screen. But Vim still knows that you are editing this buffer, so it keeps all the settings, marks, and other stuff around. Actually, a buffer can have three states: Active

Appears onscreen.

Hidden

A file is being edited, but does not appear onscreen.

Inactive

The file is not being edited, but keep the information about it anyway.

The inactive state takes a little explaining.When you edit another file, the content of the current file is no longer needed, so Vim discards it. But information about marks in the file and some other things are still useful and are remembered along with the name of the file. Also, a file that was included in the command with which you started Vim, but was not edited, will also be an inactive buffer. To find a list of buffers, use the following command: :buffers

Figure 5.7 shows the results of this command. The first column is the buffer number.The second is a series of flags indicating the state of the buffer.The third is the name of the file associated with the buffer. The state flags are as follows: -

Inactive buffer.

h

Buffer is hidden.

%

Current buffer.

#

Alternate buffer.

+

File has been modified.

49

50

Chapter 5 Windows

~ ~ ~ ~ ~ ~ two.c :buffers 1 #h "one.c" 2 % "two.c" 3 – "three.c" 4 – "four.c" 5 – "help.txt" 6 – "editing.txt" Press RETURN or enter command to continue

Figure 5.7

line 1 line 1 line 1 line 0 line 1 line 234

:buffers.

In this case, you see six buffers: 1. The next to last file you were working on, also known as the alternate file (# flag).This buffer has been hidden (h flag).You were editing file one.c and left the cursor on line 1. 2. The active buffer (% flag).This is the file you are editing. 3. An inactive buffer.You want to edit three.c, but you have made no changes to it. 4. Another file on the argument list that has not been edited. 5. When you executed a :help command, the Vim editor opened two files.The first one of these is called help.txt. 6. This is another help file called editing.txt.

Selecting a Buffer You can select which buffer to use by executing the following command: :buffer number

is the buffer number. If you do not know the number of the buffer, but you do know the filename, you can use this command:

number

:buffer file

Figure 5.8 shows the results of a typical :buffer command.

Selecting a Buffer

/* File three.c */ #include <stdio.h> int i; int main() { for (i = 1; i <= 10; ++i) { printf("%2d squared is %3d\n", i, i*i); } return (0); } ~ ~ three.c

Figure 5.8

:3buffer

or :buffer three.c.

/* File one.c */ ~ ~ ~ ~ ~ one.c /* File three.c */ #include <stdio.h> int i; int main() { for (i = 1; i <= 10; ++i) three.c “one.c” line 1 of 1 ––100%–– col 1 ((2) of 3)

Figure 5.9

Result of :sbuffer.

The following command splits the window and starts editing the buffer: :sbuffer number

If a number is specified, the new window will contain that buffer number. If no number is present, the current buffer is used.This also takes a filename as an argument. If you are editing the file three.c and execute the following command, for example, you get the results seen in Figure 5.9: :sbuffer one.c

Other buffer-related commands include the following: :bnext

Go to the next buffer.

:count bnext

Go to the next buffer count times.

:count sbnext

Shorthand for :split followed by :count

:count bprevious

Go to previous buffer. If a count is specified, go to the count previous buffer.

:count sbprevious

Shorthand for :split and :count

:count bNext

Alias for :bprevious.

bnext.

bprevious.

51

52

Chapter 5

Windows

:count sbNext

Alias for :sbprevious.

:blast

Go to the last buffer in the list.

:sblast

Shorthand for :split and :blast.

:brewind

Go to the first buffer in the list.

:sbrewind

Shorthand for :split and :rewind.

:bmodified count

Go to count modified buffer on the list.

:sbmodified count

Shorthand for :split and :bmodified.

Buffer Options Usually when the last window of a file is closed, the buffer associated with the file becomes inactive. If the option hidden is set, files that leave the screen do not become inactive; instead they automatically become hidden.Therefore if you want to keep the contents of all your old buffers around while editing, use the following command :set hidden

Note

The :hide command always hides the current file no matter what the “hidden” option is set to.

Normally, the split/buffer related commands split the current window. If the “switchbuf ” is set to “useopen” and there is a window displaying the buffer you want to display already on the screen, the Vim will just make that window the current one instead of performing the split (see Figure 5.10).

Buffer Options

$ gvim t.c Makefile

:set switchbuf=””

:snext

:srewind

int main()

{

{

i = 5; printf("Hellow World/n");

i = 5; t.c

printf("Hellow World/n"); return (0);

i = 5; printf("Hellow World/n");

t.c t: t.c

t.c t: t.c

gcc t.c ~

gcc t.c

~ ~

~ Makefile

Makefile

't.c' 7L, 90C

#include <stdio.h> int main()

:set switchfbuf=useopen :srewind

{ i = 5; printf("Hellow World/n"); t.c t: t.c gcc t.c ~ ~ ~ Makefile (3 of 6): `i´ undeclared (first use in this function)

Figure 5.10

The “switchbuf ” option.

Note the “switchbuf ” option can have the values:“(nothing),‘split,’ ‘useopen’ and ‘split,useopen’.” For a description of the “split” argument see Chapter 23,“Advanced Commands for Programmers.”

53

Basic Visual Mode

O

NE FEATURE THAT SETSVIMAPARTfrom

its predecessor is something called visual

mode.This mode gives you the ability to highlight a block of text and then execute a command on it.You can highlight a block of text, for example, and then delete it with a d command. The nice thing about visual mode is that, unlike other Vim commands where you operate blindly, with visual mode you can see what text is going to be affected before you make a change. In this chapter, you learn about the following: n

How to start visual mode

n

Visual yanking

n

Using visual mode to change text

n

Visual commands for programmers

n

Visual block mode

56

Chapter 6 Basic Visual Mode

Entering Visual Mode To enter visual mode, type the v command. Now when you move the cursor, the text from the start position to the current cursor location is highlighted (see Figure 6.1). After the text has been highlighted, you can do something with it. For example, the d command deletes it. Figure 6.2 shows the results.

The Three Visual Modes There are actually three different visual modes.The v command starts a character-bycharacter visual mode. All the characters from the start to the cursor are highlighted. Figure 6.3 shows this mode in action. The V command starts linewise visual mode.You can highlight only full lines in this mode (see Figure 6.4).

v — start visual mode

Move cursor here to highlight the text

#include <stdio.h> int i; int main() { for (i = 1; i <= 10; ++i) { printf("%2d squared is %3d\n", i, i*i); } return (0); three.c ––VISUAL ––

Figure 6.1

Pressing d deletes the highlighted text.

Visual mode.

int i; int main() { for (i = 1; i <= 10; ++i) return (0); } ~ ~ ~ three.c [+] 3 fewer lines

Figure 6.2

Visual delete.

Note To get help on the commands that operate in visual mode, use the prefix v_. Therefore :help v_d describes what the d command does in visual mode.

Entering Visual Mode

Visual start (Cursor is here when v is pressed.)

Oh woe to Mertle the turtle who found web surffing quite a hurtle. The system you see was slower than he. And that's not saying much for the turtle.

Visual end

~ ~

(Cursor is moved to here.)

[No File] [+] –– VISUAL ––

Figure 6.3

Visual start

v

(visual mode).

when V is pressed.)

Oh woe to Mertle the turtle who found web surffing quite a hurtle. The system you see was slower than he. And that's not saying much for the turtle.

Visual end

~ ~

(Cursor is here

(Cursor is moved to here.)

[No File] [+] –– VISUAL LINE ––

Figure 6.4

V

(line visual mode).

To highlight a rectangle on the screen, use CTRL-V.This mode is extremely useful if you want to work with tables as shown in Figure 6.5.You can highlight a column and delete it using the d command. Visual start (Cursor is here when CTRL-V is pressed.)

Visual end (Cursor is moved to here.)

Oh woe to Mertle the turtle who found web surffing quite a hurtle. The system you see was slower than he. And that's not saying much for the turtle. ~ ~

[No File] [+] –– VISUAL BLOCK ––

Figure 6.5

CTRL-V

(block visual mode).

Leaving Visual Mode Normally, you leave visual mode by typing a visual-mode command, such as d to delete the highlighted text. But you can also cancel visual mode by pressing the <Esc> key. Remember, you can always type <Esc> to get back to normal mode so you know where you are. Some people find <Esc> a little annoying because it beeps if you type it twice.The first <Esc> goes from visual mode to normal mode.The second <Esc> in normal mode is an error and generates the beep. (The command CTRL-C will do the same thing as well.)

57

58

Chapter 6 Basic Visual Mode

If you want to make sure that you are in normal mode and do not want to generate a beep, use the CTRL-\CTRL-N command.This acts just like <Esc> but without the noise.

Editing with Visual Mode Editing with visual mode is simple. Select the text using the visual commands just discussed, and then type an editing command.This section shows you how to perform simple edits using a visual selection.

Deleting Text in Visual Mode The d command deletes the highlighted text, as shown in Figure 6.6. The D command deletes the highlighted lines, even if only part of a line is highlighted (see Figure 6.7). Line 1 Line 2 Line 3 Line 4 Line 5. ~ ~ ~ ~

d - deletes the

highlighted text.

lines.txt

Line 1 2 Line 3 Line 4 Line 5. ~ ~ ~ ~


–– VISUAL ––

Deleting text in visual mode.

Figure 6.6

Line 1 Line 2 Line 3 Line 4 Line 5. ~ ~ ~ ~

D - deletes the highlighted lines.

lines.txt

Line 1 Line 3 Line 4 Line 5. ~ ~ ~ ~ ~


–– VISUAL ––

Figure 6.7

The visual D command.

Editing With Visual Mode

Yanking Text The y command places the highlighted text into a register.The linewise version of this command, Y, places each line of the highlighted text into a register.

Switching Modes Suppose you are in character mode (started by v) and you realize you want to be in block mode.You can switch to block mode by just pressing CTRL-V. In fact, you can switch visual modes at any time by just selecting the new mode.To cancel visual mode, press the <Esc> key; or you can switch to the mode you are already in. (In other words, if you use v to start visual mode, you can use another v to exit it.)

Changing Text The c command deletes the highlighted text and starts insert mode.The does the same thing, but it works only on whole lines.

C

command

Joining Lines The J command joins all the highlighted lines into one long line. Spaces are used to separate the lines. If you want to join the lines without adding spaces, use the gJ command. Figure 6.8 shows how the J and the gJ commands work. Line 1 Line 2 Line 3 Line 4 ~ ~ ~ ~ ~ lines.txt [+] –– VISUAL ––

J

or

Line 1 Line 2 line 3 Line 4 ~ ~ ~ ~ ~ ~ test.txt [+]

gJ Line 1 line 2line 3 Line 4 ~ ~ ~ ~ ~ ~ test.txt [+]

Figure 6.8

The visual J and gJ command.

Note r and s do the same thing as c in visual mode. The same thing goes for R and S.

59

60

Chapter 6

Basic Visual Mode

Commands for Programmers The > command indents the selected lines by one “shift width.” (The amount of white space can be set with the 'shiftwidth' option.) The < does the process in reverse. (Note that these commands have a different meaning when using visual block mode.) The = command indents the text.The CTRL-] command will jump to definition of the function highlighted.

Keyword Lookup The K command is designed to look up the selected text using the “man” command. It works just like the normal-mode K command except that it uses the highlighted text as the keyword.

Visual Block Mode Some commands work a little differently in visual block mode.Visual block mode is started by pressing CTRL-V and is used to define a rectangle on the screen.

Inserting Text The command Istring<Esc> inserts the text on each line starting at the left side of the visual block, as seen in Figure 6.9. You start by pressing CTRL-V to enter visual block mode. Now you define your block. Next you type I to enter insert mode followed by the text to insert. As you type, the text appears on the first line. After you press <Esc> to end the insert, the text will magically be inserted in the rest of the lines contained in the visual selection. Figure 6.9 shows how this process works. If the block spans short lines that do not extend into the block, the text is not inserted in that line. Figure 6.10 illustrates what happens to short lines. If the string contains a newline, the I acts just like a normal-mode insert (i) command and affects only the first line of the block.

Visual Block Mode

Do file alpha.c Do one.c Do four.c Do three.c Do two.c ~ ~ ~

Do alpha.c Do one.c Do four.c Do three.c Do two.c ~ ~ ~

test.txt [+]

test.txt [+]

–– VISUAL BLOCK ––

–– INSERT –– Enter the text by typing Ifile<Space>

Define the block CTRL-Vjjjj

Do file alpha.c Do file one.c Do file four.c Do file three.c Do file two.c ~ ~ ~ test.txt [+]

Press <Esc> to end the insert.

Figure 6.9

Inserting text in visual block mode.

This is a long line Short This is a long line ~ ~ ~ ~ ~

This is a very long line Short This is a very long line ~ ~ ~ ~ test.txt [+]

test.txt [+]

–– VISUAL BLOCK –– Select a block. Notice that the short line is not part of the selection.

Figure 6.10

Insert “very” in the line. Notice that “Short” is unchanged.

Inserting with short lines.

61

62

Chapter 6 Basic Visual Mode

Changing Text The visual block c command deletes the block and then throws you into insert mode to enable you to type in a string.The string will be inserted on each line in the block (see Figure 6.11). The c command works only if you enter less than one line of new text. If you enter something that contains a newline, only the first line is changed. (In other words, visual block c acts just normal-mode c if the text contains more than one line.) Note The string will not be inserted on lines that do not extend into the block. Therefore if the block includes some short lines, the string will not be inserted in the short lines.

The C command deletes text from the left edge of the block to the end of line. It then puts you in insert mode so that you can type in a string, which is added to the end of each line (see Figure 6.12). Again, short lines that do not reach into the block are excluded. This is a ––LONG–– line Short This is a ––LONG–– line ~ ~ ~ ~

This is a long line Short This is a long line ~ ~ ~ ~ test.txt [+]

test.txt [+]

–– VISUAL BLOCK –– Define the block to be changed.

Change the text to “--LONG--”. The command is c--LONG--<Esc>

Figure 6.11

This is a ––LONG–– line Short This is a ––LONG–– line ~ ~ ~ ~ test.txt [+]

Block visual c command.

This is a changed Short This is a changed ~ ~ ~ ~ test.txt [+]

–– VISUAL BLOCK –– Change to the end of line:

Define the block

The command is Cchanged<Esc>

Figure 6.12

Block visual C with short lines.

Visual Block Mode

The visual block A throws Vim into insert mode to enable you to input a string.The string is appended to the block (see Figure 6.13). If there are short lines in the block, spaces are added to pad the line and then string is appended. You may notice that the A command affects short lines, whereas the other editing commands do not.The developers of Vim have noticed this and will fix this bug in a future version of the editor. You can define a right edge of a visual block in two ways. If you use just motion keys, the right edge is the edge of the highlighted area. If you use the $ key to extend the visual block to the end of line, the A key will add the text to the end of each line (see Figure 6.14). This is a long AAA line Short AAA This is a long AAA line ~ ~ ~ ~

This is a long line Short This is a long line ~ ~ ~ ~

test.txt [+]

test.txt [+]

–– VISUAL BLOCK –– Append AAA<space> to the block with

Define the block

AAAAA<space>

Figure 6.13 This is a long line Short This is a long ~ ~ ~ ~ test.txt [+]

Block visual A command. This is a long line XXX Short XXX This is a long XXX ~ ~ ~ ~ test.txt [+]

–– VISUAL BLOCK –– Define the visual block by using the command CTRL-V$jj. The $ moves the cursor to the end of the line

Figure 6.14

Add "XXX" to the end of each line with the A<Space>XXX command.

Block visual $ and A commands.

63

64

Chapter 6 Basic Visual Mode

Replacing The rchar command applies all the selected characters with a single character (see Figure 6.15). Short lines that do not extend into the block are not affected. This is a xxxxxxx line Short This is a xxxxxxx line ~ ~ ~ ~

This is a changed line Short This is a changed line ~ ~ ~ ~

test.txt [+]

test.txt [+]

–– VISUAL BLOCK –– The rx command replace all characters in the block with "x"

Define the block

Figure 6.15

Block visual-mode r command.

Shifting The command > shifts the text to the right one shift width, opening whitespace.The starting point for this shift is the left side of the visual block (see Figure 6.16). The < command removes one shift width of whitespace at the left side of the block (see Figure 6.17).This command is limited by the amount of text that is there; so if there is less than a shift width of whitespace available, it removes what it can. Oh woe to Mertle the turtle who found web surffing quite a hurtle. The system you see was slower than he. And that s not saying much for the turtle. ~ ~ —— VISUAL BLOCK —— > command opens up space in the block. (Adds shiftwidth(4) spaces.)

Oh woe to Mertle the turtle who fou nd web surffing quite a hurtle. The system you see was slower than he. And tha t s not saying much for the turtle. ~ ~ 5 lines >ed 1 time

Figure 6.16

Block visual-mode > command.

Visual Block Mode

aaa BBBBBBBBBBB aaa BBBBBBBBBBB aaa BBBBBBBBBBB aaa BBBBBBBBBBB aaa BBBBBBBBBBB aaa BBBBBBBBBBB –– VISUAL BLOCK –– < command removes shiftwidth (4) spaces from the text

aaaBBBBBBBBBBB aaaBBBBBBBBBBB aaaBBBBBBBBBBB aaaBBBBBBBBBBB aaaBBBBBBBBBBB aaa BBBBBBBBBBB aaa BBBBBBBBBBB 7 lines <ed 1 time

Figure 6.17

Block visual < command.

Visual Block Help Getting help for the commands that use visual block mode differs a little from other commands.You need to prefix the command with v_b_.To get help on the visual block r command, for example, type the following: :help v_b_r

65

Commands for Programmers

T

HE VIM EDITOR CONTAINS A LARGE NUMBER of

commands to make life easier for

programming. For example, Vim contains a number of commands to help you obtain correct indentation, match parentheses, and jump around in source files. One of the best features of Vim as far as a programmer is concerned are the commands that enable you to build a program from within Vim and then go through the error list and edit the files that caused trouble. In this chapter, you learn about the following: n

Syntax coloring

n

Automatic indentation

n

Indentation commands

n

Commands to navigate through the source code

n

Getting information through the man command.

n

The use of tags to go up and down a call stack

n

Making programs with the :make command

n

File searching with :grep

68

Chapter 7

Commands for Programmers

Syntax Coloring The following command turns on syntax coloring. :syntax on

That means that things such as keywords, strings, comments, and other syntax elements will have different colors. (If you have a black-and-white terminal, they will have different attributes such as bold, underline, blink, and so on.) You can customize the colors used for syntax highlighting as well as the highlighting method itself.

Syntax Coloring Problems Most of the time syntax coloring works just fine. But sometimes it can be a little tricky to set up.The following sections take a look at some common problems and solutions. Colors Look Bad When I Use Vim (UNIX only)

Ever try and read light yellow text on a white background? It is very hard to do. If you see this on your screen, you have a problem.The Vim editor has two sets of syntax colors. One is used when the background is light, and the other when the background is dark. When Vim starts, it tries to guess whether your terminal has a light or dark background and sets the option ‘background’ to light or dark. It then decides which set of colors to use based on this option. Be aware, however, that the editor can guess wrong. To find out the value of the 'background' option, use the following command: :set background?

If Vim’s guess is not correct, you can change it using a command such as this: :set background=light

You must use this command before executing the command: :syntax on

I Turned on Syntax Colors, but All I Get Is Black and White (UNIX)

A common problem affects the xterm program used on many UNIX systems.The problem is that although the xterm program understands colors, the terminal description for xterm frequently omits colors.This cripples syntax coloring.To correct this problem, you need to set your terminal type to the color version. On Linux this is xterm-color, and on Solaris this is xtermc. To fix this problem, put the following in your $HOME/.cshrc file: if ($term == xterm) set term = xterm-color

Shift Commands

This works on Linux with the csh shell. Other systems and other shells require different changes. I’m Editing a C File with a Non-Standard Extension. How Do I Tell Vim About It? The Vim editor uses a file’s extension to determine the file type. For example, files that end in .c or .h are considered C files. But what if you are editing a C header file named settings.inc? Because this is a non-standard extension, Vim will not know what to do with it. So how do you tell Vim that this is a C file? The answer is to use the option 'filetype'.This tells Vim which type of syntax highlighting to use.With a C file, you use the following command: :set filetype=c

Now Vim knows that this file is a C file and will highlight the text appropriately. If you want to make this setting automatically, look in the help files with this command: :help new-filetype

Running the Color Test If you are still having trouble with colors, run the Vim color test.This is a short Vim program that displays all the colors on the screen so that you can verify the correctness of the Vim colors. The color test can be started with these two commands: :edit $VIMRUNTIME/syntax/colortest.vim :source %

Shift Commands The Vim editor has lots of commands that help the programmer indent his program correctly.The first ones discussed here merely shift the text to the left (<<) or the right (>>). The left shift command (<<) shifts the current line one shift width to the left.The right shift command (>>) does the same in the other direction. But what is a shift width? By default, it is 8. However, studies have shown that an indentation of 4 spaces for each level of logic is the most readable. So a shift width of 4 would be much nicer. To change the size of the shift width, use the following command: :set shiftwidth=4

Figure 7.1 shows how the shift width option affects the >> command.

69

70

Chapter 7 Commands for Programmers

printf ( "Hello world! \n") ;

:set shiftwidth=8 >>

printf ( "Hello world! \n") ;

printf ( "Hello world! \n") ;

:set shiftwidth=4 >>

printf ( "Hello world! \n");

Left Side of the screen

Figure 7.1

shiftwidth and >>.

The << command shifts a single line. As usual you can prefix this command with a count; for example, 5<< shifts 5 lines.The command <motion shifts each line from the current cursor location to where motion carries you.

Automatic Indentation The Vim editor has a variety of automatic indentation options.The major indentation modes are the following: cindent

This works for C-style programs (C, C++, Java, and so on).When this style of indentation is enabled, the Vim editor automatically indents your program according to a “standard” C style.

smartindent

In this mode, Vim indents each line the same amount as the preceding one, adding an extra level of indentation if the line contains a left curly brace ({) and removing a indentation level if the line contains a right curly brace (}). An extra indent is also added for any of the keywords specified by the 'cinwords' option.

autoindent

New lines are indented the same as the previous line.

The next few sections explore these indentation modes in detail.

C Indentation The Vim editor knows something about how C, C++, Java, and other structured language programs should be indented and can do a pretty good job of indenting things properly for you.To enable C-style indentation, just execute the following command: :set cindent

Automatic Indentation

With this option enabled, when you type something such as if (x), the next line will automatically be indented an additional level. Figure 7.2 illustrates how 'cindent' works. Automatic indent Automatic unindent Automatic indent Automatic unindent Figure 7.2

if (flag) do_the_work ( ) ; if (other_flag) { do_file ( ) ; process_file ( ) ; } cindent.

When you type something in curly braces ({}), the text will be indented at the start and unindented at the end. Note One side effect of automatic indentation is that it helps you catch errors in your code early. I have frequently entered a } to finish a procedure, only to find that the automatic indentation put it in column 4. This told me that I had accidentally left out a } somewhere in my text.

Different people have different styles of indentation. By default Vim does a pretty good job of indenting in a way that 90% of programmers do.There are still people out there with different styles, however; so if you want to, you can customize the indentation style through the use of several options. You don’t want to switch on the 'cindent' option manually every time you edit a C file.This is how you make it work automatically: Put the following lines in your .vimrc (UNIX) or _vimrc (Windows) file: :filetype on :autocmd FileType c,cpp :set cindent

The first command (:filetype on) turns on Vim’s file type detection logic.The second, performs the command :set cindent if the file type detected is c or cpp. (This includes C, C++, and header files.)

Smartindent The 'cindent' mode is not the only indent mode available to Vim users.There is also the 'smartindent' mode. In this mode, an extra level of indentation is added for each { and removed for each }. An extra level of indentation will also be added for any of the words in the cinwords option. Lines that begin with “#” are treated specially. If a line starts with “#”, all indentation is removed.This is done so that preprocesser directives will all start in column 1.The indentation is restored for the next line. 'smartindent' is not as smart as 'cindent', but smarter than 'autoindent'.

71

72

Chapter 7 Commands for Programmers

Autoindent Structured languages such as a Pascal, Perl, and Python use indentation to help the programmer figure out what the program is doing.When writing these programs, most of the time you want the next line indented at the same level as the preceding one. To help you do this, the Vim editor has an 'autoindent' option.When on, it causes lines to be automatically indented. Suppose, for example, that you have autoindent off (:set noautoident).To type the following text, you must type four spaces in front of each printf: if (true) { printf(“It is true\n”); printf(“It is really true\n”); }

If you have set the 'autoindent' option using the :set autoindent command, the Vim editor automatically indents the second printf by four spaces (to line up with the preceding line). Figure 7.3 illustrates the operation of the 'autoindent' option. Type four spaces for indent; with 'autoindent' set, the following lines are automatically indented. if (true) { printf(“It is true\n”); printf(“It is really true\n”); }

That is nice, but when you get ready to enter the } line, the Vim editor also indents four spaces.That is not good because you want the } to line up with the if statement. While in insert mode, the CTRL-D command will cause Vim to back up one shift width (see Figure 7.4). CTRL-D moves the } back one shift width. if (true) {

Type 4 spaces for indent

printf ( "It is true \n") ; printf ( "It is really true\n") ;

}

With autoindent set, following lines are automatically indented. Figure 7.3

autoindent.

if (true) { printf ( "It is true\n"); printf ( "It is really true\n"); }

CTRL-D moves the } back one shiftwidth Figure 7.4

CTRL-D.

Locating Items in a Program

The = Command The =motion command indents the selected text using Vim’s internal formatting program. If you want to indent a block of text, for example, you can use the = command to do it.The motion in this case is the % (go to matching {}) command. Figure 7.5 shows the results.

{ if (strcmp (arg, option1) == 0) return (1) ; if (strcmp (arg, option2) == 0) return (1) ; return (0) ; } 1) Position cursor on the first "{" 2) Execute the command "=%". { if (strcmp (arg, option1) == 0) return (1) ; if (strcmp (arg, option2) ==0) return (1) ; return (0) ; }

Figure 7.5

The = command.

Locating Items in a Program Programmers made the Vim editor, so it has a lot of commands that can be used to navigate through a program.These include the following: [CTRL-I, ]CTRL-I Search for a word under the cursor in the current file and any brought in by #include directives. gd, gD Search for the definition of a variable. ]CTRL-D, [CTRL-D ]d, [d, ]D, [D

Jump to a macro definition. Display macro definitions.

73

74

Chapter 7 Commands for Programmers

Instant Word Searches Including #include Files ([CTRL-I, ]CTRL-I) The [CTRL-I command jumps to the word under the cursor.The search starts at the beginning of the file and also searches files brought in by #include directives. The ]CTRL-I does the same thing, starting at the cursor location.

Jumping to a Variable Definition (gd, gD) The gd command searches for the local declaration of the variable under the cursor (see Figure 7.6).This search is not perfect because Vim has a limited understanding of C and C++ syntax. In particular, it goes to the wrong place when you ask for the local declaration of a global variable. Most of the time, however, it does a pretty good job. int global_var; int main() { int local_var;

gd

Moves cursor from here to here.

global_var = local_var = 5; printf("%d %d”, global_var, local_var); return (0); }

Figure 7.6

Note: hlsearch is set.

The gd command.

The gD command searches for the global definition of the variable under the cursor(see Figure 7.7). Again, this search is not perfect, but most of the time it does the right thing.

int global_var; gD

int main() { int local_var;

Moves cursor from here to here.

global_var = local_var = 5; printf("%d %d”, global_var, local_var); return (0); }

Figure 7.7

The gD command.

Note: hlsearch is set.

Locating Items in a Program

Jump to Macro Definition ([CTRL-D, ]CTRL-D) The [CTRL-D command searches for the first definition of the macro whose name is under the cursor.The ]CTRL-D command searches for the next definition of the macro. These commands search not only the file you are editing, but also all files that are #included from this file. Figure 7.8 shows the [CTRL-D and ]CTRL-D commands.

[CTRL-D

#include <stdio.h> #define SIZE 10 int i = EOF ; int main ( ) { for (i = 1; i <= SIZE; ++i) { printf( "%2d squared is %3d\d", i, i*i)

Start on "SIZE"

; } return (0) ;

]CTRL-D

} #undef SIZE #define SIZE 20

Figure 7.8

[CTRL-D

and ]CTRL-D.

Displaying Macro Definitions ([d, ]d, [D, ]D) The [d command displays the first definition of the macro whose name is under the cursor.The ]d command does the same thing only it starts looking from the current cursor position and finds the next definition. Figure 7.9 shows the result of [d.

Results of [d

#include <stdio.h> #define SIZE 10 int i = EOF; int main() { for (i = 1; i <= SIZE; ++i) { printf("%2d squared is %3d\n", i, i*i); } return (0); } #undef SIZE #define SIZE 20 ~ ~ ~ #define SIZE 10

Figure 7.9

[d

command.

75

76

Chapter 7 Commands for Programmers

Again, #include files are searched as well as the current one. The ]D and [D commands list all the definitions of a macro.The difference between the two is that [D starts the list with the first definition, whereas ]D starts the list with the first definition after the cursor. Figure 7.10 shows the results of a [D command.

Results of

[D

int main() { for (i = 1; i <= SIZE; ++i) { printf("%2d squared is %3d\n", i, i*i); } return (0); } #undef SIZE #define SIZE 20 ~ ~ ~ test.c 1: 2 #define SIZE 10 2: 13 #define SIZE 20 Press RETURN or enter command to continue

Figure 7.10

[D

command.

Matching Pairs The % command is designed to match pairs of (), {}, or []. Place the cursor on one, type % and you will jump to the other. Figure 7.11 shows how the % command works. % finds the matching {}

void foo () { /* Check the conditions */ if (a | | b | | c) { printf (“Alpha\n”); if (d | | e) { printf (“Beta”); } } else { printf (“Gamma\n”); } }

Figure 7.11

% finds the matching ()

% command.

The % command will also match the ends of C comments (see Figure 7.12). (For you non-C programmers, these begin with /* and end with */.)

Matching Pairs %

/* A comment */

/* * A multi-line comment. */

%

Figure 7.12

%

and comments.

Also the % command will match #ifdef with the corresponding #endif. (Same goes for #ifndef and #if.) For #if, #else, and #endif sets, the % command will jump from the #if to the #else, and then to the #endif and back to the #if. Figure 7.13 shows how % works with preprocesser directives.

%

#ifndef SIZE #define SIZE 100 #endif /* SIZE */

%

#ifdef UNIX #define EOL “\n”; #else /* UNIX */ #define EOL “\r\n”; #endif /* UNIX */

% %

Figure 7.13

%

and the #if/#else/#endif.

Note The Vim editor is smart about matching pairs of operators. It knows about strings, and {} or [] will be ignored inside a string.

Shifting a Block of Text Enclosed in {} Suppose that you want to indent the text encoded in {} one level. Position the cursor on the first (or last) {. Execute the command >%.This shifts the text right to where the motion takes you. In this case, % takes you to the matching {}. Figure 7.14 shows how these commands work.

%> Scope of %

int flag; int main () { if (flag) { printf (“Flag set/n”); do_it () ; } return (0) ; }

Figure 7.14

int flag; int main () { if (flag) { printf (“Flag set/n”); do_it (); } return (0); }

Shifting a block of text.

77

78

Chapter 7 Commands for Programmers

Unfortunately this shifts the {} in addition to the text. Suppose you just want to shift what is in the {}.Then you need to do the following: 1. Position the cursor on the first {. 2. Execute the command >i{. This shift right command (>) shifts the selected text to the right one shift width. In this case, the selection command that follows is i{, which is the “inner {} block” command. Figure 7.15 shows the execution of these commands.

int flag; int main () { if (flag) { printf (“Flag set/n”); do_it (); } return (0); }

Figure 7.15

>i{

Scope of i{

int flag; int main () { if (flag) { printf (“Flag set/n”); do_it (); } return (0); }

Shifting a block of text (better method).

Indenting a Block Using Visual Mode To indent a block using visual mode, follow these steps: 1. Position the cursor on the left or right curly brace. 2. Start visual mode with the v command. 3. Select the inner {} block with the command i}. 4. Indent the text with >.

Finding the man Pages The K command runs a UNIX man command using the word under the cursor as a subject. If you position the cursor on the word open and press K, for example, the man page for open will display. On Microsoft Windows, the K command does the equivalent of performing a :help on the word under the cursor.You can also use the visual K command to do the same thing. The format of the man command is as follows: $ man [section] subject

Tags

The K command gets the subject from the word under the cursor. But what if you need to select the section number? It is simple; the K command takes a count argument. If specified, this is used as the section number.Therefore, if you position the K over the word mkdir and execute the 2K, you will get the mkdir(2) page. You can customize the K command. It runs the program specified by the 'keywordprg' option. By default, on UNIX this is man. Solaris has a non-standard man command. Sections must be specified with the -s switch. So the 'keywordprg' option defaults to man -s on Solaris.The Vim editor is smart enough to know that if no section is specified, that it must drop the -s. On Microsoft Windows, there is no man command, so 'keywordprg' defaults to nothing (“”).This tells Vim to use the internal :help command to handle the K command. Finally, the definition of what the K command considers a word is defined by the 'iskeyword' option.

Tags The Vim editor can locate function definitions in C and C++ programs.This proves extremely useful when you are trying to understand a program. The location of function definitions (called tags in Vim terminology) is stored in a table of contents file generated by the program ctags. (This program comes with Vim.). To generate the table of contents file, which is named tags, use the following command: $ ctags *.c

Now when you are in Vim and you want to go to a function definition, you can jump to it by using the following command: :tag function

This command will find the function even if it is another file. The CTRL-] command jumps to the tag of the word that is under the cursor.This makes it easy to explore a tangle of C code. Suppose, for example, that you are in the function write_block.You can see that it calls write_line. But what does write_line do? By putting the cursor on the call to write_line and typing CTRL-], you jump to the definition of this function (see Figure 7.16). The write_line function calls write_char.You need to figure out what it does. So you position the cursor over the call to write_char and press CTRL-]. Now you are at the definition of write_char (see Figure 7.17).

79

80

Chapter 7 Commands for Programmers

:tag write_block positions us here

void write_block(char line_set[]) { int i; for (i = 0; i < N_LINES; ++i) write_line(line_set[i]); }

void write_line(char line[]) { int i; for (i = 0; line[0] != '\0') write_char(line[i]); } ~ "write_line.c" 6L, 99C

CTRL-] goes to the definition of write_line (switching files if needed).

Tag jumping with CTRL-].

Figure 7.16

CTRL-] while positioned on write_char (see previous figure), gets us here.

void write_char(char ch) { write_raw(ch); } ~ ~ ~ "write_char.c" 4L, 48C

Figure 7.17

Jumping to the write_char tag.

The :tags command shows the list of the tags that you have traversed through (see Figure 7.18). ~ :tags # TO tag FROM line 1 1 write_block 1 2 1 write_line 5 3 1 write_char 5 > Press RETURN or enter command to continue

Figure 7.18

in file/text write_block.c write_block.c write_line.c

The :tags command.

Now to go back.The CTRL-T command goes the preceding tag.This command takes a count argument that indicates how many tags to jump back.

Tags

So, you have gone forward, and now back. Let’s go forward again.The following command goes to the tag on the list: :tag

You can prefix it with a count and jump forward that many tags. For example: :3tag

Figure 7.19 illustrates the various types of tag navigation. :tag write_block

CTRL-] (on write_line)

write_block

CTRL-] (on write_char)

write_line

write_char CTRL-T

2CTRL-T

:tag

:2tag

Figure 7.19

Tag navigation.

Help and Tags The help system makes extensive use of tags.To execute a “hyperlink jump,” you press CTRL-] (jump to tag).You can return to a preceding subject with CTRL-T (jump to preceding tag) and so on.

Windows and Tags The :tag command replaces the current window with the one containing the new function. But suppose you want to see not only the old function but also the new one? You can split the window using the :split command followed by the :tag command. But Vim has a shorthand command that is shorthand for both commands: :stag tag

Figure 7.20 shows how this command works. void write_block(char line_s { int i; for (i = 0; i < N_LINES; write_line(line_set[ }

void write_char(char ch) { write_raw(ch); write_char.c for (i = 0; i < N_LINES; ++i) write_line(line_set[i]); write_block.c "write_char.c" 4L, 48C :stag write_char

Figure 7.20

The :stag command.

81

82

Chapter 7 Commands for Programmers

The CTRL-W] command splits the current window and jumps to the tag under the cursor in the upper window (see Figure 7.21). If a count is specified, the new window will be count lines high. void write_block(char line_s { int i; for (i = 0; i < N_LINES; write_line(line_set[ }

void write_line(char line[]) { int i; write_line.c for (i = 0; i < N_LINES; ++i) write_line(line_set[i]); write_block.c "write_line.c" 6L, 99C CTRL-WCTRL-[—While position on write_line

Figure 7.21

CTRL-W].

Finding a Procedure When You Only Know Part of the Name Suppose you “sort of ” know the name of the procedure you want to find? This is a common problem for Microsoft Windows programmers because of the extremely inconsistent naming convention of the procedures in the Windows API. UNIX programmers fare no better.The convention is consistent; the only problem is that UNIX likes to leave letters out of system call names (for example, creat). You can use the :tag command to find a procedure by name, or it can search for a regular expression. If a procedure name begins with /, the :tag command assumes that the name is a regular expression. If you want to find a procedure named “something write something,” for example, you can use the following command: :tag /write

This finds all the procedures with the word write in their names and positions the cursor on the first one. If you want to find all procedures that begin with read, you need to use the following command: :tag /^read

If you are not sure whether the procedure is DoFile, do_file, or Do_File, you can use this command: :tag /DoFile\|do_file\|Do_File

or :tag /[Dd]o_\=[Ff]ile

Tags

These commands can return multiple matches.You can get a list of the tags with the following command: :tselect {name}

Figure 7.22 shows the results of a typical :tselect command. ~

# pri kind tag > 1 F C f write_char

file write_char.c void write_char(char ch) 2 F f write_block write_block.c void write_block(char line_set[]) 3 F f write_line write_line.c void write_line(char line[]) 4 F f write_raw write_raw.c void write_raw(char ch) Enter nr of choice (

to abort):

Figure 7.22

Results of :tselect

:tselect command.

The first column is the number of the tag. The second column is the Priority column.This contains a combination of three letters. F

Full match (if missing, a case-ignored match)

S

Static tag (if missing, a global tag)

C

Tag in the current file

The last line of the :tselect command gives you a prompt that enables you to enter the number of the tag you want. Or you can just press Enter (

in Vim terminology) to leave things alone.The g] command does a :tselect on the identifier under the cursor. The :tjump command works just like the :tselect command, except if the selection results in only one item, it is automatically selected.The g CTRL-] command does a :tjump on the word under the cursor. A number of other related commands relate to this tag selection set, including the following: :count tnext

Go to the next tag

:count tprevious

Go to the previous tag

:count tNext

Go to the next tag

:count trewind

Go to the first tag

:count tlast

Go to the last tag

Figure 7.23 shows how to use these commands to navigate between matching tags of a :tag or :tselect command.

83

84

Chapter 7 Commands for Programmers

:tag /write

:tnext write_block

:tnext write_line

write_char :tprevious :tnext

:trewind :tlast

Figure 7.23

Tag navigation.

Shorthand Command The command :stselect does the same thing as :tselect, except that it splits the window first.The :stjump does the same thing as a :split and a :tjump.

The Care and Feeding of Makefiles The UNIX make command is designed to manage the compilation and building of programs.The commands to make are stored in a file called Makefile. The format of this file, although simple, is a little tricky to work with. In the following file, for example, the first command works, whereas the second contains an error: alpha.o: alpha.c gcc -c alpha.c beta.o: beta.c gcc -c beta.c

You may have a little difficulty seeing the problem from this listing.The problem is that the indent for the first command is a tab, whereas the indent on the second one uses eight spaces.This difference is impossible to see onscreen; so how do you tell the difference between the two versions? The following command puts Vim in list mode: :set list

In this mode, tabs show up as ^I. Also the editor displays $ at the end of each line (so you can check for trailing spaces).Therefore, if you use the following command :set list

your example looks like this: alpha.o: alpha.c$ ^Igcc -c alpha.c$ $ beta.o: beta.c$ gcc -c beta.c$

The Care and Feeding of Makefiles

From this it is easy to see which line contains the spaces and which has a tab. (You can customize list mode by using the 'listchars' option.) If the 'expandtab' option is set, when you type a tab, Vim inserts spaces.This is not good if you are editing a Makefile.To insert a real tab, no matter what the options are, type in CTRL-V

in insert mode.The CTRL-V tells Vim not to mess with the following character. Note If you have syntax coloring turned on, the Vim editor will highlight lines that begin with spaces in red, whereas lines that start with display normally.

Sorting a List of Files Frequently in a Makefile, you will see a list of files: SOURCES = \ time.cpp set_ix.cpp rio_io.cpp arm.cpp app.cpp amem.cpp als.cpp aformat.cpp adump.cpp rio.cpp progress.cpp add.cpp acp.cpp rio_glob.cpp

\ \ \ \ \ \ \ \ \ \ \ \ \

To sort this list, execute the following: 1. Position the cursor on the start of the list. 2. Mark this location as a by using the command ma. 3. Go to the bottom of the list. 4. Run the block through the external program sort using the command !’a sort. SOURCES = \ acp.cpp add.cpp adump.cpp aformat.cpp als.cpp amem.cpp app.cpp arm.cpp progress.cpp

\ \ \ \ \ \ \ \ \

85

86

Chapter 7 Commands for Programmers

rio.cpp rio_glob.cpp rio_io.cpp set_ix.cpp time.cpp

\ \ \ \

Warning All the lines, except the last one, must end with a backslash (\). Sorting can disrupt this pattern. Make sure that the backslashes are in order after a sort. Figure 7.24 shows how you might need to fix the source list.

SOURCES = \

SOURCES = \ acp.cpp add.cpp adump.cpp aformat.cpp als.cpp amem.cpp app.cpp arm.cpp progress.cpp rio.cpp rio_glob.cpp rio_io.cpp set_ix.cpp time.cpp

Figure 7.24

\ \ \ \ \ \ \ \ \ \

Fix \ \ \

Fix

acp.cpp add.cpp adump.cpp aformat.cpp als.cpp amem.cpp app.cpp arm.cpp progress.cpp rio.cpp rio_glob.cpp rio_io.cpp set_ix.cpp time.cpp

\ \ \ \ \ \ \ \ \ \ \ \ \

Fixing the source list.

Sorting a List in Visual Mode To sort a list using visual mode, you need to execute the following commands: 1. Move to the top of the text to be sorted. 2. Start line visual mode with the command V. 3. Move to the bottom of the text to be sorted. 4. Execute the command !sort.The ! tells Vim to pipe the selected text through a command.The command in this case is sort. (This command has an implied <Enter> at the end.)

Making the Program The Vim editor has a set of commands it calls the quick-fix mode.These commands enable you to compile a program from within Vim and then go through the errors generated fixing them (hopefully).You can then recompile and fix any new errors that are found until finally your program compiles without error.

The Care and Feeding of Makefiles

:make The following command runs the program make (supplying it with any argument you give) and captures the results: :make arguments

If errors were generated, they are captured and the editor positions you where the first error occurred. Take a look at a typical :make session. (Typical :make sessions generate far more errors and fewer stupid ones.) Figure 7.25 shows the results. From this you can see that you have errors in two files, main.c and sub.c. When you press Enter (what Vim calls Return), you see the results shown in Figure 7.26. The editor has moved you to the first error.This is line 6 of main.c.You did not need to specify the file or the line number, Vim knew where to go automatically.The following command goes to where the next error occurs (see Figure 7.27): :cnext

:!make | & tee /tmp/vim215953.err gcc –g –Wall –o prog main.c sub.c main.c: In function ‘main’: main.c:6: too many arguments to function ‘do_sub’ main.c: At top level: main.c:10: parse error before ‘]’ sub.c: In function ‘sub’: sub.c:3: ‘j’ undeclared (first use in this function) sub.c:3: (Each undeclared identifier is reported only once sub.c:3: for each function it appears in.) sub.c:4: parse error before ‘]’ sub.c:4: warning: control reaches end of non-void function make: *** [prog] Error 1 2 returned “main.c” 11L, 111C (3 of 12): too many arguments to function ‘do_sub’ Press RETURN or enter command to continue

Figure 7.25

:make

output.

int main() { int i=3 do_sub("foo"); ++i; return (0); } } ~ (3 of 12): too many arguments to function do_sub

Figure 7.26

The first error.

Note If you are a Visual-C++ user, the make program supplied by Microsoft is called nmake. You might need to customize Vim using the 'makeprg' option so that it uses this program rather than the default make (as discussed later in this chapter).

87

88

Chapter 7 Commands for Programmers

int main() { int 1=3 do_sub("foo"); ++i; return (0); } } ~ (5 of 12): parse error before `}´

Figure 7.27

:cnext.

The command :cprevious or :cNext goes to the previous error. Similarly, the command :clast goes to the last error and :crewind goes to the first.The :cnfile goes to first error message for the next file (see Figure 7.28). If you forget what the current error is, you can display it using the following command: :cc

To see a list of errors, execute this command: :clist

Figure 7.29 shows the output of a :clist command. If you want to list only a subset of the errors, you can give :clist a range of errors to list. For example: :clist 3,5 :clist ,5 :clist 5,

(List errors 3 through 5) (List errors 1-5) (List errors 5 to the end)

The Vim editor suppresses all informational messages. If you want everything, use the following command: :clist!

The override option (!) tells Vim to not suppress anything. int sub(int i) { return (i * j) } ~ ~ ~ ~ ~ ~ (7 of 12): ‘j’ undeclared (first use in this function)

Figure 7.28

:cnfile

command.

Searching for a Given String

~ ~ :clist 3 main.c:6: too many arguments to function ‘do_sub’ 5 main.c:10: parse error before ‘}’ 7 sub.c:3: ‘j’ undeclared (first use in this function) 8 sub.c:3: (Each undeclared identifier is reported only once 9 sub.c:3: for each function it appears in.) 10 sub.c:4: parse error before ‘}’ 11 sub.c:4: warning: control reaches end of non-void function Press RETURN or enter command to continue

Figure 7.29

:clist

command.

If you have already run make and generated your own error file, you can tell Vim about it by using the :cfile error-file command. error-file is the name of the output of the make command or compiler. If the error-file is not specified, the file specified by the 'errorfile' option is used. Finally the following command exits Vim like :quit but exits with an error status (exit code=1): :cquit

This is useful if you are using Vim in an integrated development environment and a normal exit would cause a recompilation.

The 'errorfile' Option The 'errorfile' option defines the default filename used for the :clist command as well as the -q command-line option. (This file is not used for the :make command’s output.) If you want to define your default error file, use the following command: :set errorfile=error.list

Searching for a Given String The :grep command acts much like :make. It runs the external program grep and captures the output. (This command does not work all that well on Microsoft Windows because it does not have a grep command.You can get one from the GNU people (see http://www.gnu.org). To find all occurrences of the variable ground_point, for example, you use this command: :grep -w ground_point *.c

The -w flag tells grep to look for full words only. ground_point is the variable you are looking for. Finally, there is the list of files to search through (*.c). Figure 7.30 shows the results.

89

90

Chapter 7

Commands for Programmers

++i; return (0);

} } :!grep –n –w i *.c | & tee /tmp/vim215956.err main.c:5: int i=3; main.c:7: ++i; sub.c:1:int sub(int i) sub.c:3: return (i * j) (1 of 4): : int i=3; Press RETURN or enter command to continue

Figure 7.30

:grep

output.

Note

The grep program knows nothing about C syntax, so it will find ground_point even it occurs inside a string or comment.

You can use the :cnext, :cprevious, and :cc commands to page through the list of matches. Also :crewind goes to the first error and :clast to the last. Finally, the following command goes to the first error in the next file: :cnfile

Other Interesting Commands The Vim editor can use different options for different types of files through the use of the :autocommand command. See Chapter 13, “Autocommands,” for more information. You can also customize your options on a per-file basis by putting something called a modeline in each file.The Vim editor scans your file looking for these lines and sets things up based on their content.

Basic Abbreviations, Keyboard Mapping, and Initialization Files

T

HE VIM EDITOR HAS SOME FEATURES THAT enable

you to automate repetitive tasks.

One of these is abbreviation, which enables you to type in part of a word and let Vim type the rest. Another is the ability to remap the keyboard.You can easily redefine a key to be a whole set of commands. After you design your customizations, you can save them to an initialization file that will automatically be read the next time you start Vim. This chapter discusses the most common and useful subset of these commands. For a more complete reference, see Chapter 24, “All About Abbreviations and Keyboard Mapping.”

Abbreviations An abbreviation is a short word that takes the place of a long one. For example, ad stands for advertisement.The Vim editor enables you to type in an abbreviation and then will automatically expand it for you.To tell Vim to expand the abbreviation ad into advertisement every time you type it, use the following command: :abbreviate ad advertisement

Now, when you type ad, the whole word advertisement will be inserted into the text.

92

Chapter 8

Basic Abbreviations, Keyboard Mapping, and Initialization

What Is Entered

What You See

I saw the a

I saw the a

I saw the ad

I saw the ad

I saw the ad<space>

I saw the advertisement<space>

It is possible to define an abbreviation that results in multiple words. For example, to define JB as Jack Benny, use the following command: :abbreviate JB Jack Benny

As a programmer, I use two rather unusual abbreviations: :abbreviate #b /**************************************** :abbreviate #e <space>****************************************/

These are used for creating boxed comments.The comment starts with #b, which draws the top line. I then put in the text and use #e to draw the bottom line. The number of stars (*) in the abbreviations is designed so that the right side is aligned to a tab stop. One other thing to notice is that the #e abbreviation begins with a space. In other words, the first two characters are space-star. Usually Vim ignores spaces between the abbreviation and the expansion.To avoid that problem, I spell space as seven characters: “<”, “s”, “p”, “a”, “c”, “e”, “>”.

Listing Your Abbreviations The command :abbreviate lists all your current abbreviations. Figure 8.1 shows a typical execution of this command. ~ ~ ! #j Jack Benny Show ! #l /*------------------------------------------------------*/ ! #e ********************************************************/ ! #b /********************************************************/ ! #i #include ! #d #define Press RETURN or enter command to continue

Figure 8.1

:abbreviate.

Note The abbreviation is not expanded until after you finish the word by typing a space, tab, or other whitespace. That is so that a word such as addition

won’t get expanded to advertisementdition.

Mapping

Mapping Mapping enables you to bind a set of Vim commands to a single key. Suppose, for example, that you need to surround certain words with curly braces. In other words, you need to change a word such as amount into {amount}. With the :map command, you can configure Vim so that the F5 key does this job. The command is as follows: :map

i{<Esc>ea}<Esc>

Let’s break this down:

The F5 function key.This is the trigger key that causes the command to be executed as the key is pressed. (In this example, the trigger is a single key; it can be any string.)

i{<ESC>

Insert the { character. Note that we end with the <Esc> key.

e

Move to the end of the word.

a}<ESC>

Append the } to the word.

After you execute the :map command, all you have to do to put {} around a word is to put the cursor on the first character and press F5. Note When entering this command, you can enter

by pressing the F5 key or by entering the characters <,

F, 5, and >.

Either way works. However, you must enter <Esc> as characters. That is because the <Esc>

key tells Vim to abort the command. Another way of entering an <Esc> key is to type CTRL-V by the <Esc>

key. (The CTRL-V tells Vim

followed

literally instead of acting on it.)

Warning The :map command can remap the Vim commands. If the trigger string is the same as a normal Vim command, the :map will supersede the command in Vim.

Listing Your Mappings The :map command (with no arguments) lists out all your current mappings (see Figure 8.2). ~ ~ ~

i {<Esc>ea}<Esc> <xHome> <xEnd> <End> <S–xF4> <S–F4> <S–xF3> <S–F3> <S–xF2> <S–F2> <S–xF1> <S–F1> <xF4> <xF3> <xF2> <xF1> Press RETURN or enter command to continue

Figure 8.2

:map

command.

93

94

Chapter 8

Basic Abbreviations, Keyboard Mapping, and Initialization

Fixing the Way Delete Works On most terminals, the Backspace key acts like a backspace character and the Delete key sends a delete character. Some systems try to be helpful by remapping the keyboard and mapping the Backspace key to Delete. If you find that your keyboard has the Backspace and Delete keys backward, you can use the following command to swap them: :fixdel

It does this by modifying the internal Vim definitions for backspace (t_kb) and delete (t_kD). This command affects only the Vim keyboard mappings.Your operating system may have its own keyboard mapping tables. For example, Linux users can change their keyboard mapping by using the loadkeys command. For further information, Linux users should check out the online documentation for loadkeys. The X Window system also has a keyboard mapping table. If you want to change this table, you need to check out the xmodmap command. Check the X Window system documentation for details on how to use this command.

Controlling What the Backspace Key Does The ‘backspace’ option controls how the

key works in insert mode. For example, the following command tells Vim to allow backspacing over autoindents: :set backspace=indent

The following command enables you to backspace over the end of lines: :set backspace=eol

In other words, with this option set, if you are positioned on the first column and press

, the current line will be joined with the preceding one. The following command enables you to backspace over the start of an insert: :set backspace=start

In other words, you can erase more text than you entered during a single insert command. You can combine these options, separated by commas. For example: :set backspace=indent,eol,start

Earlier versions of Vim (5.4 and prior) use the following option values.These still work but are deprecated. 0 “” (No special backspace operations allowed) 1 “indent,eol” 2 “indent,eol,start”

Saving Your Setting

Saving Your Setting After performing all your :map, :abbreviate, and :set commands, it would be nice if you could save them and use them again. The command :mkvimrc writes all your settings to a file.The format of this command is as follows: :mkvimrc file

file is the name of the file to which you want to write the settings. You can read this file by using the following command: :source file

During startup, the Vim editor looks for an initialization file. If it is found, it is automatically executed. (Only the first file found is read.) The initialization files are as follows: UNIX $HOME/.vimrc $HOME/_vimrc $HOME/.exrc $HOME/_exrc MS-DOS $HOME/_vimrc $HOME/.vimrc $VIM/_vimrc $VIM/.vimrc $HOME/_exrc $HOME/.exrc $VIM/_exrc $VIM/.exrc When you are running the GUI version, some other files are also read.The gvimrc file is found in the same location as the vimrc files mentioned in the list.The $VIMRUNTIME/menu.vim is read too. One way you can find out which initialization files are read is to use the :version command: :version

In the middle of all the junk it lists out is a list of the initialization files (see Figure 8.3).

95

96

Chapter 8

Basic Abbreviations, Keyboard Mapping, and Initialization

:version VIM – Vi IMproved 5.5 (1999 Sep 19, compiled Nov 27 1999 06:02:50) Compiled by [emailprotected],com. with (+) or without (–): +autocmd +browse +builtin_terms +byte_offset +cindent +cmdline_compl +cmdline_info +comments +cryptv –cscope +dialog_con_gui + digraphs –emacs_tags +eval +ex_extra +extra_search –farsi +file_in_path –osfiletype +find_in_path +fork() +GUI_GTK –hangul_input +insert_expand –langmap +linebreak +lispindent +menu +mksession +modify_fname +mouse –mouse_dec –mouse_gpm –mouse_netterm +mouse_xterm –multi_byte –perl +quickfix –python –rightleft +scrollbind +smartindent –sniff +statusline +syntax +tag_binary +tag_old_static –tag_any_white –tcl +terminfo +textobjects +title +user_commands +visualextra +viminfo +wildmenu +wildignore +writebackup +X11 –xfontset –xim +xterm_clipboard –xterm_save system vimrc file: "$VIM/vimrc" user vimrc file: "$HOME/.vimrc" user exrc file: "$HOME/.exrc" system gvimrc file: "$VIM/gvimrc” user gvimrc file: "$HOME/.gvimrc" system menu file: "$VIMRUNTIME/menu.vim” fall-back for $VIM: "/usr/local/share/vim” Compilation: gcc –c –I. –Iproto –DHAVE_CONFIG_H –DUSE_GUI_GTK –I/usr/X11R6/inc lude –I/usr/lib/glib/include –g –o2 –Wall –I/usr/X11R6/include Linking: gcc –o vim –L/usr/lib –L/usr/X11R6/lib –lgtk –lgdk –rdynamic –lgmodul –– More ––

Figure 8.3

Locating the initialization files with :version.

One other initialization file has not yet been discussed: .exrc.The old Vi editor used this file for initialization.This is only read if Vim cannot find any other initialization file. Because the old Vi program does not understand many of the Vim commands, you will probably want to put everything in the .vimrc file. The :mkexrc command writes the mappings to the .exrc file. If you want to use all the power of Vim, however, you must use the :mkvimrc command instead.

My .vimrc File My .vimrc file contains the following: :syntax on :autocmd FileType * set formatoptions=tcql \ nocindent comments& :autocmd FileType c,cpp set formatoptions=croql \ cindent comments=sr:/*,mb:*,ex:*/,:// :set autoindent :set autowrite :ab #d #define :ab #i #include :ab #b /**************************************** :ab #e <Space>****************************************/ :ab #l /*-------------------------------------------- */ :ab #j Jack Benny Show :set shiftwidth=4 :set hlsearch :set incsearch :set textwidth=70

The file starts with a command to turn syntax coloring on: :syntax on

Saving Your Setting

The next thing is an autocommand executed every time a file type is determined (on file load). In this case, set the formatting options to tcql, which means autowrap text (t), autowrap comments (c), allow gq to format things (q), and do not break long lines in insert mode (l). I also turn off C-style indenting (nocindent) and set the ‘comments’ option to the default (comments&): :autocmd FileType * set formatoptions=tcql \ nocindent comments&

If a C or C++ file is loaded, the following autocommand is executed. It defines some additional format options, namely adding the comment header for new lines (r) and new lines opened with an O command (o). It also turns on C indentation and defines the “comments” option for C- and C++-style comments. Because this autocommand comes after the one for all files, it is executed second (but only for C and C++ files). Because it is executed second, its settings override any set by a previous autocommand: :autocmd FileType c,cpp set formatoptions=croql \ cindent comments=sr:/*,mb:*,ex:*/,://

The next options turn on automatic indentation (indent each line the same as the preceding one) and autowriting (write files when needed). Note that because the autocommands execute when the file type is determined, any settings they have override these: :set autoindent :set autowrite

What follows is a set of abbreviations useful to programmers and a collector of old Jack Benny radio shows: :ab #d #define :ab #i #include :ab #b /**************************************** :ab #e <Space>****************************************/ :ab #l /*----------------------------------------------*/ :ab #j Jack Benny Show

The indentation size is set to 4, a value that studies have shown is best for programming: :set shiftwidth=4

The next two options turn on fancy searching: :set hlsearch :set incsearch

When working with text, I like a 70-column page: :set textwidth=70

97

Basic Command-Mode Commands

T

HIS VIM EDITOR IS BASED ON AN older

editor called Vi.The Vi editor was based on

a command-line editor called ex.The ex editor was made before screen-oriented editors were popular. It was designed for the old printing terminals that were standard at that time. Even though it was line oriented, the ex editor was an extremely versatile and efficient editor. It is still very useful today. Even with Vim’s tremendous command set, a few things are still better done with ex-style commands. So the people who created Vim give you access to all the ex commands through the use of command-line mode. Any command that begins with a colon is considered an ex-style command. This chapter shows how ex-mode commands are structured and also discusses the most useful ones, including the following: n

Printing text lines

n

Substitution

n

Shell (command prompt) escapes

100

Chapter 9

Basic Command-Mode Commands

Entering Command-Line Mode If you want to execute a single command-line-mode command, just type a colon (:) followed by the command. For example, the command :set number is actually a command-mode command. A discussion of command-mode commands makes more sense with line numbering turned on.Therefore, the first command-mode command you enter for this example is as follows: :set number

After this command has been executed, the editor returns to normal mode. Switch to command-line mode by executing the command :ex.The Q command also performs this operation.To switch back to normal mode (visual mode), use the :visual command.

The Print Command The :print command (short form :p) prints out the specified lines.Without arguments, it just prints the current line: :print 1 At one university the computer center was

Ranges The :print command can be made to print a range of lines. A simple range can be something like 1,5.This specifies lines 1 through 5.To print these lines, use the following command: :1,5 print 1 2 3 4 5

At one university the computer center was experiencing trouble with a new type of computer terminal. Seems that the professors loved to put papers on top of the equipment, covering the ventilation holes. Many terminals broke

Strictly speaking, you do not have put a space between the 5 and the print, but it does make the example look nicer. If you want to print only line 5, you can use this command: :5 print 5 the ventilation holes. Many terminals broke

You can use a number of special line numbers. For example, the line number $ is the last line in the file. So to print the whole file, use the following command: :1,$ print 1 At one university the computer center was ... 36 Notice: 37 38 If your computer catches fire, please turn it 39 off and notify computing services.

The Print Command

The

%

range is shorthand for the entire file (1,$). For example:

:% print 1 At one university the computer center was ... 36 Notice: 37 38 If your computer catches fire, please turn it 39 off and notify computing services.

The line number (.) is the current line. For example: :. print 39 off and notify computing services.

You can also specify lines by their content.The line number /pattern/ specifies the next line containing the pattern. Let’s move up to the top with :1 print, and then print the lines from the current line (.) to the first line containing the word trouble: :1 print 1 At one university the computer center was :1,/trouble/print 1 At one university the computer center was 2 experiencing trouble with a new type of computer

Similarly, ?pattern? specifies the first previous line with pattern in it. In the following example, we first move to the end of the file with :39 print and then print the last line with the word Notice in it to the end of the file: :39 print 39 off and notify computing services. :?Notice:?,39 print 36 Notice: 37 38 If your computer catches fire, please turn it 39 off and notify computing services.

Marks Marks can be placed with the normal-mode m command. For example, the ma command marks the current location with mark a. You can use marks to specify a line for command-mode commands.The line number ‘a specifies the line with mark a is to be used. Start in normal mode, for example, and move to the first line of the file.This is marked with a using the command ma.You then move to line 3 and use the command mz to mark line as z.The command :’a, ‘z print

is the same as the following command: :1,3 print

101

102

Chapter 9

Basic Command-Mode Commands

Visual-Mode Range Specification You can run a command-mode command on a visual selection.The first step is to enter visual mode and select the lines you want.Then enter the command-mode command to execute. Figure 9.1 shows that the first three lines of the text have been selected. 1 At one university the computer center was 2 experience trouble with a new type of computer 3 terminal. Seems that the professors loved to 4 put papers on top of the equipment, covering 5 the ventilation holes. Many terminals broke 6 down because they became so hot that the solder –– VISUAL ––

Figure 9.1

Visual-mode selection.

Next, enter the :print command to print these lines.The minute you press :, Vim goes to the bottom of the screen and displays the following: :’<,’>

The special mark < is the top line of the visual selection and the mark > is the bottom. Thus, Vim is telling you that it will run the command on the visual selection. Because < is on line 1, and > is on line 3, a :print at this point prints lines 1 to 3.The full command, as it appears onscreen, looks like this: :‘<,‘>print

Substitute Command The :substitute command enables you to perform string replacements on a whole range of lines.The general form of this command is as follows: :range substitute /from/to/ flags

(Spaces were added for readability.) This command changes the from string to the to string. For example, you can change all occurrences of Professor to Teacher with the following command: :% substitute /Professor/Teacher/ Note The :substitute command is almost never spelled out completely. Most of the time, people use the abbreviated version :s. (The long version is used here for clarity.)

By default, the :substitute command changes only the first occurrence on each line. For example, the preceding command changes the line Professor Smith criticized Professor Johnson today.

Substitute Command

to Teacher Smith criticized Professor Johnson today.

If you want to change every occurrence on the line, you need to add the g (global) flag.The command :% substitute /Professor/Teacher/g

results in Teacher Smith criticized Teacher Johnson today.

Other flags include p (print), which causes the :substitute command to print out each line it changes. The c (confirm) flag tells the :substitute to ask you for confirmation before it performs each substitution.When you enter the following :1,$ substitute /Professor/Teacher/c

the Vim editor displays the text it is about to change and displays the following prompt: Professor: You mean it’s not supposed to do that? replace with Teacher (y/n/a/q/^E/^Y)?

At this point, you must enter one of the following answers: y

Make this replacement.

n

Skip this replacement.

a

Replace all remaining occurrences without confirmation.

q

Quit. Don’t make any more changes.

CTRL-E

Scroll one line up.

CTRL-Y

Scroll one line down.

How to Change Last, First to First, Last Suppose you have a file containing a list of names in the form last, first, and you want to change it to first, last. How do you do it? You can use the :substitute command to do it in one operation.The command you need is shown in Figure 9.2. The to string takes the first name (\2) and last name (\1) and puts them in order.

103

104

Chapter 9

Basic Command-Mode Commands

Put matching text in \2

Put matching text in \1

\ ( [^,]*\),\ (.*\)$ Match anything except a comma Repeat 0 or more times Match the character comma Match any character ( . ), 0 or more times Match end of line

Figure 9.2

Changing last, first to first, last.

Reading and Writing Files The :read filename command (short form :r) reads in a file and inserts it after the current line. The :write command (short form :w) writes out the file.This is a way of saving your work.You can write a different file (prog.c.new, for example) by giving :write a filename as an argument: :write prog.c.new

Warning

If you exit using the emergency abort command :q!, the file reverts to the last written version.

The :write command usually does not overwrite an existing file.The force (!) option causes it to ignore this protection and to destroy any existing file. The :write command proves extremely useful when it comes to exporting portions of a large file to a smaller one—for example, if you have a collection of jokes and want to write one out to a file to send to a friend. To export a single joke, first highlight it in visual mode.Then use the following command to write it out to the file file.txt: :’<,’> write joke.txt

The :shell Command The :shell command takes you to the command prompt.You can return to Vim by executing the exit command. For example: :shell $ date Mon Jan 17 18:55:45 PST 2000 $ exit -- vim window appears --

The :shell Command

In this example, we are on UNIX, so we get the UNIX prompt ($). If we were using the UNIX version of gvim, Vim would start a shell in the GUI window. On MS-DOS, the Vim command acts just like UNIX when a :shell command is executed. If you are using the GUI, however, the :shell command causes an MS-DOS prompt window to appear.

105

Basic GUI Usage

The Vim editor works well inside a windowing environment.This graphical user interface (GUI) provides you with not only all of Vim’s keyboard commands, but also a number of menus and other options.This chapter shows you how to start Vim in GUI mode and how to make use of the special GUI features.

Starting Vim in GUI Mode To start Vim in windowing mode, use the following command: $ gvim file

This command starts up a Vim window and begins to edit file. The actual appearance of the screen depends on which operating system you are using. On UNIX it also depends on which X Window system toolkit (Motif, Athena, GTK) you have. Figures 10.1, 10.2, and 10.3 show the various types of GUIs.

Figure 10.1

UNIX with the GTK toolkit.

108

Chapter 10

Basic GUI Usage

Figure 10.2

UNIX with the Motif toolkit.

Figure 10.3

Microsoft Windows.

If you have a choice of UNIX GUIs to choose from, it is recommended that you use the GTK version.

Mouse Usage Standards are wonderful. In Microsoft Windows, you can use the mouse to select text in a standard manner.The X Window system also has a standard system for using the mouse. Unfortunately, these two standards are not the same. Fortunately, you can customize Vim.You can make the behavior of the mouse look like an X Window system mouse or a Microsoft Windows mouse.The following command makes the mouse behave like an X Window mouse: :behave xterm

The following command makes the mouse look like a Microsoft Windows mouse: :behave mswin

The default behavior of the mouse on UNIX systems is xterm.The default behavior on a Microsoft Windows system is selected during the installation process. In addition to controlling the behavior of the mouse, the :behave command affects the following options:

Setting for

Setting for

Option

:behave mswin

:behave xterm

‘selectmode’

mouse,key

(empty)

‘mousemodel’

popup

extend

‘keymodel’

startsel,stopsel

(empty)

‘selection’

exclusive

inclusive

Tear-Off Menus

X Mouse Behavior When xterm behavior is enabled, the mouse behavior is as follows:

Move the cursor.

Drag with

Select text in visual mode.

Extend select from cursor location to the location of the mouse.

<Middle Mouse>

Paste selected text into the buffer at the mouse location.

Microsoft Windows Mouse Behavior When mswin behavior is enabled, the mouse behavior is as follows:

Move the cursor.

Drag with

Select text in select mode.

<S-Left Mouse>

Extend selection to the cursor location.

<S-Right Mouse>

Display pop-up menu.

<Middle Mouse>

Paste the text on the system Clipboard into file.

Special Mouse Usage You can issue a number of other special commands for the mouse, including the following <S-Left Mouse>

Search forward for the next occurrence of the word under the cursor.

<S-Right Mouse>

Search backward for the preceding occurrence of the word under the cursor.

Jump to the tag whose name is under the cursor.

Jump to the preceding tag in the stack.

Tear-Off Menus The menus in Vim (all GUI versions except Athena) have an interesting feature: “tearoff ” menus. If you select the first menu item (the dotted lines), you can drag the menu to another location on the screen. Figure 10.4 shows how to tear off a menu.

Note

If you execute a command that requires a motion, such as dmotion, you can use the left mouse button for the motion.

109

110

Chapter 10

Basic GUI Usage

Figure 10.4

Tear-off menus.

When torn off, the menu remains as its own window until you close it using the normal window close command.

Figure 10.5

Toolbar.

Toolbar A toolbar appears in the GTK and MS-Windows versions of the GUI. It looks something like Figure 10.5. The icons perform the following functions: Open. Brings up a File Open dialog box. Save. Saves the current file. Save All. Save all the open files in all windows and buffers. Print. Print to system printer. Undo. Redo.

Toolbar

Cut. (Actually “delete.”) Copy. (Actually “yank.”) Paste. Search. Brings up a dialog box so that you can enter a pattern. Find Next. Find Previous. Replace. Brings up a Search-and-Replace dialog box. Make Session. Brings up a dialog box so that you can enter the name of a session file to write to. Load Session. Brings up a dialog box so that you can select the session file to load. Script. Brings up a dialog box so that you can select a script to run. Make. Performs a :make. Shell. Does a :shell. Make Tags. Does a :!ctags -R . command. Tag. Jumps to the definition of the tag under the cursor. Help. Brings up the general help screen. Help Search. Brings up a dialog box so that you can enter a help topic to be displayed.This button is slightly misnamed because it does not do a general search of the help documents, but only looks for tags.

111

Dealing with Text Files

D

ESPITE THE PROLIFERATION OF WORD PROCESSING tools

such as Microsoft Word,

StarOffice, and such, people still use plain-text files for documentation because this type of file is the most easily read. In this chapter, you learn about the following: n

Automatic text wrapping

n

Text formatting command

n

Text formatting options

n

Dealing with different file formats

n

Troff-related commands

n

The rot13 algorithm

Automatic Text Wrapping The Vim editor has a number of functions that make dealing with text easier. By default, the editor does not perform automatic line breaks. In other words, you have to press <Enter> yourself.This is extremely useful when you are writing programs where you want to decide where the line ends. It is not so good when you are creating documentation and do not want to have to worry about where to break the lines.

114

Chapter 11

Dealing with Text Files

If you set the ‘textwidth’ option, Vim automatically inserts line breaks. Suppose, for example, that you want a very narrow column of only 30 characters.You need to execute the following command: :set textwidth=30

Now you start typing (ruler added): 1 2 12345678901234567890123456789012345 I taught programming for a while

3

The word while makes the line longer than the 30-character limit.When Vim sees this, it inserts a line break and you get the following: I taught programming for a while

Continuing on, you can type in the rest of the paragraph: I taught programming for a while. One time, I was stopped by the Fort Worth police because my homework was too hard. True story.

You do not have to type newlines; Vim puts them in automatically. You can specify when to break the line in two different ways.The following option tells Vim to break the line 30 characters from the left side of the screen: :set textwidth=30

If you use the following option, you tell Vim to break the lines so that you have margin characters from the right side of the screen.: :set wrapmargin=margin

Therefore, if you have a screen that is 80 characters wide, the following commands do the same thing: :set wrapmargin=10 :set textwidth=70

The Vim editor is not a word processor. In a word processor, if you delete something at the beginning of the paragraph, the line breaks are reworked. In Vim they are not; so if you delete some words from the first line, all you get is a short line: I taught for a while. One time, I was stopped by the Fort Worth police because my homework was too hard. True story.

Note The ‘textwidth’ option overrules ‘wrapmargin’.

Text Formatting Command

This does not look good; so how do you get the paragraph into shape? There are several ways.The first is to select the paragraph as part of a visual selection: I taught for a while. One time, I was stopped by the Fort Worth police because my homework was too hard. True story.

Then you execute the gq command to format the paragraph. I taught for a while. One time, I was stopped by the Fort Worth police because my homework was too hard. True story.

Another way to format a paragraph is to use the gqmotion command.Therefore to format 5 lines, you use the command gq4j. (The 4j tells gq to format this line and the next 4–5 lines total.) The move forward paragraph command (})also proves useful in such cases.To format a paragraph, for example, position the cursor on the first line of the paragraph and use the command gq}. It is much easier to use this command than to count the lines. The command gqip formats the current paragraph. (The gq formats the selected text and the ip selects the “inner paragraph.”) This is easier than gq} because you don’t have to put the cursor on the beginning of a paragraph. Finally, to format a line, use the gqgq command.You can shorten this to gqq.

Text Formatting Command To center a range of lines, use the following command: :range center width

If a width is not specified, it defaults to the value of ‘textwidth’. (If ‘textwidth’ is 0, the default is 80.) For example: :1,5 center 30

results in the following: I taught for a while. One time, I was stopped by the Fort Worth police because my homework was too hard. True story.

Similarly, the command :right right-justifies the text. So, :1,5 right 30

115

116

Chapter 11

Dealing with Text Files

gives results in the following: I taught for a while. One time, I was stopped by the Fort Worth police because my homework was too hard. True story.

Finally there is this command: :range left margin

Unlike :center and :right, however, the argument to :left is not the length of the line. Instead it is the left margin. If this is 0, the text will be put against the left side of the screen. If it is 5, the text will be indented 5 spaces. For example, these commands :1 left 5 :2,5 left 0

result in the following:: I taught for a while. One time, I was stopped by the Fort Worth police because my homework was too hard. True story.

Justifying Text The Vim editor has no built-in way of justifying text. However, there is a neat macro package that does the job.To use this package, execute the following command: :source $VIMRUNTIME/macros/justify.vim

This macro file defines a new visual command _j.To justify a block of text, highlight the text in visual mode and then execute _j.

Fine-Tuning the Formatting A number of options enable you to fine-tune and customize your spaces.

The joinspaces Option The J command joins two lines putting in one space to separate them. If the ‘joinspaces’ option is set, when the first line ends with a punctuation mark (period, question mark, or exclamation point), two spaces are added. Input the following (= represents a space): This=is=a=test. Second=line.

When the ‘joinspaces’ option is turned off with the following command :set nojoinspaces

Fine-Tuning the Formatting

the result of a J on the first line is as follows: This=is=a=test.=Second=line.

If the option is set using this command :set joinspaces

the result is as follows: This=is=a=test.==Second=line.

The formatoptions Option ‘formatoptions’ controls

how Vim performs automatic wrapping.The Vim editor is smart about comments and does a proper job of formatting them.With ‘formatoptions’ you can control both how text and comments are wrapped. The format of this option is as follows: :set formatoptions=characters

where characters is a set of formatting flags.The following list identifies the formatting flags. t

Automatically wrap text.

c

Automatically wrap comments. Insert the comment leader automatically.

r

Insert comment leader in a comment when a new line is inserted.

o

Insert comment leader in a comment when a new line is created using the O and o command.

q

Allow gq to format comments.

2

Format based on the indent of the second line, not the first.

v

Do old-style Vi text wrapping.Wrap only on blanks that you enter.

b

Wrap only on blanks you type, but only if they occur before ‘textwidth’.

l

Do not break line in insert mode. Only let gq break the lines.

Take a look at how these flags affect the formatting. The t flag must be on for normal text to be wrapped.The c flag must be on for comments to be wrapped.Therefore, setting the ‘formatoptions’ option using the following command is good for programming: :set formatoptions=c

Long lines inside a comment are automatically wrapped. Long lines of code (Vim calls them text) are not wrapped. Actually you want to set this option: :set formatoptions=cq

This tells Vim to not only wrap comments, but also to reformat comments as part of a gq command.

117

118

Chapter 11

Dealing with Text Files

Vim is smart about comments.When it wraps a line in the middle of a C-style command, it automatically adds the comment header in front of the line. Suppose, for example, that you enter the following command: /* This is a test of a long line.

This line is longer than the ‘textwidth’, so it wraps. Because it is in a comment, Vim automatically puts in an asterisk (*).Therefore, although you typed everything on one line, the result is as follows: /* This is a test of a long * line.

But suppose you actually type <Enter>? By default, Vim does not insert the asterisk. This means that if you type a two-line comment, you get the following: /* Line 1 Line 2

If you put an r flag in the ‘formatoptions‘, however, Vim automatically supplies the comment leader (*) when you press Return: /* Line 1 * Line 2

If you want to have this done for the O and o commands, you need to put in the o flag as well.

Text Formatting Options The 2 option tells Vim to format based on the second line of the text rather than the first. For example, the original example text is displayed in Figure 11.1. If you do not have the 2 flag in the formatoptions and you reformat the paragraph with gq}, you get the results shown in Figure 11.2. The first Centronics Printer manual had a whole chapter devoted to how to open up the packing crate and find the manual. (What did they think we were reading anyway?) ~ ~ ~ ~ ~

Figure 11.1

The original text.

The first Centronics Printer manual had a whole chapter devoted to how to open up the packing crate and find the manual. (What did they think we were reading anyway?) ~ ~ ~ ~

Figure 11.2

Formatted text (no 2 flag).

Fine-Tuning the Formatting

If you go back to the original paragraph, however, set the 2 flag with the following :set formatoptions += 2

and reformat using gq}, you will get the results shown in Figure 11.3. The v flag character controls where a line will be split. Suppose that you have the following line: This is a test of the very long line wrapping

Now add the word logic to the end of the sentence.Without the v flag, the result is as follows: This is a test of the very long line wrapping logic.

With v in ‘formatoptions‘, you get the following: This is a test of the very long line wrapping logic.

Even though the existing line is much longer than ‘textwidth’, with v set, Vim will not break the line in the existing text. Instead it breaks only things in the text you add. If the l character is present in the ‘formatoptions’, Vim will break only the line if the space you type is less than the ‘textwidth’. If you add the word logic to the preceding example, you get the following: This is a test of the very long line wrapping logic.

If you were to type this line from scratch, however, you would get the following: This is a test of the very long line wrapping logic.

Using an External Formatting Program By default, Vim uses its internal formatting logic to format the text. If you want, however, you can run an external program to do the job. On UNIX, the standard program fmt does a good job of doing the work. If you want to use this command for the gq work, set the following option: :set formatprg=fmt

The first Centronics Printer manual had a whole chapter devoted to how to open up the packing crate and find the manual. (What did they think we were reading anyway?) ~ ~ ~ ~

Figure 11.3

Formatted text (2 set).

119

120

Chapter 11

Dealing with Text Files

Even without this option, however, you can always use the filter (!) command to format text.To run a paragraph through the program fmt, for example, use the command !}fmt.The ! starts a filter command, the } tells Vim to filter a paragraph, and the rest (fmt) is the name of the command to use.

File Formats Back in the early days, the old Teletype machines took two character times to do a newline. If you sent a character to the machine while it was moving the carriage back to the first position, it tried to print it on-the-fly, leaving a smudge in the middle of the page. The solution was to make the newline two characters:

to move the carriage to column 1, and to move the paper up. When computers came out, storage was expensive. Some people decided that they did not need two characters for end-of-line.The UNIX people decided they could use only for end-of-line.The Apple people standardized on . The MS-DOS (and Microsoft Windows) folks decided to keep the old . This means that if you try to move a file from one system to another, you have line problems.The Vim editor automatically recognizes the different file formats and handles things properly behind your back. The option ‘fileformats’ contains the various formats that will be tried when a new file is edited.The following option, for example, tells Vim to try UNIX format first and MS-DOS format second: :set fileformats=unix,dos

The detected file format is stored in the ‘fileformat’ option.To see which format you have, execute the following command: :set fileformat?

You can use the ‘fileformat’ option to convert from one file format to another. Suppose, for example, that you have an MS-DOS file named readme.txt that you want to convert to UNIX format. Start by editing the MS-DOS format file: $ vim README.TXT

Now change the file format to UNIX: :set fileformat=unix

When the file is written, it will be in UNIX format. Note

If you are an old Vi user and tried to edit an MS-DOS format file, you would have found that each line ended with a ^M character. (^M is

.) Fortunately, Vim handles both UNIX and MS-DOS file formats automatically.

Troff-Related Movement

Changing How the Last Line Ends The Vim editor assumes that your file is made up of lines.This means that Vim assumes that the last line in the file ends in an <EOL> character. Sometimes you will encounter a strange file that contains an incomplete line.When Vim encounters this type of file, it sets the ‘noendofline’ option. (If your file ends in a complete line, the ‘endofline’ option is set.) If you want to change whether or not your file ends in an <EOL>, use the command :set endofline

(Last line ends in <EOL>.) or :set noendofline

(Last line does not have an <EOL>.) This option only works when the ‘binary’ option is set.

Troff-Related Movement A number of commands enable you to move through text. The ) command moves forward one sentence. The ( command does the same thing backward. The } command moves forward one paragraph, and { moves one paragraph backward. Figure 11.4 shows how these commands work. At one time the troff program was the standard UNIX word processor. It takes as input a text file with processing directives in it and formats the text. Although troff is rarely used these days, the Vim editor still contains an option for dealing with this formatter. The troff program uses macros to tell it what to do. Some of these macros start paragraphs. In the following example, for instance, the macro .LP starts each paragraph: .LP This is a test of the \fItroff\fP text processor. It takes encode text and typesets it. .LP This is the second paragraph.

}

}

.B rgview .SH DESCRIPTION .B Vim is a text editor that is upwards compatible to Vi. It can be used to edit any ASCII text. It is especially useful for editing programs. .PP There are a lot of enhancements above Vi: multi level multi windows and buffers, syntax hightlighting, comman editing, filename completion, on–line help, visual sel See “:help vi_diff.txt” for a summary of the differenc .B Vim and Vi. .PP While running .B Vim

Figure 11.4

}

command.

121

122

Chapter 11

Dealing with Text Files

Because troff uses lots of different macro packages, Vim needs to know which macros start a paragraph.The ‘paragraphs’ option does this.The format of this option is as follows: :set paragraphs=”macromacromacro...”

Each macro is the two-character name of a troff macro. For example: :set paragraphs=”P<Space>LP”

tells Vim that the macros .P and .LP start a paragraph. (Note that you use P<Space>

to indicate the .P macro.) By default, the ‘paragraphs’ option is as follows: :set paragraphs=IPLPPPQPP LIpplpipbp

This means that the following macros .IP .LP .pp .lp

.PP .ip

.QP .bp

.P

.LI

start a new paragraph.

Section Moving The [[ and [] commands move a section backward. A section is defined by any text separated by a page break character (CTRL-L).The reason there are two movement commands is that these commands also move forward and backward through procedures. (Chapter 7, “Commands for Programmers,” contains information on programming commands.) The ]] and ][ commands perform the forward movements as seen in Figure 11.5. ]] ]]

This is page 1 ^L This is page 2 Another paragraph ^L This is page 3 with a two line paragarph And another one ~ ~ ~ ~ ~ ~

Figure 11.5

The ]] command.

Encrypting with rot13

Defining Sections You can also define a section using troff macros.The ‘sections‘ option acts much like the ‘paragraph‘ option, except that it defines the macros that separate sections rather than paragraphs.The default is as follows: :set section=SHNHH HUnhsh

Encrypting with rot13 If you want to encrypt a block of text with the rot13 algorithm, use the g?motion command.The rot13 encryption is an extremely weak encryption scheme designed to obscure text. It is frequently used in news posting for potentially offensive material. Naturally g?g? or g?? encrypts the current line. You can decrypt the rot13 encryption by encrypting the text twice.

123

Automatic Completion

T

HE VIM EDITOR CAN AUTOMATICALLY COMPLETE words

on insertion.This is where

you type the first part of a word, press CTRL-P, and Vim guesses at the rest. How it decides what to use for completion is both simple and flexible.This chapter covers every aspect of this function. This chapter discusses the following: n

Automatic completion

n

How to customize the automatic completion feature

n

How to use different types of completions

Automatic Completion When you are entering text, Vim can assist you to complete words. Suppose, for example, that you are creating a C program and want to type in the following: total = ch_array[0] + ch_array[1] + ch_array[2];

You start by entering the following: total = ch_array[0] + ch_

126

Chapter 12

Automatic Completion

At this point, you tell Vim to complete the word using the command CTRL-P.This command tells Vim to search a word to complete. In this case, it is the word ch_array. So typing CTRL-P gives you the following: total = ch_array[0] + ch_array

After a little more typing, you get this: total = ch_array[0] + ch_array[1] +

If you now type CTRL-P again, Vim will search again for a word that completes the word before the cursor. (In this case, it is “”.) The first word that matches is ch_array. Typing CTRL-P again gives you the next word that matches (in this case, total). A third CTRL-P causes the editor to run out of words, so it returns to the original entry: “ ”. A fourth CTRL-P causes the editor to start over again with ch_array.

How Vim Searches for Words The Vim editor goes through a lot of effort to find words to complete. By default, it uses the following search algorithm: 1. Current file 2. Files in other windows 3. Other file in the currently loaded buffers 4. Files in unloaded buffers 5. The current “tags” list 6. All files #included by the current file

You can customize the search order. (This is described in the section “Customization of Completion.”)

Searching Forward When you type CTRL-P, Vim searches backward for a word to complete.The CTRL-N command searches forward. Other than the direction, it acts just like the CTRL-P command.

Customization of Completion The ‘ignorecase’ option tells the editor to try all words regardless of case: :set ignorecase

Therefore, if you have the option on, when you try to complete the string ins, Vim will consider INSERT, Inside, and instep, all as candidates (assuming that they appear in the text).

Automatic Completion Details

When you match words in this way, the completed word takes on the case of the matched word.Therefore, the completion list for ins is as follows: instep Inside INSERT What if you want to match INSERT, but put the word insert (lowercase) in your text. You must tell Vim to infer the case of the new word from what is typed, not what is matched.You can set the following option: :set infercase

Then the match list is as follows: instep inside insert

Automatic Completion Details For the most part, the Vim editor does the right thing when it comes to automatic completion. At times, however, you might want to fine-tune your completions. The ‘complete’ option controls where Vim searches for words.The form of this option is as follows: :set complete=key,key,key

key is a key letter (and possible argument).The possible key values are as follows: .

Current file

b

Files in loaded buffers, not in a window

d

Definitions in the current file and in files included by a #include directive

i

Files included by the current file through the use of a #include directive

k

The file defined by the ‘dictionary’ option (discussed later in this chapter)

kfile

The file named {file}

t

The “tags” file. (The ] character can be used as well.)

u

Unloaded buffers

w

Files in other windows

The Include Path Vim uses the ‘path’ option to tell it where to look for files that were included in the current file. (Note that the ‘path’ option also is used for other commands such as :find.)

127

128

Chapter 12

Automatic Completion

Specifying a Dictionary The following option :set dictionary=file,file,...

defines a file to be searched when you press CTRL-P and CTRL-N to match words.To use on Linux, for example, the dictionary file is in /usr/dict/words.Therefore, to add this file to the list of dictionaries searched for, use the following command: :set dictionary=/usr/dict/words

If you have a local list of words, you can search this too: :set dictionary=/home/oualline/words,/usr/doc/words

You can also specify a dictionary by putting the file after the k (key). For example: :set complete=k/usr/oualline/words

You can use the k flag multiple times, each with a different file: :set complete=k/usr/dict/words,k/usr/share/words

Controlling What Is Searched For and CTRL-N enable you to perform a wide variety of searches.What if you want to restrict yourself to just one type of search, however? For that you use the CTRL-X command.When you type CTRL-X, you enter the CTRL-X submode.You can then finetune your search using one of the commands: CTRL-P

CTRL-D

Macro definitions

CTRL-F

Filenames

CTRL-K

Dictionary

CTRL-I

Current files and #included files

CTRL-L

Whole lines

CTRL-]

Tags

CTRL-P

Same as CTRL-P without the CTRL-X (find previous match)

CTRL-N

Same as CTRL-N without the CTRL-X (find next match)

The CTRL-X CTRL-D command searches for a #define macro definition. It will search included files as well. After typing this command, you can type CTRL-N to search for the next definition and CTRL-P for the previous. Take a look at how this works on the following test file.

Automatic Completion Details

File include.h #define MAX(x, y) ((x) < (y) ? (y) : (x)) #define MIN(x, y) ((x) < (y) ? (x) : (y)) int sum(int i1, int i2) {return(i1+i2);}

File main.c #include “include.h” #define MORE “/usr/ucb/more”

You can start by editing main.c. If you type CTRL-X, you enter CTRL-X mode.The editor now displays a mini-prompt at the bottom of the screen (see Figure 12.1). Suppose that you want to look for a macro definition.You would now type CTRL-D. The screen briefly displays the fact that there are three matches, and then displays a new menu (see Figure 12.2). At this point, CTRL-N searches for the next match (and CTRL-P searches for the previous one).The CTRL-D key acts just like CTRL-P. Using these keys, you can cycle through the list of definitions until you find the one that you want.

Tag Search The CTRL-X CTRL-] searches for the next tag. A tag is a C function definition.The program ctags generates a list of C function definitions (tags) and stores them in the tags file.We have generated our tags file using the following command: $ ctags *.c *.h

Now when we enter CTRL-X CTRL-] in insert mode, we get what is shown in Figure 12.3. #include “include.h” #define MORE “/usr/ucb/more” ~ ~ ~ –– ^X mode (^E/^Y/^L/^]/^F/^I/^K/^D/^N/^P) ––

Figure 12.1

CTRL-X

mode.

#include “include.h” #define MORE “/usr/ucb/more” MAX

~ ~ ~ –– Definition completion (^D/^N/^P) ––

Figure 12.2

CTRL-X CTRL-D.

129

130

Chapter 12

Automatic Completion

#include “include.h” #define MORE “/usr/ucb/more” MORE ~ ~ ~ –– Tag completion (^]/^N/^P) ––

Figure 12.3

CTRL-X CTRL-].

The result of typing CTRL-P a couple of times is shown in Figure 12.4. By default, the Vim editor just displays the name alone. If you execute the following command, the entire tag (the function prototype) displays: :set showfulltag

If you repeat your matching commands with this option enabled, you get the results shown in Figure 12.5.

Finding Filenames If you use the CTRL-X CTRL-F command, the Vim editor will match a filename. It scans the current directory for files and displays each one that matches the word in front of the cursor. Suppose, for example, that you have the following files in the current directory: main.c

sub_count.c

sub_done.c

sub_exit.c

Now enter insert mode and start typing: The exit code is in the file sub

At this point, you enter the command CTRL-X CTRL-F.The editor now completes the current word sub by looking at the files in the current directory.The first match is sub_count.c.This is not the one you want, so you match the next file by typing CTRL-N. This match is sub_done.c.Typing CTRL-N again takes you to sub_exit.c. #include “include.h” #define MORE “/usr/ucb/more” sum ~ ~ ~ –– Tag completion (^]/^N/^P) ––

Figure 12.4

Finding previous completions.

#include “include.h” #define MORE “/usr/ucb/more” int sum(int i1, int i2) ~ ~ ~ –– Tag completion (^]/^N/^P) ––

Figure 12.5

The results.

Automatic Completion Details

The results: The exit code is in the file sub_exit.c

Line Mode All the commands discussed so far work on words only.The CTRL-X CTRL-L command works on lines. If you enter CTRL-X CTRL-L in the example, for instance, you get the results shown in Figure 12.6. You can now use CTRL-N and CTRL-P to go up and down lines. #include “include.h” #define MORE “/usr/ucb/more” #define MORE “/usr/ucb/more” ~ ~ ~ –– Whole line completion (^L/^N/^P) ––

Figure 12.6

CTRL-X CTRL-L.

Adjusting the Screen There are two more CTRL-X commands which suprisingly don’t do completion. After typing CTRL-X, you can move the screen up and down a little.The CTRL-Y command scrolls down, whereas the CTRL-E scrolls up.

131

Autocommands

O

NE OF THE NICE ATTRIBUTES OF THE Vim

editor is its flexibility. One of the fea-

tures that makes it so flexible is the autocommand. An autocommand is a command executed automatically in response to some event, such as a file being read or written or a buffer change. Through the use of autocommands, for example, you can train Vim to edit compressed files. (You define an autocommand that uncompresses the file on read and another one to compress the file on write. See the file $VIMRUNTIME/vimrc_example.vim in your VIM installation.) In this chapter, you learn about the following: n

Basic autocommands

n

Autocommand groups

n

Listing and removing autocommands

134

Chapter 13

Autocommands

Basic Autocommands Suppose you want to put a date stamp on the end of a file every time it is written. One way you could do this is to define a function: :function DateInsert() : $read !date : :endfunction

“ Insert the date at the end ($) “ of the file.

Now when you want to write the file all you have to do is to call this function: :call DateInsert()

Then you write the file. That may be a little difficult, so you can map this to a key: :map

:call DateInsert() \| :write

This makes things “easy” because now you just have to press

every time you want to write the file. If you forget, however, and use the normal Vim file writing commands, you screw things up. It would be nice if you could do things automatically.That is where autocommands come in. The command :autocmd FileWritePre * :call DateInsert()

causes the command :call DateInsert() to be executed for all files (*) just before writing the file (FileWritePre).You do not need to put in a :write command because this autocommand is executed just before each :write. In other words, with this command enabled, when you do a :write, Vim checks for any FileWritePre autocommands and executes them, and then it performs the :write. The general form of the :autocmd command is as follows: :autocmd group events file_pattern nested command

The group name is optional. It is used in managing and calling the commands (more on this later).The events parameter is a list of events (comma separated) that trigger the command. (A complete list of events appears later in this chapter.) The file_pattern is a filename (including wildcards).The nested flag allows for nesting of autocommands, and finally, the command is the command to be executed.

Groups The :augroup command starts the definition of a group of autocommands.The group name is just a convenient way to refer to the set of autocommands. For example: :augroup cprograms : autocmd FileReadPost *.c :set cindent : autocmd FileReadPost *.cpp :set cindent :augroup END

Basic Autocommands

Because the :autocmd definitions are inside the scope :augroup, they are put in the cprograms group. The commands in this group are executed after reading a file that ends in .c or .cpp. If you want to add another command to this group for headers, you can use the :augroup command or just include a group name in your specification: :autocmd cprograms FileReadPost *.h :set cindent

Now suppose you are editing a file called sam.cx that you would like treated as a C program.You can tell Vim to go through all the cprograms autogroup commands and execute the ones that match *.c for the FileReadPost event.The command to do this is as follows: :doautocmd cprograms FileReadPost foo.c

The general form of the :doautocmd command is this: :doautocmd group event file_name

This executes the autocommand group pretending that the current file is file_name rather than the current one. If the group is omitted, all groups are used and if file_name is left off, the current filename is used.The event must be specified and is the event that Vim pretends has just happened. The following command does the same thing as :doautocmd except it executes once for each buffer: :doautoall group event file_name

(Note: Do not use this to trigger autocommands that switch buffers, create buffers, or delete them. In other words, when using this command, leave the buffers alone.)

Events You can use the following events to trigger an autocommand: Triggered when editing a file that does not exist.

BufNewFile BufReadPre

BufReadPost

Triggered before (BifReadPre) / after (BufReadPost) reading a buffer

BufRead

Alias for BufReadPost.

BufFilePre

BufFilePost

Before / after changing the name of a buffer with the :file command.

FileReadPre

FileReadPost

Before / after reading a file with the :read command. For FileReadPost, the marks ‘[ and ‘] will be the beginning and end of the text read in.

FilterReadPre

FilterReadPost

Before / after reading a file with a filter command.

135

136

Chapter 13

Autocommands

FileType

When the filetype option is set.

Syntax

When the syntax option is set.

StdinReadPre

StdReadPost

Before / after reading from the standard input. (The editor must have been started as vim–.)

BufWritePre

BufWritePost

Before / after writing the entire buffer to a file.

BufWrite

Alias for BufWritePre.

FileWritePre

FileWritePost

Before / after writing part of a buffer to a file.

FileAppendPre

FileAppendPost

Before / after appending to a file.

FilterWritePre

FilterWritePost

Before / after writing a file for a filter command.

FileChangedShell

FocusGained

This is triggered when Vim runs a shell command and then notices that the modification time of the file has changed. FocusLost

CursorHold

BufEnter

Triggered when Vim gets or loses input focus.This means that Vim is running in GUI mode and becomes the current window or something else becomes the current window. Occurs after the user pauses typing for more than the timeout specified by the updatetime option.

BufLeave

When a buffer is entered or left. Triggered just before a buffer is unloaded.

BufUnload

BufCreate

BufDelete

Just after a buffer is created or just before it is deleted.

WinEnter

WinLeave

Going into or out of a window.

GuiEnter

The GUI just started.

VimEnter

The Vim editor just started and the initialization files have been read.

VimLeavePre

The Vim editor is exiting, but has not written the .viminfo file.

VimLeave

The Vim editor is exiting, and the .viminfo file has been written.

Basic Autocommands

FileEncoding

The fileencoding option has just been set.

TermChanged

The term option changed.

User

Not a real event, but used as a fake event for use with :doautocmd.

When writing a file, Vim triggers only one pair of the following events: BufWritePre

BufWritePost

FilterWritePre

FilterWritePost

FileAppendPre

FileAppendPost

FileWritePre

FileWritePost

When reading a file, one of the following set of events will be triggered: BufNewFile BufReadPre

BufReadPost

FilterReadPre

FilterReadPost

FileReadPre

FileReadPost

File Patterns The filename pattern matching uses the UNIX standard system.The following list identifies the special characters in the file matching patterns. *

Match any characters, any length

?

Match any single character

,

Separates alternate patterns one,two,three Match the string one, two, or three.

\?

The ?.

\,

The ,.

\character

Treat character as a search pattern character. For example, a\+ matches a, aa, aaa, and so on.

Nesting Generally, commands executed as the result of an autocommand event will not trigger any new events. If you read a file in response to a Syntax C, for example, it will not trigger a FileReadPre event. If you include the keyword nested, these events will be triggered. For example: :autocmd FileChangedShell *.c nested e!

137

138

Chapter 13

Autocommands

Listing Autocommands The following command lists all the autocommands: :autocmd

For example: :autocmd —- Auto-Commands —filetype BufEnter *.xpm if getline(1) =~ “XPM2”|set ft=xpm2|endif *.xpm2 set ft=xpm2 ... FileType * set formatoptions=tcql nocindent comments& c set formatoptions=croql cindent ... filetype StdinReadPost * if !did_filetype()|so scripts.vim|endif Syntax OFF syn clear abc so $VIMRUNTIME/syntax/abc.vim

(Listing truncated.) From this, you can see a number of commands under the group filetype.These command are triggered by the BufEnter and StdinReadPost events.There are also a couple of commands with no group name triggered by the FileType event. If you want a subset of all the commands, try the following: :autocmd group event pattern

If group is specified, only the commands for that group are listed. Event can be one of the previously defined events or * for all events.The pattern specifies an optional file matching pattern. Only the commands that match are listed. For example: :autocmd filetype BufEnter *.xpm —- Auto-Commands —filetype BufEnter *.xpm if getline(1) =~ “XPM2”|set ft=xpm2|endif

Removing Commands The command :autocmd! removes autocommands.The matching rules are the same for listing commands, so the following removes all the autocommands: :autocmd!

To remove the commands for a specific group, execute this command: :autocmd! group

Ignoring Events

You can also specify events and patterns for the group, as follows: :autocmd! group event pattern

Again, event can be * to match all events. You can use the :autocmd! command to remove existing commands and define a new one in one command.The syntax for this is as follows: :autocmd! group event pattern nested command

This is the equivalent of the following: :autocmd! group event pattern :autocmd group event pattern nested command

Ignoring Events At times, you will not want to trigger an autocommand.The eventignore option contains a list of events that will be totally ignored. For example, the following causes all Window Enter and Leave events to ignored: :set eventignore=WinEnter,WinLeave

To ignore all events, use the following command: :set eventignore=all

139

File Recovery and Command-Line Arguments

T

HE VIM EDITOR IS DESIGNED TO SURVIVE system

crashes with minimum losses of

data.This chapter discusses how to use Vim’s crash recovery procedures. In this chapter, you learn about the following: n

Command-line arguments for file recovery

n

Encryption

n

Batch files and scripts

n

Additional command-line arguments

n

Backup file options

n

How to do file recovery

n

Advanced swap file management

142

Chapter 14

File Recovery and Command-Line Arguments

Command-Line Arguments There are several useful command-line arguments.The most useful is --help, which displays a short help screen listing all the command-line arguments: $ vim --help VIM - Vi IMproved 5.6 (2000 Jan 16, compiled Jan 20 2000 17:35:46) usage: vim [options] [file ..] edit specified file(s) or: vim [options] read text from stdin or: vim [options] -t tag edit file where tag is defined or: vim [options] -q [errorfile] edit file with first error Options: --g — lots of other help —

End of options Run using GUI (like “gvim”)

To find out which version of Vim you have as well as to list the compilation options, use the following command: $ vim --version VIM - Vi IMproved 5.6 (2000 Jan 16, compiled Jan 20 2000 17:35:46) Compiled by [emailprotected], with (+) or without (-): +autocmd +browse +builtin_terms +byte_offset +cindent +cmdline_compl +cmdline_info +comments +cryptv -cscope +dialog_con_gui +digraphs -emacs_tags +eval +ex_extra +extra_search -farsi +file_in_path -osfiletype +find_in_path +fork() +GUI_GTK -hangul_input +insert_expand -langmap +linebreak +lispindent +menu +mksession +modify_fname +mouse -mouse_dec -mouse_gpm -mouse_netterm +mouse_xterm -multi_byte -perl +quickfix -python -rightleft +scrollbind +smartindent -sniff +statusline +syntax +tag_binary +tag_old_static -tag_any_white -tcl +terminfo +textobjects +title +user_commands +visualextra +viminfo +wildignore +wildmenu +writebackup +X11 -xfontset -xim +xterm_clipboard -xterm_save system vimrc file: “$VIM/vimrc” user vimrc file: “$HOME/.vimrc” user exrc file: “$HOME/.exrc” system gvimrc file: “$VIM/gvimrc” user gvimrc file: “$HOME/.gvimrc” system menu file: “$VIMRUNTIME/menu.vim” fall-back for $VIM: “/usr/local/share/vim” Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -DUSE_GUI_GTK -I/usr/X11R6/include -I/usr/lib/glib/include -g -O2 -Wall -I/usr/X11R6/include Linking: gcc -o vim -L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -lXext -lX11 -lm -L/usr/X11R6/lib -lXt -lX11 -lncurses

To view a file, you can “edit” it in read-only mode by using the -R command: $ vim -R file.txt

On most systems, the following command does the same thing: $ view file.txt

Inserting Registers

Encryption The -x argument tells Vim to encrypt the file. For example, create a file that contains something you want to keep secret: $ vim -x secret.txt

The editor now prompts you for a key used for encrypting and decrypting the file: Enter encryption key:

You can now edit this file normally and put in all your secrets.When you finish editing the file and tell Vim to exit, the file is encrypted and written. If you try to print this file using the cat or type commands, all you get is garbage. Switching Between Encrypted and Unencrypted Modes The option 'key' contains your encryption key. If you set this option to the empty string (“”), you turn off encryption: :set key=

If you set this to a password, you turn on encryption. For example: :set key=secret (Not a good idea!)

Setting the encryption key this way is not a good idea because the password appears in the clear. Anyone shoulder surfing can read your password. To avoid this problem, the :X command was created. It asks you for an encryption key and sets the key option to whatever you type in. (Note that the password will not be echoed. Instead * is printed for each character entered.) :X Enter encryption key:

Limits on Encryption The encryption algorithm used by Vim is weak. It is good enough to keep out the casual prowler, but not good enough keep out a cryptology expert with lots of time on his hands. Also you should be aware that the swap file is not encrypted; so while you are editing, people with superuser privileges can read the unencrypted text from this file. One way to avoid letting people read your swap file is to avoid using one. If the -n argument is supplied on the command line, no swap file is used (instead, Vim puts everything in memory). For example, to edit the encrypted file file.txt and to avoid swap file problems use the following command: $ vim -x -n file.txt

Note

If you use the –n argument, file recovery is impossible.

143

144

Chapter 14

File Recovery and Command-Line Arguments

Also while the file is in memory, it is in plain text. Anyone with privilege can look in the editor’s memory and discover the contents of the file. If you use a session file, be aware that the contents of text registers are written out in the clear as well. If you really want to secure the contents of a file, edit it only on a portable computer not connected to a network, use good encryption tools, and keep the computer locked up in a big safe when not in use.

Executing Vim in a Script or Batch File Suppose you have a lot of files in which you need to change the string —person— to Jones. How do you do that? One way is to do a lot of typing.The other is to write a shell script or batch file to do the work. The Vim editor does a superb job as a screen-oriented editor when started in normal mode. For batch processing, however, it does not lend itself to creating clear, commented command files; so here you will use ex mode instead.This mode gives you a nice command-line interface that makes it easy to put into a batch file. The ex mode commands you need are as follows: :%s/—person—/Jones/g :write :quit

You put these commands in the file change.vim. Now to run the editor in batch mode, use this command: $ vim -es file.txt


This runs the Vim editor in ex mode (-e flag) on the file file.txt and reads from the file change.vim.The -s flag tells Vim to operate in silent mode. In other words, do not keep outputting the : prompt, or any other prompt for that matter.

Additional Command-Line Arguments A number of command-line arguments are designed to control the behavior of the editor. For example, you may want to restrict what you can do in Vim. The arguments to support this are as follows: -R

Open the file for read-only.

-m

Modifications are not allowed.This argument is more of a recommendation than a restriction because all it does is set the 'nowrite' option. It does not prevent you from setting the 'write' option and modifying the file.

-Z

Restricted mode. This prevents the user from using :shell or other commands to run an external shell. It does not prevent the user from trying to edit another file using the :vi file command.

Additional Command-Line Arguments

The other arguments enable you to choose which initialization files you read: -u file

Use file rather than .vimrc for initialization. If the filename is NONE, no initialization file is used.

-U file

Use file rather than .gvimrc for initialization. If the filename is NONE, no initialization file is used. Use file rather than the .viminfo file.

-i file

In UNIX, the Vim editor is actually one file with several different names (links).The editor starts in different modes, depending on with which name it is started.The names include the following: vim

Start Vim in console mode. (Edits inside the current window.)

gvim

Start Vim in GUI mode. (The editor creates its own window for editing.)

ex

Start in ex mode.

view

Start in normal mode, read-only.

gview

Start in GUI mode, read-only.

rvim

Start in console mode, restricted.

rview

Start in console mode, read-only, restricted.

rgvim

Start in GUI mode, restricted.

rgview

Start in GUI mode, read-only, restricted.

vi

Linux only. Alias for vim.

You can use command-line arguments to set the initial mode as well: -g

Start Vim in GUI mode (same as using the command gvim).

-v

Start Vim in visual mode (same as using the command vim).

-e

Start Vim in ex mode (same as using the command ex on most systems).

You can use a number of command-line arguments to debug and test, including the following: -Vnumber

Display extra messages letting you know what is going inside the editor.The higher the number, the more output you get.This is used for debugging your Vim scripts.

-f

Foreground. Do not start a GUI in the background.This proves useful when gvim is run for another program that wants to wait until the program finishes. It is also extremely useful for debugging.

-w script

Write all characters entered by the user into the script file. If the script file already exists, it is appended to.

-W script

Like -w, but overwrite any existing data.

-s script

Play back a script recorded with -w.

145

146

Chapter 14

File Recovery and Command-Line Arguments

-T terminal

Set the terminal type. On UNIX, this overrides the value of the $TERM environment variable. (Of course, if the $TERM environment is wrong, lots of other programs will be screwed up as well.)

You also have compatibility arguments.These are of use only if you really want Vim to act like Vi. -N

Non-compatible mode.This argument makes Vim act like Vim rather than Vi. This argument is set by default when a .vimrc file is present.

-C

Compatible.This turns off many of the Vim special features and makes the editor look as much like Vi as possible.

-l

Lisp mode.This mode is an obsolete holdover from the old Vi days. It sets the 'lisp' and 'showmatch' options.The Vim file-type-related commands do a much better job of handling Lisp programs, and they do it automatically.

Finally, you have a few arguments that cannot be classified any other way: -d device

Amiga only. Open the given device for editing.

-b

Binary mode. Sets noexpandtab, textwidth=0, nomodeline, and binary.

Foreign Languages The Vim editor can handle a variety of languages. Unfortunately, to edit these languages, you do not only need a Vim editor with the language features compiled in, but you also need special fonts and other operating system support.This means that unfortunately foreign language support is beyond the scope of this book. But the command-line arguments for the foreign languages are as follows: -F

Farsi

-H

Hebrew

Backup Files Usually Vim does not produce a backup file. If you want to have one, all you need to do is execute the following command: :set backup

The name of the backup file is the original file with a “~” added to the end. If your file is named data.txt, for example, the backup file name is data.txt~. If you do not like the fact that the backup files end with ~, you can change the extensions by using the following: :set backupext=string

If 'backupext' is .bak, data.txt is backed up to data.txt.bak.

Backup Files

The Vim editor goes you one better when it comes to the backup file. If you set the 'patchmode' option, Vim backs up the file being edited to a file with the same name, but with the 'patchmode' string appended to it.This will be done only if the file does not exist. For example, suppose you execute this command: :set patchmode=.org

Now you edit the existing file data.txt for the first time.When you exit Vim checks to see whether the file data.txt.org exists. It does not, so the old file is saved under that name.The next time you edit, the file does exist; so the backup is written to data.txt~.The file data.txt.org is not used from now on. Instead, all backups will go to data.txt~. Usually Vim puts the backup file in the same directory as the file itself.You can change this with the 'backupdir' option. For example, the following causes all backup files to be put in the ~/tmp directory: :set backupdir=~/tmp/

This can create problems if you edit files of the same name in different directories. That is because their backup files will all go to the ~/tmp directory and the name collision will cause the old backup files to disappear. The 'backupdir' option can actually take a series of directories, separated by comma.The editor puts the backup file in the first directory where a backup file can be created.

Controlling How the File Is Written Generally when Vim writes a file, the following operations are performed: 1. Vim checks to see whether the file has been changed outside of Vim. For example, someone could have overwritten the file with a new one. If this happens, a warning is issued and the editor asks if you want to continue. 2. If the 'writebackup' or 'backup' option is set, any old backup file is removed. The current file is then copied to the backup file. 3. The buffer is written out to the file. 4. If the 'patchmode' option is set and no patch file exists, the backup file is renamed to become the patch file. 5. If the 'backup' option is not set, and 'writebackup' is set, remove the backup file. The reason that Vim overwrites the existing file is to preserve any hard links that you might have on a UNIX system. On non-UNIX systems the backup is created by renaming the original file instead of making a copy. Note

If you set the 'nobackup' and 'nowritebackup' options, Vim just overwrites the existing file. This can cause loss of data if the disk fills up during the file update.

147

148

Chapter 14

File Recovery and Command-Line Arguments

By default, the 'writebackup' option is set.This means that the system Vim uses to write a file makes it very difficult to lose data. By using this method, there is no chance you will lose your file if the disk fills up. You may not be able to write out the new version of the file, but at least you do not lose the old one.

Basic File Recovery Suppose that you want to edit a file called sample.txt.You start Vim with the following command: $ gvim sample.txt

The editor now creates a swap file to temporarily hold the changes you make until you write the file.When you finish editing, the swap file is deleted. If the editor is aborted during mid-edit, however, it does not get a chance to delete the swap file.This means that if you are in the middle of Vim sessions and your system locks, forcing a reboot, the swap file will not be deleted. When Vim first starts editing a file, it checks for a swap file. If it finds one, that means that either another editing session is in progress or another editing session was started and the editor got aborted.Therefore, Vim issues a warning (see Figure 14.1), and gives you a chance to decide what to do. ~ ~ ~ ~ ~ ATTENTION Found a swap file by the name ".sample.txt.swp" dated: Thu Feb 17 22:44:00 2000 owned by: sdo file name: /tmp/sample.txt modified: no host name: www.oualline.com user name: sdo process ID: 8449 (still running) While opening file "sample.txt" dates: Thu Feb 17 22:45:33 2000 (1) Another program may be editing the same file. If this is the case, be careful not to end up with two different instances of the same file when making changes. Quit, or continue with caution. (2) An edit session for this file crashed. If this is the case, use ":recover" or "vim –r sample.txt" to recover the changes (see ":help recovery)". If you did this already, delete the swap file ".sample.txt.swp" to avoid this message.

Figure 14.1

File in use

warning.

At this point, you have four options: Open Read-Only

This option causes Vim to open the file read-only.You should choose this option if you want to look at the file and there is another editing session still running.

Basic File Recovery

Edit anyway

A.K.A. Damn the torpedoes, full steam ahead. If you select this option, you can edit the file. Do not choose this option unless you really know what you are doing. Note that if you have two or more edit sessions running on a single file, the last session to write the file wins.

Recover

If you were editing the file and the editor got aborted due to a system crash or some other reason, choose this option. It examines the swap file for changes and attempts to restart you session from where you left off. It usually comes close, but examine your file carefully because the last few edits may have disappeared.

Quit

Forget about trying to change this file.

After selecting one of these options, you can edit normally. Be careful if you choose Recover, because all your changes may not have been saved.

Recovering from the Command Line If you know the name of the file you were editing when your editing session was aborted, you can start Vim in recovery mode using the -r argument. If you were editing the file commands.c when you were rudely interrupted, for example, you can recover with the following command: $ vim -r commands.c

If you want to get a list of recoverable editor sessions, use this command: $ vim -r

This causes Vim to check for swap files in the current directory and the standard temporary directories. For example: $ vim -r Swap files found: In current directory: -- none -In directory ~/tmp: -- none -In directory /var/tmp: -- none -In directory /tmp: 1. .script.txt.swp dated: Fri Feb 18 19:48:46 2000 owned by: sdo file name: /tmp/script.txt modified: no host name: www.oualline.com user name: sdo process ID: 26473 (still running)

In this example, you see that there is a swap file for the file /tmp/script.txt.The process number of the editor that created the swap file is 26473.The process is still

149

150

Chapter 14

File Recovery and Command-Line Arguments

running, so you probably do not want to try to edit or recover the file using this edit session.You probably want to find the window for process 26473 and use it instead. Several options and other commands affect file recovery. See the section “Advanced File Recovery” for more information.

Advanced Swap File Management The Vim editor goes to a great deal of trouble not to overwrite any old swap files.The first time a file is edited, the swap file name is .file.txt.swp. If the editor is aborted and you start editing again, the next swap file is called .file.txt.swo, and then .file.txt.swn, and so on. You can tell Vim to recover using a specific swap file by specifying the name of the swap file with the command: $ vim -r file.txt.swo

To find out the name of the swap file you are currently using, execute the following command: :swapname

This displays the name of the swap file.

Controlling When the Swap File Is Written Usually the swap file is written every 4 seconds or when you type 200 characters. These values are determined by the 'updatecount' and 'updatetime' options.To change the amount of time Vim waits before writing the swap file to 23 seconds, for example, use the following command: :set updatetime=23000

To change the number of characters you have to type before Vim writes stuff to the swap file to 400, for instance, use this command: :set updatecount=400

If you change the 'updatecount' to 0, the swap file will not be written. However, the decision whether to write a swap file is better controlled by the 'swapfile' option. If you have this option set, a swap file will be created (the default): :set swapfile

If you do not want a swap file, use the following command: :set noswapfile

This option can be set/reset for each edited file. If you edit a huge file and don’t care about recovery, set 'noswapfile'. If you edit a file in another window, it will still use a swap file. Note

The 'updatetime' is specified in milliseconds.

Advanced Swap File Management

On UNIX and Linux, when you “write” a file, the data usually goes into a memory buffer and is actually written to the disk when the operating system “thinks” it is appropriate.This usually takes only a few seconds. If you want to make sure that the data gets to disk, however, you want to use the following command: :set swapsync

This command tells Vim to perform a sync operation after each writing of the swap file to force the data onto the disk.The 'swapsync' option can be empty, 'fsync', or 'sync', depending on what system call you want to do the writing.

Controlling Where the Swap File Is Written Generally, Vim writes the swap file in the same directory as the file itself.You can change this by using the 'directory' option. For example, the following tells Vim to put all swap files in /tmp: :set directory=/tmp

(Not a good idea)

This is not a good idea because if you try to edit the file readme.txt in two different directories at the same time, you encounter a swap file collision. You can set the 'directory' option to a list of directories separated by a comma (,). It is highly recommended that you use a period (.) as the first item it this list.The swap file will be written to the first directory in the list in which Vim can write the file. For example, the following tells Vim to write the swap file in the current directory, and then to try /tmp: :set directory=.,/tmp

Saving Your Work Suppose you have made a bunch of changes and you want to make sure they stick around even if Vim or the operating system crashes. One way to save your changes is to use the following command to write out the file: :write

However, this command overwrites your existing file with all your changes. The following is a related command: :preserve

This command writes all the edits to the swap file.The original file remains unchanged and will not be changed until you do a :write or exit with ZZ. If the system crashes, you can use the swap file to recover all your edits. Note that after a :preserve, you can recover even if the original file is lost.Without this command, you need both the original file and the swap file to recover.

151

152

Chapter 14

File Recovery and Command-Line Arguments

The :recover Command The following command tries to recover the file named file.txt: :recover file.txt

It is just like this command: $ vim -r file.txt

If the file you are trying to recover is currently being edited this command fails. If no filename is specified, it defaults to the file in the current buffer. If you want to discard any changes you have made to the file and attempt to recover, use the following command: :recover! file.txt

MS-DOS Filenames If you are on an MS-DOS or Windows 3.1 machine, you are stuck with very limited filenames.The Vim editor detects this and limits the swap filename to something that can be used on this type of machine.Whereas the normal swap file for foo.txt is .foo.txt.swp, for example, if you are in short name mode, it is foo_txt.swp. You can set the 'shortname' option to force Vim to use this convention.This is useful if have a Linux or other system and are editing files on an MS-DOS partition. In this case, the operating system (Linux) supports long filenames, but the actual disk you are working on (MS-DOS format) does not.Therefore, you need to tell Vim to use the short swap names by giving it the following command: :set shortname

This option is not available for the MS-DOS version of Vim because it would be always on. Instead, it is used when you are cross-platform editing.

readonly and modified Options The 'modified' flag is set if the buffer has been modified.You probably do not want to set this option yourself because it is handled automatically.You can use the value of this option in macros, however. The 'readonly' flag is also set automatically if the file is read-only. In only one circumstance should you reset this: when you are using a source control system that normally leaves files in read-only mode.You want to edit the file, so you start Vim. The editor warns you that the file is read-only and sets the 'readonly' option. At this point, you realize that you forgot to tell the source control system that you want to edit the file. So you use :shell to go to the command prompt and execute the commands needed to tell the system that you want to edit the file.The RCS system uses the co -l command to do this, for example; the SCCS system uses sccs edit.

readonly and modified Options

After getting permission to edit the file, you use the exit command to return to Vim, where you execute the following command to mark the file as editable: :set noreadonly

153

Miscellaneous Commands

T

HIS CHAPTER DISCUSSES ALL THE COMMANDS that

do not quite fit in any other

chapter. In this chapter, you learn about the following: n

Getting character number information

n

How to go to a specific byte in the file

n

Redrawing the screen

n

Sleeping

n

Terminal control

n

Suspending the editor

n

Reshowing the introduction screen

Printing the Character The command :ascii or ga prints the number of the character under the cursor.The output looks like this: <*> 42, Hex 2a, Octal 052

If editing a multibyte (Japanese or Chinese for example) file, and the character under the cursor is a double-byte character, the output shows both bytes.

156

Chapter 15

Miscellaneous Commands

Going to a Specific Character in the File The countgo command goes to byte number count of the file.The command g CTRL-G displays the current byte number of a file (along with the current line, column, and other information). The command :goto offset also positions the cursor to a given byte location within the file. The gg command acts much like the G command. It goes to the line specified by its count. For example, 5gg goes to line 5.The difference between gg and G is that if no count is specified, gg goes to the first line and G goes to the last.

Screen Redraw The CTRL-L command redraws the screen.This proves useful when you are on a terminal and some system message or other text screws up your screen.With the advent of the dedicated GUI, the need for this command is greatly diminished.

Sleep The :sleep time command does nothing for the specified number of seconds. If time ends in m, it is specified in milliseconds.This command proves useful when you want to pause during the execution of a macro. The countgs command also sleeps for count seconds.

Terminal Control On most terminals, the CTRL-S command stops output.To restart it again, you type CTRL-Q.These commands are not part of Vim; to avoid keyboard conflicts, however, they are not used by any Vim commands. You should not try to use these commands in a :map command because your terminal might interpret them and they might never get to Vim.

Suspending the Editor If you are on UNIX in terminal mode, you can suspend the editor with the normalmode command CTRL-Z.To continue editing, use the shell command fg.This works only on shells that have job control.The :suspend command does the same thing.

Note CTRL-Z in insert mode inserts the character CTRL-Z; it does not suspend the editor.

Open Mode

General Help The :help,

and commands all display the general help screen.

Window Size The z height

command resizes the current window to height. If there is only one window open, Vim will desplay only height lines. (The rest will be blank.) This is useful for slow terminals.

Viewing the Introduction Screen If you start Vim without a filename, you will see an introductory flash screen.This screen disappears when you type the first character. If you want to see it again, issue the following command: :intro

Open Mode The Vim editor has all the capabilities of the Vi editor except one: open mode.This mode is Vi’s way of coping with terminals it does not understand. It is difficult to get into this mode, difficult to use it, and the fact that Vim does not have it is no great loss. Vim does have a command to enter open mode, but when you issue the command :open

all you get is an error message.

157

Cookbook

T

HIS CHAPTER PRESENTS A COOKBOOK FULL OF short

recipes for doing some

common (and not so common) Vim editing. The “recipes” include the following: n

Character twiddling

n

Replacing one word with another using one command

n

Interactively replacing one word with another

n

Moving text

n

Copying a block of text from one file to another

n

Sorting a section

n

Finding a procedure in a C program

n

Drawing comment boxes

n

Reading a UNIX man page

n

Trimming the blanks off an end-of-line

n

Oops, I left the file write-protected

n

Changing Last, First to First Last

n

How to edit all the files containing a given word

n

Finding all occurrences of a word

160

Chapter 16

Cookbook

Character Twiddling If you type fast, your fingers can easily get ahead of your mind. Frequently people transpose characters. For example, the word the comes out teh. To swap two characters (for example, e with h), put the cursor on the e and type xp. The x command deletes a character (the e), and the p pastes it after the cursor (which is now placed over the h).

Replacing One Word with Another Using One Command Suppose you want to make all idiots into managers. Execute the following command: :1,$s/idiots/managers/g

The colon (:) indicates that you are going to execute an ex type command. All ex commands begin with range of line numbers on which the command operates. In this case, the whole document is chosen, from line 1 to the last line ($).The shorthand for 1,$ is simply % as shown previously. The :s (abbreviation for :substitute) command performs a substitution.The old text follows enclosed in slashes (/idiots/).The replacement text comes next, also delimited by the slashes (/managers/).The g flag tells the editor that this is a global change and so if the word idiots appears more than once on a line, to change them all.

The Virgin What!?

A church just bought its first computer and was learning how to use it. The church secretary decided to set up a form letter to be used in a funeral service. Where the person’s name was to be, she put in the

word name. When a funeral occurred, she would change this word to the actual name of the departed. One day, there were two funerals, first for a lady named Mary, and then later one for someone named Edna. So the secretary used global replace to change name to Mary. So far, so good. Next, she generated the service for the second funeral by changing the word Mary Imagine the minister’s

to Edna. That was a mistake

surprise when he started reading the part containing the Apostles’ Creed and saw,

“Born of the Virgin Edna.”

Interactively Replacing One Word with Another Suppose you want to replace every occurrence of the word idiot with the word manager, but you want the chance to review each change before you do it.

Moving Text

To do so, follow these steps: 1. Use 1G to go to the top of the document. 2. Execute /idiot to find the first occurrence of the word idiot. 3. Issue the command cwmanager<Esc>. 4. Change the word (cw) to manager. 5. Use the n command to repeat the last search (find the next idiot). 6. Execute the . command to repeat the last edit (change one word to manager). If you do not want to change the word, skip this step. 7. Repeat steps 4 and 5 until you have replaced all occurrences of idiot to manager.

Alternate Method Execute the following command: :%s/idiot/manager/cg

This starts an ex-mode command :substitute (abbreviated :s).The % tells Vim to apply this command to every line in the file.You change idiot to manager.The c flag tells :substitute to get confirmation before each change.The g flag tells the command to change all occurrences on the line. (The default is to change just the first occurrence.)

Moving Text Suppose you want to move a bunch of paragraphs from the top of the document to the bottom. To do so, follow these steps: 1. Move the cursor to the top of the paragraph you want to move. 2. Use

ma

to place a mark named a at this location.

3. Move the cursor to the bottom of the paragraph to be moved. 4. Execute d’a to delete to mark a.This puts the deleted text in a register. 5. Move the cursor to the line where the text is to go.The paragraph will be placed after this one. 6. Use the p command to paste the text below the cursor. Another method consists of the following steps: 1. Select the first line as in the previous list; make it mark a. 2. Move to the bottom of the paragraph (use the } command). Mark b. 3. Move to the line above where you want to put the text, and type the command: :’a,’b move .

161

162

Chapter 16

Cookbook

Copying a Block of Text from One File to Another The old Vi editor did not handle multiple files very well. Fortunately, Vim does a superb job of dealing with more than one file.There are lots of different ways to copy text from one to another. If you are used to the traditional Vi-style commands, you can use a method based around that style. On the other hand, Vim has a very nice visual mode.You can use it as well. Finally, Vim can make use of the system Clipboard to move text from one Vim program to another. All these methods work, and work well.Which one you should use is a matter of taste.

Method: Two Windows with Traditional Vi-Style Commands To copy a block of text between files, follow these steps: 1. Edit the first file. 2. Execute :split second_file to go to the second file. Opens another window and starts editing the second file in it. 3. Use CTRL-W p to go to the “previous” window, the one with the original file. 4. Go to the top line to be copied. 5. Mark this line as mark a by using the ma command. 6. Go to the bottom line to be copied 7. Execute y’a to yank (copy in Microsoft parlance) the text from the current cursor location to mark a (‘a) into the default register. 8. Use CTRL-W p to go to the file that will receive the text. 9. Go to the line where the insert is to occur.The text will be placed before this line. 10. Issue the P command to put (paste in Microsoft terminology) the text in the default register above the current line.

Method: Two Windows Using Visual Mode To copy a block of text between files, follow these steps: 1. Edit the first file. 2. Execute :split to edit the second file. 3. Use CTRL-W p to go to the “previous” window, the one with the original file. 4. Go to the start of the text to be copied. 5. Issue the V command to start visual mode. 6. Go to the end of the text to be copied.The selected text will be highlighted. 7. Execute y to yank (Copy in Microsoft parlance) the text into the default register.

Sorting a Section

8. Use CTRL-W p to go to the file that will receive the text. 9. Go to the line where the insert is to occur.The text will be placed before this line.

10. Issue the P command to put (paste in Microsoft terminology) the text in the default register above the current line.

Method: Two Different Vim Programs In this method, you start up two Vim programs and copy text from one to another. You do this by using the system Clipboard register (“*). 1. Edit the first file. 2. Start another Vim program to edit the second file. 3. Go to the window with the first file in it. 4. Go to the start of the text to be copied. 5. Issue the V command to start visual mode. 6. Go to the end of the text to be copied.The selected text will be highlighted. 7. Use the “*y command to yank (copy in Microsoft parlance) the text into the system Clipboard register (“*). 8. Change to the other editing command. (Make that editor your active window.) 9. Go to the line where the insert is to occur.The text will be placed before this line.

10. Issue the command “*P to put (paste in Microsoft terminology) the text in the system Clipboard register (“*) above the current line. Note

This method enables you to not only move text between two Vim applications, but also to “yank” and “put” between Vim and other applications as well. For example, you can select text in an xterm window using the mouse and paste it into a Vim editing using “*P.

Or you can copy text into the system register

in a Vim session and paste it into a Microsoft Word document using the Edit, Paste commands.

Sorting a Section Frequently you will be editing a file with a list of names in it (for example, a list of object files that make up a program). For example: version.o pch.o getopt.o util.o getopt1.o inp.o patch.o backupfile.o

163

164

Chapter 16

Cookbook

This list would be nice in alphabetic order (or at least ASCII order).To alphabetize this list, follow these steps: 1. Move the cursor to the first line to be sorted. 2. Use the command ma to mark the first line as mark a. 3. Move to the bottom of the text to be sorted. 4. Execute the !’asort command.The ! command tells Vim to run the text through a UNIX command.The ‘a tells the editor that the text to be worked on starts at the current line and ends at mark a. The command that the text is to go through is sort. The result looks like this: backupfile.o getopt.o getopt1.o inp.o patch.o pch.o util.o version.o

Visual Method 1. Move the cursor to the first line to be sorted. 2. Issue the v command to enter visual mode. 3. Move to the bottom of the text to be sorted.The text will be highlighted. 4. Execute the !sort command.The ! command tells Vim to run the highlighted text through the UNIX command sort. Warning In actual practice, what you see in most Makefiles (files used by UNIX to control compilation) looks more like this: OBJS = \ version.o pch.o getopt.o util.o getopt1.o inp.o patch.o backupfile.o

\ \ \ \ \ \ \

Finding a Procedure in a C Program

Notice that the backslash (\) is used to indicate a continuation line. After sorting this looks like the following: OBJS = \ backupfile.o getopt.o getopt1.o inp.o patch.o pch.o util.o version.o

\ \ \ \ \ \ \

The names are in order, but the backslashes are wrong. Do not forget to fix them using normal editing before continuing: OBJS = \ backupfile.o getopt.o getopt1.o inp.o patch.o pch.o util.o version.o

\ \ \ \ \ \ \

Finding a Procedure in a C Program The Vim program was designed by programmers for programmers.You can use it to locate procedures within a set of C or C++ program files. First, however, you must generate a table of contents file called a tags file. (This file has been given the obvious name tags.) The ctags command generates this table of contents file. To generate a table of contents of all the C program files in your current working directory, use the following command: $ ctags *.c

For C++, use this command: $ ctags *.cpp

If you use an extension other than .cpp for your C++ files, use it rather than .cpp. After this file has been generated, you tell Vim that you want to edit a procedure and it will find the file containing that procedure and position you there. If you want to edit the procedure write_file, for example, use the following command: $ gvim -t write_file

165

166

Chapter 16

Cookbook

Now suppose as you are looking at the write_file procedure that it calls setup_data and you need to look at that procedure.To jump to that function, position the cursor at the beginning of the word setup_data and press CTRL-].This tells Vim to jump to the definition of this procedure.This repositioning occurs even if Vim has to change files to do so. Note

If you have edited the current file and not saved it, Vim will issue a warning and ignore the CTRL-] command.

A number of tag-related commands enable you to jump forward/backward through tags, split the windows and put the called procedure in the other window, find inexact tags, and many more things.

Drawing Comment Boxes I like to put a big comment box at the top of each of my procedures. For example: /******************************************************* * Program — Solve it — Solves the worlds problems. * * All of them. At once. This will be a great * program when I finish it. *******************************************************/

* *

Drawing these boxes like this is tedious at best. But Vim has a useful feature called abbreviations that makes things easier. First, you need to create a Vim initialization file called ~/.vimrc.The ~/.vimrc file must contain the following lines: :ab #b /*************************************** :ab #e <Space>****************************************/

These commands define a set of Vim abbreviations. Abbreviations were discussed in Chapter 8,“Basic Abbreviations, Keyboard Mapping, and Initialization Files.” To create a comment box, enter #b<Enter>;.The screen looks like this: /************************************************

Enter the comments, including the beginning and ending * characters. Finally, end the comment by typing #e<Enter>.This causes the ending comment to be entered. Another (better) option is to use an external program like boxes (see http:// www.vim.org), which generates all kinds of ASCII art boxes and can be customized. Here, one might visually select the text and then issue the command :’<,’> !boxes –r ,which would remove an existing box and put a new box around the text. Note This page was written in Vim.

So how did we enter the #b and #e? Easy, we typed in #bb and the

deleted a character. (We could not enter #b or it would have been expanded.) The actual command was i#bb<Esc>x.

Trimming the Blanks off an End-of-Line

Another good tool for this sort of thing is tal, which lines up the final character (the *, here) so it looks nice.

Reading a UNIX man Page You can use the Vim editor to browse through text files. One of the most useful sets of files to browse through is the man pages. Unfortunately, man pages try to simulate formatting by underlining characters using a sequence such as

x for x.This make viewing of the man page in Vim difficult. If you try to read a man page directly, you will see something like this: N^HNA^HAM^HME^HE date - print or set the system date and time

To get rid of these characters, use the standard UNIX command ul -i.This is a formatting program that removes the hard-to-read control characters.The result looks like this: NAME

!!!! date - print or set the system date and time

Now all that is needed is to put three commands together: the man command to get the manual page, the ul -i command to fix the formatting, and vim to read the page. The resulting command is as follows: $ man date | ul -i | vim –

Another technique is to use Vim: :%s/.\b//g

This will remove all characters followed by the backspace (\b), rendering the file readable.

Trimming the Blanks off an End-of-Line Some people find spaces and tabs at the end of a line useless, wasteful, and ugly.To remove whitespace at the end of every line, execute the following command: :%s/\s*$//

The colon (:) tells Vim to enter command mode. All command-mode commands start with a line range; in this case, the special range % is used, which represents the entire file. The first set of slashes encloses the “from text.”The text is “any whitespace” (\s), repeated zero or more times (*), followed by “end-of-line” ($).The result is that this pattern matches all trailing whitespace. The matching text is to be replaced by the text in the next set of slashes.This text is nothing, so the spaces and tabs are effectively removed.

167

168

Chapter 16

Cookbook

Oops, I Left the File Write-Protected Suppose you are editing a file and you have made a lot of changes.This is a very important file and to preserve it from any casual changes, you write-protected it, even against yourself. The Vim editor enables you to edit a write-protected file with little or no warning. The only trouble is that when you try to exit using ZZ you get the following error: file.txt

File is read-only

And Vim does not exit. So what can you do? You do not want to throw away all those changes, but you need to get out of Vim so that you can turn on write permission. Use the command :w! to force the writing of the file. Another option: Use the :w otherfilename command to save your work in a different file so you can fix the file permissions if that is what is required.

Changing Last, First to First, Last You have a list of names in the following form: Last, First

How do you change them to First, Last

You can do so with one command: :1,$s/\([^,]*\), \(.*$\)/\2 \1/

The colon (:) tells Vim that this is an ex-style command. The line range for this command is the whole file, as indicated by the range 1,$. The s (abbreviations for :substitute) tells Vim to perform a string substitution. The old text is a complex regular expression.The \( . . . \) delimiters are used to inform the editor that the text that matches the regular expression inside the parentheses is to be remembered for later use. The text in the first \( . . . \) is assigned to \1 in the replacement text.The second set of text inside \( . . . \) is assigned \2, and so on. In this case, the first regular expression is any bunch of characters that does not include a comma.The [^,] means anything but a comma, and the * means a bunch (zero or more characters). Note:This means that all leading spaces will also be matched, which may not be what is desired. The second expression matches anything ( .* up to the end-of-line: $). The result of this substitution is that the first word on the line is assigned to \1 and the second to \2.These values are used in the end of the command to reverse the words.

How to Edit All the Files that Contain a Given Word

The following example shows the relationship between the \( \) enclosed strings and the \1, \2 markers. Match anything but comma Any Character Repeated 0 or more times The end of the line

:1,$s/\([ˆ,]*\) , \(.*$\) /\2 \1/ Any character, repeated, followed by EOL The character space The character comma Repeated 0 or more times Closes the [ ] expression The character comma Match anything except the next character Starts a set of matches

The next example breaks out the various parts of the regular expressions used in this illustration: :l,$s/\([ˆ,]*\), \(.*$\)/\2 \1/ String matched by first \( \) String matched by second \( \( Slash separating old/new strings Second \( \) First \( \)

How to Edit All the Files that Contain a Given Word If you are a UNIX user, you can use a combination of Vim and grep to edit all the files that contain a given word.This is extremely useful if you are working on a program and want to view or edit all the files that contain a specified variable. For example, suppose you want to edit all the C program files that contain the word frame_counter.To do this you use the command: $ vim `grep -l ‘frame_counter’ *.c`

Let’s look at this command in detail.The grep command searches through a set of files for a given word. Because the -l option is specified, the command will only list the files containing the word and not print the line itself.The word it is searching for is frame_counter. Actually, this can be any regular expression. (Note:What grep uses for regular expressions is not as complete or complex as what Vim uses.)

169

170

Chapter 16

Cookbook

The entire command is enclosed in backticks (`).This tells the UNIX shell to run this command and pretend that the results were typed on the command line. So what happens is that the grep command is run and produces a list of files, these files are put on the Vim command line.This results in Vim editing the file list that is the output of grep.You can then use the commands :n and :rewind to browse through the files. Why show this here? This is a feature of the UNIX shell (such as ‘bash’), and isn’t part of Vim’s repertoire.The way to accomplish something similar within Vim, and which works on Win32 as well is: :args `grep –l ‘frame_counter’ *.c`

which will set the ‘argument list’, in other words, the files “on the command line.”

Finding All Occurrences of a Word Using the Built-in Search Commands The Vim editor has a built-in :grep command that you can use to search a set of files for a given string. If you want to find all occurrences of error_string in all C program files, for example, enter the following command: :grep error_string *.c

This causes Vim to search for a string (error_string) in all the specified files (*.c). The editor will now open the first file where a match is found. Position the file on the first matching line.To go to the next matching line (no matter what file), use the :cnext command.To go to the previous match, use the :cprev command. Note:The Vim grep command uses the external grep (on Unix) or findstr (on Windows) commands.You can change the external command used by setting the option 'grepprg'.

Topics Not Covered

T

HE VIM EDITOR HAS A TREMENDOUSLY RICH set

of features. Unfortunately, a few

areas are beyond the scope of this book, and therefore are not covered here.These include support for commercial applications that I do not have access to and foreign languages.This chapter briefly describes the commands omitted from the rest of the book.

Interfaces to Other Applications The Vim editor is designed to interface with many common commercial packages as well as a few Open Source packages. Because I do not have these packages installed, I could not examine and test these commands. Some brief documentation appears here.

Cscope The cscope command is designed to examine a set of C or C++ programs and produce a database containing information about the location of functions and variables in the programs.You can then use the Cscope program to query this database to locate where an identifier is defined or used. Cscope is available from http://cscope.sourceforge.net.

172

Chapter 17

Topics Not Covered

For full information use the following command: :help cscope

Cscope-Related Command Reference :cs arguments :cscope argument

Handle various activities associated with the Cscope program.

:cstag procedure

Go to the tag in the CScope database named procedure.

:set csprg=program :set cscopeprg=program

Define the name of the Cscope program (Default=cscope).

:set cst :set cscopetag :set nocst :set nocscopetag

If set, this option causes the commands that do tag navigation (:tags, CTRL-], and so on) to use the Cscope database rather than tags.

:set csto=flag :set cscopetagorder=flag

Define the search order for the CScope tag-searching commands. If flag is 0, the default, search the CScope database, followed by tags. If flag is 1, search tags first.

:set csverb :set cscopeverbose :set nocsverb :set nocscopeverbose

If set, output error messages occur when Vim looks for a CScope database and fails to find it.This proves useful when debugging initialization files that try to load a set of databases (default=nocscopeverbose).

OLE The OLE system is a method by which programs running under Microsoft Windows can communicate with each other.The Vim editor can act as an OLE server.This means that you can write Microsoft Windows programs that interface to it. For those of you who know how to write Visual Basic or other Microsoft-based applications, you can find more information by using the command: :help ole-interface

Interfaces to Other Applications

Perl The Perl interface enables you to execute perl command from Vim and also gives the Perl programs an interface that they can use to access some of Vim’s functions. For a complete description of what is available, execute the following command: :help perl

Perl Interface Command Reference :pe command :perl command

Execute a single perl command.

:rangeperld command :rangeperldo command

Execute a perl command on a range of lines.The perl variable $_ is set to each line in range.

Python The Python interface enables you to execute Python statements and programs from within Vim. Like Perl, the Python interface provides you with lots of functions and objects that enable you to access parts of the Vim editor. For complete help, execute the following: :help python

Python Interface Command Reference :rangepy statement :rangepython statement

Execute a single Python statement.

:rangepyf file :rangepyfile file

Execute the Python program contained in file.

Sniff+ Sniff+ is a commercial programming environment.The Vim editor enables you to interface with this program. To get complete help on using this programming tool, execute the following command: :help sniff

173

174

Chapter 17

Topics Not Covered

Sniff+ Interface Command Reference :sni command :sniff command

Perform a command using the interface to Sniff+. If no command is present, list out information on the current connection.

Tcl Tcl is another scripting language. As usual, Vim provides you with a way to execute Tcl scripts as well as an interface for accessing parts of Vim from within Tcl. For full information, use the following command: :help tcl

Tcl Interface Command Reference :tc command :tcl command

Execute a single Tcl command.

:rangetcld command :rangetcldo command

Execute a Tcl command once for each line in the range.The variable line is set to the contents of the line.

:tclf file :tclfile file

Execute the Tcl script in the given file.

Foreign Languages The Vim editor can handle many different types of foreign languages. Unfortunately, the author cannot. Here is a very short listing of the commands available to you for editing in other languages. For complete information, you need to consult the Vim documentation and as well as the documentation that came with your computer system. Although Vim contains many language-specific options, a few are fairly generic.

Toggle between left-to-right and right-to-left modes.

:set rl :set rightleft :set norl :set norightleft

When set, indicates that the file is displayed right to left rather than left to right (default=norightleft).

Foreign Languages

:set ari :set allowrevins :set noari :set noallowrevins

When set, let CTRL-_ toggle the revins option. This enables you to input languages that run from right to left rather than left to right.

:set ri :set revins :set nori :set norevins

When set, insert mode works right to left rather than left to right.The CTRL-_ command toggles this option if the option allowrevins is set.

:set gfs=f1,f2 :set guifontset=f1,f2

Define a font f1 for English and another f2 for a foreign language. This works only if Vim was compiled with the fontset enabled and only applies on UNIX systems.

:set lmap=ch1ch2,ch1ch2 :set langmap=ch1ch2,ch1ch2

Define a keyboard mapping for a foreign language.

Chinese Written Chinese is a beautiful pictographic language where one character can convey a world of meaning. Unfortunately typing that one character can be extremely difficult given the limits of a computer keyboard. Chinese can be written left to right, right to left, or up to down.The Vim editor supports right to left and left to right. It also supports both traditional Chinese characters as well as simplified Chinese.

Note The Vim documentation does not contain help on the subject of Chinese input. That is operating system dependent.

175

176

Chapter 17

Topics Not Covered

Chinese-Related Command Reference :set fe=encoding :set fileencoding=encoding

Set the file encoding to be used for this file. For the Chinese language, this can be taiwan for the traditional Chinese character set or prc for simplified Chinese.

Farsi The Farsi language is supported, although you must explicitly enable Farsi when you compile the editor. It is not enabled by default.To edit in a Farsi file, start Vim in Farsi mode by using the —F option. For example: $ vim —F file.txt

You can get complete information on Farsi editing by executing the following command: :help farsi

Farsi-Related Command Reference :set fk :set fkmap :set nofk :set nofkmap

If set, this option tells Vim that you are using a Farsi keyboard (default=nofkmap).

:set akm :set altkeymap :set noakm :set noaltkeymap

When altkeymap is set, the alternate keyboard mapping is Farsi. If noaltkeymap is set, the default alternate keyboard mapping is Hebrew (default=noaltkeymap).

CTRL-_

Toggle between Farsi and normal mode (insert-mode command).

Toggles the encoding between ISIR-3342 standard and Vim extended ISIR-3342 (supported only in right-to-left mode).

Foreign Languages

Hebrew Hebrew is another language that goes right to left.To start editing a Hebrew file, use the following command: $ vim —H file.txt

To get help editing in this language, execute the following command: :help hebrew

Hebrew-Related Command Reference :set hk :set hkmap :set nohk :set nohkmap

Turn on (or off) the Hebrew keyboard mapping (default=nohkmap).

:set hkp :set hkmapp :set nohkp :set nohkmapp

When set, this option tells Vim that you are using a phonetic Hebrew keyboard, or a standard English keyboard (default=nohkmapp).

:set al=number :set aleph=number

Define the numeric value of the first character in the Hebrew alphabet.The value used depends on how your system encodes the Hebrew characters. (Default: Microsoft DOS: 128. Other systems: 224)

CTRL-_

Toggle between reverse insert and normal insert modes. Hebrew is usually inserted in reverse, like Farsi.

:set akm :set altkeymap :set noakm :set noaltkeymap

If altkeymap is set, the alternate keyboard mapping is Farsi. If noaltkeymap is set, the default alternate keyboard mapping is Hebrew (default=noaltkeymap).

177

178

Chapter 17

Topics Not Covered

Japanese Japanese-encoded files are supported. Unfortunately there is no specific online help for Japanese.

Japanese-Related Command Reference :set fe=japan :set fileencoding=japan

Tells Vim that the current file is encoded using the Japanese character set.

Korean To edit in Korean, you need to tell Vim about your keyboard and where your fonts reside.You can obtain information on how to do this by executing the following command: :help hangul

Korean-Related Command Reference :set fe=korea :set fileencoding=korea

Tells Vim that the current file is encoded using the Korean character set.

Binary Files Editing binary files using a text editor is tricky at best and suicidal at worst. If you have the right combination of expertise and desperation, you can use Vim to edit binary files. :set bin :set binary :set nobin :set nobinary

If set, then set things up for editing a binary file.

Note

I realize that some people out there need to edit a binary file and that you know what you are doing. For those of you in that situation, Vim is an excellent editor. Fortunately for those who need to, Vim comes with a great utility, ‘xxd’ which allows one to edit binary files almost painlessly. See the online docs for more information:

:help xxd

Operating System File Modes

Modeless (Almost) Editing If you enable the 'insertmode' option, insert mode is the default. If you want to switch to normal, use the CTRL-O command to execute a normal-mode command. This option is for people who do not like modes and are willing to deal with the confusing setting it generates. :set im :set insertmode :set noim :set noinsertmode

Make insert mode the default.

CTRL-L

Leave insert mode if 'insertmode' is set.

Operating System File Modes Some operating systems keep file type information around on the file.The two operating systems covered in this book do not have this feature. If the OS does determine the file type, the result will be saved in the 'osfiletype' option. :set osf=type :set osfiletype=type

This is set to the file type detected by an OS capable of doing so.

:set st=type :set shelltype=type

Define the shell type for an Amiga.

179

The Details

18

Complete Basic Editing

19

Advanced Searching Using Regular Expressions

20

Advanced Text Blocks and Multiple Files

21

All About Windows and Sessions

22

Advanced Visual Mode

23

Advanced Commands for Programmers

24

All About Abbreviations and Keyboard Mapping

25

Complete Command-Mode Commands

26

Advanced GUI Commands

27

Expressions and Functions

28

Customizing the Editor

29

Language-Dependent Syntax Options

30

How to Write a Syntax File

Complete Basic Editing

NCHAPTER2,“EDITING ALITTLEFASTER,”you

were introduced to some of the

basic editing commands.You can do 90% of most common edits with these commands. If you want to know everything about basic editing, however, read this chapter. Chapter 2, for example, discussed the w command to move forward one word.This chapter devotes a page to discussing in detail how to define exactly what a word is. Chapter 2 described how to use two commands (CTRL-D and CTRL-U) to move screen up and down through the text.There are actually six commands to do this, with options, and that does not include the other dozen or so positioning commands.This chapter discusses the complete command list. Generally you will not use all the commands in this chapter. Instead you will pick out a nice subset you like and use them. Chapter 2 presented one subset. If you prefer to pick your own, however, read this chapter and have fun.

Word Movement The Vim editor has many different commands to enable you move to the beginning or end of words. But you can also customize the definition of a word through the use of some of the Vim options.The following sections explore in depth the wordmovement commands.

184

Chapter 18

Complete Basic Editing

Move to the End of a Word The w command moves forward one word.You actually wind up on the beginning of the next word.The e command moves forward one word, but leaves you on the end of the word. The ge command moves backward to the end of the preceding word. Figure 18.1 shows how the various word-movement commands work. w

w

w

w

e

e

e

Profanity is the one language that all programmers understand. ge

ge

ge

Figure 18.1

b

b

b

Word movement commands.

Defining What a Word Is So what is a word, anyway? There are two answers to this question: 1. The Vim editor does a good job of defining a sane answer to this question. (Skip to the next section.) 2. If you want to know the details, read the rest of this section. Your first answer to “What is a word?” might be the easy answer: It is a series of letters. However, a C programmer might consider something like size56 to be word. Therefore, another answer might be to use the C identifier definition: the letters, digits, and the underscore. But LISP programmers can use the dash (-) in a variable name.They consider the word total-size a single word. C programmers consider it two words. So how do you resolve this conflict? The Vim solution is to create an option that defines what is in a word and what is not.The following command defines the characters that belong in a word: :set iskeyword=specification

To see what the current value of this option is, use this command: :set iskeyword?

The following represents a typical value: iskeyword=@,48-57,_,192-255

This is all the letters (@), the digits (ASCII characters numbered 48-57 or 0-9), the underscore (_) and the international letters (192-255, à through Ÿ).

Word Movement

The specification consists of characters separated by commas. If you want the word characters to be exclusively vowels, for instance, use this command: :set iskeyword=a,e,i,o,u

You can specify a range of characters by using a dash.To specify all the lowercase letters, for example, issue the following command: :set iskeyword=a-z

For characters that cannot be specified directly (such as comma and dash), you can use a decimal number. If you want a word to be the lowercase letters and the dash (character #45), use the following command: :set iskeyword=a-z,45

The @ character represents all characters where the C function isalpha() returns true. (This might vary, depending on the setting of the C locale, and also depending on the C compiler and OS you are using to build Vim!) To exclude a character or set of character, precede it with a circumflex (^).The following command defines a word as all the letters except lowercase q: :set iskeyword=@,^q

The @ character is represented by @-@.

Special Characters for the iskeyword Option a

Character a.

a-z

Character range (all characters from a to z).

45

Character number 45 (in this case, -).

@

All letters (as defined by isalpha()).

@-@

The character @.

^x

Exclude the character x.

^a-c

Exclude the characters in the range a through c.

Note You can abbreviate the 'iskeyword' option as isk.

185

186

Chapter 18

Complete Basic Editing

Other Types of Words The 'iskeyword' option controls what is and is not a keyword. Other types of characters are controlled by similar options, including the following: Filenames

'isfname' 'isident'

Identifiers

'isprint'

Printing characters

The 'isfname' option is used for commands such as the gf command, which edits the file whose name is under the cursor. (See Chapter 23, “Advanced Commands for Programmers,” for more information on this command.) The 'isident' option is used for commands such as [d, which searches for the definition of a macro whose identifier is under the cursor. (See Chapter 7, “Commands for Programmers,” for information on this command.) The 'isprint' option defines which characters can be displayed literally on the screen. Careful: If you get this wrong the display will be messed up.This is also used by the special search pattern \p, which stands for a printable character. (See Chapter 19, “Advanced Searching Using Regular Expressions,” for information on search patterns.)

There Are “words,” and Then There Are “WORDS” So now you know what words are, right? Well, the Vim editor also has commands that affect WORDS.These two terms, WORDS and words, represent two different things. (Only a programmer could think up terms that differ only by case.) The term word means a string of characters defined by the 'iskeyword' option.The term WORD means any sequence of non-whitespace characters.Therefore that-all

is two words, but it is one WORD. The W command moves forward WORDS and the B command moves backward WORDS.The complete list of WORD-related commands is as follows:

[count] B

Move count WORDS backward.

[count] E

Move count WORDS forward to the end of the WORD.

[count] gE

Move count WORDS backward to the end of the WORD.

[count] W

Move count WORDS forward.

Note:

is the same as CTRL. See Appendix B for a list of <> key names.

Moving Lines Up and Down

Beginning of a Line The ^ command moves you to the first non-blank character on the line. If you want to go to the beginning of the line, use the 0 command. Figure 18.2 shows these commands. current_state = modified

Figure 18.2

^ and 0 commands.

Repeating Single-Character Searches The fx command searches for the first x after the cursor on the current line.To repeat this search, use the ; command. As usual, this command can take an argument that is the number of times to repeat the search. The ; command continues the search in the same direction as the last f or F command. If you want to reverse the direction of the search, use the , command. Figure 18.3 shows several typical searches.

;

fe

;

To err is human, To really foul up you need a computer

, Figure 18.3

, Repeat single-character search.

Moving Lines Up and Down The — command moves up to the first non-blank character on the preceding line. If an argument is specified, the cursor moves up that many lines. The + command moves down to the beginning of the next line. If an argument is specified, the cursor moves down that number of lines. Figure 18.4 shows these commands. ATTENTION

3– – + 4+

This room is fullfilled mit special electronische equippment. Fingergrabbing and pressing the cnoeppkes from the computers is allowed for die experts only! So all the “lefhanders” stay away and do not disturben the brainstorming von here working intelligencies. Otherwise you will be out thrown and kicked anderswhere! Also: please keep still and only watchen astaunished the blinkenlights.

Figure 18.4

The + and - commands.

187

188

Chapter 18

Complete Basic Editing

The _ command moves to the first non-blank character of the line. If a count is specified, it moves the first character of the count – 1 line below the cursor.

Cursor-Movement Commands Several commands enable you to move to different parts of the screen.The H command moves to the top of the screen. If a count is specified, the cursor will be positioned to the count line from the top.Therefore, 1H moves to the top line, 2H the second line, and so on. The L command is just like H except that the end of the screen is used rather than the start. The M command moves to the middle of the screen. Figure 18.5 summarizes the cursor-positioning commands. H 2H 3H M

3L 2L L

Figure 18.5

Line 40 Line 41 Line 42 Line 43 Line 44 Line 45 Line 46 Line 47 Line 48 Line 49

Cursor-positioning commands.

Jumping Around The Vim editor keeps track of where you have been and enables you to go back to previous locations. Suppose, for example, that you are editing a file and execute the following commands: 1G

Go to line 1

10G

Go to line 10

20G

Go to line 20

Now, you execute this command: :jumps

You get the following: jump line col file/text 2 1 0 Dumb User Stories 1 10 0 ventilation holes. Many terminals >

Controlling Some Commands

From this you see that you have recorded as jump 1, line 10, column 0, the “ventilation holes” line. Jump 2 is at line 1, column, the “Dumb User Stories” line. Line 20 is not recorded in the jump list yet, because you are on it.The jump list records only things after you jump off of them.The > points to the current item in the list; in this case, it points to the blank line at the end indicating an unrecorded location. Now that you know what the jump list is, you can use it.The CTRL-O command jumps back one line. Executing this command takes you back to line 10.The jump list now looks like this: jump line col file/text 2 1 0 Dumb User Stories > 0 10 0 ventilation holes. Many terminals 0 20 0

The > has moved up one line. If you use the CTRL-O command again, you move to line 1.The CTRL-I or

command moves you to the next jump in the list.Thus you have the following: 1G

Go to line 1.

10G

Go to line 10.

20G

Go to line 20.

CTRL-O

Jump to previous location (line 10).

CTRL-O

Jump to previous location (line 1).

Jump to next location (line 10).

Using these commands, you can quickly navigate through a series of jumping off points throughout your file.

Controlling Some Commands Normally Vim stops any left or right movement at the beginning or end of the line. The 'whichwrap' option controls which characters are allowed to go past the end and in which modes.The possible values for this option are as follows: Character

Command

Mode(s)

b

Normal and visual

s

<Space>

Normal and visual

h

h

Normal and visual

l

l

Normal and visual

<

Normal and visual

>

Normal and visual

~

~

Normal

[

Insert and replace

]

Insert and replace

189

190

Chapter 18

Complete Basic Editing

Figure 18.6 shows how 'whichwrap' affects cursor movement. Without “b” in whichwrap

stops here.

Carelessly planned projects take three time

With “b” in whichwrap the

continues

complete than expected, mostly because the

at the end of the previous line.

longer to complete than expected. Carefully planned projects take four times longer to

planners expect their planning to reduce the time it takes.

Figure 18.6

Effects of the 'whichwrap' option.

Where Am I, in Detail The CTRL-G command displays summary information at the bottom of the screen telling you where you are in the file (see Chapter 2). However, you can get more detailed information if you ask.The basic CTRL-G output looks like this: “c02.txt” [Modified] line 81 of 153 —52%— col 1

To get more information, give CTRL-G a count.The bigger the count, the more detailed information you get.The 1CTRL-G command gives you the full path of the file, for example: “/usr/c02.txt” [Modified] line 81 of 153 —52%— col 1

The 2CTRL-G command lists a buffer number as well. (You can read more on buffers in Chapter 5, “Windows.”) buf 1: “/usr/c02.txt” [Modified] line 81 of 153 —52%— col 1

The gCTRL-G command displays another type of status information indicating the position of the cursor in terms of column, line, and character: Col 1 of 0; Line 106 of 183; Char 3464 of 4418

If you are interested in having the current cursor location displayed all the time, check out the 'ruler' option in Chapter 28, “Customizing the Appearance and Behavior of the Editor.”

Scrolling Up As discussed in Chapter 2, the CTRL-U command scrolls up half a screen. To be precise, the CTRL-U command scrolls up the number of lines specified by the 'scroll' option.You can explicitly set this option with a :set command: :set scroll=10

Scrolling Up

You can also change the value of this option by giving an argument to the CTRL-U command. For example, 2CTRL-U changes the scroll size to 2 and moves up 2 lines. All subsequent CTRL-U commands will only go up 2 lines at a time, until the scroll size is changed. Figure 18.7 shows the operation of the CTRL-U command. Line 31 Line 32 Line 33 Line 34 Line 35 Line 36 Line 37 Line 38 Line 39 Line 40

CTRL-U (up 1/2 screen. In this case, 5 lines)

2CTRL-U (Set scroll to 2, then move up two lines.)

Line 26 Line 27 Line 28 Line 29 Line 30 Line 31 Line 32 Line 33 Line 34 Line 35

Figure 18.7

Line 24 Line 25 Line 26 Line 27 Line 28 Line 29 Line 30 Line 31 Line 32 Line 33

The CTRL-U command.

To scroll the window up one line at a time, use the CTRL-Y command.This command can be multiplied by an argument. For example, 5CTRL-Y scrolls up 5 lines (see Figure 18.8).

Line 20 Line 21 Line 22 Line 23

CTRL-Y

Line 24 Line 25 Line 26 Line 27 Line 28 Line 29

Line 19 Line 20 Line 21 Line 22

Line 14 Line 15 Line 16 Line 17

Line 23 Line 24 Line 25 Line 26 Line 27 Line 28

Line 18 Line 19 Line 20 Line 21 Line 22 Line 23

Figure 18.8

5CTRL-Y

The CTRL-Y command.

The CTRL-B command scrolls up an entire screen at a time (see Figure 18.9). Line 40 Line 41 Line 42 Line 43 Line 44

Line 32 Line 33 CTRL-B

Line 34 Line 35 Line 36

Line 45 Line 46

Line 37 Line 38

Line 47 Line 48 Line 49

Line 39 Line 40 Line 41

Figure 18.9

The CTRL-B command.

191

192

Chapter 18

Complete Basic Editing

You can specify this command as <PageUp> or <S-Up>. (<S-Up> is the Vim notation for the Shift+up-arrow key.)

Scrolling Up Summary Figure 18.10 illustrates the various scrolling commands. Commands move the top line to the indicated location. Line 40 Line 41 CTRL-Y

Line 42 Line 43

2CTRL-Y

Line 44 Line 45 Line 46

CTRL-U

Line 47 Line 48 CTRL-B

Line 49

Scrolling commands.

Figure 18.10

Scrolling Down There are similar commands for moving down as well, including the following: CTRL-D

Move down. The amount is controlled by the 'scroll' option.

CTRL-E

Move down one line.

CTRL-F

Move down one screen of data (also <PageDown> or <S-Down>).

Figure 18.11 summarizes the scrolling commands. CTRL-E 2CTRL-E CTRL-D CTRL-F Screen

Two Lines

Line 43 Line 44 Line 45 Line 46 Line 47

One Line

Line 48 Line 49

1/2 Screen (value of ’scroll’)

CTRL-U CTRL-B

Line 40 Line 41 Line 42

One Line Two Lines 1/2 Screen (value of ’scroll’)

Screen

CTRL-Y

2CTRL-Y

Figure 18.11

More scrolling commands.

Adjusting the View

Define How Much to Scroll When you move the cursor off the top or bottom, the window scrolls.The amount of the scrolling is controlled by the 'scrolljump' option. By default this is a single line; if you want more scrolling, however, you can increase this to a jump of 5, as follows: :set scrolljump=5

The 'sidescroll' option does the same thing, except in the horizontal direction. Usually the cursor must reach the top or bottom line of the screen for scrolling to occur. If you want to add a little padding to this margin, you can set the 'scrolloff' option.To make sure that there are at least 3 lines above or below the cursor, use the following command: :set scrolloff=3

Adjusting the View Suppose you want a given line at the top of the screen.You can use the CTRL-E (up one line) and CTRL-Y (down one line) commands until you get the proper line at the top. Or you can position the cursor on the line and type the command z<Enter>. Figure 18.12 shows how this command changes the screen. Enjoys work, but she likes the beach more.

***** A very intelligent turtle Found programming UNIX a hurdle The system, you see, Ran as slow as did he, And that's not saying much for the turtle.

She found a good way To combine work and play: She sells C shells by the seashore. ***** A very intelligent turtle Found programming UNIX a hurdle The system, you see, Ran as slow as did he, And that's not saying much for the turtle. §

Figure 18.12

z<Enter>

§ Albert Einstein, when asked to describe radio, replied: "You see, wire telegraph is a kind of a very, very long cat. You pull his tail in New York and his head is meowing in Los Angeles. Do you understand this?

The z<Enter> command.

If you supply an argument to this command, it will use that line rather than the current one. z<Enter> positions the current line at the top of the screen, for instance, whereas 88z<Enter> positions line 88 at the top. The z<Enter> command not only positions the line at the top of the screen, it also moves the cursor to the first non-blank character on the line. If you want to leave the cursor where it is on the line, use the command zt. (If you change the current line by giving the command an argument, Vim will try to keep the cursor in the same column.) Figure 18.13 shows the zt command.

193

194

Chapter 18

Complete Basic Editing

the beach more. She found a good way To combine work and play:

zt

She sells C shells by the seashore.

A very intelligent turtle Found programming UNIX a hurdle The system, you see, Ran as slow as did he, And that's not saying much for the turtle. §

*****

Albert Einstein, when asked to describe radio, replied: "You see, wire telegraph is a kind of a very, very long cat. You pull his tail in New York and his head is meowing in Los Angeles. Do you understand this? And radio operates

A very intelligent turtle Found programming UNIX a hurdle The system, you see, Ran as slow as did he, And that's not saying much for the turtle. §

@

Figure 18.13

The zt command.

If you want to position a line to the end of the screen, use the zb or z- command.The z- positions the cursor on the first non-blank column, whereas zb leaves it alone. Figure 18.14 shows the effects of these commands. the beach more.

Equals nine squared plus zero, no more.

She found a good way To combine work and play:

*****

She sells C shells by the seashore.

A UNIX sales lady, Lenore, Enjoys work, but she likes the beach more.

***** A very intelligent turtle Found programming UNIX a hurdle The system, you see, Ran as slow as did he, And that's not saying much for the turtle.

She found a good way To combine work and play:

zb

§

z-

Figure 18.14

She sells C shells by the seashore. ***** A very intelligent turtle

The zb and z- commands.

Finally, the zz and z. commands position the line at the center of the window.The zz command leaves the cursor in its current column, and z. moves it to the first nonblank column. Figure 18.15 shows what these commands do.

The C Command 195

Equals nine squared plus zero, no more.

She found a good way To combine work and play:

*****

She sells C shells by the seashore.

A UNIX sales lady, Lenore, Enjoys work, but she likes the beach more.

z.

She found a good way To combine work and play:

zz

She sells C shells by the seashore.

***** A very intelligent turtle Found programming UNIX a hurdle The system, you see, Ran as slow as did he, And that's not saying much for the turtle. §

*****

Albert Einstein, when asked

A very intelligent turtle

Figure 18.15

The z. and zz commands.

Delete to the End of the Line The D command deletes to the end of the line. If preceded by a count, it deletes to the end of the line and count – 1 more lines. (The D command is shorthand for d$.) See Figure 18.16 for some examples of this command. ATTENTION This room is fullfilled mit special electronische equippment. Fingergrabbing and pressing the cnoeppkes from the computers is allowed for die experts only! So all the “lefhanders” stay away and do not disturben the brainstorming von here working intelligencies. Otherwise you will be out thrown and kicked anderswhere! Also: please keep still and only watchen astaunished the blinkenlights.

Figure 18.16

D

3D

The D command.

The C Command The C command deletes text from the cursor to the end of the line and then puts the editor in insert mode. If a count is specified, it deletes an additional count – 1 lines. In other words, the command works like the D command, except that it puts you in insert mode.

196

Chapter 18

Complete Basic Editing

The s Command The s (substitute) command deletes a single character and puts the editor in insert mode. If preceded by a count, then count characters are deleted. Figure 18.17 illustrates this command. Profanity is the q language that all programmers know. sone<Esc>

4sunderstand<Esc>

Profanity is the one language that all programmers understand.

Figure 18.17

The s command.

The S Command The S command deletes the current line and puts the editor in insert mode. If a count is specified, it deletes count lines.This differs from the C command in that the C command deletes from the current location to the end of the line, whereas the S command always works on the entire line. Figure 18.18 illustrates the use of the S command. Text deleted by C<Esc>

Over the years system installers have developed many different ways to string cables above false ceilings. One of the more innovative is the “small dog” method. One person takes a small dog, ties a string to its collar and puts the dog in the ceiling. The owner then goes to the spot where they want the cable to come out and calls the dog. Dog runs to owner. The attach a cable to the string, pull it through, and the cable is installed.

Figure 18.18

2C<Esc> S<Esc> (Even if the cursor is in the middle of the line.) 2S<Esc>

The S command.

Deleting Text The “register count x command deletes characters starting with the one under the cursor moving right.The X command deletes characters to the left of the cursor. Figure 18.19 shows how these two commands work.

Arithmetic

1 is equal to 2 for sufficiently large values of 1. 3x

1 is equal to 2 for suffintly large values of 1.

1 is equal to 2 for sufficiently large values of 1. 3X

1 is equal to 2 for suciently large values of 1.

Figure 18.19

The x and X commands.

Insert Text at the Beginning or End of the Line The I command inserts text like the i command does.The only difference is that the I command inserts starting at the beginning of the line. (In this case, “beginning” means at the first non-blank character.) To insert at the first character of the line (space or not), use the gI command.The A command appends text like the a command, except the text is appended to the end of the line.

Arithmetic The Vim editor can perform simple arithmetic on the text.The CTRL-A command increments the number under the cursor. If an argument is specified, that number is added to the number under the cursor. Figure 18.20 shows how various types of numbers are incremented. 123

0177 CTRL-A

124

0x1E CTRL-A

0200

Figure 18.20

123 CTRL-A

0x1F

CTRL-A 128

Incrementing.

If a number begins with a leading 0, it is considered an octal number.Therefore, when you increment the octal number 0177, you get 0200. If a number begins with 0x or 0X, it is considered a hexadecimal number.That explains 0x1E to 0x1F. The Vim editor is smart about number formats, so it will properly increment decimal, hexadecimal, and octal. The CTRL-X command works just like the CTRL-A command, except the number is decremented; or if an argument is present, the number is subtracted from the number. Figure 18.21 shows how to decrement numbers.

197

198

Chapter 18

Complete Basic Editing

123

0120 CTRL-X

124

0x1E CTRL-X

123 CTRL-X

0117

0x1F

5 CTRL-X 118

Decrementing.

Figure 18.21

By default, Vim recognizes the octal and hexadecimal numbers.Which formats are recognized is controlled by the nrformats option. If you want to recognize decimal and octal numbers, for instance, execute the following command: :set nrformats=””

If you want to recognize just octal numbers, use this command: :set nrformats=octal

The default recognizes decimal, hexadecimal, and octal: :set nrformats=octal,hex Note

Decimal is always recognized. Unlike hexadecimal and octal, there is no way to turn off decimal recognition.

The Vim editor can do more sophisticated calculations. See Chapter 27, “Expressions and Functions,” for information on the “= register.

Joining Lines with Spaces The J command joins the current line with the next one. A space is added to the end of the first line to separate the two pieces that are joined. But suppose you do not want the spaces.Then you use the gJ command to join lines without spaces (see Figure 18.22). It works just like the J command, except that no space is inserted between the joined parts. This is a test

This is a test

gJ

This is a test with two lines

2gJ

Figure 18.22

This is a test with two lines

The gJ command.

Note If the first line ends with some trailing spaces, the gJ

command will not remove them.

Replace Mode

Replace Mode The R command causes Vim to enter replace mode. In this mode, each character you type replaces the one under the cursor.This continues until you type <Esc>. Figure 18.23 contains a short example. This is a test. Rmess<Esc>

This is a mess.

Figure 18.23

The R command.

If a count is specified, the command will be repeated count times (see Figure 18.24). This is a test. 3Rmess<Esc>

This is a messmessmess.

Figure 18.24

R

command with a count.

You may have noticed that this command replaced 12 characters on a line with only 5 left on it.The R command automatically extends the line if it runs out of characters to replace.

Virtual Replace Mode One of the problems with replace comes when you have a

in the text. If you are sitting on a and execute the command rx, the will be replaced by x.This can shift your line around (see Figure 18.25).

This is a test

rx

xThis is a test

Figure 18.25

Simple non-virtual replace.

If you use the virtual replace command, grcharacter, you replace the “virtual character” under the cursor (see Figure 18.26). If the real character under the cursor is part of a tab, only the space representing the tab jumped over is replaced.

199

200

Chapter 18

Complete Basic Editing

This is a test

Rx

x

Figure 18.26

This is a test

Virtual replacement.

The gR command enters virtual replace mode. Each character you type will replace one character in screen space until you finish things off with <Esc>.

Digraphs As learned in Chapter 2, executing CTRL-K character1 character2 inserts a digraph. You can define your own digraphs by using the following command: :digraphs character1 character2 number

This tells Vim that when you type CTRL-K character1 character2 that you should insert the character whose character number is number. If you are entering a lot of digraphs, you can turn on the 'digraph' option by using this command: :set digraph

This means that you can now enter digraphs by using the convention character1

character2. ( is the backspace character.) This mode has its drawbacks, however.The digraph c0 is the copyright character (©). If you type x but want to type y, you can correct your mistake by typing x (oops), , and y. If you do that with c and 0, however, it does not erase the c and put in the 0; instead, it inserts ©. Therefore, you need to type c (oops), , 0 (darn, © appeared), , and 0. To turn off digraph mode, use the following command: :set nodigraph

Changing Case The ~ command changes a character’s case.The behavior of the ~ command depends on the value of the 'tildeop' option.With the option unset, the command behaves normally: :set notildeop

If you set the following option, however, the syntax of the command changes to ~motion: :set tildeop

For example the command ~fq changes the case of all the characters up to and including the first q on the line. Figure 18.27 shows some examples.

Other Case-Changing Commands

now

is the time. . . .

NOW

3~l

IS the TIME. . . .

~fM Now is the time. . . .

Now is THE time. . . .

Figure 18.27

~motion

commands.

The g~motion command changes the case of the indicated characters. It is just like the ~motion command except that it does not depend on the tildeop option. Figure 18.28 shows some examples. now is the time. . . .

NOW

3g~l

IS the TIME. . . .

g~fm Now is the time. . . .

Now is THE time. . . .

Figure 18.28

The g~ command.

A special version of this command, g~~ or g~g~, changes the case of the entire line (see Figure 18.29). Now

IS the Time. . . .

g~~ nOW IS THE TIME. . . .

Figure 18.29

The g~~ command.

Other Case-Changing Commands The gUmotion command makes the text from the cursor to motion all uppercase.The command gUU or gUgU works on a single line. If count is specified, count lines are changed. The gumotion, guu, and gugu act just like their gU counterparts, except that they make the text lowercase. Figure 18.30 illustrates these commands. This is Mixed Case line.

This is Mixed Case line.

Figure 18.30

g~~ gUU

tHIS IS mIXED cASE LINE.

THIS IS MIXED CASE LINE.

Case-changing commands.

201

202

Chapter 18

Complete Basic Editing

Undo Level You can execute only so many undo commands.This limit is set by the undolevels option.To set this limit to 5,000 changes, use the following command: :set undolevels=5000

Getting Out The ZQ command is an alias for the :q! or :quit! command.The command exits and discards all changes.

The :write command writes out the file.The :quit command exits.You can use a shorthand for these commands: :wq

This command can take a filename as an argument. In this case, the edit buffer will be written to the file and then Vim will exit.To save your work under a new filename and exit, for instance, use the following command: :wq count.c.new

This command will fail with an error message if the file count.c.new exists and is read-only. If you want Vim to overwrite the file, use the override option (!): :wq! count.c.new

Finally, you can give the :wq command a line-range argument. (See Chapter 25, “Complete Command-Mode Commands” for more on ranges.) If a line range is present, only those lines are written to the file.To write out only the first 10 lines of a file and exit, for example, execute the following command: :1,10wq count.c.new

The :xit command acts much like the :wq command except that it only writes the file if the buffer has been modified.

Advanced Searching Using Regular Expressions

V

IMHAS A POWERFUL SEARCH ENGINE THATenables

you to perform many different

types of searches. In this chapter, you learn about the following: n

Turning on and off case sensitivity

n

Search options

n

Instant word searching

n

How to specify a search offset

n

A full description of regular expressions

Searching Options This section describes some of the more sophisticated options that you can use to fine-tune your search. 'hlsearch' has been turned on to show you how these options affect the searching. Case Sensitivity By default, Vim’s searches are case sensitive.Therefore, include, INCLUDE, and Include are three different words and a search will match only one of them.The following example searched for include. Notice that INCLUDE, Include and iNCLude are not highlighted. Figure 19.1 shows the result of an /include command.

204

Chapter 19 Advanced Searching Using Regular Expressions * Report the speed of a cd–rom * * (Also works on hard drives and other * * devices) * * * * Usage: * * cd–speed <device> * * * ********************************************************/ #include

#INCLUDE #Include #iNCLude <stdlib.h> /include

Figure 19.1

Case-sensitive search.

Now let’s turn on the 'ignorecase' option by entering the following command: :set ignorecase

Now when you search for include, you will get all four flavors of the word as (see Figure 19.2). * Report the speed of a cd–rom * * (Also works on hard drives and other * * devices) * * * * Usage: * * cd–speed <device> * * * ********************************************************/ #include

#INCLUDE #Include #iNCLude <stdlib.h>

Figure 19.2

Non-case-sensitive search.

To turn on case sensitivity, use this command: :set noignorecase

(Technically what you are doing is turning off case insensitivity, but it tortures the English language too much to say it this way.) If you have 'ignorecase' set, word matches word, WORD, and Word. It also means that WORD will match the same thing. If you set the following two options, any search string typed in lowercase is searched, ignoring the case of the search string: :set ignorecase :set smartcase

If you have a string with at least one uppercase character, however, the search becomes case sensitive. Thus you have the following matches:

String

Matches

word

word,Word,WORD, worD

Word

Word

WORD

WORD

WorD

WorD

Searching Options 205

Wrapping By default, a forward search starts searching for the given string starting at the current cursor location. It then proceeds to the end of the file. If it does not find the string by that time, it starts from the beginning and searches from the start of the file to the cursor location. Figure 19.3 shows how this works.

Start 1) /unsigned 2) n

1 2 // Read at most 10MB 3 const. unsigned int MAX_READ = (10 * 1024 *1024 4 5 // Size of a buffer 6 const unsigned int BUF_SIZE = (62 * 1024); 7 8 // Buffer to be written 9 static unsigned char buffer[BUF_SIZE]; 10

3) n

Figure 19.3

Wrapping.

This example starts by searching for unsigned.The first search goes to line 6.The next search moves to line 9.When trying to search again, you reach the end of the file without finding the word. At this point, the search wraps back to line 1 and the search continues.The result is that you are now on line 3. Turning Off Search Wrapping To turn off search wrapping, use the following command: :set nowrapscan

Now when the search hits the end of the file, an error message displays (see Figure 19.4). #include <sys/fcntl.h> #include <sys/time.h> #include <errno.h> // Read at most 10MB const unsigned int MAX_READ = (10 * 1024 *1024); // Size of a buffer const unsigned int BUF_SIZE = (62 * 1024); // Buffer to be written static unsigned char buffer[BUF_SIZE]; search hit BOTTOM without match for: unsigned

Figure 19.4

nowrapscan.

To go back to normal wrapping searches, use the following command: :set wrapscan

206

Chapter 19 Advanced Searching Using Regular Expressions

Interrupting Searches If you are in the middle of a long search and want to stop it, you can type CTRL-C on a UNIX system or CTRL-BREAK on Microsoft Windows. On most systems, unless you are editing a very large file, searches are almost instantaneous.

Instant Word Searches The * command searches for the word under the cursor. For example, position the cursor on the first const. Pressing * moves the cursor to the next occurrence of the word, specifically line 26. Figure 19.5 shows the results.

*

19 #include <sys/fcntl.h> 20 #include <sys/time.h> 21 #include <errno.h> 22 23 // Read at most 10MB 24 const. unsigned int MAX_READ = (10 * 1024 *1024); 25 // Size of a buffer 26 const unsigned int BUF_SIZE = (62 * 1024); 27 28 // Buffer to be written 29 static unsigned char buffer[BUF_SIZE];

Figure 19.5

*

command.

The # or £ command does an instant word search in the backward direction.These commands work on whole words only. In other words, if you are on const and conduct a * search, you will not match constant.The g* command performs an instant word search, but does not restrict the results to whole words. So whereas * will not match constant, the g* command will match it. The g# command does the same thing in the reverse direction.

Search Offsets By default, the search command leaves the cursor positioned on the beginning of the pattern.You can tell Vim to leave it some other place by specifying an offset. For the forward search command (/), the offset is specified by appending a slash (/) and the offset, as follows: /const/2

This command searches for the pattern const and then moves to the beginning of the second line past the pattern. Figure 19.6 shows how this works.

Search Offsets 207

/const/2

Find const

Move to the start of the pattern +2 lines

19 #include <sys/fcntl.h> 20 #include <sys/time.h> 21 #include <errno.h> 22 23 // Read at most 10MB 24 const unsigned int MAX_READ = (10 * 1024 *1024); 25 // Size of a buffer 26 const unsigned int BUF_SIZE = (62 * 1024); 27 28 // Buffer to be written 29 static unsigned char buffer[BUF_SIZE];

Figure 19.6

Search offsets.

If the offset is a simple number, the cursor will be placed at the beginning of the offset line from the match.The offset number can be positive or negative. If it is positive, the cursor moves down that many lines; if negative, it moves up. If the offset begins with b and a number, the cursor moves to the beginning of the pattern, and then travels the “number” of characters. If the number is positive, the cursor moves forward, if negative, backward.The command /const/b2 moves the cursor to the beginning of the match, for instance, and then two characters to the right (see Figure 19.7). const unsigned int BUF_SIZE = (62 * 1024);

2 characters to the right Results of

/const/b2

pattern

Figure 19.7

/const/b2.

Note The b offset is a synonym for s. Therefore, you can use b (begin), and s (start) for the first character of the match.

The e offset indicates an offset from the end of the match.Without a number it moves the cursor onto the last character of the match.The command /const/e puts the cursor on the t of const. Again, a positive number moves the cursor to the right, a negative number moves it to the left (see Figure 19.8). const unsigned int BUF_SIZE = (62 * 1024);

pattern end Results of

/const/e-3

3 characters to the left

Figure 19.8

/const/e-3.

208

Chapter 19

Advanced Searching Using Regular Expressions

Finally, there is the null offset.This is the empty string.This cancels the preceding offset.

Specifying Offsets To specify an offset on a forward search (/ command), append /offset to the command, as follows: /const/e+2

If you want to repeat the preceding search with a different offset, just leave out the pattern and specify the new offset: //5

To cancel an offset, just specify an empty offset. //

For example: /const/e+2

Search moves to the end of the pattern, and then to the right two characters.

/

Repeats last search, with the preceding offset.

//

Repeats the last search with no offset. (Cursor will be placed on the first character of the pattern.)

To specify an offset for a reverse search (? command), append ?offset to the command, as follows: ?const?b5

To repeat with the same pattern and a new offset, use the following: ??-2

To remove the offset and repeat the search with the preceding pattern, use the following: ??

One thing to remember when using search offsets, the search always starts from the current cursor position.This can get you into trouble if you use a command such as this: /const/-2

This command searches for const and then moves up two lines. If you then repeat the search with the n command, it goes down two lines, finds the const you just found, and then moves the cursor back up two lines for the offset.The result is that no matter how many times you type n, you go nowhere.

Complete Regular Expressions 209

Complete Regular Expressions The search logic of Vim uses regular expressions.You saw some simple ones in Chapter 3,“Searching,” but this chapter goes into them in extreme detail. Regular expressions enable you to search for more than simple strings. By specifying a regular expression in your search command, you can search for a character pattern, such as “all words that begin with t and end in ing” (regular expression = \

). However, the power of regular expressions comes with a price. Regular expressions are quite cryptic and terse. It may take some time for you to get used to all the ins and outs of this powerful tool. While learning regular expressions, you should execute the following command: :set hlsearch

This causes Vim to highlight the text you matched with your last search.Therefore, when you search for a regular expression, you can tell what you really matched (as opposed to what you thought you matched). A regular expression consists of a series of atoms. An atom is the smallest matching unit in a regular expression. Atoms can be things like a single character, such as a (which matches the letter a), or a special character, such as $ (which matches the end of the line). Other atoms, such as \< (word start, see the following section), consist of multiple characters.

Beginning (\<) and End (\>) of a Word The atom \< matches the beginning of a word.The atom \> matches the end of a word. For example, a search for the expression for finds all occurrences of for, even those in other words, such as Californian and Unfortunately. Figure 19.9 shows the results of this search. If you use the regular expression \

, however, you match only the actual word for. Figure 19.10 contains the results of this refined search. Calls and letters to the company failed to correct this problem. Finally the fellow just gave up and wrote a check for $0.00 and the bills ceased.

A Californian who loved sailing went down and applied for a personalized license plate. He filled in his three choices as 1)SAIL 2)SAILING and 3)NONE. He got a new plate labeled "NONE." Unfortunately, when the police write out a ticket /for

Figure 19.9

Search for /for.

210

Chapter 19 Advanced Searching Using Regular Expressions

Calls and letters to the company failed to correct this problem. Finally the fellow just gave up and wrote a check for $0.00 and the bills ceased.

A Californian who loved sailing went down and applied for a personalized license plate. He filled in his three choices as 1)SAIL 2)SAILING and 3)NONE. He got a new plate labeled "NONE." Unfortunately, when the police write out a ticket /\

Figure 19.10

Search for /\

.

Modifiers and Grouping The modifier * is used to indicate that an atom is to be matched 0 or more times.The match is “greedy.” In other words, the editor will try to match as much as possible. Thus, the regular expression te* matches te, tee, teee, and so on. The expression te* also matches the string t.Why? Because e* can match a zerolength string of e’s. And t is the letter t followed by zero e’s. Figure 19.11 shows the results of the search for te*. This is a test. te tee teee teee ~ ~ /te*

Figure 19.11

Search for /te*.

The \+ modifier indicates that the atom is to be matched one or more times. Therefore, te\+ matches te, tee, and teee, but not t. (te\+ is the same as tee*.). Figure 19.12 illustrates what is matched for the search /te\+. This is a test. te tee teee teee ~ ~ /te\+

Figure 19.12

Search for /te\+.

Finally, there is the \= modifier. It causes the preceding atom to be matched zero or one time.This means that te\= matches t and te, but not tee. (Although it will match the first two characters of tee.) Figure 19.13 shows a typical search.

Complete Regular Expressions 211

This is a test. te tee teee teee ~ ~ /te\=

Figure 19.13

Search for /te\=.

Special Atoms A number of special escaped characters match a range of characters. For example, the \a atom matches any letter, and the \d option matches any digit.The regular expression \a\a\a matches any three letters. Now try a search for any four digits. Figure 19.14 displays the results. 1 2 // Read at most 10MB 3 const unsigned int MAX_READ = (10 * 1024 *1024); 4 5 // Size of a buffer 6 const unsigned int BUF_SIZE = (62 * 1024); 7 8 // Buffer to be written 9 static unsigned char buffer[BUF_SIZE]; 10 /\d\d\d\d

Figure 19.14

Search for /\d\d\d\d.

Now try a search for any three letters followed by an underscore. Figure 19.15 displays the results.

/\a\a\a_

1 2 // Read at most 10MB 3 const unsigned int MAX_READ = (10 * 1024 *1024); 4 5 // Size of a buffer 6 const unsigned int BUF_SIZE = (62 * 1024); 7 8 // Buffer to be written 9 static unsigned char buffer[BUF_SIZE]; 10

Figure 19.15

Search for /\a\a\a.

Character Ranges The \a atom matches all the letters (uppercase and lowercase). But suppose you want to match only the vowels.The range operator enables you to match one of a series of characters. For example, the range [aeiou] matches a single lowercase vowel.The string t[aeiou]n matches tan, ten, tin, ton and tun.

212

Chapter 19

Advanced Searching Using Regular Expressions

You can specify a range of characters inside the brackets ([]) by using a dash. For example, the pattern [0-9], matches the characters 0 through 9. (That is 0,1,2,3,4,5,6,7,8,9.) You can combine ranges with other characters. For example, [0-9aeiou] matches any digit or lowercase vowel. The ^ character indicates a set of characters that match everything except the indicated characters.To match the constants, for example, you can specify [^aeioAEIOU]. Note To match the ^, you need to escape it. For example, [\^$.] matches any one of the three symbols ^, $, or ..

Pattern

Matches

one[\-]way

one-way, but not one way or one+way

2\^4

2^4

2[\^*]4

2^4, 2*4

Character Classes Suppose you want to specify all the uppercase letters. One way to do this is to use the expression [A-Z]. Another way is to use one of the predefined character classes.The class [:upper:] matches the uppercase characters.Therefore, you can write [A-Z] as [[:upper:]]. You can write the entire alphabet, upper- and lowercase, [[:upper:][:lower:]]. There are a large number of different character classes. Note You cannot use the special atoms like \a and \d in a range. For example, [\a\d] matches the characters \, a, \, and d. It does not match the letters (\a) and digits (\d).

Repeat Modifiers You can specify how many times an atom is to be repeated.The general form of a repeat is as follows: \{minimum, maximum}

For example, the regular expression a\{3,5} will match 3 to 5 a’s. (that is, aaa, aaaa, or aaaaa.) By default, the Vim editor tries to match as much as possible. So a\{3,5} will match as many a’s as it can (up to 5). The minimum can be omitted, in which case it defaults to zero.Therefore, a,\{,5} matches 0–5 repeats of the letter.The maximum can be omitted as well, in which case it defaults to infinity. So a\{3,} matches at least 3 a’s, but will match as many a’s as you have got on the line.

Complete Regular Expressions 213

If only one number is specified, the atom must match exactly that number of times. Therefore, a\{5} matches 5 a’s, exactly.

Repeating as Little as Possible If you put a minus sign (-) before any of the numbers, the Vim editor tries to match as little as possible. Therefore, a\{-3,5} will match 3 to 5 a’s, as little as possible. Actually if this expression is by itself, it will always match just three a’s.That is because even if you have the word aaaaa, the editor will match as little as possible. The specification a\{-3,} matches 3 or more a’s, as little as possible.The expression a\{-,5} matches 0–5 letters. The expression a\{-} matches 0 to infinity number of characters, as little as possible. Note that this pattern by itself will always match zero characters. It only makes sense when there is something after it. For example: [a-z]\{-}x will match cx in cxcx. Using [a-z]*x would have matched the whole cxcx. Finally, the specification a\{-5} matches exactly 5 a’s, as little as possible. Because as little as possible is exactly 5, the expression a\{-5} acts just like a\{5}.

Grouping ( \(\) ) You can specify a group by enclosing it in a \( and \). For example, the expression a*b matches b, ab, aab, aaab, and so on.The expression a\(XY\)*b matches ab, aXYb, aXYXYb, aXYXYXYb, and so on. When you define a group using \(\), the first enclosed string is assigned to the atom \1.To match the string the the, for instance, use the regular expression \(the\) \1.To find repeated words, you can get a bit more general and use the expression \(\<\a\+\>\) \1. Figure 19.16 breaks this into its components. Put matching text in \1 \ ( \ < \ a + \ > \ ) Match beginning of a word Match a single letter Repeat 1 or more times Ending of a word Match space Match what was in the first \ (... \ )

Figure 19.16

The repeat (\1) expression.

The first group is assigned to \1, the second \2, and so on.

\1

214

Chapter 19

Advanced Searching Using Regular Expressions

The Or Operator (\|) The \| operator enables you to specify two or more possible matches.The regular expression foo\|bar matches foo or bar. For example, the search /procedure\|function

searches for either procedure or function.

Putting It All Together Let’s create a regular expression to match California license plate numbers. A sample license plate looks like 1MGU103.The pattern is one digit, three uppercase letters, and three digits.There are several ways of doing this. Start by specifying the digit as [0-9], now add the uppercase letter: [0-9][A-Z]. There are three of them, so you get [0-9][A-Z]\{3}. Finally, you add the three digits on the end, resulting in [0-9][A-Z]\{3}[0-9]\{3}. Another way to do this is to recognize that \d represents any digit and \u any uppercase character.The result is \d\u\{3}\d\{3}. The experts tell us that this form is faster than using the [] form. If you are editing a file where this speed up makes a difference, however, your file might be too big. You can accomplish this without repeats as well: \d\u\u\u\d\d\d. Finally, you can use the character classes, yielding [[:digit:]][[:upper:]]\{3][[:digit:]]\{3}. All four of these expressions work.Which version should you use? Whichever one you can remember.You should remember this old adage:The simple way you can remember is much faster than the fancy way you can’t.

The magic Option The expressions discussed so far assume that the 'magic' option is on.When this option is turned off, many of the symbols used in regular expressions lose their magic powers.They only get them back when escaped. Specifically, if you execute the command :set nomagic

the *, ., [, and ] characters are not treated as special characters. If you want to use the * for “0 or more repeats,” you need to escape it: \*. You should keep the 'magic' option on (the default) for portability and macro files.

Regular Expressions Reference

Offset Specification Reference [num]

+[num]

Down [num] lines. Cursor is placed at the beginning of the line.

-[num]

Up [num] lines. Cursor is placed at the beginning of the line.

e

End of the match.

e[num]

End of the match, the move [num]. If [num] is positive, move right, negative, move left.

b s

Start of the match.

b[num] s[num]

Start of the match, then move [num]. If [num] is positive, move right; negative, move left.

Regular Expressions Reference The following table assumes that the 'magic' option is on (the default).

Simple Atoms x

The literal character x.

^

Start of line.

$

End of line.

.

A single character.

\<

Start of a word.

\>

End of word.

Range Atoms [abc]

Match either a, b, or c.

[^abc]

Match anything except a, b, or c.

[a-z]

Match all characters from a through z.

[a-zA-Z]

Match all characters from a through z and A through Z.

Character Classes [:alnum:]

Match all letters and digits.

[:alpha:]

Match letters.

[:ascii:]

Match all ASCII characters.

[:backspace:]

Match the backspace character (

).

215

216

Chapter 19

Advanced Searching Using Regular Expressions

[:blank:]

Match the space and tab characters.

[:cntrl:]

Match all control characters.

[:digit:]

Match digits.

[:escape:]

Matches the escape character (<Esc>).

[:graph:]

Match the printable characters, excluding space.

[:lower:]

Match lowercase letters.

[:print:]

Match printable characters, including space.

[:punct:]

Match the punctuation characters.

[:return:]

Matches the end-of-line (carriage return, <Enter>,

, ).

[:space:]

Match all whitespace characters.

[:tab:]

Match the tab character (

).

[:upper:]

Match the uppercase letters.

[:xdigit:]

Match hexadecimal digits.

Patterns (Used for Substitutions) \(pattern\)

Mark the pattern for later use.The first set of \(\) marks a subexpression as \1, the second \2, and so on.

\1

Match the same string that was matched by the first subexpression in \( and \). For example: \([a-z]\).\1 matches ata, ehe, tot, and so forth.

\2

Like \1, but uses second subexpression,

\9

Like \1, but uses ninth subexpression.

Special Character Atoms \a

Alphabetic character (A-Za-z).

\A

Non-alphabetic character (any character except A-Za-z).

\b

.

\d

Digit.

\D

Non-digit.

\e

<Esc>.

\f

Any filename character as defined by the isfname option.

\F

Any filename character, but does not include the digits.

\h

Head of word character (A-Za-z_).

\H

Non-head of word character (any character except A-Za-z_).

\i

Any identifier character as defined by the isident option.

\I

Any identifier character, but does not include the digits.

Regular Expressions Reference

\k

Any keyword character as defined by the iskeyword option.

\K

Any keyword character, but does not include the digits.

\l

Lowercase character (a-z).

\L

Non-lowercase character (any character except a-z).

\o

Octal digit (0-7).

\O

Non-octal digit.

\p

Any printable character as defined by the isprint option.

\P

Any printable character, but does not include the digits.

\r

.

\s

Whitespace (<Space> and

).

\S

Non-whitespace character. (Any character except <Space> and

).

\t

.

\u

Uppercase character (A-Z).

\U

Non-uppercase character (any character except A-Z).

\w

Word character (0-9A-Za-z_).

\W

Non-word character (any character except 0-9A-Za-z_).

\x

Hexadecimal digit (0-9 a-f A-F).

\X

Non-hexadecimal digit.

\~

Matches the last given substitute string.

Modifiers *

Match the previous atom 0 or more times.As much as possible.

\+

Match the previous atom 1 or more times.As much as possible.

\=

Match the previous atom 0 or 1 times.

\{}

Match the previous atom 0 or more times. (Same as the * modifier.)

\{n} \{-n}

Match the previous atom n times.

\{n,m}

Match the previous atom n to m times.

\{n,}

Match the previous atom n or more times.

\{,m}

Match the previous atom from 0 to m times.

\{-n,m}

Match the previous atom n to m times. Match as little as possible.

\{-n,}

Match the previous atom at least n times. Match as little as possible.

217

218

Chapter 19

Advanced Searching Using Regular Expressions

\{-,m}

Match the previous atom up to m times. Match as little as possible.

\{-}

Match the previous atom 0 or more times. Match as little as possible.

str1\|str2

Match str1 or str2.

Advanced Text Blocks and Multiple Files

T

HE

VIM EDITOR

HAS LOTS OF DIFFERENT ways

of doing things. Chapter 4,“Text

Blocks and Multiple Files,” presented a representative subset of the commands dealing with text blocks and multiple files and described them. It is entirely possible for you to edit efficiently using only those commands. This chapter shows you all the other ways of doing things. If you find that you do not like the limitations of the commands in Chapter 4, read this one; you should find a way to get around your annoyances. For example, you learned how to yank and put (cut and paste) using a single register to hold the text.That is fine if you are dealing with a single block of text. If you want to deal with more, however, check out how to use multiple registers later in this chapter. This chapter covers the following: n

Different ways to yank and put

n

How to use special registers

n

How to edit all the files containing a specific string

n

Advanced commands for multiple files

n

Global marks

n

Advanced insert-mode commands

n

How to save and restore your setting by using a VIMINFO file

n

Dealing with files that contain lines longer than the screen width

220

Chapter 20 Advanced Text Blocks and Multiple Files

Additional Put Commands When inserting lines, p and P commands do not move the cursor.The gp command works just like the p command, except that the cursor is left at the end of the new text.The gP command does the same things for the P command. Figure 20.1 shows the effects of these commands. Line 1 Line that we yy Line 3 Line 4 paste line Line 5 ~ ~ ~ ~ Line 1 Line that we yy Line 3 Line 4 paste line Line that we yy Line 5 ~ ~ ~ Line 1 Line that we yy Line 3 Line 4 paste line Line that we yy Line 5 ~ ~ ~

p

gp

Figure 20.1

P

gP

Line 1 Line that we yy Line 3 Line that we yy Line 4 paste linee Line 5 ~ ~ ~ Line 1 Line that we yy Line 3 Line that we yy Line 4 paste line Line 5 ~ ~ ~

Paste (put) commands.

Multiple Registers

Special Marks Vim has a number of special built-in marks.The first one is the single quotation (‘) mark. It marks the location of the cursor before the latest jump. In other words, it is your previous location (excluding minor moves such as up/down and so on). Other special marks include the following: ]

The beginning of the last inserted text

[

The end of the last inserted text

The last place the cursor was resting when you left the file

Multiple Registers So far, you have performed all your yanks and deletes without specifying which register to use. If no register is specified, the unnamed register is used.The characters that denote this register are two double quotation marks (“”).The first double quote denotes a register; the second double quote is the name of the register. (Therefore, for example, “a means use register a.) You can specify which register the deleted or yanked text is to go into by using a register specification before the command.The format of a register specification is “register, where register is one of the lowercase letters. (This gives you 26 registers to play around with.) Therefore, whereas yy puts the current line into the unnamed register, the command “ayy places the line in the a register, as seen in Figure 20.2. (The text also goes into the unnamed register at the same time.) Line 1 Line 2 Line 3 (yy here) Line 4 ("ayy here) ~ ~ Figure 20.2

unamed register “= “Line 3 (yy here) register a = “Line 4 (“ayy here)

Using the a register for yank and put.

Unnamed Register

It seems a bit silly to name the unnamed register, “The Unnamed Register,” because this gives it a name. The name is a misnomer, because the unnamed register is named “The Unnamed Register.” So, in fact, the unnamed register has a name even though it calls itself “The Unnamed Register.” Persons understanding the preceding paragraph have demonstrated aptitude for writing programs and are urged to enroll in their nearest engineering college.

221

222

Chapter 20 Advanced Text Blocks and Multiple Files

To get an idea of what the registers contain, execute the following command: :registers

Figure 20.3 shows the results of this command. ~ :registers ––– Registers ––– ““ Line 3 (yy here)^J "0 Line 3 (yy here)^J "1 We will tdelete he word in the middle "2 /* File for bad names */^J "3 Line 2^J "4 To err is human ––^J to really scre "5 ^J "6 ^J "7 to really screw up, you need a com "a Line 4 ("ayy here)^J "– to be yy’ed) ". "ayy here) ": registers "% test.txt "# tmp.txt Press RETURN or enter command to continue

Figure 20.3

:registers

command.

This illustration shows that the unnamed register (“) contains Line 3 (yy here). The a register contains Line 4 ("ayy here). The alphabetic registers are the normal ones used for yanking and pasting text. Other, special registers are described in the following sections. You can display the contents of specific registers by giving them as an argument to the :registers command. For example, the following command displays the contents of registers a and x: :registers ax

Appending Text When you use a command such as “ayy, you replace the text in the register with the current line.When you use the uppercase version of a register, say “Ayy, you append the text to what is already in the register (see Figure 20.4). Note that the result is two lines, “Line 3” and “Line 2”. (The ^J in the register indicates end of line.)

Special Registers 223 Line 1 Line 2 ("Ayy here) Line 3 ("ayy here) Line 4 ~ ~ ~ ~ ~ ~ ~

1) ayy Yank the line into register a

2) Ayy Append the line onto register a

This results in:

Line 4 ~ ~ ~ ~ ~ ~ ~ :register a ––– Registers ––– “a Line 3 (“ayy here)^JLine 2 (“Ayy here)^J Press RETURN or enter command to continue

Figure 20.4

Appending text to a register.

Special Registers Vim has a number of special registers.The first is the unnamed register, whose name is double quote (“). Others include the registers 1 through 9. Register 1 contains the last text you deleted; register 2 the next to last, and so on. (Back in the bad old days of Vi, these registers were a lifesaver.You see, Vi had only one level of undo. So if you deleted three lines by executing dd three times, you were out of luck if you wanted to undo the delete using the u command. Fortunately, the three lines were stored in registers 1, 2, and 3, so you could put them back with “1P”2P”3P.You can also use the command “”P.. (“”P and two dots). Other special registers include the following: Register

Description

Writeable

The last yanked text

Yes

-

The last small delete

No

.

The last inserted text

No

%

The name of the current file

No

#

The name of the alternate file

No

/

The last search string

No

:

The last “:” command

No

_

The black hole (more on this later)

Yes

=

An expression (see next page)

No

*

The text selected with the mouse

Yes

224

Chapter 20 Advanced Text Blocks and Multiple Files

The Black Hole Register (_) Placing text into the black hole register causes it to disappear.You can also “put” the black hole register, but this is pretty much useless because the black hole register always contains nothing. The black hole register is useful when you want to delete text without having it go into the 1 through 9 registers. For example, dd deletes a line and stores it in 1.The command “_dd deletes a line and leaves 1 alone.

The Expression Register (=) The expression register (=) is designed so that you can enter expressions into text. When you enter a command beginning with an expression register specification, the Vim editor displays the prompt = at the end of the screen.This gives you an opportunity to type in an expression such as 38*56, and you can then put the result into the text with the p command. For example “=38*56<Enter>p gives you 2128. Figure 20.5 shows this register in action. The width is 38. The height is 56. So the area is ~ ~ ~ ~ ~ ~ ~ ~ =38*56

Enter the text, press <Esc> to enter normal mode. Execute “= to start expression mode. The cursor jumps to here.

Enter the expression and press <Enter>. (The cursor jumps back to it’s former location.)

The width is 38. The height is 56. So the area is 2128 ~ ~ ~ ~ ~ ~ ~ ~ =38*56

The p command pastes the answer in after the cursor.

Figure 20.5

The expression register.

An expression can contain all the usual arithmetic operators (*, +, -, /, and so on) as well as a ton of specialized Vim functions and operators. If you are doing more than simple arithmetic, you will want to check the full expression documentation. You can specify the value of an environment variable, for example, by using the expression $NAME (for instance, $HOME).You can determine the value of a Vim variable by just specifying the variable (LineSize, for instance).

Editing a Specific File

The Clipboard Register (*) The clipboard register (*) enables you to read and write data to the system clipboard. This can be the X selection (UNIX) or the Microsoft Windows Clipboard.This enables you to cut and paste text between the Vim editor and other applications.

How to Edit All the Files That Contain a Given Word If you are a UNIX user, you can use a combination of Vim and Grep to edit all the files that contain a given word.This proves extremely useful if you are working on a program and want to view or edit all the files that contain a specified variable. Suppose, for example, that you want to edit all the C program files that contain the word frame_counter.To do this, you use the following command: $ vim `grep -l ‘frame_counter’ *.c`

Consider this command in detail.The grep command searches through a set of files for a given word. Because the -l option is specified, the command will list only the files containing the word and not print the line itself.The word it is searching for is frame_counter. Actually, this can be any regular expression. (Note that what Grep uses for regular expressions is not as complete or complex as what Vim uses.) The entire command is enclosed in backticks (`).This tells the UNIX shell to run this command and pretend that the results were typed on the command line. So what happens is that the grep command is run and produces a list of files; these files are put on the Vim command line.This results in Vim editing the file list that is the output of Grep. You might be asking, “Why show this here?”This is a feature of the UNIX shell (for example, bash), and is not part of Vim’s repertoire.The way to accomplish something similar within Vim, and which works on Win32 as well, is as follows: :arg `grep –l ‘frame_counter’ *.c`

This command sets the argument list (for example, the files “on the command line,” as it were). Note The Vim command :grep can perform a similar function.

Editing a Specific File To edit a specific file in this list (file 2, for instance), you need the following command: :argument 2

225

226

Chapter 20

Advanced Text Blocks and Multiple Files

This command enables you to specify a file by its position in the argument list. Suppose, for instance, that you start Vim with this command: $ gvim one.c two.c three.c four.c five.c six.c seven.c

The following command causes you to be thrown into the file four.c. :argument 4

Changing the File List The file list is initially set to the list of files you specify on the command line.You can change this list by specifying a new list to the :args command. For example: :args alpha.c beta.c gamma.c

After executing this command, you start editing alpha.c; the next file is beta.c and so on. (The previous file list is lost.) Note The :next file-list command will do the same thing.

The +cmd Argument Suppose that you want to start editing a file at line 97.You can start Vim and execute a 97G, or you can tell Vim to start editing with the cursor on line 97.You can do this by using the option +linenumber on the command line. For example: $ gvim +97 file.c

You can also use the +cmd to search for a string by using +/string on the command line.To start editing a file with the cursor positioned on the first line containing #include, for instance, use this command: $ vim +/#include file.c

Finally, you can put any command-mode command after the plus sign (+). You can specify the +cmd argument in a number of commands. For example, the general form of the :vi command is as follows: :vi [+cmd] {file}

These other commands can take a +cmd: :next [+cmd] :wnext [+cmd] :previous [+cmd] :wprevious [+cmd] :Next [+cmd] :wNext [+cmd] :rewind [+cmd] :last [+cmd]

Global Marks

Global Marks The marks a–z are local to the file. In other words, you can place a mark a in file one.c and another mark a in file two.c.These marks are separate and have nothing to do with each other. If you execute a go-to-mark command, such as ‘a, you will jump within that file to the given mark. The uppercase marks (A–Z) differ.They are global.They mark not only the location within the file, but also the file itself. Take a look at an example.You are editing the file one.c and place the mark A in it.You then go on to edit file two.c.When you execute the jump-to-mark-A command (‘A), the Vim editor will switch you from file two.c to file one.c and position the cursor on the mark. For example, you are editing a bunch of C files named alpha.c, beta.c, and gamma.c.You execute the following commands: 1.

/#include

2.

mi

Find the first #include (in alpha.c).

Mark it with the mark i. mark “i”

/* alpha.c */ #include <stdio.h> int alph(void) { printf(“In alpha\n”); }

3.

:next

4.

n

5.

mi

6.

/magic_function

7.

mF

Go to file beta.c. Find the first include. Mark it with the mark i. Find the magic function.

Mark it with the mark F. mark “i” mark “F”

/* beta.c */ #include <stdio.h> int magic_function(void) { printf(“In beta\n”); } “beta.c” 8L, 88C

227

228

Chapter 20

Advanced Text Blocks and Multiple Files

8.

:next

9.

/#include

10.

mi

Go to file gamma.c. Find the first include.

Mark it with the mark i. mark “i”

/* gamma.c */ #include <stdio.h> int gamma(void) { printf(“In gamma\n”); } “gamma.c” 8L, 81C

After executing these commands, you have three local marks, all named i. If you execute the command ‘i, you jump to the mark in your buffer.The mark F is global because it is uppercase. Currently you are in file gamma.c.When you execute the command to go to mark F (‘F), you switch files to beta.c. Now you use the following command to go to alpha.c. :rewind

Place the F mark there because this is a global mark (you can put it in only one place), the mark named F in the file beta.c disappears.

Advanced Text Entry When you are entering text in insert mode, you can execute a number of different commands. For example, the

command erases the character just before the cursor. CTRL-U erases the entire line (or at least the part you just inserted). CTRL-W deletes the word before the cursor.

Movement Even though you are in insert mode, you can still move the cursor.You cannot do this with the traditional Vim keys h, j, k, and l, because these would just be inserted. But you can use the arrow keys

, , , and . If you hold down the Control key, you can move forward and backward words. In other words, execute to go backward one word, and forward. The command moves the cursor to the beginning of a line, and <End> moves to the end.The key moves to the beginning of the file, and moves to the end. The <PageUp> moves one screen backward, and <PageDown> a screen forward.

Advanced Text Entry

Inserting Text If you type CTRL-A, the editor inserts the text you typed the last time you were in insert mode. Assume, for example, that you have a file that begins with the following: “file.h” /* Main program begins */

You edit this file by inserting #include at the beginning of the first line: #include “file.h” /* Main program begins */

You go down to the beginning of the next line using the command j^.You now start to insert a new line that contains a new include line. So you type iCTRL-A.The result is as follows: #include “file.h” #include /* Main program begins */

The #include was inserted because CTRL-A inserts the contents of the previous insert. Now you type “main.c”<Enter> to finish the line: #include “file.h” #include “main.h” /* Main program begins */

The CTRL-@ command does a CTRL-A and then exits insert mode. The CTRL-V command is used to quote the next character. In other words, any special meaning the character has, it will be ignored. For example, CTRL-V<Esc> inserts an escape.You can also use the command CTRL-Vdigits to insert the character number digits. For example, the character number 64 is @. So CTRL-V64 inserts @.The CTRL-Vdigits uses “decimal” digits by default, but you can also insert the “hex” digits. For example, CTRL-V123

and CTRL-Vx7b

both insert the { character. The CTRL-Y command inserts the character above the cursor.This is useful when you are duplicating a previous line. One of my favorite tricks is to use ASCII art to explain complex things such as regular expressions. For example: [0-9]*[a-z]* |||||||||||+—— Repeat 0 or more times ||||||+++++——- Any lower case letter |||||+————— Repeat 0 or more times +++++—————- Any digit

229

230

Chapter 20

Advanced Text Blocks and Multiple Files

Take a look at how you can use CTRL-Y to create this file.You start by entering the first two lines: [0-9]*[a-z]* |||||||||||+—— Repeat 0 or more times

Now you type CTRL-Y six times.This copies the | from the previous line down six times: [0-9]*[a-z]* |||||||||||+—— Repeat 0 or more times ||||||

The CTRL-E command acts like CTRL-Y except it inserts the character below the cursor.

Inserting a Register The command CTRL-Rregister inserts the text in the register. If it contains characters such as

or other special characters, they are interpreted as if they had been typed from the keyboard. If you do not want this to happen (you really want the to be inserted in the text), use the command CTRL-R CTRL-R register. First you enter the following line: All men^H^H^Hpeople are created equal Note

To enter the backspace characters (which show up as ^H), you need to type CTRL-V

or CTRL-V CTRL-H.

Now you dump this into register a with the command “ayy. Next you enter insert mode and use CTRL-Ra to put the text into the file.The result is as follows: All men^H^H^Hpeople are created equal (original line) All people are created equal (CTRL-Ra line)

Notice that Vim put the contents in as if you had typed them. In other words, the

character (^H) deletes the previous character. Now if you want to put the contents of the register in the file without interpretation, you could use CTRL-R CTRL-R a.This results in the following: All men^H^H^Hpeople are created equal (original line) All people are created equal (CTRL-Ra line) All men^H^H^Hpeople are created equal (CTRL-R CTRL-R a)

Leaving Insert Mode The command CTRL-\ CTRL-N ends insert mode and goes to normal mode. In other words, it acts like <Esc>.The only advantage this has over <Esc> is that it works in all modes.

The viminfo File

Finally, CTRL-O executes a single normal-mode command and goes back to insert mode. If you are in insert mode, for instance, and type CTRL-Odw, the Vim editor goes into normal mode, deletes a word (dw), and then returns to insert mode.

The viminfo File The problem with global marks is that they disappear when you exit Vim. It would be nice if they stuck around. The viminfo file is designed to store information on marks as well as the following: n

Command-line history

n

Search-string history

n

Input-line history

n

Registers

n

Marks

n

Buffer list

n

Global variables

The trick is that you have to enable it.This is done through the following command: :set viminfo=string

The string specifies what to save. The syntax of this string is an option character followed by an argument.The option/argument pairs are separated by commas. Take a look at how you can build up your own viminfo string. First, the ‘ option is used to specify how many files for which you save local marks (a–z). Pick a nice even number for this option (1000, for instance).Your viminfo option now looks like this: :set viminfo=’1000

The f option controls whether global marks (A–Z 0–9) are stored. If this option is 0, none are stored. If it is 1 or you do not specify an f option, the marks are stored.You want this feature, so now you have this: :set viminfo=’1000,f1

The r option tells Vim about removable media. Marks for files on removable media are not stored.The idea here is that jump to mark is a difficult command to execute if the file is on a floppy disk that you have left in your top desk drawer at home.You can specify the r option multiple times; therefore, if you are on a Microsoft Windows system, you can tell Vim that floppy disks A and B are removable with the r option: :set viminfo=’1000,f1,rA:,rB:

231

232

Chapter 20

Advanced Text Blocks and Multiple Files

UNIX has no standard naming convention for floppy disks. On my system, however, the floppy disk is named /mnt/floppy; therefore, to exclude it, I use this option: :set viminfo=’1000,f1,r/mnt/floppy Note There is a 50-character limit on the names of the removable media.

The \” option controls how many lines are saved for each of the registers. By default, all the lines are saved. If 0, nothing is saved.You like the default, so you will not be adding a \” specification to the viminfo line. The : option controls the number of lines of : history to save. 100 is enough for us: :set viminfo=’1000,f1,r/mnt/floppy,:100,

The / option defines the size of the search history. Again 100 is plenty: :set viminfo=’1000,f1,r/mnt/floppy,:100,/100

Note that Vim will never store more lines than it remembered.This is set with the 'history' option. Generally, when Vim starts, if you have the 'hlsearch' option set, the editor highlights the previous search string (left over from the previous editing sessions).To turn off this feature, put the h flag in your 'viminfo' option list. (Or you can just start Vim, see the highlighting, and decide you do not like it and execute a :nohlsearch.) The '@' option controls the number of items to save in the input-line history. (The input history records anything you type as result of an input function call.) For this example, let this default to the size of the input-line history. If the '%' option is present, save and restore the buffer list.The buffer list is restored only if you do not specify a file to edit on the command line: :set viminfo=’1000,f1,r/mnt/floppy,:100,/100,%

The '!' option saves and restores global variables. (These are variables whose names are all uppercase.) :set viminfo=’1000,f1,r/mnt/floppy,:100,/100,%,!

Finally, the n option specifies the name of the viminfo file. By default, this is $HOME/.viminfo on UNIX. On Microsoft Windows, the file is as follows: $HOME\_viminfo $VIM\_viminfo C:\_viminfo

if $HOME is set if $VIM is set otherwise

The 'n' option must be the last option parameter. Because we like the default filename, we leave this option off.Therefore, the full viminfo line is this: :set viminfo=’1000,f1,r/mnt/floppy,:100,/100,%,!

Dealing with Long Lines

You can put this command and other initializations into a vimrc initialization file.The viminfo file is automatically written when the editor exits, and read upon initialization. But you may want to write and read it explicitly. The following command writes the viminfo file: :wviminfo[!] [file]

If a file is specified, the information is written to that file. Similarly, you can read the viminfo file using this command: :rviminfo [file]

This reads all the settings from file. If any settings conflict with currently existing settings, however, the file settings will not be used. If you want the information in the viminfo file to override the current settings, use the following command: :rviminfo! [file]

Dealing with Long Lines Sometimes you will be editing a file that is wider than the number of columns in the window.When that occurs, Vim wraps the lines so that everything fits on the screen (see Figure 20.6). If you set the 'nowrap' option, each line in the file shows up as one line on the screen.Then the ends of the long lines disappear off the screen to the right (see Figure 20.7). Wrapped line

A programmer once worked on a form let ter generation program for a bank. They wanted to send out a special, personalized letter to their richest 1000 customers . Unfortunately for the programmer, he didn't adequately debug his code. Even worse, the bank didn't check the first batch of form letters.

Figure 20.6

Text wrapping.

A programmer once worked on a form let for a bank. They wanted to send out a letter to their richest 1000 customers programmer, he didn't adequately debug the bank didn't check the first batch The result: the wealthiest 1000 custom that began, “Dear Rich Bastard.” ~ ~ ~ :set nowrap

Figure 20.7

:set nowrap.

233

234

Chapter 20 Advanced Text Blocks and Multiple Files

By default, Vim does not display a horizontal scrollbar on the GUI. If you want to enable one, as shown in Figure 20.8, use the following command: :set guioptions+=b

A programmer once worked on a form let

for a bank. They wanted to send out a letter to their richest 1000 customers programmer, he didn't adequately debug the bank didn't check the first batch The result: the wealthiest 1000 custom that began, “Dear Rich Bastard.” ~ ~

Figure 20.8

Horizontal scrollbar.

This window can be scrolled horizontally. All you have to do is position the cursor on a long line and move to the right using the l or $ command. Figure 20.9 shows what happens when you do a little horizontal scrolling.

r generation program ecial, personalized Unfortunately for the is code. Even worse, form letters. s all got a letter ~ ~

Figure 20.9

Horizontal scrolling.

The ^ command moves to the first non-blank character of the line.The g^ command moves to the first non-blank character on the screen. If there is text to the left of the window, it is ignored.There are a number of similar g-type commands:

Command

Command

Meaning (When nowrap Set)

^

g^

g

g0

<End>

g<End>

$

g$

Rightmost character on the screen

gm

Move to the middle of the screen

Leftmost non-blank character on the screen Leftmost character on the screen

Figure 20.10 shows how these commands work.

Dealing with Long Lines

A programmer once worked on a form letter generation program for a bank. They wanted to send out a special, personalized letter to their richest 1000 customers. Unfortunately for the programmer, he didn't adequately debug his code. Even worse, the bank didn't check the first batch of form letters. The result: the wealthiest 1000 customers all got a letter that began, “Dear Rich Bastard.” g

Figure 20.10

gm

g$

$

Line-movement commands.

The [count]| command goes to the count column on the screen. The [count]zh command scrolls the screen [count] characters left while the zl command does the same thing to the right. The zL command scrolls half a screen to the left and the zR command scrolls half screen to the right. The j or

command moves down a line.These command move down lines in the file.Take a look at Figure 20.11. 1 j

wrap

j

wrap

j

wrap

2 3

A programmer once worked on a form let ter generation program for a bank. They wanted to send out a special, personalized letter to their richest 1000 customers . Unfortunately for the programmer, he didn't adequately debug his code. Even worse, the bank didn't check the first batch of form letters.

Figure 20.11

The j (down) command.

In this case, line 3 has wrapped. Now you start with the cursor on line 2. Executing a j command moves you to the beginning of line 3. Another j and you are down to the beginning of line 4. Note that although you have moved down a line in text space, you have moved down two lines in screen space. Typing a gj or g

command moves one line down in screen space.Therefore, if you start at the beginning of line 3 and type gj, you wind up one line down in screen space (see Figure 20.12).This is halfway between line 3 and line 4. (In file space, you are on the middle of line 3.) The gk and g commands do the same thing going up.

235

236

Chapter 20 Advanced Text Blocks and Multiple Files

gj gj gj

1 wrap 2 wrap 3 wrap

A programmer once worked on a form let ter generation program for a bank. They wanted to send out a special, personalized letter to their richest 1000 customers . Unfortunately for the programmer, he didn't adequately debug his code. Even worse, the bank didn't check the first batch of form letters.

Figure 20.12

The gj (down screen line) command.

Wrapping By default, the Vim editor wraps long lines. It does this by putting as much of the line as possible on the first screen line, and then to breaking it, and putting the rest on the next line. You can to turn this off by setting the following option: :set nowrap

With this option set, long lines just disappear off the right side of the screen.When you move the cursor along them, the screen scrolls horizontally and you can see what you are doing. You can customize wrapping by setting some Vim options. First of all, you can tell Vim to break lines at nice places by setting the option: :set linebreak

Figure 20.13 shows how this option affects the screen. A programmer once worked on a form letter generation program for a bank. They wanted to send ou t a special, personalized letter to their richest 1000 custo mers. Unfortunately for the programmer, he didn't adequately d ebug his code. Even worse, the bank didn't check the first ba tch of form letters. :set nolinebreak

Figure 20.13

A programmer once worked on a form letter generation program for a bank. They wanted to send out a special, personalized letter to their richest 1000 customers. Unfortunately for the programmer, he didn't adequately debug his code. Even worse, the bank didn't check the first batch of form letters. :set linebreak :set linebreak

The linebreak option.

But what defines a “nice” place on the line.The answer is the characters in the 'breakat' option. By default, these are ^ I ! @ * - + _ ; : , . / ?. Now suppose you do not want to break words with _ in them.You need to remove _ from the list of 'breakat' characters, so you execute the following command: :set breakat -=_

Dealing with Long Lines

Usually when lines are broken, nothing is put at the beginning of the continuation lines.You can change this, however, by defining the 'showbreak' option. For example: :set showbreak=”——>”

Finally, there is the question of what to do if you need to break a line at the end of the screen.You have two choices: First, you can refuse to display half of a line.The Vim editor will display an @ at the bottom of the screen to indicate “there is a long line here that we cannot fit it on the screen. Second, you can display half the line. The Vim default is method one. If you want to use method two, execute this command: :set display=lastline

237

All About Windows and Sessions

N CHAPTER

5,“WINDOWS,”YOU

basic commands for using windows.

LEARNED THE

But there are a lot more window-related commands.This chapter discusses many different commands for selecting and arranging windows.You will also learn how to customize the appearance of the windows. Finally, this chapter discusses session files.These files enable you to save and restore all your editing and window settings so that you can return to editing where you left off. The topics covered in this chapter include the following: Moving between windows Moving windows up and down n

n

n

n

n

n

n

n

Performing operations on all windows Editing the “alternate” file Split searches

Shorthand operators Advanced buffer commands Session files

240

Chapter 21

All About Windows and Sessions

Moving Between Windows As previously discussed, CTRL-Wj goes to the next window and CTRL-Wk goes to the preceding one.The following commands also change windows. CTRL-Wt Go to the top window. CTRL-Wb

Go to the bottom window.

CTRL-Wp

Go to the window you were in before you switched to this one. (Go to the preceding window.) 1CTRL-Ww 1CTRL-WW CTRL-Wt

2CTRL-Ww 2CTRL-WW

3CTRL-Ww 3CTRL-WW CTRL-Wb

Figure 21.1

/* File one.c */ ~ ~ ~ one.c /* File two.c */ ~ ~ ~ two.c /* File three.c */ #include <stdio.h> int i; three.c

Window selection commands.

countCTRL-Ww

Go down a window. If at the bottom, wrap. If count is specified, go to the window number count.

countCTRL-WW

Go up a window. If at the top, wrap. If count is specified, go to the window number count.

CTRL-Ww CTRL-Ww

CTRL-Ww

Figure 21.2

/* File one.c */ ~ ~ ~ one.c /* File two.c */ ~ ~ ~ two.c /* File three.c */ #include <stdio.h> int i; three.c

More window selection commands.

CTRL-WW

CTRL-WW

CTRL-WW

Moving Windows Up and Down

Moving Windows Up and Down The CTRL-Wr command rotates the windows downward (see Figure 21.3). The CTRL-Wr command takes a count argument, which is the number of times to perform the rotate down. The CTRL-WR command rotates the windows upward (see Figure 21.4). /* File one.c */ ~ ~ one.c /* File two.c */ ~ ~ two.c /* File three.c */ #include <stdio.h> int i; three.c /* This file four.c * / ~ four.c

Figure 21.3

/* File one.c */ ~ ~ one.c /* File two.c */ ~ ~ two.c /* File three.c */ #include <stdio.h> int i; three.c /* This file four.c * / ~ four.c

Figure 21.4

CTRL-Wr

/* This file four.c * / ~ four.c /* File one.c */ ~ ~ one.c /* File two.c */ ~ ~ two.c /* File three.c */ #include <stdio.h> int i; three.c

Rotating a window down. CTRL-W R

/* File two.c */ ~ ~ two.c /* File three.c */ #include <stdio.h> int i; three.c /* This file four.c * / ~ four.c /* File one.c */ ~ ~ one.c

Rotating a window up.

241

242

Chapter 21

All About Windows and Sessions

The CTRL-Wx command exchanges the current window with the next one (see Figure 21.5). If the current window is the bottom window, there is no next window, so it exchanges the current window with the previous one. /* File one.c */ ~ ~ one.c /* File two.c */ ~ ~ two.c /* File three.c */ #include <stdio.h> int i; three.c /* This file four.c * / ~ four.c

Figure 21.5

CTRL-W x

/* File two.c */ ~ ~ two.c /* File one.c */ ~ ~ one.c /* File three.c */ #include <stdio.h> int i; three.c /* This file four.c * / ~ four.c

Exchanging a window.

Performing Operations on All Windows The :write command writes out the current file. If you want to write all the files that have been modified (including hidden buffers), use the following command: :wall

The quit command (:quit) closes the current window. (If this is the last window for a file, the file is closed.) If you have multiple windows up, you can quit them all using this command: :qall

If some of the files have been modified, and the changes have not been saved, the :qall command fails. If you want to abandon the changes you have made, use the force option (!), which gives you this command: :qall!

(Use this with caution because you can easily discard work you wanted to keep.) If you want to perform a combination of :wall and :qall, use this command: :wqall

Performing Operations on All Windows

Other Window Commands The CTRL-Wo command makes the current window the only one on the screen. As Figure 21.6 shows, all the other windows are closed. (The system pretends that you did a :quit in each of them.) If you have specified multiple files on the command line or through the :argument file-list command, the :all command opens up a window for each file (see Figure 21.7). /* File one.c */ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ :only

CTRL-WO

Figure 21.6

/* File one.c */ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ :only

/* File one.c */ ~ ~ one.c /* File two.c */ ~ ~ two.c /* File three.c */ #include <stdio.h> int i; three.c /* This file four.c * / ~ four.c

The CTRL-Wo command.

:all

Figure 21.7

/* File one.c */ ~ ~ one.c /* File two.c */ ~ ~ two.c /* File three.c */ #include <stdio.h> int i; three.c /* This file four.c * / ~ four.c

:all.

243

244

Chapter 21

All About Windows and Sessions

A variation of the :all command opens a new window for each hidden buffer: :unhide

This command can take an argument that limits the number of windows that can be opened at one time.To unhide all the buffers but put no more than five windows onscreen, for example, use the following command: :unhide 5

Editing the Alternate File You can split the window and edit the alternate file with the command CTRL-W CTRL-^. Figure 21.8 shows the results. /* File three.c */ #include <stdio.h> int i; int main() { for (i = 1; i <= 1 0; ++i) {

CTRL-^

@

“three.c” 11L, 160C

CTRL-W CTRL-^

Figure 21.8

/* File two.c */ ~ ~ ~ ~ ~ ~ ~ ~ “two.c” 1L, 17C /* File two.c */ ~ ~ ~ two.c /* File three.c */ #include <stdio.h> int i; three.c “two.c” 1L, 17C

CTRL-W CTRL-^.

Split Search The CTRL-W CTRL-I command splits the window, and then searches for the first occurrence of the word under the cursor.This search goes through not only the current file, but also any #include files. If you position the cursor of the printf on Hello World and press CTRL-W CTRL-I, you get a screen that looks like Figure 21.9.

Advanced Buffers 245

extern int fprintf _P ((FILE *_restrict _stream, _const char *_restrict _format, ...)); /* Write formatted output to stdout. */ extern int printf _P ((_const char *_restrict _format, ...)); /* Write formatted output to S. */ extern int sprintf _P ((char *_restrict _s, const char_* restrict _format, ...)); /usr/include/stdio.h [RO] #include <stdio.h> int main() { printf("Hello World!\n"); return (0); } /tmp/hello.c

Figure 21.9

The CTRL-W CTRL-I command.

Shorthand Commands The Vim editor contains some shorthand commands that do the work of multiple commands, including the following: :countsnext

:split

followed by :countnext

:countsprevious

:split

followed by :countprevious

:countsNext

:split

followed by :countNext

:srewind

:split

followed by :rewind

:slast

:split

followed by :last

:sargument

:split

followed by :argument

CTRL-W CTRL-D

:split

followed by ]CTRL-D

CTRL-W f

:split

followed by a :find

CTRL-Wg]

:split

followed a CTRL-]

One nice thing about these commands is that they do not open a new window if they fail.

Advanced Buffers The following sections discuss adding, deleting, and unloading buffers.

Adding a Buffer The Vim editor maintains a list of buffers. Usually you put a file on the list by editing it. But you can explicitly add it with the following command: :badd file

246

Chapter 21

All About Windows and Sessions

The named file is merely added to the list of buffers.The editing process will not start until you switch to the buffer.This command accepts an argument: :badd +lnum file

When you open a window for the buffer, the cursor will be positioned on lnum.

Deleting a Buffer The

:bdelete

command deletes a buffer.You can specify the buffer by name:

:bdelete file.c

Or by number: :bdelete 3 :3 bdelete

You can also delete a whole range of buffers, as follows: :1,3 bdelete

If you use the override (!) option, any changes to the buffer are discarded: :bdelete! file.c

Unloading a Buffer The command :bunload unloads a buffer.The buffer is unloaded from memory and all windows for this buffer are closed. However, the file remains listed in the buffer list. The :bunload command uses the same syntax as the :bdelete.

Opening a Window for Each Buffer The :ball command opens a window for each buffer.

Windowing Options The ‘laststatus’ option controls whether the last window has a status line. (See Figure 21.10.) The three values of this option are as follows: 0

The last window never has a status line.

1 If there is only one window on the screen, do not display the status line. If there are two or more, however, display a status line for the last window. (default). 2 Always display a status line even if there is only one window onscreen.

Windowing Options

laststatus=0 /* File one.c */ ~ ~ ~ ~ ~ :set laststatus=0

laststatus=1 /* File one.c */ ~ ~ ~ ~ ~ :set laststatus=1

One file

One file

/* File one.c */ ~ one.c /* File two.c */ ~ ~ :set laststatus=0

laststatus=2 /* File one.c */ ~ ~ ~ ~ one.c :set laststatus=2 One file

/* File one.c */ ~ one.c /* File two.c */ ~ two.c :set laststatus=1

/* File one.c */ ~ one.c /* File two.c */ ~ two.c :set laststatus=2

Two Files

Two Files

Figure 21.10

'laststatus'

Two Files

option.

The ‘winheight’ option sets the minimum number of lines for a window.This is not a hard limit; if things get too crowded, Vim will make smaller windows. When the ‘equalalways’ option is enabled (the default), Vim will always split the screen into equal-size windows.When off, splits can result in windows of different sizes. Figure 21.11 shows the effect of this option. The ‘winheight‘ option is the minimum height of the current window.The ‘winminheight’ option controls how small any other window can be. Generally a :split command opens a window above the current window.The ‘splitbelow’ option causes a new window to appear below the current one. gvim one.c :split :split

/* File one.c */ ~ ~ ~ ~ one.c /* File one.c */ ~ ~ ~ ~ one.c /* File one.c */ ~ ~ ~ ~ one.c :split

/* File one.c */ ~ ~ ~ one.c /* File one.c */ ~ ~o one.c /* File one.c */ ~ ~ ~ ~ ~ ~ ~ one.c :split :set noequalalways

:set equalalways

Figure 21.11

'equalalways'

option.

247

248

Chapter 21

All About Windows and Sessions

Sessions Suppose you are editing along, and it is the end of the day.You want to quit work and pick up where you left off the next day.You can do this by saving your editing session and restoring it the next day. A Vim session contains all the information about what you are editing.This includes things such as the file list, windows, marks, registers, and other information. (Exactly what is controlled by the ‘sessionoptions’ option is described later in the section “Specifying What Is Saved in a Session.”) The following command creates a session file: :mksession file

For example: :mksession vimbook.vim

Later if you want to restore this session, you can use this command: :source vimbook.vim

If you want to start Vim and restore a specific session, you can use the following command: $ vim -c “:source vimbook.vim”

(This tells Vim to execute a specific command on startup (-c).The command is :source vimbook.vim, which loads the session vimbook.vim.)

Specifying What Is Saved in a Session The ‘sessionoption’ option controls what is saved in a session file. It is a string of keywords separated by commas. For example, the default ‘sessionoptions’ setting is as follows: :set sessionoptions=buffers,winsize,options,help,blank

The various keywords are buffers

Saves all buffers.This includes the ones on the screen as well as the hidden and unloaded buffers.

globals

Saves the global variables that start with an uppercase letter and contain at least one lowercase letter.

help

The help window.

blank

Any blank windows on the screen.

options

All options and keyboard mapping.

winpos

Position of the GUI Vim window.

resize

Size of the screen.

Sessions

winsize

Window sizes (where possible).

slash

Replace backslashes in filenames with forward slashes.This option is useful if you share session files between UNIX and Microsoft Windows. (You should set UNIX as well.)

unix

Write out the file using the UNIX end-of-line format.This makes the session portable between UNIX and Microsoft Windows.

Note

If you enable both the slash and unix options, the session files are written out in a format designed for UNIX. The Microsoft Windows version of Vim is smart enough to read these files.

Unfortunately, the UNIX version of Vim is not smart enough to read Microsoft Windows format session files. Therefore, if you want to have portable sessions, you need to force Vim to use the UNIX format.

249

Advanced Visual Mode

N CHAPTER6,“BASICVISUALMODE,”YOU LEARNED HOW TOperform

the simple

visual commands. Now you can take a look at many of the other visual-related commands. Many of these commands have a limited audience; but read on, that audience may include you. In this chapter, you learn about the following: n

Using visual mode with text registers

n

Using the $ selection command

n

Reselecting text

n

Additional highlighting commands

n

Miscellaneous editing commands

n

Select mode

Visual Mode and Registers Chapter 4, “Text Blocks and Multiple Files,” showed you how to use the yank, put, and delete commands with registers.You can do similar things with the visual-mode commands. To delete a block of text, for instance, highlight in visual mode and then use the d command.To delete the text into a register, use the command “register d.

252

Chapter 22

Advanced Visual Mode

To yank the text into a register, use the y command. The D and the Y commands act like their lowercase counterparts, except they work on entire lines, whereas d and y work on just the highlighted section.

The $ Command In block visual mode, the $ command causes the selection to be extended to the end of all the lines in the selection. Moving the cursor up or down extends the select text to the end of the line.This extension occurs even if the new lines are longer than the current ones. Figure 22.1 shows what happens when you don’t use the $ command, and Figure 22.2 shows what happens when this command is used. Oh woe to Mertle the turtle who found web surffing quite a hurtle. The system you see was slower than he. And that’s not saying much for the turtle.

Start visual

Move using l to the end of line. End visual

~ ~ poem.txt –– VISUAL BLOCK ––

Figure 22.1

Block visual mode without $ command.

Oh woe to Mertle the turtle who found web surffing quite a hurtle. The system you see was slower than he. And that’s not saying much for the turtle.

Start visual Use $ to go to the end of line. Use j to go down. Block follows the line ends.

End visual

~ ~ poem.txt –– VISUAL BLOCK ––

Figure 22.2

Block visual mode with the $ command.

Repeating a Visual Selection The gv command repeats the preceding visual mode selection. If you are already in visual mode, it selects the preceding selection. Repeated gv commands toggle between the current and preceding selection. Figure 22.3 shows the effects of these commands. The steps are as follows: 1. First visual selection. 2. Finished with visual. 3.

gv reselects

the old visual.

4. Define new visual.

Repeating a Visual Mode

reselects the old visual

Define new visual

Line 1 Line 2 Line 3 Line 4 Line 5. ~ ~ ~ ~ lines.txt –– VISUAL ––

Line 1 Line 2 Line 3 Line 4 Line 5. ~ ~ ~ ~ lines.txt –– VISUAL ––

gv

First visual selection.

Line 1 Line 2 Line 3 Line 4 Line 5. ~ ~ ~ ~ lines.txt –– VISUAL ––

Finished with visual

Line 1 Line 2 Line 3 Line 4 Line 5. ~ ~ ~ ~ lines.txt

gv - Goes to previous visual

reselect gv -

Figure 22.3

Toggles back if done twice

The gv command.

Selecting Objects A number of commands in visual mode are designed to help you highlight the text you want. The aw command, for example, highlights the next word. Actually it highlights not only the word, but also the space after it. At first this may seem a bit useless. After all, the w command moves you forward one word, so why not just use it? That is because when you perform a selection, the text selected is from the old cursor location to the new one inclusive. Now if you use the w command to move, the result is that the cursor is placed on the first character of the next word.Therefore if you delete the text, you not only get the words you selected, but the first character of the next word. The aw command leaves the cursor positioned just before the first character of the next word. In other words, it selects the word and the spaces beyond it, but not the next word. Another reason to use aw rather than w is that aw selects the whole word, no matter which part of the word the cursor is on, whereas w just selects from the current location to the end of the word. If you want to just select the word, and nothing but the word, use the iw (inner word) command. Figure 22.4 shows how iw and aw work.

253

254

Chapter 22

Advanced Visual Mode

This is a test of some commands such as aw and iw iw aw

Figure 22.4

iw

and aw commands.

You can use the following commands to select text: countaw

Select a word and the space after it.

countiw

Select a word only (inner word).

countaW

Select a WORD and the space after it.

countiW

Select inner WORD (the word only)

countas

Select a sentence (and spaces after it.)

countis

Select the sentence only.

countap

Select a paragraph and the following space.

countip

Select a paragraph only.

counta(

From within text enclosed in (), select the text up to and including the ().

counti(

Like ab, except the () characters are not selected. for (i = 0; i < 100; ++1)

for (i = 0; i < 100; ++1)

a(

i(

Figure 22.5

a(

and i( commands.

counta<

Select matching <> pair, include the <>.

counti<

Select matching <> pair, excluding the <>.

counta[

Select matching [] pair, including the [].

counti[

Select matching [] pair, excluding the [].

counta{

Select matching {} pair, including the {}.

counti{

Select matching {} pair, excluding the {}.

Moving to the Other End of a Selection The o command moves the cursor to the other end of a selection (see Figure 22.6). You can then move back to the other end (where you came from) with another o.

Case Changes 255

0 Toggle between the two ends of a selection.

#include <stdio.h> int i; int main() { for (i = 1; i <= 10; ++i) { printf(“%2d squared is %3d\n”, i, i*i); } return (0); } three.c [+] –– VISUAL ––

Figure 22.6

The o command.

The O command moves the cursor to the other corner of the selection in block visual mode (see Figure 22.7). In other words, the O command moves to the other end of the selection on the same line. Oh woe to Mertle the turtle who found web surffing quite a hurtle. The system you see was slower than he. And that’s not saying much for the turtle.

O Toggle between the two sides of the block visual

~ ~ poem.txt –– VISUAL BLOCK ––

Figure 22.7

The O command.

Case Changes The ~ command inverts the case of the selection.The U command makes the text uppercase and the u command turns the text into lowercase. Figure 22.8 illustrates how the various case-changing commands work.The figures show initial selection, ~, U, and u, respectively. Line 1 Line 2 Line 3 Line 4 ~ ~ ~ ~ ~ test.txt –– VISUAL ––

Line 1 lINE 2 lINE 3 Line 4 ~ ~ ~ ~ ~ test.txt [+] 3 lines ~ed

Line 1 LINE 2 LINE 3 Line 4 ~ ~ ~ ~ ~ test.txt [+] 3 lines ~ed

Initial selection

~

U

Figure 22.8

Case-changing commands.

Line 1 line 2 line 3 Line 4 ~ ~ ~ ~ ~ test.txt [+] 3 lines ~ed u

256

Chapter 22

Advanced Visual Mode

Joining Lines The J command joins all the highlighted lines into one long line. Spaces are used to separate the lines. If you want to join the lines without adding spaces, use the gJ command. Figure 22.9 shows how the J and gJ commands work. Line 1 line 2 line 3 Line 4 ~ ~ ~ ~ ~ test.txt [+] –– VISUAL ––

J

gJ

Figure 22.9

J

Line 1 line 2 line 3 Line 4 ~ ~ ~ ~ ~ ~ test.txt [+]

Line 1 line 2line 3 Line 4 ~ ~ ~ ~ ~ ~ test.txt [+]

and gJ commands.

Formatting a Block The gq command formats the text (see Figure 22.10).

Select a block

Oh woe to Mertle the turtle who found web surffing quite a hurtle. The system you see was slower than he. And that’s not saying much for the turtle. ~ poem.txt –– VISUAL ––

Format it with gq

Oh woe to Mertle the turtle who found web surffing quite a hurtle. The system you see was slower than he. And that’s not saying much for the turtle. ~ ~ poem.txt [+]

Figure 22.10

The gq command.

Pipe (!) Command

The Encode (g?) Command The g? command encodes or decodes the highlighted text using the rot13 encoding. (This primitive encoding scheme is frequently used to obscure potentially offensive Usenet news postings.) With rot13, if you encode something twice, you decode it.Therefore if the text is encoded, g? decodes it. If it is in plain text, g? encodes it. Figure 22.11 shows how this encryption works. g?

This is some text to be obscured by rot13. ~

Toggles encryption

test.txt [+]

Guvf vf fbzr grkg gb or bofpherq ol ebg13. ~ test.txt [+]

–– VISUAL ––

Figure 22.11

The g? command.

The Colon (:) Commands The : command starts a command-mode command with a range already specified. If you want to write a block to a file, for example, select the text using visual mode, and then execute the following command: :write block.txt

This writes the text to the file block.txt. Note:The : command only works on whole lines.

Pipe (!) Command The ! command pipes a region of text through an external program. For example, the !sort pipes the selection through the UNIX sort program. Figure 22.12 shows the visual ! command used to sort a range of lines. one.c three.c alpha.c two.c four.c ~ ~ ~

one.c three.c alpha.c two.c four.c ~ ~ ~

test.txt [+]

test.txt [+]

–– VISUAL ––

:´<,´>!sort Execute “!sort” to filter through the sort program (N0 <Enter> pressed)

Define the visual selection

Figure 22.12

The ! (pipe) command.

alpha.c four.c one.c three.c two.c ~ ~ ~ test.txt [+] Result after <Enter> done.

257

258

Chapter 22

Advanced Visual Mode

Note The ! command always works on lines even if you are in character visual mode or visual block mode.

Select Mode Select mode is yet another visual mode that allows for quick deletion or replacement of the selected text.The way you use select mode is simple.You highlight the text and then type

to delete it. Or you can highlight the text, and then replace it by just typing the replacement. How does select mode compare with visual mode? With visual mode, you highlight the text and then perform an operation. In other words, you need to end the visual mode operation with a command.With select mode, the commands are limited to (for delete) and printable characters (for replacement).This makes things faster because you do not need to enter a command, but it is much more limited than visual mode. You can choose from three select-mode flavors.The commands to start the various flavors of the select mode are as follows: gh

Start characterwise selection.

gH

Start linewise selection.

gCTRL-H

Start block selection.

Moving the cursor in select mode is a little more difficult than moving it in normal visual mode because if you type any printable character, you delete the selected text and start inserting.Therefore, to select text, you must use the arrow, CTRL, and function keys. You can also use the mouse to select text if you set the 'selectmode' option to mouse, as follows: :set selectmode=mouse

(Without this option, the mouse performs a visual selection rather than a select-mode selection.) You can also use the 'selectmode' option to let the shifted cursor keys enter select mode.

Deleting the Selection The backspace command (

or CTRL-H) deletes the selected text (see Figure 22.13).

Select Mode

Oh woe to Mertle the turtle who found web surffing quite a hurtle. The system you see was slower than he. And that’s not saying much for the turtle. –– SELECT –– gh í—Start select

...Select the text — Delete text Oh woe the turtle who found web surffing quite a hurtle. The system you see was slower than he. And that’s not saying much for the turtle.

Figure 22.13

Deleting text in select mode.

Replacing Text Typing any printable character causes the selected text to be deleted and throws Vim into insert mode (see Figure 22.14). Oh woe to Mertle the turtle who found web surffing quite a hurtle. The system you see was slower than he. And that’s not saying much for the turtle. –– SELECT –– Select the word Type “Sam” to replace it. Oh woe to Sam the turtle who found web surffing quite a hurtle. The system you see was slower than he. And that’s not saying much for the turtle. –– INSERT ––

Figure 22.14

Replacing text in select mode.

Switching Modes The CTRL-O command switches from selection mode to visual mode for one command.The CTRL-G command switches to visual mode without returning.To switch from visual mode to select mode, use the CTRL-G command.

259

260

Chapter 22

Advanced Visual Mode

Avoiding Automatic Reselection Usually when you select text, the text remains selected. Even if you execute a command, the selection remains.The gV command causes the selection to disappear after the command is executed.This proves extremely useful for macros that make a selection, do something with it, and then want it to disappear.

Advanced Commands for Programmers

T

HE VIM EDITOR WAS WRITTEN BY PROGRAMMERS who

wanted a good text editor.

Because of that, Vim includes a lot of commands you can use to customize and enhance it to make editing programs easier. Consider, for example, the problem of the

character.You can deal with this character in many different ways.You can set the tab stops to the indentation size, leave them at the default eight characters, or eliminate them altogether (force everyone to use spaces).The Vim editor supports all these types of editing.This chapter shows you how to use each of them. Previously, you saw how to turn on C indent mode.This chapter describes, in detail, how to customize this mode. You have learned how to turn syntax highlighting on as well.This chapter takes you a step further, showing you how to customize it. This chapter discusses the following: n

Removing autoindents

n

Inserting registers and indent

n

Indentation program options

n

Tabbing options

n

Customizing C indentation

262

Chapter 23

Advanced Commands for Programmers

n

Comparing two files

n

Using the preview window

n

Matching options

n

Additional motion commands for programmers

n

Commands for editing files in other directories

n

Advanced :make options

n

Customizing the syntax highlighting

Removing an Automatic Indentation Suppose you are editing a program.You have ’autoindent’ set and are currently indenting in about three levels.You now want to put in a comment block.This is a big block, and you want to put it in column 1, so you need to undo all the automatic indents. One way to this is to type CTRL-D a number of times. Or you can use 0CTRL-D. The 0CTRL-D command in insert mode removes all the automatic indentation and puts the cursor in column 1. (Note that when you type the 0, it appears on the screen—at this point, Vim thinks you are trying to insert a 0 into the text.When you type in the CTRL-D, it realizes you are executing a 0CTRL-D command and the 0 disappears.) When you use 0CTRL-D, the cursor returns to column 1 (see Figure 23.1).The next line also starts in column 1 (normal autoindent behavior). Suppose, however, that you are typing in a label or an #ifdef directive and want to go to column 1 for one line only. In this case, you want the ^CTRL-D command.This places you in column 1 for the current line only.When you enter the next line, the indent is automatically restored (see Figure 23.2). if (flag) { go to skip_it; { do something();

0CTRL-D moves to the first column.

/* This is the start of comment block */ /* This is the second line of the block */

Next line is not indented

Figure 23.1

0CTRL-D moves to column 1 Next line is autoindented

The 0CTRL-D command.

if (flag) { go to skip_it; } #ifdef FLAG if (flag2) {

Figure 23.2

The ^CTRL-D command.

Inserting Registers

Inserting Indent The CTRL-T command is like a

, except that it inserts an indent the size of the ’shiftwidth’ option. If you use a ’shiftwidth’ of 4, for instance, pressing moves you to the next 8-column boundary (a 'tabstop’, assuming that you have the default setting of ‘tabstop=8’). But pressing CTRL-T moves us you to the next 4-column boundary. The CTRL-T and CTRL-D commands work at any point on the line (not just the beginning).Therefore, you can type some text and then use CTRL-T and CTRL-D to adjust the indentation.

Inserting Registers Generally when you use CTRL-R to insert the contents of a register, the contents are autoindented. If you do not want this to happen, use the command CTRL-R CTRL-O register. On the other hand, if you want to insert a register and have Vim “do the right thing,” use the CTRL-R CTRL-P register command. Take a look at how this works. Assume that you are editing a file that contains the following: 1 int main() 2{ 3 if (x) 4 { 5 y(); 6 }

The following settings have been made: :set number :set cindent :set shiftwidth=4

You start on line 3 and do a V to enter line visual mode. Going down to line 6, you highlight the entire if block.You dump this in register a with the command “ay. Next you add two lines at the end to start another if.Your text now looks like this: 1 int main() 2 { 3 if (x) 4 { 5 y(); 6 } 7 if (z) 8 {

Register a contains the following: if (x) { y(); }

263

264

Chapter 23

Advanced Commands for Programmers

Next you go into insert mode and insert the contents of register a using the command CTRL-R a.The result is ugly: 1 int main() 2{ 3 if (x) 4 { 5 y(); 6 } 7 if (z) 8 { 9 if (x) 10 11 12

{ y(); }

So what happened? Register a contains indented lines. But Vim has indenting turned on. Because you inserted the register indent and all, you wound up with double indentation.That was not what you wanted. Go back to where you were (CTRL-Ou, undo) and execute a CTRL-R CTRL-O a. The result is as follows: 1 int main() 2{ 3 if (x) 4 { 5 y(); 6 } 7 if (z) 8 { 9 if (x) 10 { 11 y(); 12 }

This is better.You do not have the double indents.Trouble is, you still do not have the right indent.The problem is that Vim kept the old indent from the original text. Because this line is under the if (z) statement, however, it should be indented an extra level. So you go back and try CTRL-R CTRL-P a.The result is as follows: 1 int main() 2{ 3 if (x) 4 { 5 y(); 6 } 7 if (z) 8 { 9 if (x) 10 { 11 y(); 12 }

To Tab or Not to Tab

Now Vim correctly indented the text by recalculating the indent of each line as it was put in. In normal mode, the “registerp command inserts the text in the specified register into the buffer.The “register]p command does the same thing, except each line has its indent adjusted. Similarly, the “register]P command acts like the “registerP command with indent adjustment.

To Tab or Not to Tab Back in the early days, B.C. (before computers), there existed a communication device called a Teletype. Some models of Teletype could do tabs. Unfortunately, tab stops were set at every eight spaces.When computers came along, their first consoles were Teletypes. Later, when more modern devices (such as video screens) replaced Teletypes, the old tab size of eight spaces was kept for backward compatibility. This decision has caused programmers no end of trouble. Studies have shown that the most readable indentation size is four spaces.Tab stops are normally eight spaces. How do we reconcile these two facts? People have chosen several ways.The three main ones are as follows: 1. Use a combination of spaces and tabs in your program to enter code. If you need an indentation of 12, for example, use a tab (8) and four spaces (4). 2. Tell the machine that tab stops are only 4 spaces and use tabs everywhere. (This is one solution I personally frown upon, because I do not use the special setting and the text appears to be over-indented.) 3. Throw up your hands and say that tabs are the work of the devil and always use spaces. The Vim editor, thank goodness, supports all three methods.

Spaces and Tabs If you are using a combination of tabs and spaces, you just edit normally.The Vim defaults do a fine job of handling things. But you can make life a little easier by setting the ‘softtabstop’ option.This option tells Vim to make the Tab key look and feel as if tabs were set at the value of ‘softtabstop’, but use a combination of tabs and spaces to fake things (see Figure 23.3). After you execute the following command, every time you press the Tab key the cursor moves to the next 4-column boundary: :set softtabstop=4

The first time you press it, however, you get 4 spaces inserted in your text.The second time, Vim takes out the 4 spaces and puts in a tab (thus taking you to column 8).

265

266

Chapter 23

Advanced Commands for Programmers

What was typed

Result

111111111122222222222 123456789012345678901234567890

X ....X XX

....X

X

....X

XX ....X

X

XX ....X

. — A space — A tab

(softtabstop=4)

Figure 23.3

Soft tabs.

Smart Tabs Another related option is the ‘smarttab’ option.With this option on (:set smarttab), tabs inserted at the beginning of a line are treated like soft tabs.The tab size used in this case is defined the ‘shiftwidth’ option. But tabs inserted elsewhere in the text act just like normal tabs. Note that you must have soft tabs off (:set softtabstop=0) for this option to work. Figure 23.4 shows sample results. Smart indenting is a combination of soft tabs and normal tabs.When you execute the following command, Vim treats tabs at the beginning of a line differently: :set smarttab

Suppose, for example, that you have the following settings: :set shiftwidth=4 :set tabstop=8 :set smarttabs

Tab stops are every eight spaces and the indentation size is four spaces.When you type

at the beginning of a line, the cursor will move over the indentation size (four spaces). Doing a double moves over two indention sizes (eight spaces [4*2]). What was typed

Result

111111111122222222222 123456789012345678901234567890

X ....X X X

X

....X ....X

XX ....X

X

XX ....X

. — A space — A tab

(softtabstop=4)

Figure 23.4

Smart tabs.

To Tab or Not to Tab

The following table shows you what happens if you type certain things at the beginning of the line.

You Type

What Is Inserted

Four spaces

One tab

One tab, four spaces

Two tabs

When you type

anywhere else in the line, however, it acts like a normal tab.

Using a Different Tab Stop The following command changes the size of the tab stop to 4: :set tabstop=4

You can actually change it to be any value you want. Figure 23.5 shows what happens when ‘tabstop’ is set to 4. What was typed

Result

111111111122222222222 123456789012345678901234567890

X

X X

X

X

X XX XX

X

X

X

X

(tabstop=4)

— A tab

Figure 23.5

tabstop

set at 4.

Note Just because you change it in Vim does not mean that it will change in your terminal window, that your printing program will not still use eight-character tab stops, or that other editors will use the new setting. Therefore, your type and print commands might require special options to handle things.

No Tabs If you want absolutely no tabs in your file, you can set the ‘expandtab’ option.When this option is set, the Tab key inserts a series of spaces. (Note that setting ‘expandtab’ does not affect any existing tabs. In other words, any tabs in the document remain tabs. If you want to convert tabs to spaces, use the :retab command, which is explained later.)

267

268

Chapter 23

Advanced Commands for Programmers

Note

If you really want to insert a tab when this option is on, type CTRL-V

. The CTRL-V command tells Vim

that you really want to insert this

as a tab and not a bunch of spaces.

The :retab Command The :retab command transforms text with tab stops at one setting to tab stops with another.You can use it to turn tabs into a series of spaces as well, or a series of spaces into tabs.The :retab command transforms text with tab stops at one setting to tap stops with another. For example, suppose that you have a file that was created with tab stops of 4 (:set tabstop=4).This is a non-standard setting, and you want to change things so that the tab stops are 8 spaces. (You want the text to look the same, just with different tab stops.) To change the tap stop in the file from 4 to 8, first execute the command :set tabstop=4

The text should appear on the screen correctly. Now execute the command :%retab 8

This changes the tab stops to 8.The text will appear unmodified, because Vim has changed the white space to match the new value of ‘tabstop‘. For another example, suppose that you are required to produce files with no tabs in them. First, you set the ‘expandtabs’ option.This causes the

key to insert spaces on any new text you type. But the old text still has tabs in it.To replace these tabs with spaces, execute the command :%retab

Because you didn’t specify a new tabstop, the current value of ‘tabstop’ is used. But because the option ‘expandtabs’ is set, all tabs will be replaced with spaces.

Modelines One of the problems with all these tabbing options is that people use them.Therefore, if you work with files created by three different people, you can easily have to work with many different tab settings. One solution to this problem is to put a comment at the beginning or end of the file telling the reader what tab stops to use. For example: /* vim:tabstop=8:expandtabs:shiftwidth=8 */

When you see this line, you can establish the appropriate Vim settings, if you want to. But Vim is a smart editor. It knows about comments like this and will configure the settings for you. A few restrictions apply.The comment must be formatted in this manner and it must appear in the first or last five lines of the program (unless you change the setting of ‘modelines’). This type of comment is called a modeline.

Defining a Comment

Shift Details Suppose that you are typing with a shift width of 4 and you enter a line with 3 spaces in front of it.What should the >> command do? Should it add 4 spaces in front of the line or move it to the nearest shift width.The answer depends on the value of the ‘shiftround’ option. Usually this option is not set, so >> puts in 4 spaces. If you execute the following command, >> moves the indent to the next shift-width boundary: :set shiftround

Figure 23.6 shows how this works. 12345678901234567890 size = 20; size = 20;

(Note “shiftwidth=4”) With “noshiftround”>>moves the text over 4 spaces

With “shiftround”>>moves the text to the next “shiftwidth” boundary. (In this case, column 4.)

Figure 23.6

12345678901234567890 size = 20; size = 20;

The ‘shiftround’ option.

Specifying a Formatting Program You can define the program Vim uses when executing the = command, by setting the ‘equalprg’ option. If this option is not set (and you are not editing a lisp program), the Vim editor uses its own built-in indentation program that indents C or C++ programs. If you want to use the GNU indent program (available from www.gnu.org), for instance, execute this command: :set equalprg=/usr/local/bin/indent

Formatting Comments One of the great things about Vim is that it understands comments.You can ask Vim to format a comment and it will do the right thing. Suppose, for example, that you have the following comment: /* * This is a test. * Of the text formatting. */

You then ask Vim to format it using the following commands: 1. Position the cursor to the start of the comment. 2. Press v to start visual mode.

269

270

Chapter 23

Advanced Commands for Programmers

3. Go to the end of the comment. 4. Format the visual block with the command gq. The result is as follows: /* * This is a test. Of the text formatting. */

Note that Vim properly handled the beginning of each line. (For deciding what is and is not a comment, Vim uses the ‘comments’ option, described in the following section.) The gq{motion} command accomplishes the same thing.

Defining a Comment The ‘comments’ option defines what is a comment.This option is a series of flag:string pairs.

The possible flags are as follows: b

Blank must follow.This means the character begins a comment only if followed by a blank or other whitespace.

f

Only the first line has the comment string. Do not repeat the string on the next line, but preserve indentation.

l

When used on part of a three-piece comment, make sure that the middle lines up with the beginning or end.This must be used with either the s or e flag.

n

Indicates a nested comment.

r

Same as l, only right-justify.

x

Tells Vim that a three-part comment can be ended by typing just the last character under the following circumstances: 1. You have already typed in the beginning of the comment. 2. The comment has a middle. 3. The first character of the end string is the first character on the line.

For three-part comments, the following flags apply: s

Start of three-piece comment.

m

Middle of a three-piece comment.

e

End of a three-piece comment.

number

Add the number of spaces (can be negative) to the indentation of a middle part of a three-part comment.

A C comment starts with /*, has a middle of *, and ends with */, as follows: /* * This is a comment */

Customizing the C Indentation

This results in the ‘comments’ option specification of s1:/*,mb:*,ex:*/

The s1 indicates that this is the start of a three-part comment (s) and the other lines in the command need to be indented an extra space (1).The comment starts with the string /*. The middle of the comment is defined by the mb:* part.The m indicates a middle piece, and the b says that a blank must follow anything that is inserted.The text that begins the comment is *. The ending is specified by ex:*/.The e indicates the end, and the x indicates that you have only to type the last character of the ending to finish the comment.The end delimiter is */. Take a look at how this definition works. First, you need to set the following option: :set formatoptions=qro

The following options prove useful for formatting text (see Chapter 11, “Dealing with Text Files,” for complete details): q

Allow formatting of comments using gq.

r

Automatically insert the middle of a comment after pressing <Enter>.

o

Automatically insert the middle of a comment when a line inside a comment is opened with an O or o command.

Now start typing in comments.You start with a line containing the comment header, /*, as follows: /*

When you type <Enter>, because r is in the format options, you get the following: /* *

The Vim editor automatically inserted the * surrounded by a space on each side to make the comment look good. Now enter a comment and a new line: /* * This is an example *

Now you need to end the comment. But Vim has already typed a space after the asterisk. How can you enter */? The answer is that Vim is smart and will end the comment properly if you just type /.The cursor moves back, the slash is inserted, and you get the following: /* * This is an example */

271

272

Chapter 23

Advanced Commands for Programmers

You can use a number of different formatting commands to format text or comments. For more information on these, see Chapter 11 and Chapter 20, “Advanced Text Blocks and Multiple Files.”

Customizing the C Indentation The C indentation process is controlled by the following options: cinkeys

Defines the keys that trigger an indent event

cinoptions

Defines how much to indent

cinwords

Defines the C and C++ keywords

The ‘cinkeys’ option defines which keys cause a change to indentation.The option is actually a set of type-char key-char pairs. The type-chars are as follows: !

The following key is not inserted.This proves useful when you want to define a key that just causes the line to be re-indented. By default, CTRL-F is defined to effect re-indentation.

*

The line will be re-indented before the key is inserted.

The key causes an indentation change only if it is the first character typed on the line. (This does not mean that it is the first character on the line, because the line can be autoindented. It specifies the first typed character only.)

The key-chars are as follows:

The named key. See Appendix B, “The < > Key Names,” for a list of names.

^X

Control character (that is, CTRL-X).

o

Tells Vim to indent the line when you use an o command to open a new line.

O

Line o, but for the O command.

e

Re-indent the line when you type the final e in else.

:

Re-indent the line when you type a colon after a label or case statement.

<^>, <<>, <>>,

, <e>,

The literal character inside the angle brackets.

The default value for this the ‘cinkeys’ option is as follows: 0{,0},:,0#,!^F,o,O,e

Figure 23.7 shows how the ‘cinkeys’ option works.

Customizing the C Indentation

if (x) {

0{ - { is the first character typed on the line

do_it();

0} - } is the first character

} else {

typed on the line

goto_here:

e - Second “e” of “else” : - Colon anywhere on the line

do_other(); 0} - } is the first character entered on the line

Figure 23.7

} #define DONE 1

The ‘cinkeys’ option.

The ‘cinoptions’ Options The ‘cinoptions’ option controls how much Vim indents each line.This option consists of a series of key indent pairs.The key is a single letter that controls what part of the program is affected (see the following table and Figures 23.8 and 23.9).The indent tells the program how much indentation to use.This can be a number of spaces (for example, 8), or a negative number of spaces (–8). It can also be a multiple of the ‘shiftwidth’ option that is specified as s. For example, 1s is a shift width, 0.5s is half a shift width, and –1s un-indents a shift width. Key

Default

Description

>

s

Normal shift used for indents not covered by another letter.

e

Extra indent added to lines following a line with a curly brace that ends a line (or more technically, one that does not begin a line).

n

Extra indent added to single lines not inside curly braces after an if, while, and so on.

f

Extra indent added to a function body. Includes the outermost {} that define the function.

{

Spaces to be added to opening {.

}

Spaces to be added to closing }.

^

Spaces to be added to text inside a set of {} that start in column 1. For example, a value of -1s causes the body of a function to be pushed one shift width to the left.

:

s

Amount to indent a case inside a switch statement.

=

s

Extra indent for statements after the case statement.

g

s

Indentation for C++ protection keywords (public, private, protected).

h

s

Indentation for statements that follow a protection keyword.

p

s

Shift for K&R-style parameters.

273

274

Chapter 23

t

Advanced Commands for Programmers

s

Indent the type declaration for a function if it is on a separate line.

+

s

Indent for continuation lines (the 2-n lines of a statement).

c

3

Indent the middle of a multiline comment (if no middle * is present).

(

2s

Indent for a line in the middle of an expression. Actually, the indent for a line that breaks in the middle of a set of ().

u

s

Indent for a line that breaks in the middle of a nested set of () (like (, but one level deeper).

)

20

Specify the number of lines to search for closing ().

*

30

Specify the number of lines to search for unclosed comment.

g - C++ protection keywords h - Statements in a C++ class

class foo { public: int i; private: int j; }; int func (pl, p2) int p1; int p2; { if (x) do_x();

p - K&R Parameters

n - After if/while...no {}

if (y) { do_y(); }

e - { at the end of line

if (z) {

{ - All braces inside a function

do_z(); } else { do_no_z(); } switch (flag) { case 1: do_one(); break }

} - Closing bracket : - Case label = - Statements in a case

}

- Inside {} in the first column.

Figure 23.8

Indentation options (part 1).

f - function body

Comparing Two Files 275

Middle comment leader present (No special action).

/* * Comment. */ /* Comment.

c - Comment middle

*/ t - Function type

int func(void) { int i;

+ - Continuation line

i=1+ 2;

( - Line break inside ()

i = (1 + 2); i = (1 * (2 + 3)); return (0);

u - Line break inside (())

}

Figure 23.9

Indentation options (part 2).

The ‘cinwords’ Option The ‘cinwords’ option defines what words cause the next C statement to be indented one level in the Smartindent and Cindent mode.The default value of this option is as follows: :set cinwords=if,else,while,do,for,switch

Comparing Two Files Suppose you want to compare two files that differ by a just a few edits.To do this, start by opening two windows, one for each edit. Next, execute the following command in each window: :set scrollbind

Now when one window scrolls, so does the other. Figure 23.10 demonstrates how this command works. (Go down to line 14 in the first window; the second window scrolls.) As you scroll through both windows, you might encounter a place where you must move one window without moving the other.To do so, all you have to do is execute the following command in the window you want to move and move it: :set noscrollbind

Then to synchronize scrolling, you execute this command: :set scrollbind

276

Chapter 23

Advanced Commands for Programmers

:set scrollbind

:set scrollbind

Line 1 Line 2 Line 3 Line 4 Line 5 Line 6 Line 7 Line 8 Line 9 Line 10 Line 11 /tmp/l1.txt Line 1 Line 2 Line 3 Changed line Line 4 Line 5 Line 6 Line 7 Line 8 Line 9 Line 10 /tmp/l2.txt

Line 4 Line 5 Line 6 Line 7 Line 8 Line 9 Line 10 Line 11 Line 12 Line 13 Line 14 /tmp/l1.txt Line 4 Line 5 Line 6 Line 7 Line 8 Line 9 Line 10 Line 11 Line 12 Line 13 /tmp/l2.txt Go down to line 14 in the first window. The second window scrolls.

Figure 23.10

‘scrollbind’.

The ‘scrollopt’ option controls how ‘scrollbind’ works. It is a set of the following keywords: ver

Vertical scrolling

hor

Horizontal scrolling

jump

When switching between windows, make sure the offsets are 0.

Finally, the following command synchronizes the two windows: :syncbind

Suppose, for example, that you have been looking at two versions of a file, moving both around.To look at some things, you turned off ‘scrollbind’. Now the files point at two different places. You want to go back to synchronized scrolling.You could synchronize the windows by going to each and moving it to the right location; you let Vim do the work. In this case, you set scrollbind in both windows and then execute the following: :syncbind

Vim then synchronizes the two files.

The Preview Window Suppose you are going through a program and find a function call that you do not understand.You could do a CTRL-] on the identifier and jump to the location represented by the tag. But there is a problem with this.The current file disappears because the file with the function definition replaces it.

Showing Matches

A solution to this is to use a special window called the “preview” window. By executing the following command, you open a preview window and display the function definition: :ptag {function}

(If you already have a preview window up, it is switched to the definition of the function.) Figure 23.11 shows a typical example. Assume that you have just executed the following command: :ptag copy_p_date

After you have finished with the preview window, execute the following command: :pclose

(CTRL-Wz or ZZ accomplishes the same thing.) A whole set of commands is designed to manipulate the file in the preview window.The commands are as follows: :ppop

Do a :pop command in the preview window.

:ptselect {identifier}

Open a preview window and do a :tselect.

:ptjump {identifier}

Open a preview window and do a :tjump.

:[count] ptnext

Do a :[count] tnext in the preview window.

:[count] ptprevious

Do a :[count] tprevious in the preview window.

:[count] ptrewind

Do a :[count] trewind in the preview window.

:ptlast

Do a :tlast in the preview window.

CTRL-W}

Do a :ptag on the word under the cursor.

CTRL-Wg}

Do a :ptjump on the word under the cursor. assert((*the_data–>n_data_ptr) <1000); return (result);

} /* Create data from a db data record */ void copy_p_data( struct p_data *the_data, const datum db_data ){ the_data–>n_data_ptr = (int *)&the_data–>raw_data[0]; set_datum(the_data, db_data); } /mnt/sabina/sdo/tools/local/proto/p_data.c [Preview] copy_p_data(&cur_entry, cur_value); pq.c

Figure 23.11

:ptag

example.

277

278

Chapter 23

Advanced Commands for Programmers

Match Options The ‘matchpairs’ option controls what characters are matched by the % command. The default value of this option is as follows: :set matchpairs = (:),{:},[:]

This tells Vim to match pairs of (), [], and {}. To match <> (useful if you are editing HTML documents), for example, use the following command: :set matchpairs=<:>

This matches just <> pairs. If you want to match <> in addition to the other characters, you need this command: :set matchpairs=(:),{:},[:],<:>

This is a little long and awkward to type.The += flavor of the :set command adds characters to an option.Therefore, to add <> to the match list, use the following command: :set matchpairs+=<:>

Showing Matches If you execute the following command, when you enter any type of bracket ( (, ), [, ], {, }),Vim will cause the cursor to jump to the matching bracket briefly when entering: :set showmatch

Generally this jump lasts only for a half second, but you can change it with the ‘matchtime’ option. If you want to make it 1.5 seconds, for instance, use the following command: :set matchtime=15

The value of this option is 1/10 second.

Finding Unmatched Characters The [{ command finds the previous unmatched { (see Figure 23.12).The ]{ command finds the next unmatched {. Also, [} finds the next unmatched }, whereas ]} finds the previous unmatched }. int main() { if (flag) { do_part2(); do_part1();

[{

return (0) ; }

Figure 23.12

The [{ command.

Movement

The ]) command finds the next unmatched ). The [( finds the previous unmatched (. The command [# finds the previous unmatched #if or #else (see Figure 23.13). The command ]# finds the next unmatched conditional. #ifdef FOO # define SIZE 1 #else /* FOO */ # ifdef BAR # define SIZE 20 # else /* BAR */ # define SIZE 30 # endif /* BAR */ #endif

[# moves up to here.

Figure 23.13

The [# command.

These commands are not that reliable because matching by mechanical means is impossible. It is possible to tell that you have three { and two }, but Vim can only guess at which { is missing a }.

Method Location The following commands move to the beginning or end of a Java method: [m

Search backward for the start of a method.

[M

Search backward for the end of a method.

]m

Search forward for the start of a method.

]M

Search forward for the end of a method.

Movement Several movement commands are designed to help programmers navigate through their text. The first set finds the characters { and } in column 1. (This usually indicates the start of a procedure, structure, or class definition.) The four curly brace–related movement commands are as follows: [count] [[

Move backward to the preceding { in column 1.

[count] []

Move backward to the preceding } in column 1.

[count] ]]

Move forward to the next { in column 1.

[count] ][

Move forward to the next } in column 1.

Figure 23.14 shows how these commands work.

279

280

Chapter 23

Advanced Commands for Programmers

int sub1 (void) { return (1); } int sub2 (void) { return (2); } int sub3 (void) { return (3); }

[] [[ Cursor starts here

][ ]]

Figure 23.14

Curly brace movement commands.

Comment Moves The commands [/ and [* move you backward to the start of the first C comment it can find.The commands ]/ and ]* move you forward to the end of the next C comment it can find. Figure 23.15 illustrates some simple comment motions. /* * Comment. */ int a; int b; /* * Comment. */

[/

Cursor starts here

]/

Figure 23.15

Comment motions.

Dealing with Multiple Directories As programming projects grow larger and larger, you might find it convenient to organize things in different directories.Take a look at a small project.You have a main directory that contains main.c and main.h.The other directory is lib and it contains lib.c and lib.h. (This naming has no imagination, but it does make a good example.) Figure 23.16 shows this example organization.

prog

main

lib

main.c

lib.c

main.h

lib.h

Figure 23.16

File layout.

Dealing with Multiple Directories

You start editing in the directory main.The first thing you need to do is tell Vim about your new directory.You use the :set ^= command to put the directory at the top of the search path with the following command: :set path ^= ../lib

Suppose you are editing the file main.c.The file looks like this: #include “main.h” #include “lib.h” int main(int argc, char *argv[])

Now you need to check out a subroutine declaration in lib.h. One way of going to that file is to execute the following command: :vi ../lib/lib.h

This assumes you know where lib.h resides. But there is a better way. First, you position the cursor over the filename in the following line: #include “lib.h”

Now you execute the command gf.The Vim editor tries to edit the filename which is under the cursor.The editor searches for the file in each directory in the path variable. Suppose, however, that you want to edit the file lib.c.This name does not appear in the text, so you cannot use the gf command. Instead, you execute the following command: :find lib.c

This acts just like the :vi command, except the editor searches for the file along the path.The following command does the same thing, but it splits the window and then does a :find: :sfind lib.c

The gf command acts like a :find command but use the word under the cursor as the name of the file to edit. If there is more than one file along the ‘path’ that matches the given file name, then you can select which one Vim edits by giving the gf command a count. In other words if you position the cursor on the name param.h and execute the command 2gf, Vim will edit the second param.h file it finds looking through the directories specified by the ‘path’ option. The ]f and [f command are older, depreciated versions of the gf command. The include Path The path option is used by Vim to tell it where to look for files that were included in the current file.The format of this option is as follows: :set path=directory,directory,...

281

282

Chapter 23

Advanced Commands for Programmers

Directory is a directory to search. For example: :set path=/usr/include,/usr/X11R6/include

You can use wildcards (*) in any directory of the path specification: :set path=/usr/include,/usr/include/*

There are a number of special directories: **

Match an entire tree. For example: :set path=/usr/include/**

This command searches /usr/include and all its subdirectories.The following path specification searches the files in any directory that starts with /home/oualline/progs and ends with include: :set path=/home/oualline/progs/**/include “”

The empty string indicates the current directory. (For example, the middle directory of the trio “first,, last”.)

.

The directory in which the file being edited resides.

For example, the following command tells Vim to search /usr/include and all it is subdirectories, the directory in which the file resides (.), and the current directory (,,). :set path=/usr/include/**,.,,

Checking the Path To make sure that you can find all the #include files, you can execute the following command: :checkpath

This command works not only on the #include directives in the file you are editing, but also on any files that they #include and so on.The result is that all #include files are checked. Figure 23.17 shows how this command works. In this case, a number of files include the files stddef.h and stdarg.h. But Vim cannot find these files. If you want to tell Vim to search the Linux-specific include directory, you can execute the following command: :set path+=/usr/include/linux

Customizing the :make Command

get_rel_name(&cur_entry, i), get_full_name(&cur_entry, i));

}

if (gdbm_errno != 0) { ––– Included files not found in path ––– /usr/include/stdio.h ––> <stddef.h> <stdarg.h> /usr/include/bits/types.h ––> <stddef.h> /usr/include/libio.h ––> /usr/include/_G_config.h ––> <stddef.h> <stdarg.h> /usr/include/bits/stdio–lock.h ––> /usr/include/pthread.h ––> /usr/include/sched.h ––> /usr/include/time.h ––> <stddef.h> /usr/include/stdlib.h ––> <stddef.h> /usr/include/sys/types.h ––> <stddef.h> /usr/include/alloca.h ––> <stddef.h> /usr/include/string.h ––> <stddef.h> Press RETURN or enter command to continue

Figure 23.17

The :checkpath command.

Now do another: :checkpath

Figure 23.18 shows the results. for (i = 0; i < *cur_entry.n_data_ptr; i++) { printf(“\t%d %s (%s)\n”, (int)get_flags(&cur_entry, i), get_rel_name(&cur_entry, i), get_full_name(&cur_entry, i)); } if (gdbm_errno != 0) { All included files were found

Figure 23.18

:checkpath

with all files found.

This command lists only the files that cannot be found. If you want to list all #include files, use this command: :checkpath!

Figure 23.19 shows the results.

283

284

Chapter 23

Advanced Commands for Programmers

––– Included files in path ––– <stdio.h> /usr/include/stdio.h ––>

/usr/include/features.h ––> <sys/cdefs.h> /usr/include/sys/cdefs.h ––> (Already listed) <stddef.h> <stdarg.h> /usr/include/bits/types.h ––> (Already listed) <stddef.h> (Already listed) /usr/include/bits/pthreadtypes.h ––> /usr/include/libio.h ––> –– More ––

Figure 23.19

The :checkpath! command.

Defining a Definition The Vim editor knows about C and C++ macro definitions. But what about other languages? The option 'define' contains the regular expression that Vim uses when it looks for a definition.To have Vim look for macros that start with the string function, for instance, use the following command: :set define=function

Locating include Files The 'include' option defines what an include directive looks like.This option is used for the ]CTRL-I, [CTRL-I, ]d, and [d searches that look through #include’d files. This option is used for the :checkpath command as well. Like the 'define' option, the value of this option is a regular expression. The [i command searches for the first occurance of the word under the cursor. Text inside comments is ignored. The ]j command searches for the next occurance of the word under the cursor. Again, text inside comments is ignored. The [I command lists all the lines which contain the keyword under the cursor. (Comments ignored.) The ]I command does the same thing starting at the current cursor location.

Multiple Error Lists The :make file generates an error list.The Vim editor remembers the results of your preceding 10 :make or :grep commands.To go to a previous error list, use the following command: :colder

Customizing the :make Command

To go to a newer one, use this command: :cnewer

Customizing the :make Command The name of the program to run when the :make command is executed is defined by the 'makeprg' option. Usually this is set to make, but Visual C++ users should set this to nmake by executing the following command: :set makeprg=nmake

The :make command redirects the output of Make to an error file.The name of this file is controlled by the 'makeef’ option. If this option contains the characters ##, the ## will be replaced by a unique number.The default value for this option depends on the operating system you are on.The defaults are as follows: Amiga

t:vim##.Err

UNIX:

/tmp/vim##.err

Microsoft Windows and others

vim##.err

You can include special Vim keywords in the command specification.The % character expands to the name of the current file. So if you execute the command :set makeprg=make\ %

and you do a :make

it executes the following command: $ make file.c File.c is the name of the file you are editing.This is not too useful, so you will refine

the command a little and use the :r (root) modifier: :set makeprg=make\ %:r.o

Now if you are editing file.c, the command executed is as follows: $ make file.o

The Error Format The option 'errorformat’ controls how Vim parses the error file so that it knows the filename and line number where the error occurred. The format of this option is as follows: :set errorformat={string},{string},{string}

285

286

Chapter 23

Advanced Commands for Programmers

The string is a typical error message with the special character % used to indicate special operations (much like the standard C function scanf).The special characters are as follows: %f

Filename

%l

Line number

%c

Column

%t

Error type (a single character)

%n

Error number

%m

Error message

%r

Matches the remainder of the line

%*{char}

Matches (and skips) any scanf conversion specified by {char}.

%%

The character %

When compiling a program, you might traverse several directories.The GNU make program prints a message when it enters and leaves a directory. A sample make log looks like this: make[1]: Entering directory `/usr/src/linux-2.2.12’ make -C kernel fastdep make[2]: Entering directory `/usr/src/linux-2.2.12/kernel’ /usr/src/linux/scripts/mkdep sysctl.c time.c > .depend make[2]: Leaving directory `/usr/src/linux-2.2.12/kernel’ make -C drivers fastdep make[2]: Entering directory `/usr/src/linux-2.2.12/drivers’ /usr/src/linux/scripts/mkdep > .depend make[3]: Entering directory `/usr/src/linux-2.2.12/drivers’ make -C block fastdep make[4]: Entering directory `/usr/src/linux-2.2.12/drivers/block’ /usr/src/linux/scripts/mkdep xd.c xd.h xor.c z2ram.c > .depend make _sfdep_paride _FASTDEP_ALL_SUB_DIRS=” paride” make[5]: Leaving directory `/usr/src/linux-2.2.12/drivers/block’ make[4]: Leaving directory `/usr/src/linux-2.2.12/drivers/’

To get the filename right Vim needs to be aware of this change.The following error format specifications are used to tell Vim about directory changes: %D

Specifies a message printed on entering a directory.The %f in this string indicates the directory entered.

%X

Specifies the leave directory message.The %f in this string specifies the directory that make is done with.

Some compilers, such as the GNU GCC compiler, output very verbose error messages.The GCC error message for an undeclared variable is as follows: tmp.c: In function `main’: tmp.c:3: `i’ undeclared (first use in this function) tmp.c:3: (Each undeclared identifier is reported only once tmp.c:3: for each function it appears in.)

Customizing the :make Command

If you use the default Vim ’errorformat’ settings, this results in three error messages. This is really annoying. Fortunately, the Vim editor recognizes multiline error messages.The format codes for multiline error misusages are as follows: %A

Start of a multiline message (unspecified type)

%E

Start of a multiline error message

%W

Start of a multiline warning message

%C

Continuation of a multiline message

%Z

End of a multiline message

%G

Global; useful only in conjunction with + or -

%O

Single-line file message: overread the matched part

%P

Single-line file message: push file %f onto the stack

%Q

Single-line file message: pop the last file from stack

A + or - can precede any of the letters.These signify the following %-letter

Do not include the matching line in any output.

%+letter

Include the whole matching line in the %m error string.

Therefore, to define a format for your multiline error message, you begin by defining the start message.This matches the following: tmp.c:3: ‘i’ undeclared (first use in this function) %E%f:%l:\ %m\ undeclared\ (first\ use\ in\ this\ function)

Note the use of \ to tell Vim that the space is part of the string. Now you have a problem. If you use this definition, the %m will match just ‘i’.You want a longer error message. So you use + to make Vim put the entire line in the message: %+E%f:%l:\ %m\ undeclared\ (first\ use\ in\ this\ function)

The middle matches this: tmp.c:3: (Each undeclared identifier is reported only once %-C%f:%l:\ (Each\ undeclared\ identifier\ is\ reported\ only\ once

Note the use of the - modifier to keep this message out of the list of messages.The end of the error is as follows: tmp.c:3: for each function it appears in.) %-Z%f:%l:\ for\ each\ function\ it\ appears\ in.)

So you add these three lines to the error format: %+E%f:%l:\ ‘%*\k*’\ undeclared\ (first\ use\ in\ this\ function), %-C%f:%l:\ (Each\ undeclared\ identifier\ is\ reported\ only\ once, %-Z%f:%l:\ for\ each\ function\ it\ appears\ in.)

Now this works, but there is a slight problem.When the GNU compiler encounters the second undefined variable, it does not output the three-line message. Instead, it outputs just the first line. (It figures you have already seen the stuff in parenthesis, so why output it again.)

287

288

Chapter 23

Advanced Commands for Programmers

Unfortunately, your error specification tries to match all three lines.Therefore, you need a different approach.The solution is to globally tell Vim to forget about the second two lines: %-G%f:%l:\ (Each\ undeclared\ identifier\ is\ reported\ only\ once %-G%f:%l:\ for\ each\ function\ it\ appears\ in.)

Now all you have to do is to add this option to your vimrc file.You can just add them on to the ‘errorformat’ option by using the following command: “ This will not work :set errorformat+= \%-G%f:%l:\ (Each\ undeclared\ identifier\ is\ reported\ only\ once, \%-G%f:%l:\ for\ each\ function\ it\ appears\ in.)

Note that in Vim, continuation lines start with a backslash (\). Also, you have added a comma at the end of the first error message to separate it from the second. There is only one problem with this technique: It doesn’t work.The problem is that Vim goes through the list of strings in ‘errorformat’ in order, stopping on the first one that matches. The error string for the GNU compiler (%f:%l:%m) is matched first, and therefore you never get to your two new error messages.You need to put the more specific matches (your two new messages) at the beginning.This is accomplished with the following command: “ This will work :set errorformat ^= \%-G%f:%l:\ (Each\ undeclared\ identifier\ is\ reported\ only\ once, \%-G%f:%l:\ for\ each\ function\ it\ appears\ in.)

Remember, the :set ^= operator adds the string to the beginning of the list.

The ‘switchbuf’ Option Normally when you do a :make and errors occur,Vim will display the offending file in the current window. If you set the ‘switchbuf’ option to split, then the editor will split the current window displaying the bad file in the new window. Note the ‘switchbuf’ option can have the values: “‘(nothing),‘split,’‘useopen’ and ‘split,useopen’.” For a description of the “useopen” argument see Chapter 5, “Windows.”

Defining How a Tag Search Is Done

:set switchbuf=””

$ gvim Makefile

:make

$ gvim Makefile

Figure 23.20

The ‘switchbuf’ option.

Customizing :grep The :grep command runs the program specified by the ‘grepprg’ option.This option contains the command line to use.The # and % characters will be expanded to be the names of the current and alternate file. Also the string $* will be replaced by any arguments to the :grep command. Note that on UNIX, the ‘grepprg’ defaults to grep -n. On Microsoft Windows, it defaults to findstr/s.The capabilities of these two programs differ vastly. The :grep command uses the ‘grepformat’ option to tell Vim how to parse the output of Grep. (It uses the same format as the ‘errorformat’ option.)

Defining How a Tag Search Is Done Usually Vim does a binary search for a given tag name.This makes things quick if the tag file is sorted. Otherwise, a linear search is performed. To force a linear search, use this command: :set notagbsearch

The ‘notagbsearch’ option is useful if your tag file is not sorted.

289

290

Chapter 23

Advanced Commands for Programmers

Some systems limit the number of characters you can have in a function name. If you want this limit to be reflected in Vim, you can set the ‘taglength’ option to the maximum length of your function names. You specify the name of the tags file with the ‘tags’ option.This can be made to point to a file in another directory. For example: :set tags+=/home/oualline/tools/vim/tags

But this causes a little confusion. Did you start in the current directory and tell ctags to put the tag file in the directory /home/oualline/tools/vim or did you execute the ctags command in this directory? The Vim editor solves this problem with yet another option. If you set the following, all tags are relative to the directory that contains the tag file: :set tagrelative

Otherwise, they are relative to the current directory. With the ‘tagstack’ option set, the :tag and :tjump commands build a tag stack. Otherwise, no stack is kept.

Customizing the Syntax Highlighting The Vim editor enables you to customize the colors used for syntax hightlighting. The Vim editor recognizes three different types of terminals: term

A normal black-and-white terminal (no color)

cterm

Color terminal, such as xterm or the Microsoft Windows MS-DOS window

gui

A window created by Gvim

Black-and-White Terminals To change the highlighting for a normal terminal, use this command: :highlight group-name term=attribute

The group-name is the name of the syntax group to be highlighted.This is the name of a syntax-matching rule set used by Vim to tell what part of the program to highlight. A list of the standard group names can be found later in this section. The attribute is a terminal attribute.The terminal attributes for a normal black-andwhite terminal are as follows: bold

underline reverse (also

italic

standout

called inverse)

You can combine attributes by separating them with commas, as follows: :highlight Keyword term=reverse,bold

Suppose, however, that you have a terminal that has very unusual terminal codes.You can define your own attributes with the start and stop highlight options.These define a string to be sent to start the color and one to stop it. For example:

Define How a Tag Search Is Done

:highlight Keyword start=<Esc>X stop=<Esc>Y

With this definition, when Vim displays keywords (for example, if, it will output <Esc>Xif<Esc>Y). If you are familiar with the terminal definition files used on UNIX (called termcap or terminfo files), you can use terminal codes.The termcap entry us defines the underline start code, for example, and ue is the exit underline-mode string.To specify these in a highlight entry, you use the following command: :highlight Keyword start=t_us stop=t_ue

Color Terminals The color entries are defined by the cterm settings.You can set them using cterm=attribute just like a normal term entry. But there are additional options for a color terminal.The setting ctermfg=colornumber defines the foreground color number.The ctermbg=color-number defines the background. Color names are recognized rather than color numbers. The following tells Vim to display comments in red on blue, underlined: :highlight Comment cterm=underline ctermfg=red ctermbg=blue

(Incidentally, this looks really ugly.)

GUI Definition The GUI terminal uses the option gui=attribute to display the attributes of a syntax element in the GUI window.The options guifg and guibg define the colors.These colors can be named. If the name contains a space, the color name should be enclosed in single quotation marks.To keep things portable, the Vim people suggest you limit your color names to the following. Black

Blue

Brown

Cyan

DarkBlue

DarkCyan

DarkGray

DarkGreen

DarkMagenta

DarkRed

Gray

Green

LightBlue

LightCyan

LightGray

LightGreen

LightMagenta

LightRed

LightYellow

Magenta

Orange

Purple

Red

SeaGreen

SlateBlue

Violet

White

Yellow

You can define the color as well by using the standard X11 color numbers. (This works on all systems, regardless of whether you are using X11.) These are of the form #rrggbb, where rr is the amount of red, bb is the amount of blue, and yy is the amount of yellow. (These three numbers are in hexadecimal.) Under Microsoft Windows, the following colors are available: Black

Blue

Brown

Cyan

291

292

Chapter 23

Advanced Commands for Programmers

DarkBlue

DarkCyan

DarkGray

DarkGreen

DarkMagenta

DarkRed

Green

LightBlue

LightCyan

LightGray

LightGreen

LightMagenta

LightRed

Magenta

Red

Sys_3DDKShadow

Sys_3DFace

Sys_3DHighlight

Sys_3DHilight

Sys_3DLight

Sys_3DShadow

Sys_ActiveBorder

Sys_ActiveCaption Sys_AppWorkspace

Sys_BTNFace

Sys_BTNHighlight

Sys_BTNHilight

Sys_BTNShadow

Sys_BTNText

Sys_Background

Sys_CaptionText

Sys_Desktop

Sys_GrayText

Sys_Highlight

Sys_HighlightText

Sys_InactiveBorder

Sys_InactiveCaption Sys_InactiveCaptionText Sys_InfoBK

Sys_InfoText

Sys_Menu

Sys_MenuText

Sys_ScrollBar

Sys_Window

Sys_WindowFrame

Sys_WindowText

White

Yellow

You can use the font=x-font as well to define which font to use.This is not for the faint of heart, because X11 font names are complex. For example: :highlight Comment font= \font=-misc-fixed-bold-r-normal—14-130-75-75-c-70-iso8859-1

Microsoft Windows fonts can be used as well: :highlight Comment font=courier_helv:h12

Combining Definitions You can define colors for multiple terminals on a single highlight line. For example: :highlight Error term=reverse \ cterm=bold ctermfg=7

ctermbg=1

Syntax Elements The syntax elements are defined by the macros in $VIMRUNTIME/syntax.To make things easier, however, the following names are generally used.

Boolean

Character

Comment

Conditional

Constant

Debug

Define

Delimiter

Error

Exception

Float

Function

Identifier

Include

Keyword

Label

Macro

Number

Operator

PreCondit

PreProc

Repeat

Special

SpecialChar

SpecialComment

Statement

StorageClass

String

Structure

Tag

Todo

Type

Typedef

The ‘syntax’ Option

In addition to these syntax elements, Vim defines the following for the various things it generates: Cursor

The character under the cursor.

Directory

Directory names (and other special names in listings).

ErrorMsg

Error messages displayed on the bottom line.

IncSearch

The result of an incremental search.

ModeMsg

The mode shown in the lower-left corner (for example, --INSERT--).

MoreMsg

The prompt displayed if Vim is displaying a long message at the bottom of the screen and must display more.

NonText

The Vim editor displays ~ for lines past the end of the file. It also uses @ to indicate a line that will not fit on the screen. (See Chapter 20.) This syntax element defines what color to use for these elements.

Question

When Vim asks a question.

SpecialKey

The :map command lists keyboard mapping.This defines the highlight to use for the special keys, such as <Esc>, displayed.

StatusLine

The status line of current window.

StatusLineNC

Status lines of the other windows.

Title

Titles for output from :set all, :autocmd, and so on.

Visual

This color is used to highlight the visual block.

VisualNOS

Visual-mode selection when Vim is “Not Owning the Selection.”This works only on X Windows Systems.

WarningMsg

Warning messages displayed on the last line of the window.

WildMenu

Current match in ’wildmenu’ completion.

LineNr

Line number for :number and :# commands, and when the ’number’ option is set.

Normal

Normal text.

Search

The results of the last search when the ‘hlsearch’ option is enabled.

User1 through User9

The ‘statusline’ option enables you to customize the status line.You can use up to nine different highlights on this line, as defined by these names.

Menu

Menu color for the GUI.

Scrollbar

Scrollbar color for the GUI.

293

294

Chapter 23

Advanced Commands for Programmers

Color Chart If you want to see what the various colors look like on your terminal, you can use Vim’s color chart.To access this chart, either pull down the Syntax|Color test menu (Gvim) or follow these steps: 1. Edit the file $VIMRUNTIME/syntax/colortest.vim.Your directories might be different if you install Vim in a different place. 2. Execute the following command: :source %

3. Browse the color list (in the third column). Figure 23.20 shows the results. Unfortunately, this book is in black and white, but you can imagine what it would look like in color. “ Vim syntax file “ Language: none; used to test colors “ Maintainer: Bram Moolenaar

“ Last change: 1998 Nov 1 “ edit this file, then do “:source %”, and check if the color s match syn clear syn keyword col_wh_bl syn keyword col_wh_dblue syn keyword col_wh_dgreen syn keyword col_wh_dcyan syn keyword col_wh_dred

white_on_black white_on_darkblue white_on_darkgreen white_on_darkcyan white_on_darkred

@

Figure 23.21

Color test.

The ‘syntax’ Option The ‘syntax’ option contains the name of the current language used for syntax highlighting.You can turn syntax highlighting off by entering the command: :set syntax=off

To turn it back on, use this command: :set syntax=on

All About Abbreviations and Keyboard Mapping

NCHAPTER8,“BASICABBREVIATIONS,

KEYBOARDMAPPING, and Initialization Files,”

you learned about abbreviations and keyboard mappings, but that discussion focuses on only the most useful subset of the commands.This chapter examines things in complete detail.These commands have a lot of different variations, and this chapter covers them all. In this chapter, you learn about the following: n

How to remove an abbreviation

n

Creation of mode-specific abbreviations

n

Listing abbreviations

n

How to force abbreviation completion in insert mode

n

Mode-specific mappings

n

Clearing and listing mappings

n

Other mapping options

296

Chapter 24

All About Abbreviations and Keyboard Mapping

Removing an Abbreviation To remove an abbreviation, use the command :unabbreviate. Suppose you have the following abbreviation, for example: :abbreviate @a fresh

You can remove it with this command: :unabbreviate @a

To clear out all the abbreviations, use the following command: :abclear

Note One problem with this command is that the abbreviation @a is expanded on the command line. Vim is smart, however, and it will recognize that fresh is really @a expanded and will remove the abbreviation for @a.

Abbreviations for Certain Modes The :abbreviate command defines abbreviations that work for both insert mode and command-line mode. If you type the abbreviation @a in the text, for example, it will expand to fresh. Likewise, if you put it in a command-mode (:) command, it will also expand. Normal mode

i@a<ESC>

Inserts fresh

Command mode

:s/xx/@a/

Executes :s/xx/fresh/

If you want to define an abbreviation that works only in insert mode, you need the :iabbreviate command, as follows: :iabberviate @a fresh

This means that in command mode, @a is just @a.The noremap version of this command is :inoreabbrev.To unabbreviate an insert-mode abbreviation, use the command :iunabbreviate.To clear out all the insert abbreviations, use the following command: :iabclear

If you want an abbreviation defined just for command mode, use the :cabbreviate command.The noremap version of this command is :cnoreabbrev.To remove a definition, use the :cunabbreviate command; and to clear out the entire abbreviation list, use the command :cabclear.

Listing Abbreviations You can list all abbreviations by using the :abbreviate command with no arguments (see Figure 24.1).

Mapping

~ ~ ~ c r :rewind i ab abbreviate ! h Help Press RETURN or enter command to continue

Figure 24.1

:abbreviate

output.

The first column contains a flag indicating the abbreviation type.The flags are as follows: c

Command mode

i

Insert mode

!

Both

Forcing Abbreviation Completion In insert mode, the command CTRL-] causes Vim to insert the current abbreviation. The command CTRL-C causes Vim to exit insert mode.The difference between CTRL-C and <Esc> is that CTRL-C does not check for an abbreviation before entering normal mode.

Mapping and Modes The map command enables you to define mappings limited to certain modes. Suppose, for example, that you want to use the F5 key to yank the current visual-mode select into register v.You can define the following command: :map

“vy

This maps the F5 key for normal, visual, and operator-pending modes. But you want this mapping to be valid only for visual mode.To do that, use a special version of the mapping command: :vmap

“vy

The “v” flavor of the :map command tells Vim that this mapping is valid only for visual mode.Table 24.1 lists seven different flavors of the :map command.

297

298

Chapter 24

All About Abbreviations and Keyboard Mapping

Table 24.1

:map Commands

Command

Normal

Visual

Operator Pending

:map

X X

X

X

:nmap :vmap :omap

Insert

Command Line

X X

:map! :imap

X X

:cmap

X X

Note Operator-pending mode is the mode that occurs when you enter a command such as d that expects a motion to follow. (For example, dw deletes a word. The w is entered in operator-pending mode.)

Now suppose that you want to define

so that the command d deletes the C program block (text enclosed in curly braces, {}). Similarly y would yank the program block into the unnamed register.Therefore, what you need to do is to define to select the current program block.You can do this with the following command: :omap a{

This causes

to perform a select block (a{) in operator-pending mode.With this mapping in place, when you press the d of d, you enter operator-pending mode. Pressing executes the command a{ in operator-pending mode, selecting the block. Because you are performing a d command, the block is deleted.

Other :map Commands A number of commands relate to mapping.The first is this: :map lhs rhs

This adds the mapping of lhs to rhs.Therefore, pressing lhs results in the execution of rhs. The :map command allows remapping of rhs.The following command, however, does not: :noremap lhs rhs

For example: :map ^A dd :map ^B ^A

Mapping

This causes Vim to delete a line when you type CTRL-A. It also causes the CTRL-B command to do the same thing as CTRL-A—that is, delete a line. Note:When entering the control characters, you must “quote” them with CTRL-V. In other words, you must type :map CTRL-VCTRL-A dd

to get: :map ^A dd

Suppose you use the following :noremap command: :map ^A dd :noremap ^B ^A

When you type CTRL-B, you execute a normal CTRL-A (not mapped) CTRL-A command.Therefore, CTRL-B will now increment the value of the number under the cursor.

Undoing a Mapping The :unmap command removes a mapping.To cause a mapped CTRL-A command to revert to the default, use the following command: :unmap ^A

This also proves useful if you want to map a command for a limited set of modes.To define a command that exists in only normal and visual modes, but not operatorpending mode, for example, use the following commands: :map ^A 3w :ounmap ^A

The first command maps the CTRL-A to 3w in normal, visual, and operator-pending modes.The second removes it from the operating-pending mode map.

Clearing Out a Map The following command removes all mapping: :mapclear

Be careful with this one because it also removes any default mappings you might have.

Listing the Mappings The :map command with no arguments lists out the mappings (see Figure 24.2).

299

300

Chapter 24

All About Abbreviations and Keyboard Mapping

~ ~ ~

<xHome>

<xEnd> <End> <S–xF4> <S–F4> <S–xF3> <S–F3> <S–xF2> <S–F2> <S–xF1> <S–F1> <xF4> <xF3> <xF2> <xF1> Press RETURN or enter command to continue

Figure 24.2

Output of :map command.

The first column lists flags indicating the modes for which the mapping is valid. Character Mode <Space>

Normal, visual, and operator-pending

n

Normal

v

Visual

o

Operator-pending

!

Insert and command line

i

Insert

c

Command line

The second column indicates the various lhs of any mappings.The third column is the value of the rhs of the mapping. If the rhs begins with an asterisk (*),the rhs cannot be remapped. The :map command lists all the mappings for normal, visual, and operator-pending modes.The :map! command lists all the mappings for insert and command-line mode. The :imap, :vmap, :omap, :nmap, and :cmap commands list only the mappings for the given modes.

Recursive Mapping By default, Vim allows recursive command mapping.To turn off this feature, execute the following command: :set noremap

This may break some scripts. Using :noremap will avoid this problem. The ‘suffixes’ option lists a set of file name suffixes that will be given a lower priority when it comes to matching wildcards. In other words if a file has one of these suffixes it will be placed at the end of any wildcard list.

Remapping Abbreviations

Remapping Abbreviations Abbreviations can cause problems with mappings. Consider the following settings, for example: :abbreviate @a ad :imap ad adder

Now when you type @a, the string ad is inserted. Because ad is mapped in insert mode to the string adder, however, the word adder is inserted in the text. If you use the command :noreabbrev, however, you tell Vim to avoid this problem. Abbreviations created with this command are not candidates for mapping. One of the problems with the :abbreviate command is that the abbreviations on the right side are expanded when the abbreviations are defined.There is a clumsy way of avoiding this:Type an extra character before the word, type the word, then go back and delete the extra character. :map

Mode Table

The modes are as follows: N

Normal

V

Visual

O

Operator pending

I

Insert

C

Command line

NVO

N

:map

:nm :nmap

:no

O

IC

:vm

:om

:map!

:vmap

:omap

I

C

:im

:cm

:imap

:cmap

:vn

:ono

:no!

:noremap! :nnremap

:vnoremap

:onoremap

:noremap! :inoremap

:unm

:nun

:vu

:ou

:unm!

:iu

:cu

:unmap

:nunmap

:vunmap

:ounmap

:unmap!

:iunmap

:cunmap

:mapc

:nmapc

:vmapc

:omapc

:mapc!

:imapc

:cmapc

:mapclear

:nn

V

:nmapclear :vmapclear

:ino

:omapclear :mapclear! :imapclear :cmapclear

:cno :cnoremap

301

Complete Command-Mode (:) Commands

A

LTHOUGH THEVIMEDITOR IS SUPERBwhen

it comes to doing things visually,

sometimes you need to use command mode. For example, command-mode commands are much easier to use in scripts. Also, a number of other specialized commands are found only in command mode. Being expert in the command-mode command means that you are a Vim power user with the ability to execute a number of amazing high-speed editing commands.

Editing Commands The :delete command deletes a range of lines.To delete lines 1 through 5 (inclusive), for example, use the following command: :1,5 delete

The general form of the :delete command is as follows: : range delete register count

The register parameter specifies the text register in which to place the deleted text.This is one of the named registers (a–z). If you use the uppercase version of the name (A–Z), the text is appended to what is already in the register. If this parameter is not specified, the unnamed register is used.

304

Chapter 25

Complete Command-Mode (:) Commands

The count parameter specifies the number of lines to delete (more on this later in this section). The range parameter specifies the lines to use. Consider the following example (spaces added for readability): :1, 3 delete

Figure 25.1 shows the results of this command. 1 A UNIX sales lady, Lenore, 2 Enjoys work, but she likes the beach more. 3 She found a good way 4 To combine work and play: 5 She sells C shells by the seashore.

~

1 To combine work and play: 2 She sells C shells by the seashor ~ ~ ~ ~ 3 fewer lines

Figure 25.1

:1,3 delete.

You have learned how to use search patterns for line specification. For example, the following command deletes starting from the first line with hello to the first line that contains goodbye. :/hello/,/goodbye/ delete

Note: If goodbye comes before hello, the line range will be backwards, and the command will not work. You can refine the search string specification by adding an offset. For example, /hello/+1 specifies the line one line after the line with the word hello in it.Therefore, the following command results in the screen shown in Figure 25.2. :/beach/+1, /seashore/-1 delete

1 A UNIX sales lady, Lenore, 2 Enjoys work, but she likes the beach more. 3 She sells C shells by the seashore.

~ ~ ~ : /beach/+1, /seashore/–1 delete

Figure 25.2

Results of :/beach/+1, /seashore/-1 delete.

You can also use special shorthand operators for patterns, as follows: \/

Search forward for the last pattern used.

\?

Search backward for the last pattern used.

\&

Search forward for the pattern last used as substitute pattern.

Editing Commands 305

You can also chain patterns.The following command, for example, finds the string first and then searches for the string second. /first//second/

Figure 25.3 shows the result of this command: :/found//work/ delete

1 A UNIX sales lady, Lenore, 2 Enjoys work, but she likes the beach more. 3 She found a good way 4 She sells C shells by the seashore. ~ ~ :/found//work/ delete

Figure 25.3

:/found//word/delete.

You can also specify a line number on which to start.To start the search at line 7, for instance, use the following command-line specification: 7/first/

Other Ways to Specify Ranges If you execute a : command with no count (as most users generally do), the Vim editor puts you into command mode and enables you to specify the range. If you give the command a count(5:, for example), the range is count lines (including the current one).The actual specification of this arrangement is that if you include a count, your line range is as follows: :.,count - 1

In the example original file, for instance, if you move to the top line and then execute the following command, you get the results shown in Figure 25.4: 3:delete 1 To combine work and play: 2 She sells C shells by the seashore. ~ ~ ~ ~ 3 fewer lines

Figure 25.4

3:delete.

306

Chapter 25

Complete Command-Mode (:) Commands

Deleting with a Count Another form of the delete command is as follows: :line delete count

In this case, the :delete command goes to line (default = the current line) and then deletes count lines. If you execute the following command on the original example file, for instance, you get the results shown in Figure 25.5: :3 delete 2

1 A UNIX sales lady, Lenore, 2 Enjoys work, but she likes the beach more. 3 She sells C shells by the seashore. ~ ~ ~ :3 delete 2

Figure 25.5

:3 delete 2.

Note

You can specify a line range for this type of command, but the first line is ignored and the second one is used.

Copy and Move The :copy command copies a set of lines from one point to another.The general form of the copy command is as follows: :range copy address

If not specified, range defaults to the current line.This command copies the line in range to the line specified after address. Consider the following command, for example: :1,3 copy 4

Executed on the original joke, you get the results shown in Figure 25.6.

1 A UNIX sales lady, Lenore, 2 Enjoys work, but she likes the beach more. 3 She found a good way 4 To combine work and play: 5 A UNIX sales lady, Lenore, 6 Enjoys work, but she likes the beach more. 7 She found a good way 8 She sells C shells by the seashore. ~ 3 more lines

Figure 25.6

:1,3 copy 4.

Inserting Text

The :move command is much like the :copy command, except the lines are moved rather than copied.The following command results in what is shown in Figure 25.7: :1,3 move 4

1 To combine work and play: 2 A UNIX sales lady, Lenore, 3 Enjoys work, but she likes the beach more. 4 She found a good way 5 She sells C shells by the seashore.

~ ~ ~ ~ 3 lines moved

Figure 25.7

:1,3 move 4.

Inserting Text Suppose that you want to insert a bunch of lines and for some reason you want to use command mode.You need to go to the line above where you want the new text to appear. In other words, you want the text to be inserted after the current line. Now start the insert by executing the :append command.Type the lines that you want to add and finish by typing a line that consists of just a period (.). The following example illustrates the :append command. :% print A UNIX sales lady, Lenore, Enjoys work, but she likes the beach more. She found a good way To combine work and play: She sells C shells by the seashore. :1append This line is appended. . :% print A UNIX sales lady, Lenore, This line is appended. Enjoys work, but she likes the beach more. She found a good way To combine work and play: She sells C shells by the seashore.

The general form of the :append command is as follows: :line append

The line is the line after which to insert the new text.

307

308

Chapter 25

Complete Command-Mode (:) Commands

The :insert command also inserts text. It has a similar form: :line insert

It works just like :append except that :append inserts after and :insert inserts before the current line.

Printing with Line Numbers You do not have to turn on the number option to print the text with line numbers. The :# command accomplishes the same thing as :print but includes line numbers: :1 print A UNIX sales lady, Lenore, :1 # 1 A UNIX sales lady, Lenore,

Printing with list Enabled The 'list' option causes invisible characters to be visible.The :list command lists the specified lines, assuming that this option is on: :1,5 list

The following example shows the difference between :print and :list: :100,111 print open_db(void) { if (proto_db == NULL) { proto_db = gdbm_open(proto_db_name, 512, GDBM_READER , 0666, NULL); if (proto_db == NULL) { fprintf(stderr, “Error: Could not open database %s\n”, proto_db_name); exit (8); } } } :100,111 list open_db(void)$ {$ if (proto_db == NULL) {$ ^Iproto_db = gdbm_open(proto_db_name, 512, GDBM_READER, $ ^I^I^I^I0666, NULL);$ ^Iif (proto_db == NULL) {$ ^I fprintf(stderr, “Error: Could not open database %s\n”, $ ^I ^I^I proto_db_name);$ ^I exit (8);$ ^I}$ }$ }$

Substitute

Print the Text and Then Some The :z command prints a range of lines (the current one being the default) and the lines surrounding them. For example, the following command prints line 100 and then a screen full of data: :100 z

The :z command takes a count of the number of extra lines to list. For example, the following command lists line 100 and three additional lines: :100 z 3

The :z command can be followed by a code indicating how much to display.The following table lists the codes: Code

Listing Start

Listing End

New Current Line

+ ^ . =

Current line One screen back Two screens back One-half screen back One-half screen back

One screen forward Current line One screen back One-half screen forward One-half screen forward

One screen forward Current line One screen back One-half screen forward Current line

Substitute The format of the basic substitute command is as follows: :range substitute /from/to/flags count Note

This example uses a slash (/) to separate the patterns. Actually you can use almost any character that does not appear in the patterns. The following, for example, is perfectly valid: :substitute +from+to+

This can prove extremely useful when you are dealing with patterns that contain slashes, such as filenames: :1,$ substitute +/home/user+/apps/product+

Delimiters can be any character except letters, digits, backslash, double quote, or vertical bar. The Vim editor uses a special set of magic characters to represent special things. For example, star (*) stands for “repeat 0 or more times.” If you set the 'nomagic' option, however, the magic meanings of some of these characters are turned off. (For a complete list of the magic characters and how the 'nomagic' option affects them, see Chapter 19, “Advanced Searching Using Regular Expressions.”)

309

310

Chapter 25

Complete Command-Mode (:) Commands

The :smagic command performs a substitute but assumes that the 'magic' option is set during the command. For example, start in command mode with a one-line file.You start by printing the entire file: :%print Test aaa* aa* a*

Now set the 'magic' option and perform a substitution.The p flag tells the editor to print the line it changed: :set magic :1 substitute /a*/b/p bTest aaa* aa* a*

This command made only one change at the beginning of the line. So why did it change Test to b*Test when there is no a around? The answer is that the magic character star (*) matches zero or more times. Test begins with zero a’s. But why did it make only one change? Because the :substitute command changes only the first occurrence unless the g flag is present. Now undo the change and try again: :undo :1 substitute /a*/b/pg bTbebsbtb b*b b*b b*b

This time you got what you wanted. Now try it again with the 'nomagic' option set: :undo :set nomagic :1 substitute /a*/b/pg Test aab ab b

Without 'magic', a star (*) is just a star. It is substituted directly. The :smagic command forces magic on the star (*) and other characters while the substitution is being made, resulting in the following: :undo :1 smagic /a*/b/pg bTbebsbtb b*b b*b b*b

The :snomagic forces 'magic' off. :undo :set magic :1 snomagic /a*/b/pg Test aab ab b

The & command repeats the substitution.This enables you to keep your old from and to strings, but also to supply a different range or flags. The general form of this command is as follows: :range& flags count

For example: :1 substitute /a\+/b/p Test b* aa* a*

Global Changes

The command changes the first occurrence of from on the line.You want the entire line, so you repeat the substitution with the g option: :&g

Of course, this does not print (because the new flags—in this case g—replaces the flags and you did not specify p or, more specifically, pg).Take a look at the result: :1 print Test b* b* b*

This is what you wanted. The :& command and the :substitute command with no from or to specified acts the same. The normal-mode & command repeats the last :substitute command. If you were to execute the following command, for instance, you would change the first manager on line 5 to an idiot: :5 substitute /manager/idiot/

Now if you enter normal mode (through the :vi command) and execute an & command, the next manager on this line would change as well. If you were to move down to another line and execute an & command, you would change that line as well. If you give & a count, it will work on that many lines. The :~ command acts just like the &g command, except that it uses as from the last search pattern (used for a / or ? search) rather than the last :substitute from string. The general form of this command is as follows: :range~ flags count

Repeat Substitution The & command repeats the last substitution.

Making g the Default Generally the :substitute command changes only the first occurrence of the word unless you use the 'g' option.To make the 'g' option the default, use the following command: :set gdefault

Note:This can break some scripts you may use.

Global Changes The command-mode commands covered so far have one limitation:They work only on a contiguous set of lines. Suppose, however, that you want to change just the lines that contain a certain pattern. In such a case, you need the :global command. The general form of this command is as follows: :range global /pattern/ command

311

312

Chapter 25

Complete Command-Mode (:) Commands

This tells Vim to perform the given command on all lines that contain the pattern in the specified range.To print all the lines within a file that contain the word Professor, for instance, use the following command: :% global /Professor/ print Professor: Yes. Professor: You mean it’s not supposed to do that? Professor: Well there was no Computer Center Bulletin Professors of mathematics will prove the existence of

The :global! command applies the command to all the lines that do not match the given pattern, as will the :vglobal command.

Commands for Programs The following sections describe some commands for programs.

Include File Searches The :ijump command searches for the given pattern and jumps to the first occurrence of the word in the given range. It searches not only the current file, but all files brought in by #include directives.The general form of this command is as follows: :range ijump count [/]pattern[/]

If a count is given, jump to the count occurrence of the pattern. The pattern is considered literal text unless it is enclosed in slashes (in which case, it is a regular expression). Consider the file hello.c, for example: #include <stdio.h> int main() { printf(“Hello World\n”); return (0); }

The following command goes to the first line that contains define EOF: :ijump /define\s*EOF/

In this case, it is in the include file stdio.h. The :ilist command acts like :ijump, except it lists the lines instead of jumping to them: :ilist EOF /usr/include/libio.h 1: 84 #ifndef EOF 2: 85 # define EOF (-1) 3: 327 && __underflow (_fp) == EOF ? EOF \ /usr/include/stdio.h

Commands for Programs

4: 83 #ifndef EOF 5: 84 # define EOF (-1) 6: 408 null terminator), or -1 on error or EOF. */ /usr/include/bits/stdio.h 7: 138 if (__c == EOF) 8: 157 if (_IO_putcun (*__ptr++, __stream) == EOF)

\ \

The :isearch command is like :ilist, except that the first occurrence is listed: :isearch EOF #ifndef EOF

Finally, the command :isplit works like a :split and a :ijump.

Jumping to Macro Definitions You learned how to use the command [CTRL-D to jump to the definition of the macro under the cursor.The following command accomplishes the same thing for the macro named name: :djump name

To jump to the macro MAX, for example, use this command: :djump MAX

You do not have to know the full name of the macro to find its definition. If you know only part of a name, you can perform a regular expression search for the definition by enclosing the name in slashes, as follows: :djump /MAX/

This command finds the first definition of the macro with the word MAX in it. You can give the :djump command a range argument that restricts the search to the given range: :50,100 djump /MAX/

This command finds the first definition of any macro containing the word MAX in lines 50 through 100. If you do not want the first definition, but the second, you can add a count to the command.To find the second definition of MAX, for instance, use this command: :djump 2 MAX

Split the Window and Go to a Macro Definition The following command is shorthand for :split and :djump: :range dsplit count [/]pattern[/]

313

314

Chapter 25

Complete Command-Mode (:) Commands

Listing the Macros The :dlist command works just like :djump, except that instead of moving to the macro definition, the command just lists all the definitions that match: :dlist EOF /usr/include/libio.h 1: 85 # define EOF (-1) /usr/include/stdio.h 2: 84 # define EOF (-1)

Listing the First Definition The :dsearch command works just like :dlist, except that it displays only the first definition: :dsearch EOF # define EOF (-1)

Override Option (!) The :ilist, :ijump, :djump, :dlist, and :dsearch commands take an override option (!). If the ! is present, definitions within comments found as well.

Directory Manipulation To change the current working directory, use the following command: :cd dir

This command acts just like the system cd command. On UNIX, it changes the current working directory to the given directory. If no directory is specified, it goes to the user’s home directory. On Microsoft Windows, it goes to the indicated directory. If no directory is specified, it prints the current working directory. The following command changes the directory to the previous path: :cd -

In other words, it does a cd to the last directory you used as the current working directory. To find out which directory Vim is currently using, use this command: :pwd

Start deep in the directory tree, for instance: :pwd /mnt/sabina/sdo/writing/book/vim/book/11

Current File

You are working on a UNIX system, so go to your $home directory: :cd :pwd /home/sdo

Jump into another directory: :cd tmp :pwd /home/sdo/tmp

Return to the previous directory: :cd :pwd /home/sdo

Return to the previous directory before this one: :cd :pwd /home/sdo/tmp

Current File The following command prints out the current file and line information: :file

If you want to change the name of what Vim thinks is the filename, use this command: :file name

Suppose, for example, that you start editing a file called complete.txt.You get this file just right, so you write it out using the :write command. Now you want shorten the file and write it out as summary.txt. So now you execute this command: :file summary.txt

Now when you continue to edit, any changes are saved to summary.txt. Take a look at how this works.You start by editing the file star.txt. :file “star.txt” line 1 of 1 —100%— col 1

The :write command with no arguments writes the file to the current filename (in this case, star.txt). :write “star.txt” 1 line, 18 characters written

Now you want to change the filename to new.txt.The editor tells you that this is a new filename. :file new.txt “new.txt” [Not edited] line 1 of 1 —100%— col 1

315

316

Chapter 25

Complete Command-Mode (:) Commands

The :write command is used to write the file. In this case, the current filename differs; it is new.txt. :write “NEW.TXT” [New File] 1 line, 18 characters written

There is another command similar to :file; the following command prints the current line number: :=

For example: := line 1

Advanced :write Commands The :write command writes the buffer (or a selected range of lines) to a file. It has some additional options.The following command, for example, appends the contents of the file you are editing to the file named collect.txt: :write >> collect.txt

If the collect.txt file does not exist, this command aborts with an error message. If you want to “append” to the file even if does not exist, use the force (!) option: :write! >> collect.txt

The :write command can not only write to a file, but it can also be used to pipe the file to another program. On Linux or UNIX, for instance, you can send the file to a printer by using the following command: :write !lpr

Warning

The following two commands are different; the difference being only the spacing: :write! lpr :write !lpr

The first writes to the file named lpr with the force option in place. The second sends the output to the command lpr.

Updating Files The :update command acts just like the :write command, with one exception: If the buffer is not modified, the command does nothing.

Simple Edits

Reading Files The :read command reads in a file.The general form of this command is as follows: :line read file

The preceding command reads the file in and inserts it just after line. If no file is specified, the current file is used. If no line is supplied, the current line is used. Like :write, the :read command can use a command rather than a file.To read the output of a command and insert it after the current line, use the following command: :line read !command

Register Execution Chapter 2, “Editing a Little Faster,” showed you how to record macros in registers. If you want to use these macros in command mode, you can execute the contents of a register with the following command: :line@register

This command moves the cursor to the specified line, and then executes the register. This means that the following command executes the previous command line: :@:

To execute the previous :@register command, use this command: :line@@

Simple Edits The following sections describe simple edits.

Shifting The :> command shifts lines to the right.The :< command shifts lines to the left. The following command, for example, shifts lines 5 through 10 to the right: :5, 10 >

Changing Text The :change command acts just like the :delete command, except that it performs an :insert as

well.

317

318

Chapter 25

Complete Command-Mode (:) Commands

Entering Insert Mode The :startinsert command starts insert mode as if you were in normal mode and were to press i.

Joining Lines The :join command joins a bunch of lines (specified by the range parameter) together into one line. Spaces are added to separate the lines. If you do not want the added spaces, use the :join! command.

Yanking Text The following command yanks the specified lines into the register: :range yank register

If no register is specified, the unnamed register is used.

Putting Text The :put command puts the contents of a register after the indicated line.To dump the contents of register a after line 5, for example, use the following command: :5put a

If you want to put the text before the line, use this command: :5put! a

Undo/Redo The :undo command undoes a change just like the u command does.The :redo command redoes a change like CTRL-R does. To mark the beginning of the line, use the :mark {register}

command. If a line is specified, that line will be marked.The :k command does the same thing, with the exception that you don’t have to put a space in front of the register name.The following two commands are equivalent: :100 mark x :100 ka

Miscellaneous Commands The following sections describe some miscellaneous commands you can use.

Miscellaneous Commands

The :preserve Command The :preserve command writes out the entire file to the “swap” file.This makes it possible to recover a crashed editing session without the original file. (If you do not use this command, you need both the swap file and the original to perform recovery.) See Chapter 14, “File Recovery and Command Line Arguments,” for information on recovering crashed sessions.

The Shell Commands To execute a single shell command, use the following Vim command (where cmd is the system command to execute): :!cmd

To find the current date, for instance, use this command: :!date

The following command repeats the last shell command you executed: :!!

Finally, the following command suspends Vim and goes to the command prompt: :shell

You can now enter as many system commands as you want. After you have finished, you can return to Vim with the exit command.

Shell Configuration The following several options control the actual execution of a command. shell

The name of the shell (command processor).

shellcmdflag

Flag that comes after the shell.

shellquote

The quote characters around the command.

shellxquote

The quote characters for the command and the redirection.

shellpipe

String to make a pipe.

shellredir

String to redirect the output.

shellslash

Use forward slashes in filenames (MS-DOS only).

319

320

Chapter 25

Complete Command-Mode (:) Commands

Command History The

:history

command prints out the current command-mode command history:

:history

>

# cmd history 2 1 print 3 5 4 7 print 5 . print 6 history

The Vim editor maintains a set of histories for various commands. A code identifies each of these:

Code

History Type

c

cmd

:

Command-line history (command-mode commands)

s

search

/

Search strings (See Chapter 3, “Searching”)

e

expr

=

Expression register history

i

input

@

Input line history (data typed in response to an :input operator)

a

all

All histories

Therefore, to get a list of all the various history buffers, use the :history all command: :history all # cmd history 2 1 print 3 5 4 7 print 5 . print 6 history > 7 history all # search history 1 human 2 uni 3 comp 4 Seem > 5 \

# expr history 1 55 2 2*88 > 3 5+99 # input history Press Return or enter command to continue

The general form of the :history command is as follows: :history code first , last

Miscellaneous Commands

If no first and last are specified, the whole history is listed.The first parameter defaults to the first entry in the history, and the last defaults to the last. Negative numbers indicate an offset from the end of the history. For example, –2 indicates the next-to-last history entry. The following command, for example, list history entries 1 through 5 for command-mode commands: :history c 1,5

And, this next command lists the last 5 search strings: :history s –5,

Setting the Number of Remembered Commands The 'history' option controls how may commands to remember for commandmode (: mode) commands.To increase the number of commands to remember (to 50, for instance), use this command: :set history=50

Viewing Previous Error Messages The Vim editor keeps track of the last few error and information messages displayed on the last line of the screen.To view the message history, use the following command: :messages “../joke.txt” 6092 lines, 174700 characters Entering Ex mode. Type “visual” to go to Normal mode. search hit BOTTOM, continuing at TOP Not an editor command: xxxxx search hit BOTTOM, continuing at TOP search hit BOTTOM, continuing at TOP Pattern not found: badbad Not an editor command: :^H Invalid address

Redirecting the Output The following command causes all output messages to be copied to the file as well as to appear on the screen: :redir > file

To end the copying, execute the following command: :redir END

This command proves useful for saving debugging information or messages for inclusion in a book.

321

322

Chapter 25

Complete Command-Mode (:) Commands

You can also use the :redir command to append to a file by using this command: :redir >> file

Executing a :normal Command The :normal command executes a normal-mode command.The following command, for instance, changes the word where the cursor is located to the word DONE: :normal cwDONE<Esc>

The group of commands is treated as one for the purposes of undo/redo. The command should be a complete command. If you leave Vim hanging (suppose that you executed a command cwDone, for instance), the display will not update until the command is complete. If you specify the '!' option, mappings will not be done on the command.

Getting Out The following command writes the current file and closes the window: :exit

When the last window is closed, the editor stops. If the override flag (!) is given, an attempt will be made to write the file even if it is marked read-only. You can also specify a filename on the command line.The data will be written to this file before exiting.The following command, for example, saves the current file in save-it-it.txt and exits. :exit save-it.txt

If you want to save only a portion of the file, you can specify a range of lines to write.To save only the first 100 lines of a file and exit, for example, use this command: :1,100 exit save-it.txt

Write and Quit The following command does the same thing that :exit does, except it always writes the file: :range wq! file

The :exit command writes only if the file has been changed.

Advanced GUI Commands

T

HE VIM EDITOR IS HIGHLY CONFIGURABLE.

This chapter shows you how to

customize the GUI. Among other things, you can configure the following in Vim: n

The size and location of the window

n

The display of menus and toolbars

n

How the mouse is used

n

The commands in the menu

n

The buttons on the toolbar

n

The items in the pop-up menu

The remainder of this chapter introduces you to the commands that enable you to customize all these features.

Switching to the GUI Mode Suppose you are editing in a terminal window and want to switch to the GUI mode. To do so, use the following command: :gui

324

Chapter 26

Advanced GUI Commands

Window Size and Position When you first start gvim (GUI Vim), the window is positioned by the windowing system.The size of the window on UNIX is set to the size of the terminal window that started the editor. In other words, if you have a 24×80 xterm window and start gvim, you get a 24×80 editing window. If you have a larger window, say 50×132, you get a 50×132 editing window. On UNIX you can tell gvim to start at a given location and size by using the -geometry flag.The general format of this option is as follows: -geometry width+ x heightx_offset-y_offset

The width and height options specify the width and height of the window (in characters).The x-offset and y-offset tell the X Windows System where to put the window. The x-offset specifies the number of pixels between the left side of the screen and the right side of the window. If the x-offset specification is negative, it specifies the distance between the left edge of the editor and the right side of the screen. Similarly, the y-offset specifies the top margin, or if negative, the bottom margin. Thus, the -geometry +0+0 option puts the window in the upper-left corner, whereas -geometry -0-0 specifies the lower-right corner. The width and height parameters specify how big the editing window is to be in lines and columns.To have a 24-by-80 editing window, for example, use the option -geometry 80x24. Figure 26.1 shows how these options work. y-offset

x-offset height

width

Figure 26.1

-geometry option.

The guioptions

Microsoft Windows Size and Position Command-Line Specification The Microsoft Windows version of gvim starts with an editing window of 80×25.The gvim editor uses the standard Microsoft Windows command-line option to specify an initial size and position. Because Microsoft Windows does not have a standard option for this value, gvim does not have one either.

Moving the Window The following command displays the current location (in pixels) of the upper-left corner of the window: :winpos

If you want to move the window, you can use this command: :winpos X Y

To position the screen 30 pixels down and 20 pixels over from the left, for instance, use the following command: :winpos 20 30

Window Size The following command displays the number of lines in the editing window: :set lines?

To change this number, use this command: :set lines=lines

Lines is the number of lines you want in the new editing window. To change the number of columns on the screen, use this command: :set columns=columns

The :winsize Command Older versions of Vim use a :winsize command.This command is deprecated because the :set lines and :set columns commands have superseded it.

The guioptions You can control a number of GUI-based features with the 'guioptions' option.The general form this command is as follows: :set guioptions=options

Options is a set of letters, one per option.

325

326

Chapter 26

Advanced GUI Commands

The following options are defined: a

Autoselect

When set, if you select text in the visual mode, Vim tries to put the selected text on the system’s global clipboard.This means that you can select text in one Vim session and paste it in another using the “*p command.Without this option you must use the “*y command to copy data to the clipboard. It also means that the selected text has been put on the global clipboard and is available to other applications. On UNIX, for example, this means that you can select text in visual mode, and then paste it into an xterm window using the middle mouse button. If you are using Microsoft Windows, any text selected in visual mode is automatically placed on the clipboard. (Just as the Copy ^C menu item does in most other applications.) This means that you can select the text in Vim and paste it into a Microsoft Word document.

f

Foreground

On UNIX, the gvim command executes a fork() command so that the editor can run in the background. Setting this flag prevents this, which is useful if you are writing a script that needs to run the gvim command to let the user edit a file, and that needs to wait until the editing is done. (The -f command-line option accomplishes the same thing.) The f flag also proves useful if you are trying to debug the program.

Note You must set this in the initialization file (because by the time you can set it from the edit window, it is too late).

i

Icon

If set, gvim displays an attractive icon when the editor in minimized on an X Windows System. If not present, the program just displays the name of the file being edited with no icon (see Figure 26.2).

Figure 26.2

m

Menu

i option

Display menu bar (see Figure 26.3)

The guioptions

Figure 26.3 M

No menu

m

option.

If this option is present during initialization, the system menu definition file $VIMRUNTIME/menu.vim is not read in.

Note This option must be set in the vimrc file. (By the time givmrc is read, it is too late.)

g

Gray

Turn menu items that cannot be used gray. If not present, these items are removed from the menu (see Figure 26.4).

t

Tear off

Enable tear off menus.

These items are grayed-out.

Items are removed.

Figure 26.4

g

option.

327

328

Chapter 26

Advanced GUI Commands

T

Toolbar

Include toolbar (see Figure 26.5)

r

Right scrollbar

Put a scrollbar on the right (see Figure 26.6).

Figure 26.5

T

option.

l

Left scrollbar

Put a scrollbar on the left (see Figure 26.6).

b

Bottom scrollbar

Put a scrollbar on the bottom (see Figure 26.6).

Right scrollbar

Left scrollbar Bottom scrollbar

Figure 26.6

v

Vertical dialog boxes

Use vertical alignment for dialog boxes (see Figure 26.7).

Figure 26.7 p

Pointer callback fix

Scrollbars.

v option.

This option is designed to fix some problems that might occur with some X11 window managers. It causes the program to use pointer callbacks.You must set this in the gvimrc file.

The guioptions

Changing the Toolbar The 'toolbar' option controls the appearance of the toolbar. It is a set of values: icon

Display toolbar icons

text

Display text

tooltips

When the cursor hovers over an icon, display a ToolTip.

The default displays ToolTips and icons: :set toolbar=icons,tooltips

Figure 26.8 shows how this option affects the screen.

:set toolbar=icons,tooltips

:set toolbar=icons,text,tooltips

:set toolbar=text,tooltips

Figure 26.8

The 'toolbar' option.

Note To turn off the toolbar, you cannot set this option to the empty string. Instead use the following command:

:set guioptions -= T

Customizing the Icon If you are editing in a terminal window, some terminals enable you to change the title of their window and their icon. If you want Vim to try to change the title to the name of the file being edited, set this option: :set title

329

330

Chapter 26

Advanced GUI Commands

Sometimes the name of the file with its full path name is longer than the room you have for the title.You can change the amount of space used for the filename with the following command: :set title=85

In this case, the title text can consume 85% of the title bar. For example: :set titlelen=45

Figure 26.9 shows how 'titlelen' can affect the display.

Figure 26.9

'titlelen'

option.

If you do not like what Vim selects for your title, you can change it by setting the following: :set titlestring=Hello\ World!

When you exit Vim, it tries to restore the old title. If it cannot restore it (because it is impossible to remember it), the editor sets the title to the string specified by the 'titleold' option. For example: :set titleold=vim\ was\ here!

When the window is iconified, the icon option tells Vim whether to attempt to put the name of the file in the icon title. If this option is set, Vim attempts to change the icon text. If you do not like the Vim default, you can set the 'iconstring' option and that text will be used for the icon string. The ‘icon’ option, if set causes the string under the icon to contain the name of the file being edited (or the value of ‘iconstring’ if set). If the option is turned off, the icons just have the generic title Vim. Figure 26.10 shows the results of the following command: :set iconstring=Now\ editing\ tutorial

Mouse Customization

:set icon (Editing the file Makefile)

Figure 26.10

:set noicon

The ‘icon’ option.

Mouse Customization The Vim editor is one of the few UNIX text editors that is mouse-aware.That means you can use the mouse for a variety of editing operations.You can customize the utility of the mouse by using the options discussed in the following sections.

Mouse Focus Generally when you want to move from one Vim editing window to another, you must use one of the window change commands such as CTRL-Wj or CTRL-Wk. If you execute the following command, the current Vim editing window is the one where the mouse pointer is located: :set mousefocus

Note This option affects only the windows within a Vim session. If you are using the X Windows System, the selection of the current window (X Client window) is handled by the window manager. On Microsoft Windows, the current window selection is handled by Microsoft Windows, which always forces you to use “click to type.”

The ‘mousemodel’ Option The 'mousemodel' option defines what the mouse does.There are three possible modes: extend, popup, and popup_setpos.To set the mouse model, use the following command: :set mousemodel=mode

In all modes, the left mouse button moves the cursor, and dragging the cursor using the left button selects the text. In extend mode, the right mouse button extends the text and the middle button pastes it in.This behavior is similar to the way an xterm uses the mouse. In popup mode, the right mouse button causes a small pop-up menu to appear.This behavior is similar to what you find in most Microsoft Windows applications. The popup_setpos mode is exactly like popup mode, except when you press the right mouse button, the text cursor is moved to the location of the mouse pointer, and then the pop-up menu appears. The following table illustrates how 'mousemodel' affects the mouse buttons.

331

332

Chapter 26

Advanced GUI Commands

Mouse

extend

popup

popup_setpos

Left

Place cursor

Place cursor

Place cursor

Drag-left

Select text

Select text

Select text

Shift-left

Search word

Extend selection

Extend selection

Right

Extend selection

Pop-up menu

Move cursor, and then pop-up menu

Drag-right

Extend selection

Middle

Paste

Paste

Paste

Mouse Configuration The 'mouse' option enables the mouse for certain modes.The possible modes are as follows: n

Normal

v

Visual

i

Insert

c

Command-line

h

All modes when in a help file except “hit-return”

a

All modes except the “hit-return”

r

“more-prompt” and “hit-return” prompt

Mouse Mapping The left mouse button (

) moves the text cursor to where the mouse pointer is located.The command causes Vim to enter visual mode.The area between the text cursor and the mouse pointer is selected.The <MiddleMouse> acts like the P command and performs a put to insert in the unnamed register in the file. If you precede the mouse click with a register specification (such as “a, for instance), the contents of that register are inserted. If you have a wheel on your mouse, the up-wheel (<MouseUp>) moves three lines up. Similarly, a down-wheel movement (<MouseDown>) moves three lines down. If you press Shift, the screen moves a page. In other words, <S-MouseUp> goes up a page and <S-MouseDown> goes down a page.

Double-Click Time The 'mousetime' option defines the maximum time between the two presses of a double-click.The format of this command is as follows: :set mousetime=time

Time is the time in milliseconds. By default, this is half a second (500ms).

Custom Menus

Hiding the Mouse Pointer When you are editing with the GUI, you have a text cursor and a mouse pointer to deal with. If that is too confusing, you can tell Vim to turn off the mouse pointer when not in use.To enable this feature, use the following command: :set mousehide

When you start typing, the mouse pointer disappears. It reappears when you move the mouse.

Select Mode The 'selectmode' option defines when the editor starts select mode instead of visual mode.The following three events can trigger select mode: mouse

Moving the mouse (see 'mousemode', discussed earlier)

key

Using some special keys

cmd

The v, V, or CTRL-V command

The general form of the command is as follows: :set selectmode=mode

Mode is a comma-separated list of possible select events (mouse, key, cmd). option allows the keys

, , , , <End>, and <PageDown> to do special things. If you set this option as follows, Shift+key starts a selection: The

'keymodel'

, <PageUp>,

:set keymodel=startsel

If the option is set as follows, an unshifted Key results in the section being stopped: :set keymodel=stopsel

You can combine these options as well, as follows: :set keymodel=startsel,stopsel

Custom Menus The menus that Vim uses are defined in the file $VIMRUNTIME/menu.vim. If you want to write your own menus, you might first want to look through that file. To define a menu item, use the :menu command.The basic form of this command is as follows: :menu menu-item command-string

(This command is very similar to the :map command.) The menu-item describes where on the menu to put the item. A typical menu-item is File.Save, which represents the item Save under the menu File.The ampersand charac-

333

334

Chapter 26

Advanced GUI Commands

ter (&) is used to indicate an accelerator. In the gvim editor, for instance, you can use Alt-F to select File and S to select save.Therefore, the menu-item looks like &File.&Save. The actual definition of the File.Save menu item is as follows: :menu 10.340 &File.&Save

:w

:confirm w

Vi IMproved - Vim - PDF Free Download (2024)

References

Top Articles
Latest Posts
Recommended Articles
Article information

Author: Jeremiah Abshire

Last Updated:

Views: 5558

Rating: 4.3 / 5 (54 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: Jeremiah Abshire

Birthday: 1993-09-14

Address: Apt. 425 92748 Jannie Centers, Port Nikitaville, VT 82110

Phone: +8096210939894

Job: Lead Healthcare Manager

Hobby: Watching movies, Watching movies, Knapping, LARPing, Coffee roasting, Lacemaking, Gaming

Introduction: My name is Jeremiah Abshire, I am a outstanding, kind, clever, hilarious, curious, hilarious, outstanding person who loves writing and wants to share my knowledge and understanding with you.