vim is a very featureful editor. We cannot describe everything in full detail here. Instead, we've chosen to discuss several of the most important and unique features that it has.
vim will notice how the lines of a text file end.
It sets the fileformat
variable to
one of dos
(CR-LF),
unix
(LF), or
mac
(CR) to indicate the file's current mode.
By default, vim will write the file back out in
the same format, but if you change the value of fileformat
,
vim will use that convention.
This is an easy way to convert between Linux (or UNIX) and MS-DOS files,
and makes editing DOS files under UNIX or Linux very easy.
(In contrast, the other clones all display a ^M
at the end of each line.)
The licensing terms are described later in this chapter; they are fairly liberal. However, the author encourages users who like vim to send a donation to a children's center in Uganda.
vim has a large set of features for working with C and C++ programs.
vim defines a large number of events, such as before or after reading a file, entering or leaving a window, and so on. For each event, you can set up an "auto command," i.e., a command to be executed when that event occurs.
With vim, Bram Moolenaar has taken a different approach from the usual shareware or freeware author. If you use vim and you like it, Mr. Moolenaar requests that you send a donation to help orphans in Uganda. We applaud his efforts.
Mr. Moolenaar spent a year as a volunteer at Kibaale Children's Centre (KCC), located in Kibaale, a small town in the south of Uganda, near Tanzania. The KCC works to provide food, medical care, and education for children in this area, which is suffering from AIDS more than in any other part of the world. Because of the high incidence of AIDS, many of the children are orphans.
In order to continue supporting KCC, Mr. Moolenaar is trying to raise funds and organize sponsorship. You can find a much longer explanation in the file uganda.txt in the vim distribution. This includes directions for sending donations. You can also look at http://www.vim.org/iccf/.
vim, in the grand tradition of vi, is first and foremost a programmer's editor. In particular, it is a C programmer's editor, and happily, C++ programmers can take advantage of it too. There are lots of features that make the C programmer's life easier. We describe the most significant ones here.
All versions of vi have the autoindent
option, which, when set, automatically indents the current line by the
same amount as the one next to it. This is handy for C programmers
who indent their code, and for anyone else who may need to indicate
some kind of structure in their text via indentation.
vim carries this feature further, with two
options, smartindent
and cindent
.
The cindent
option is the more interesting of the
two, and is the topic of this subsection. See Table 11.14 for a list of vim indentation and formatting options.
Option | Function |
---|---|
autoindent | |
smartindent | Similar to |
cindent | Enables automatic indenting for C programs, and is quite smart. C formatting is affected by the rest of the options in this table. |
cinkeys | |
cinoptions | |
cinwords | Keywords that start an extra indentation on the following line. |
formatoptions | Made up of a number of single letter flags that control several behaviors, notably how comments are formatted as you type them. |
comments | Describes different formatting options for different kinds of comments, both those with starting and ending delimiters, as in C, and those that start with a single symbol and go to the end of the line, such as in a Makefile or shell program. |
When set up appropriately, vim automatically
rearranges the indentation of your C program as you type.
For instance, after an if
, vim
automatically indents the next line. If the body of the
if
is enclosed in braces, when you type
the right brace, vim will automatically
indent it back one tab stop, to line up underneath the
if
.
As another example, with the settings shown below,
upon typing the colon that goes with a case
,
vim will shift the line with the case
left one tab stop to line up under the switch
.
The following .vimrc produces, in our opinion, very nicely formatted C code:
set nocp incsearch set cinoptions=:0,p0,t0 set cinwords=if,else,while,do,for,switch,case set formatoptions=tcqr set cindent syntax on source ~/.exrc
The nocp
option turns off strict vi
compatibility. The incsearch
option turns on
incremental searching. The settings for cinoptions
,
cinwords
, and formatoptions
differ from the defaults; the result is to produce a
fairly strict "K&R" C formatting style.
Finally, syntax coloring is turned on, and then the rest
of the vi options are read in from
the user's .exrc file.
We recommend that you start up vim, set these options as shown, and then spend some time working on a C or C++ program. Five minutes of playing with this facility will give you a better feel for it than whatever static examples we could present on the printed page. We think you'll find the facility really enjoyable to use.
Often, when working with large C programs, it is helpful to be able to see where a particular type name, function, variable or macro is defined. The tag facility can help with this, but doing a tag lookup actually moves you to the found location, which may be more than you need.
vim has a number of commands that search through the current file and through included files to find other occurrences of a keyword. We summarize them here.
The vi and ex commands fall into four categories: those that display the first occurrence of a particular object (in the status line), those that display all occurrences of a particular object, those that jump to the location of the first occurrence, and those that open a new window and jump to the first occurrence. Commands that do all four exist to look for keywords, usually the identifier under the cursor, and to look for macro definitions of the identifier under the cursor.
These commands use the smart syntax facilities (the
comments
variable described earlier)
to ignore occurrences of the searched-for identifier
inside comments.
With a preceding count,
they go to the count
th occurrence.
The search for the identifier starts at the beginning of the file,
unless otherwise noted.
See Table 11.15 for a list of the vim identifier searching commands.
Command | Function |
---|---|
[i | Display the first line that contains the keyword under the cursor. |
]i | Display the first line that contains the keyword under the cursor, but start the search at the current position in the file. This command is most effective when given a count. |
[I | Display all lines that contain the keyword under the cursor. Filenames and line numbers are displayed. |
]I | Display all lines that contain the keyword under the cursor, but start from the current position in the file. |
[ ^I | Jump to the first occurrence of the
keyword under the cursor.
(Note that |
] ^I | Jump to the first occurrence of the keyword under the cursor, but start the search from the current position. |
^W i | Open a new window showing the location of the first (or countth) occurrence of the identifier under the cursor. |
^W ^I | |
[d | Display the first macro definition for the identifier under the cursor. |
]d | Display the first macro definition for the identifier under the cursor, but start the search from the current position. |
[D | Display all macro definitions for the identifier under the cursor. Filenames and line numbers are displayed. |
]D | Display all macro definitions for the identifier under the cursor, but start the search from the current position. |
[ ^D | Jump to the first macro definition for the identifier under the cursor. |
] ^D | Jump to the first macro definition for the identifier under the cursor, but start the search from the current position. |
^W d | Open a new window showing the location of the first (or countth) macro definition of the identifier under the cursor. |
^W ^D |
Two options, define
and include
,
describe the source code lines that define macros and include
source files. They have default values appropriate for C, but
can be changed to suit your programming language (e.g., the value
^\(#\s*define\|[a-z]*\s*const\s*[a-z]*\)
for define
could be used
to also look for definitions of C++ named constants).
The same facilities are also available as ex commands, shown in Table 11.16.
Command | Function |
---|---|
[range ]is [earch ][! ] [count ] [/ ]pattern [/ ] | Like |
[range ]il [ist ][! ] [/ ]pattern [/ ] | Like |
[range ]ij [ump ][! ] [count ] [/ ]pattern [/ ] | Like |
[range ]isp [lit ][! ] [count ] [/ ]pattern [/ ] | Like |
[range ]ds [earch ][! ] [count ] [/ ]pattern [/ ] | Like |
[range ]dl [ist ][! ] [/ ]pattern [/ ] | Like |
[range ]dj [ump ][! ] [count ] [/ ]pattern [/ ] | Like |
[range ]dsp [lit ][! ] [count ] [/ ]pattern [/ ] | Like |
che [ckpath ][! ] | List all the included files that could not be
found. With the |
The path
option is used to search for included files
that do not have an absolute pathname. Its default value is
.,/usr/include,,
, which looks in
the directory where the edited file resides,
in /usr/include, and in the current directory.
A number of enhanced and new cursor motion commands make it
easier to find the opposite ends of matching constructs, as well
as to find unmatched constructs that should be matched, for
example, #if
statements that do not have
a corresponding #endif
.
Most of these commands may be preceded by a count, which
defaults to one if not given.
See Table 11.17 for a list of the extending matching commands.
Command | Function |
---|---|
% | Extended to match the |
[( | |
[) | Move to the countth
next unmatched |
[{ | |
[} | Move to the countth
next unmatched |
[# | |
]# | Move to the countth
next unmatched |
[* , [/ | Move to the countth
previous unmatched start of a C comment, |
]* , ]/ | Move to the countth
next unmatched end of a C comment, |
vim allows you to specify actions that should be executed when a particular event occurs. This facility gives you a great deal of flexibility and control. As always though, with power comes responsibility; the vim documentation warns that you should be careful with the autocommand facility so that you don't accidentally destroy your text!
The facility is complicated and detailed. In this section we outline its general capabilities, and provide an example to give you a sense of its flavor.
The autocommand command is named :autocmd
.
The general syntax is:
:auevent
filepat
command
The event is the kind of event to which this
command applies, for example, before and after reading a file
(FileReadPre
and FileReadPost
),
before and after writing a file
(FileWritePre
and FileWritePost
),
and upon entering or leaving a window
(WinEnter
and Winleave
).
There are more defined events, and case in the event name does not matter.
The filepat is a shell-style wildcard pattern that vim applies to filenames. If they match, then the autocommand will be applied for this file.
The command is any ex mode command. vim has a special syntax for retrieving the different parts of filenames, such as the file's extension, or the name without the extension. These can be used in any ex command, but are very useful with autocommands.
Multiple autocommands for the same events and file patterns
add commands onto the list. Autocommands can be removed
for a particular combination of events and file patterns
by appending !
to the :autocmd
command.
A particularly elegant example allows you to edit files compressed with the gzip program. The file is automatically decompressed when editing starts, and then recompressed when the file is written out (the fourth line is broken for readability):
:autocmd! BufReadPre,FileReadPre *.gz set bin :autocmd! BufReadPost,FileReadPost *.gz '[,']!gunzip :autocmd BufReadPost,FileReadPost *.gz set nobin :autocmd BufReadPost,FileReadPost *.gz \ execute ":doautocmd BufReadPost " . expand("%:r") :autocmd! BufWritePost,FileWritePost *.gz !mv <afile> <afile>:r :autocmd BufWritePost,FileWritePost *.gz !gzip <afile>:r :autocmd! FileAppendPre *.gz !gunzip <afile> :autocmd FileAppendPre *.gz !mv <afile>:r <afile> :autocmd! FileAppendPost *.gz !mv <afile> <afile>:r :autocmd FileAppendPost *.gz !gzip <afile>:r
The first four commands are for reading compressed files.
The first two in this set use !
to
remove any previously defined autocommands
for compressed files (*.gz).
The compressed file is read into the buffer as a binary file, so
the first command turns on
the bin
(short for binary
)
option.
vim sets the marks
'[
and ']
to the first and
last lines of the just read text. The second command uses this to
uncompress the just read file in the buffer.
The next two lines unset the binary
option, and then apply any autocommands that apply to the
uncompressed version of the file (e.g., syntax highlighting).
The %:r
is the current filename without the extension.
The next two lines are for writing the compressed file.
The first one in this set first removes any previously defined autocommands
for compressed files (*.gz), with these events.
The commands invoke a shell to rename the file to not have the
.gz
extension, and then run gzip
to compress the file.
The <afile>:r
is the filename
without the extension.
(The use of <afile>:r
is restricted
to autocommands.)
vim writes the uncompressed buffer to
the file with the .gz extension, thus the
need for the renaming.
The second line in this set runs gzip to compress the file. gzip automatically renames the file, adding the .gz extension.
The last four lines handle the case of appending to a compressed file. The first two of these lines uncompress the file and rename it before appending the contents to the file.
Finally, the last two lines recompress the file after writing to it, so that the uncompressed file is not left laying around.
This section just touches the tip of the iceberg of autocommands.
For example, autocommands can be placed into groups, so that they
can all be executed or removed together.
All of the syntax coloring commands
described in
Section 11.9.2
are placed into the highlight
group.
An autocommand then executes all of them together when an
appropriate file is read.
As an example, instead of having your .vimrc file
always execute set cindent
for smart C indenting,
you might use an autocommand to do it just for C source code, like
this:
autocmd BufReadPre,FileReadPre *.[chy] set cindent