LDP/LDP/howto/docbook/C-editing-with-VIM-HOWTO/C-editing-with-VIM-HOWTO.sgml

1418 lines
32 KiB
Plaintext

<!DOCTYPE Article PUBLIC "-//OASIS//DTD DocBook V4.2//EN">
<Article id="index">
<!-- Article Header -->
<articleinfo>
<Title>
C editing with VIM HOWTO
</Title>
<Author>
<FirstName>
Siddharth
</FirstName>
<SurName>
Heroor
</SurName>
<AuthorBlurb>
<para>
<ULink URL="mailto:s_heroor@yahoo.com">
s_heroor@yahoo.com
</ULink>
</para>
</AuthorBlurb>
</Author>
<revhistory>
<revision>
<revnumber>
v1.0
</revnumber>
<date>
Jan 14, 2001
</date>
<authorinitials>
sh
</authorinitials>
<revremark>
Second Revision. Corrected some typos.
</revremark>
</revision>
<revision>
<revnumber>
v0.1
</revnumber>
<date>
Dec 04, 2000
</date>
<authorinitials>
sh
</authorinitials>
<revremark>
First Revision. I would love to have your feedback
</revremark>
</revision>
</revhistory>
<abstract>
<para>
This document gives an introduction to editing C and
other language files, whose syntax is similar, like C++ and
Java in vi/VIM.
</para>
</abstract>
</articleinfo>
<!-- Section 1: Introduction -->
<sect1 id="intro">
<title>
Introduction
</title>
<para>
The purpose of this document is to introduce the novice VIM
user to the editing options available in VIM for C files. The
document introduces some commands and keystrokes which will
help in improving the productivity of programmers using VIM
to edit C files.
</para>
<para>
The scope of the document is to describe how one can edit C
files with VIM. However most of what is described is also
applicable for vi. Plus what is mentioned here about editing
C files is more or less applicable to C++, Java and other similar
languages.
</para>
</sect1>
<!-- Section 2: Moving Around -->
<sect1 id="moving">
<title>
Moving around.
</title>
<sect2>
<title>
w, e and b keystrokes
</title>
<para>
One can use the <keycap>w</keycap>, <keycap>e</keycap> and
<keycap>b</keycap> keys to move around a file. VIM is
capable of recognizing the different tokens within a C expression.
</para>
<para>
Consider the following C code
</para>
<figure>
<title>
A C snippet
</title>
<mediaobject>
<imageobject>
<imagedata fileref="images/moving1.png" format="png">
</imageobject>
<textobject>
<ProgramListing>
...
if(( NULL == x ) &amp;&amp; y &gt; z )
...
</ProgramListing>
</textobject>
</mediaobject>
</figure>
<para>
Assume that the cursor is positioned at the beginning of
the <keycap>if</keycap> statement. By pressing w once the
cursor jumps to the first <keycap>(</keycap>. By typing
<keycap>w</keycap> again the cursor moves to
<keycap>NULL</keycap>. Next time the cursor will move to the
<keycap>==</keycap> token. Further keystrokes will take
you as follows. <keycap>x.</keycap>..
<keycap>)</keycap>... <keycap>&amp;&amp;</keycap>...
<keycap>y</keycap>... <keycap>&gt;</keycap>...
<keycap>z</keycap>... and finally <keycap>)</keycap>...
</para>
<para>
<keycap>e</keycap> is similar to <keycap>w</keycap> only
that it takes you to the end of the current word and not
to the beginning of the next word.
</para>
<para>
<keycap>b</keycap> does the exact opposite of
<keycap>w</keycap>. It moves the cursor in the opposite
direction. So you can moving backwards using the
<keycap>b</keycap> keystroke.
</para>
</sect2>
<sect2>
<title>
{, }, [[ and ]] keystrokes
</title>
<para>
The <keycap>{</keycap> and <keycap>}</keycap> keys are
used to move from paragraph to paragraph. When editing C
files these keys have a slightly different meaning. Here a
paragraph is taken as a bunch of lines separated by an
empty line.
</para>
<para>
For Example
</para>
<figure>
<title>
Another C snippet
</title>
<mediaobject>
<imageobject>
<imagedata fileref="images/moving2.png" format="png">
</imageobject>
<textobject>
<programlisting>
...
C-statement;
/* Comment */
...
/* Next Set of C-statements */
...
</programlisting>
</textobject>
</mediaobject>
</figure>
<para>
The above snippet shows two paragraphs. One can easily
move from the beginning of one to the other, by using the
<keycap>{</keycap> and <keycap>}</keycap>
keys. <keycap>{</keycap> will take the cursor to the
paragraph above and <keycap>}</keycap> will take the
cursor to the paragraph below.
</para>
<para>
Many people have the coding style where a logical set of
statements are grouped together and separated by
one or more blank lines.
</para>
<para>
For Example
</para>
<figure>
<title>
Another C snippet
</title>
<mediaobject>
<imageobject>
<imagedata fileref="images/moving3.png" format="png">
</imageobject>
<textobject>
<programlisting>
void function1()
{
/* Declarations */
int x;
char y;
double z;
/* Some code */
x = 1;
y = 'a';
z = 1.2;
/* Some more code */
x++;
y++;
z++;
}
</programlisting>
</textobject>
</mediaobject>
</figure>
<para>
The <keycap>{</keycap> and <keycap>}</keycap> keys are
very useful in such situations. One can very easily move
from one "paragraph" to another.
</para>
<para>
Another set of keys which are useful are the
<keycap>[[</keycap> and <keycap>]]</keycap> keys. These
keys allow you to jump to the previous { or next { in the
first column.
</para>
<para>
For Example
</para>
<figure>
<title>
The next snippet of C code
</title>
<mediaobject>
<imageobject>
<imagedata fileref="images/moving4.png" format="png">
</imageobject>
<textobject>
<programlisting>
void foo()
{
/* Some C-statements */
}
void bar()
{
/* Some other C-statements */
}
</programlisting>
</textobject>
</mediaobject>
</figure>
<para>
Lets say you were editing foo() and now you want to edit
bar(). Just type <keycap>]]</keycap> and the cursor will
take you to the opening { of the bar() function. The
reverse is slightly different. If you were in the middle of bar()
and you type <keycap>[[</keycap> the cursor will move to
the first { above i.e. the beginning of bar() itself. One
has to type <keycap>[[</keycap> again to move to the
beginning of foo(). The number of keystrokes can be
minimized by typing <keycap>2[[</keycap> to take the
cursor to the beginning of the previous function.
</para>
<para>
Another set of similar keystrokes are the <keycap>][</keycap> and
<keycap>[]</keycap> keystrokes. <keycap>][</keycap> takes
the cursor to next } in the first column. If you were
editing foo() and wanted to go to the end of foo() then
<keycap>][</keycap> will take you there. Similarly if you were
editing bar() and wanted to go to the end of foo() then
<keycap>[]</keycap> would take the cursor there.
</para>
<para>
The way to remember the keystrokes is by breaking them
up. The first keystroke will indicated whether to move up
or down. <keycap>[</keycap> will move up and
<keycap>]</keycap> will move down. The next keystroke
indicates the type of brace to match. If it same same as
the previous keystroke then the cursor will move to {. If
the keystroke is different then the cursor will move to
}.
</para>
<para>
One caveat of the <keycap>]]</keycap>, <keycap>][</keycap>,
<keycap>[[</keycap> and <keycap>[]</keycap> keystrokes is
that they match the braces which are in the
<Emphasis>first column</Emphasis>. If one wants to match
all braces upwards and downwards regardless of whether its
in the first column or not is not possible. The VIM
documentation has a workaround. One has to map the
keystrokes to find the braces. Without spending too much
time on mapping, the suggested mappings are
</para>
<para>
<command>
:map [[ ?{&lt;CTRL-VCTRL-M&gt;w99[{
</command>
</para>
<para>
<command>
:map ][ /}&lt;CTRL-VCTRL-M&gt;b99]}
</command>
</para>
<para>
<command>
:map ]] j0[[%/{&lt;CTRL-VCTRL-M&gt;
</command>
</para>
<para>
<command>
:map [] k$][%?}&lt;CTRL-VCTRL-M&gt;
</command>
</para>
</sect2>
<sect2>
<title>
% keystroke
</title>
<para>
The <keycap>%</keycap> is used to match the item under the
cursor. The item under the cursor can be a parenthesis, a
curly bracket or a square bracket. By pressing the % key
the cursor will jump to the corresponding match.
</para>
<para> Amongst other things, the <keycap>%</keycap> keystroke
can be used to match #if, #ifdef, #else #elif and #endif
also.
</para>
<para>
This keystroke is very useful in validating code that one
has written. For Example
</para>
<figure>
<title>
The next snippet of C code
</title>
<mediaobject>
<imageobject>
<imagedata fileref="images/moving5.png" format="png">
</imageobject>
<textobject>
<programlisting>
...
if((x==y)&amp;&amp;((z-=a)||(y&gt;x)))
...
</programlisting>
</textobject>
</mediaobject>
</figure>
<para>
Checking the above code will involve checking the correctness
of the parenthesis. The <keycap>%</keycap> can be used to
jump from one ( to its corresponding ) and vice versa.
Thus, one can find which opening parenthesis corresponds to
which closing parenthesis and use the information to
validate the code.
</para>
<para>
Similarly the <keycap>%</keycap> can also be used to jump
from a { to its corresponding }.
</para>
</sect2>
</sect1>
<!-- Section 3: Jumping to Random positions -->
<sect1 id="Random">
<title>
Jumping to random positions in C files
</title>
<sect2>
<title>
ctags
</title>
<para>
A Tag is a sort of placeholder. Tags are very useful in
understanding and editing C. Tags are a set of
book-marks to each function in a C file. Tags are very
useful in jumping to the definition of a function from
where it is called and then jumping back.
</para>
<para>
Take the following example.
</para>
<figure>
<title>
Tags Example
</title>
<mediaobject>
<imageobject>
<imagedata fileref="images/tags.png" format="png">
</imageobject>
<textobject>
<programlisting>
...
foo()
{
...
bar();
...
}
bar()
{
...
}
...
</programlisting>
</textobject>
</mediaobject>
</figure>
<para>
Lets say that you are editing the function foo() and you
come across the function bar(). Now, to see what bar()
does, one makes uses of Tags. One can jump to the
definition of bar() and then jump back later. If need be,
one can jump to another function called within bar() and back.
</para>
<para>
To use Tags one must first run the program ctags on all
the source files. This creates a file called tags. This
file contains pointers to all the function definitions and
is used by VIM to take you to the function definition.
</para>
<para>
The actual keystrokes for jumping to and fro are
<keycap>CTRL-]</keycap> and <keycap>CTRL-T</keycap>. By
hitting <keycap>CTRL-]</keycap> in foo() at the place
where bar() is called, takes the cursor to the beginning of
bar(). One can jump back from bar() to foo() by just
hitting <keycap>CTRL-T</keycap>.
</para>
<para>
ctags are called by
</para>
<screen>
<prompt>$ </prompt><command>ctags options file(s)</command>
</screen>
<para>
To make a tags file from all the *.c files in the current
directory all one needs to say is
</para>
<screen>
<prompt>$ </prompt><command>ctags *.c</command>
</screen>
<para>
In case of a source tree which contains C files in
different sub directories, one can call ctags in the root
directory of the source tree with the -R option and a tags
file containing Tags to all functions in the source tree
will be created. For Example.
</para>
<screen>
<prompt>$ </prompt><command>ctags -R *.c</command>
</screen>
<para>
There are many other options to use with ctags. These
options are explained in the man file for ctags.
</para>
</sect2>
<sect2>
<title>
marks
</title>
<para>
Marks are place-holders like Tags. However, marks can be
set at any point in a file and is not limited to only
functions, enums etc.. Plus marks have be set manually by
the user.
</para>
<para>
By setting a mark there is no visible indication of the
same. A mark is just a position in a file which is
remembered by VIM. Consider the following code
</para>
<figure>
<title>
The marks example
</title>
<mediaobject>
<imageobject>
<imagedata fileref="images/marks.png" format="png">
</imageobject>
<textobject>
<programlisting>
foo()
{
int x,y;
x=0;
y=1;
x++;
y++;
if( x != y )
x = y;
y = x;
}
</programlisting>
</textobject>
</mediaobject>
</figure>
<para>
Suppose you are editing the line x++; and you want to come
back to that line after editing some other line. You can
set a mark on that line with the keystroke
<keycap>m'</keycap> and come back to the same line later
by hitting <keycap>''</keycap>.
</para>
<para>
VIM allows you to set more than one mark. These marks are
stored in registers a-z, A-Z and 1-0. To set a mark and
store the same in a register say j, all one has to hit is
<keycap>mj</keycap>. To go back to the mark one has to hit
<keycap>'j</keycap>.
</para>
<para>
Multiple marks are really useful in going back and fro
within a piece of code. Taking the same example, one might
want one mark at x++; and another at y=x; and jump between
them or to any other place and then jump back.
</para>
<para>
Marks can span across files. To use such marks one has to
use upper-case registers i.e. A-Z. Lower-case registers are
used only within files and do not span files. That's to
say, if you were to set a mark in a file foo.c in register
"a" and then move to another file and hit
<keycap>'a</keycap>,
the cursor will not jump back to the previous
location. If you want a mark which will take you to a
different file then you will need to use an upper-case
register. For example, use <keycap>mA</keycap> instead of
<keycap>ma</keycap>. I'll talk about editing multiple
files in a later section.
</para>
</sect2>
<sect2>
<title>
gd keystroke
</title>
<para>
Consider the following piece of code.
</para>
<figure>
<title>
The third example
</title>
<mediaobject>
<imageobject>
<imagedata fileref="images/gd.png" format="png">
</imageobject>
<textobject>
<programlisting>
struct X x;
void foo()
{
struct Y y;
struct Z z;
...
/* Lots of lines later */
x.bar();
y.bar();
z.bar();
}
</programlisting>
</textobject>
</mediaobject>
</figure>
<para>
For some reason you've forgotten what y and z are and want
to go to their declaration double quick. One way of doing
this is by searching backwards for y or z. VIM offers a
simpler and quicker solution. The <keycap>gd</keycap>
keystroke stands for Goto Declaration. With the cursor on
"y" if you hit <keycap>gd</keycap> the cursor will take
you to the declaration :- struct Y y;.
</para>
<para>
A similar keystroke is <keycap>gD</keycap>. This takes you
to the global declaration of the variable under the
cursor. So if one want to go to the declaration of x, then
all one needs to do is hit <keycap>gD</keycap> and the
cursor will move to the declaration of x.
</para>
</sect2>
</sect1>
<!-- Section 4: Auto-completing words -->
<sect1 id="Auto-Complete">
<Title>
Auto-Completing Words
</Title>
<para>
Consider the following code
</para>
<figure>
<title>
Auto-completion example
</title>
<mediaobject>
<imageobject>
<imagedata fileref="images/auto.png" format="png">
</imageobject>
<textobject>
<programlisting>
void A_Very_Long_Function_Name()
{
...
}
short A_Very_Long_Variable_Name;
void Another_Function()
{
...
A_Very_Long_Function_Name();
...
}
</programlisting>
</textobject>
</mediaobject>
</figure>
<para>
The function A_Very_Long_Function_Name() can be quite
exasperating to type over and over again. While still in
insert-mode, one can auto-complete a word by either searching
forwards or backwards. In function, Another_Function() one can
type A_Very... and hit <keycap>CTRL-P</keycap>. The first
matching word will be displayed first. In this case it would
be A_Very_Long_Variable_Name. To complete it correctly, one can
hit <keycap>CTRL-P</keycap> again and the search continues
upwards to the next matching word, which is
A_Very_Long_Function_Name. As soon as the correct word is matched
you can continue typing. VIM remains in insert-mode during
the entire process.
</para>
<para>
Similar to <keycap>CTRL-P</keycap> is the keystroke
<keycap>CTRL-N</keycap>. This searches forwards instead of
backwards. Both the keystrokes continue to search until they
hit the top or bottom.
</para>
<para>
Both <keycap>CTRL-P</keycap> and <keycap>CTRL-N</keycap> are
part of a mode known as CTRL-X mode. CTRL-X mode is a
sub-mode of the insert mode. So you can enter this mode when
you are in the insert-mode. To leave CTRL-X mode you can
hit any keystroke other than CTRL-X, CTRL-P and CTRL-N. Once
you leave CTRL-X mode you return to insert-mode.
</para>
<para>
CTRL-X mode allows you do auto-completion in a variety of
ways. One can even autocomplete filenames. This is
particularly useful when you have to include header
files. Using CTRL-X mode you can include a file foo.h using
the following mechanism.
</para>
<programlisting>
#include "f CTRL-X CTRL-F"
</programlisting>
<para>
That's CTRL-X CTRL-F. I know... I know... Its sounds like
emacs ;-). There are other things you can do in the CTRL-X
mode. One of them is dictionary completion. Dictionary
completion allows one to specify a file containing a list of
words which are used for completion. By default the
dictionary option is not set. This option is set by the
command <command>:set dictionary=file</command>. Typically
one can put in C keywords, typedefs, #defines in the
dictionary file. C++ and Java programmers may be interested
in adding class names as well.
</para>
<para>
The format of a dictionary file is simple. Just put a word
you want in line by itself. So a C dictionary file would look
something like this.
</para>
<figure>
<title>
A sample dictionary file
</title>
<mediaobject>
<imageobject>
<imagedata fileref="images/dict.png" format="png">
</imageobject>
<textobject>
<programlisting>
case
continue
default
define
do
double
else
enum
float
for
goto
if
ifdef
ifndef
include
int
pragma
return
struct
switch
typedef
void
while
</programlisting>
</textobject>
</mediaobject>
</figure>
<para>
To use the dictionary completion, one needs to hit
<keycap>CTRL-X CTRL-K</keycap>. The completion is similar to
the <keycap>CTRL-P</keycap> and <keycap>CTRL-N</keycap>
keystrokes. So... to type "typedef" all one needs to do is
t CTRL-X CTRL-K and poof... the name completed.
</para>
</sect1>
<!-- Section 5: Auto Formating -->
<sect1 id="auto-format">
<title>
Formating automatically
</title>
<sect2>
<title>
Restricting column width
</title>
<para>
One often has to restrict the column width to 80 or 75 or
whatever. One can set this quite easily by using the
command
</para>
<screen>
<command>:set textwidth=80</command>
</screen>
<para>
To do this automatically just put the command in your .vimrc.
</para>
<para>
In addition to textwidth you may want the text to wrap at
a certain column. Often such choices are dictated by the
terminal one is using or it could just be by choice. The
command for such a case is
</para>
<screen>
<command>:set wrapwidth=60</command>
</screen>
<para>
The above command makes the text wrap at 60 columns.
</para>
</sect2>
<sect2>
<title>
Automatically indent code
</title>
<para>
While coding in C, one often indents inner-blocks of
code. To do this automatically while coding, VIM has an
option called cindent. To set this, just use the command
</para>
<screen>
<command>:set cindent</command>
</screen>
<para>
By setting cindent, code is automatically beautified. To
set this command automatically, just add it to your .vimrc
</para>
</sect2>
<sect2>
<title>
Comments
</title>
<para>
VIM also allows you to auto-format comments. You can split
comments into 3 stages: The first part, the middle part
and the end part. For example your coding style
requirements may require comments to be in the following
style
</para>
<programlisting>
/*
* This is the comment
*/
</programlisting>
<para>
In such a case the following command can be used
</para>
<screen>
<command>:set comments=sl:/*,mb:*,elx:*/</command>
</screen>
<para>
Let me decipher the command for you. The commands has
three parts. The first part is sl:/*. This tells VIM that
three piece comments begin with /*. The next part tells
VIM that the middle part of the comment is *. The last
part of the command tells vim a couple of things. One that
the command should end with */ and that it should
automatically complete the comment when you hit just /.
</para>
<para>
Let me give another example. Lets say your coding
guidelines are as follows
</para>
<programlisting>
/*
** This is the comment
*/
</programlisting>
<para>
In such a situation you can use following command for comments
</para>
<screen>
<command>:set comments=sl:/*,mb:**,elx:*</command>
</screen>
<para>
to insert a comment just type /* and hit enter. The next line
will automatically contain the **. After you've finished
the comment just hit enter again and another ** will be
inserted. However to end the comment you want a */ and not
**/. VIM is quite clever here. You don't need to delete
the last * and replace it with /. Instead, just hit / and
VIM will recognise it as the end of the comment and will
automatically change the line from ** to */.
</para>
<para>
For more info hit
<command>
:h comments
</command>
</para>
</sect2>
</sect1>
<!-- Section 6: Editing Multiple files -->
<sect1 id="multi">
<title>
Multi-file editing
</title>
<para>
One often needs to edit more than one file at a time. For
example one maybe editing a header file and a source file at
the same time. To edit more than one file at a time,
invoke VIM using the following command
</para>
<screen>
<prompt>$ </prompt><command>vim file1 file2 ...</command>
</screen>
<para>
Now you can edit the first file and move onto the next file
using the command
</para>
<screen>
<command>:n</command>
</screen>
<para>
You can jump back using the command
</para>
<screen>
<command>:e#</command>
</screen>
<para>
It may be useful while coding if you could see both the files
at the same time and switch between the two. In other words,
it would be useful if the screen was split and you could see
the header file at the top and the source file at the
bottom. VIM has such a command to split the screen. To invoke
i, simply say
<command>
:split
</command>
</para>
<para>
The same file will be displayed in both the windows. Whatever
command is invoked, will affect only the window in focus. So
one can edit another file in another window by using the
command
<command>
:e file2
</command>
</para>
<para>
After executing that command, you'll find that there are two
files visible. One window shows the first file and the other shows
the second file. To switch between the files one has to use the
keystroke <keycap>CTRL-W CTRL-W</keycap>. To learn more about
split windows, just run help on it.
</para>
</sect1>
<!-- Section 7: Quickfix -->
<sect1 id="quickfix">
<title>
Quickfix
</title>
<para>
When coding in C one often has a edit-compile-edit
cycle. Typically you would edit C file using some the things
I've mentioned earlier, save the file, compile the code and
go to the error(s) and start editing again. VIM helps save
the cycle time slightly using a mode called
quickfix. Basically, one has to save the compiler errors in a file
and open the file with VIM using the command
</para>
<screen>
<prompt>$ </prompt><command>vim -q compiler_error_file</command>
</screen>
<para>
VIM automatically opens the file containing the error and
positions the cursor at the location of the first error.
</para>
<para>
There is a shortcut to the cycle. Using the command "make", one
can automatically compile code and goto the position where
the first error occurs. To invoke the make command type the
following
</para>
<screen>
<command>:make</command>
</screen>
<para>
Basically, this command calls make in a shell and goes to the
first error. However, if you are not compiling using make and
are compiling using a command such as cc, then you have to
set a variable called makeprg to the command you want invoked
when you use the make command. For eg.
<command>
:set makeprg=cc\ foo.c
</command>
</para>
<para>
After setting makeprg, you can just call the make command and
quickfix will come into play.
</para>
<para>
After you have corrected the first error, the next thing to
do would be go to the next error and correct that. The
following command is used go to the next error.
<command>
:cn
</command>
</para>
<para>
To go back, you can use the command
<command>
:cN
</command>
</para>
<para>
Let me demonstrate this using an example. Consider the
following code
</para>
<figure>
<title>
Quickfile Program Listing
</title>
<mediaobject>
<imageobject>
<imagedata fileref="images/quickfix_prog.png" format="png">
</imageobject>
<textobject>
<programlisting>
1 #include &lt;stdio.h&gt;
2
3 int main()
4 {
5 printf("Hello World\n")
6 }
</programlisting>
</textobject>
</mediaobject>
</figure>
<para>
As you can see there is an error on line number 5. The file
is saved as test.c and makeprg is set using the command
</para>
<screen>
<command>:set makeprg=gcc\ test.c</command>
</screen>
<para>
Next the make command is invoked using the command
<command>:make</command>. gcc gives an error and the output
of the make command is something like this
</para>
<figure>
<title>
:make error
</title>
<mediaobject>
<imageobject>
<imagedata fileref="images/make_error.png" format="png">
</imageobject>
<textobject>
<programlisting>
:!gcc test.c 2&gt;&amp;1| tee /tmp/vim9821.err
test.c: In function `main':
test.c:6: parse error before `}'
test.c:4: warning: return type of `main' is not `int'
(2 of 3): parse error before `}'
Press RETURN or enter command to continue
</programlisting>
</textobject>
</mediaobject>
</figure>
<para>
On pressing <keycap>RETURN</keycap>, the cursor moves to line
number 6.
</para>
<para>
Now, the command <command>:cn</command> will move the cursor
to the line number 4.
</para>
<para>
To move back to the previous error, one can use the command
<command>:cN</command> and the cursor will move back to the
line 6.
</para>
<para>
After correcting the error on line 5 and adding "return 1;",
one can run <command>:make</command> again and the output
will be
</para>
<figure>
<title>
No Error
</title>
<mediaobject>
<imageobject>
<imagedata fileref="images/make_no_error.png" format="png">
</imageobject>
<textobject>
<programlisting>
:!gcc test.c 2&gt;&amp;1| tee /tmp/vim9822.err
Press RETURN or enter command to continue
</programlisting>
</textobject>
</mediaobject>
</figure>
<para>
That was just a small example. You can use quickfix to solve
your compile time problems and hopefully reduce the
edit-compile-edit cycle.
</para>
</sect1>
<!-- Section 8: Copyright -->
<sect1 id="copying">
<title>
Copyright
</title>
<para>
Copyright (c) 2000,2001 Siddharth Heroor.
</para>
<para>
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation
License, Version 1.1 or any later version published by the
Free Software Foundation; with no Invariant Sections, with no
Front-Cover Texts, and with no Back-Cover Texts. A copy of
the license can be found at
<ulink url="http://www.gnu.org/copyleft/fdl.html">
http://www.gnu.org/copyleft/fdl.html
</ulink>
</para>
</sect1>
<!-- Section 9: References -->
<sect1 id="references">
<title>
References
</title>
<para>
You can get more information on VIM and download it at
<ulink url="http://www.vim.org">
http://www.vim.org
</ulink>
</para>
</sect1>
</Article>