mirror of https://github.com/tLDP/LDP
1418 lines
32 KiB
Plaintext
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 ) && y > 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>&&</keycap>...
|
|
<keycap>y</keycap>... <keycap>></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 [[ ?{<CTRL-VCTRL-M>w99[{
|
|
</command>
|
|
</para>
|
|
|
|
<para>
|
|
<command>
|
|
:map ][ /}<CTRL-VCTRL-M>b99]}
|
|
</command>
|
|
</para>
|
|
|
|
<para>
|
|
<command>
|
|
:map ]] j0[[%/{<CTRL-VCTRL-M>
|
|
</command>
|
|
</para>
|
|
|
|
<para>
|
|
<command>
|
|
:map [] k$][%?}<CTRL-VCTRL-M>
|
|
</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)&&((z-=a)||(y>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 <stdio.h>
|
|
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>&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>&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>
|