Day 1

Living around computers, we always need to use an editor to edit text files, therefore knowing how to use a good editor can be of extensive use; Vim (Vi Improved) is one of the most powerful and
popular text editors one can learn and do a lot in few key strokes but learning it at the first place needs patience. So here I try to post a daily tutorial on how to use Vim, so that by simply reading one small
e-mail a day, hopefully you'll learn an editor you'll be happy all your life time being with.

Basic Editing:

$ vim <filename>
will open <filename> for editing using vim

$ gvim <filename>
same thing, but this time a graphical user interface for vim, not ncurses based.

Vim is a modal editor, meaning that depending on which mode you are in, different commands and keys mean differently.
Modes are: normal, insert, visual; if the bottom of the screen shows the filename or blank, you're in normal mode, if there's a --INSERT--, then insert mode and if --VISUAL--, obvious.

Press i to switch from normal to insert, ESC for the other way, and
leave the visual mode for later, but if so curious, try v.

You can insert text only if you're in insert mode.

Commands starting with : must be issued in normal mode.

Some of the basic commands you need for your hello world are:
:w or :write to save the file (buffer actually, but we'll talk about it later).
:q or :quite to exit

So here is a what a key logger would capture when I write the hello world:

vim hello.txt<enter>
iHello World<ESC>
:w
:q

And here we have our first file edited by Vim.
$ cat hello.txt
Hello World

Tomorrow on how to move around in Vim way and some other commands such as undo, redo, delete a line, open a new line, help and so on...


 Day 2

Vim uses an alternative set of key binding for moving around, though the usual arrow keys work fine, but what every Vim user would recommend you is to use the Vim style which is: (all in normal mode)

h -> left

j -> down

k -> up

l -> right

I know it might look a bit odd at the first place, but believe me, the moment you get comfortable with these keys, you'll start pushing them even for your web browser.

You can use x or d to delete a character in normal mode.

dd deletes a line, and o opens a new line to insert below the cursor; O opens a new line to insert above the cursor and D deletes from cursor to the end of the line (remember that D means SHIFT+d).

Undo is u and redo is CTRL+r.

One of the most interesting features of almost every command in Vim is that you can specify a counter for them, meaning that one would enter 10dd to delete the next 10 lines or 5ix to insert xxxxx.

And the last point for today's tutorial is :help.

Try these to learn more:
ZZ to save and quite; equivalent to :wq
:help x
:help :q
:help :w


 Day 3

All of the commands below are to be issued in normal and visual mode, not in insert mode:

w to move one word forward
b to move one word backward
$ to move to the end of the line
^ to move to the beginning of the line
fX forward search until it finds X and stop over the character
FX backward search and the rest just like f
t and T work exactly same as f and F respectively, except that they stop
on one character before X.

That's it, only a few examples to demonstrate:

One would press 5w to move to 5 words next to it's current position, and 10$ will get you to the end of a line which is 10 line after where you currently are located; Same goes with b and ^. Suppose in the following sentence I want to jump from beginning of the line to the fourth occurrence of t which is the first t in truth, I would press 4ft.

"A lie told often enough becomes the truth."


 Day 4

gg goes to the first line of the text
G goes to the last line
23G goes to line 23, you can do this by 23j too, and also by :23, choose the one you prefer, all are same.
CTRL+g tells you what position are you in what file at the bottom of the screen, so does CTRL+G.
":set number" configures Vim to show you the line number and ":set nonumber" removes them.
Note that ":set" command is to configure some of the environment configurations of Vim, and one can add them to his ~/.vimrc or /etc/vimrc file (in Linux) or (I'm not quite sure if it's the right place but seems like) C:\Program Files\Vim\_vimrc file (in Windows) so that your configurations are saved and will be loaded every time you open Vim.

CTRL-d moves half a page down and CTRL-u moves half a page up.

Tips: We already know that d and x can be used to delete in normal mode.
Now, something nice about the d command is that you can add a motion command to it, and it will delete from the current position of cursor to where the motion command moves.

Example: 

Suppose in "The shortest distance between two points is under construction." the cursor is on 's' in shortest, if you press 'dw', Vim will delete the next word, and in the same fashion, if you press 'd3w' it will delete up to 'two'. 

Experiment with the following commands yourself:

d10G
dfX
dG
dgg
dj
d$
d^
3dfX
d3fX

Tomorrow, we'll talk about more interesting stuff that not every editor can do. 
 
By the way, for those who want to write programs in Vim, check this out: ":syntax on".


 Day 5

In our way to edit a file faster, we can also use the following commands:

c followed by a motion, deletes the text from the current position of the cursor until where the motion ends and enters the insert mode. 

Example: Use cw to replace a word, c$ to change the text from cursor to the end of line. 

C to change a whole line.

dd to delete a whole line. Note that C does exactly what ddi does. 

J to join lines, meaning that assuming we have the following lines in a file:

"How can you govern a country which
has 246 varieties of cheese?"

Now if you press J while cursor is on the first line, you'll get something like this:

"How can you govern a country which has 246 varieties of cheese?"

And you know that as always, you can specify a number before a command, so 3J concatenates next three lines.

gJ does exactly what J does, except that it will not remove the spaces and indentations.

. command, yes "dot", repeats the last delete or change command! Use it to learn it, but a small example is this:

iostream
fstream
sstream
vector

Move the cursor to i in iostream, press i to insert, and type #include < and then press escape, now move the cursor to f in fstream, press . and do the same for all the other lines!

Vim macros:

I have the following lines in a file:

iostream
fstream
sstream
vector

And here is exactly the sequence of keys I press:

qa^i#include <ESC$a>ESCjq

Note that ESC is not E S C, but the escape key; And then press: 3@a

Here is the result:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>

What happened is this: q start recording a macro, a after that is the name of the macro, characters after that are a sequence of keys needed to change the iostream to #include <iostream> and then q again will stop recording macro a, and finally @ executes a macro, so 3@a executes macro a for three times.


 Day 6

There's something called "digraph", I'm don't really use, if you want, type :digraphs and search in :help for it (basically, for special signs like the copyright sign).

To search for word X in the text, one can use /X in normal mode, and after you press enter, cursor will be locate on X (if present). So suppose I have the following text in a file:

"My way of joking is to tell the truth. It is the funniest joke in the world."

Now press /joke and then enter, you'll see that the cursor is located over j in joke.

? to search backward.
n to repeat the search command, meaning that if it was forward, find next, if it was backward, find previous.
N does exactly opposite of n.

":set hlsearch" will highlight found strings in the text.
":set nohlsearch" turns off the highlighting thing.
":set incsearch" starts the search while you type. (I like it.)

Tomorrow on regular expressions.


Day 7

Regular Expressions: As defined in http://en.wikipedia.org/wiki/Regular_expression, in computing, a regular expression is a string that is used to describe or match a set of strings, according to certain syntax rules.

For example, I think we are all familiar with * which in most Unix shells is substituted by everything matched in the context, so that "cp * foo/" will copy every file in the current directory to foo.

The syntax used in Vim to represent regular expressions is like the one grep and most of other Unix programs use, so just a small recap for those who already know.

. (dot) can be used to represent any single character
.* (dot-star) matches everything
$ end of line
^ beginning of the line
x the character x
\x changes the meaning of x (not always, but most of the time)

Here are few examples of regular expressions used by '/' (search) to find a string or set of strings:

/^$    will search for empty lines
/^#    will search for all preprocessor definitions in your C/C++ source file
/\\$   will search for every line that is broken into two lines (most of them are macros)
/ .*@.*\.com  will search for email addresses in a file

We have quite a lot more to say about REs, but for now let's practice with these. 
Tomorrow on how to copy/cut/paste and marks. 
 

Day 8

When you delete something with x or d command, the text is saved and you can paste with p command. I just told you how to cut! d<motion> and then go to where you want to paste and press p. You might find it strange as you've always been using other programs which paste before the character under cursor, but in Vim, p command pastes after the character under the cursor, if you want it the other way, use P (capital p: shift+p). 

To copy, press y<motion>, it will copy the text from cursor to where motion ends, and paste it as described above; note that y stands for "yank", so you don't copy actually, you yank it out.

yy or Y to copy a line.
dd to cut a line.
p to paste after the cursor
P to paste before the cursor

Marks: You can mark a position in the text and use it just like a bookmark. Mark using m<a-z> (don't use capitals or numbers, we'll talk about them later) to set a mark with the name of the alphabet that comes after it, meaning that if you press ma you've just marked your position (where the cursor is) with letter a, so later on you can return to this position by pressing `a.

m<a-z> to mark a position with the given letter
`<a-z> to go to the given mark
'<a-z> to go to the beginning of the "line" with given mark (not the exact position).

Marks are quite useful if you're dealing with large text file and need to jump from position to position quite frequently, and also can be useful in deleting and copying a large block of text; for doing so, follow these steps: 

Go to the first line of the block of text you want to delete or copy.

Press ma to mark it with a (assuming you don't already have a "a" mark, which if that's the case, the old mark will be overwritten). 

Go the the last line of the block. 

Press d`a or d'a or y`a or y'a, whichever suits your task. 

Note that you can use marks with every command that expects a "motion".

There are a few hard-coded marks you might find interesting:

`] or '] the first character of the previously changed or yanked text.
`[ or '[ the last character of the previously changed or yanked text.
`` or '' the position before the last jump.
Follow the convention:
`( or '( and `) or ') for sentence.
`{ or '{ and `} or '} for paragraph.

:marks to see all the marks in your buffer.

Tomorrow is interesting: Filters. 
 

Day 9

Filters: For those who are not familiar with the word "filter" in Unix jargon, a filter is any program that takes some input, does some specific task on that input, and returns some output; A good example would be "grep" program, or the "sort" program, which each of them take some values as input and with respect to the options provided by the user, return something.

In Vim, you can use these filters to automate some tasks: 

!<motion><filter>  will use the block of text from cursor up to where the motion ends as the input for the specified filter and substitutes this block with the output of the filter.

Example: Suppose we have a list of names in a file:

Hamm
Slink
Potato
Woody
Sarge
Etch
Lenny

and you want to sort them in ascending order; follow these steps:

Move the cursor the beginning of first line (Hamm)
Press !
Press G to move the last row (Lenny); note that you can use marks to do so.
and now you will be prompted in the last row of the screen to enter the filter name.
Enter "sort" followed by enter, and this is what you get:

Etch
Hamm
Lenny
Potato
Sarge
Slink
Woody

!!  takes the whole current line as the input for a filter.
Note that if the line is empty, means that the filter can accept no input;
This is what I do to insert the exact time and date I've edited a source file in a comment at the top of the source code.

Go to a blank line: !!date

Expand your experiment by using grep, strings, sed, awk, cut, seq, ...

Tomorrow on multiple files navigation.


Day 10

You can use :vi <filename> or :e <filename> to open a new file for editing, and :view <filename> to open a file in read-only mode, which in this case to write possible changes to the file, you need to add a "!" at the end of :w command, resulting in :w!

One can alternatively open multiple files as command arguments passed to Vim, e.g.: 

$ vim foo.c foo.h bar.c bar.h

:next     to show the next opened file
:wnext   to write the current file and then show next opened file

In case you've made changes to the current buffer and still haven't saved it, you need to write changes to file before moving to next buffer, or skip changes by :next!. In case you want Vim to save every file the moment you close it's buffer, you can set the autowrite option by :set autowrite or for the opposite case use :set noautowrite to turn off this feature.

Just like many other commands, you can use a counter before :next, so that :3next will act like :next :next :next.

:previous  to show the previous opened file
:Next    same as previous
:wprevious   guess what!
:wNext    guess what!
:first   puts you in the first opened file
:last   puts you in the last opened file

Tomorrow on how to manage windows (of course not that product of Microsoft!)...


Day 11

One point that I left out yesterday, is CTRL-^ to switch to an alternative file, meaning that suppose you've opened Vim with four command line arguments (press :args to see what arguments are passed to Vim), pressing <count>CTRL-^ puts you in the specified file.

OK, "Windows" as I promised:

:split    to split your window to two horizontal separate windows; Note that you'll see the same file in both windows
:split <filename>    to split but edit the given file
:vsplit   to split vertically
:vsplit <filename>   obvious!
:<counter>[split|vsplit]  to set the size of the new window to counter
:[vsplit|split] +<command> <filename>  to split and issue the initial <command>

Example:

:15split +/System\.out\.print foo.java    will split the window to two horizontal windows, open foo.java in the new window, set its height to 15 lines, and searches for System.out.print and so puts the cursor at the first line containing so; Note that in case System.out.print is not found, Vim
will prompt that is unable to find the string and puts the cursor at the beginning of the file.

CTRL-w w   to switch between windows
CTRL-w [h|j|k|l] to switch to the window in the given direction
CTRL-w q to close a window
CTRL-w s to split
CTRL-w v to vsplit
CTRL-w + to increase the size of the window
CTRL-w - to decrease
CTRL-w = to set all windows sizes equal
CTRL-w o to set the current window as the only active window
CTRL-w _ to minimize the current window

Tomorrow on Buffers... 


Day 12

Vim uses the term "buffer" for a file that is being edited, which is actually a copy of a file that you edit.  

A buffer has three states:

Active: Appears on screen
Hidden: A file being edited but not on the screen.
Inactive:
The file is not being edited, but Vim keeps the information about it anyway.

:hide  to hide the current active buffer
:buffers to see a list of buffers

In this list:
-  means inactive
h  means hidden
%  current buffer
#  alternative buffer
+  file has been modified

:buffer <number>  to switch to the given buffer
:buffer <filename>  you tell me!
:sbuffer [<number>|<filename>]  to split the window and open the buffer in the new window
:bnext  go to the next buffer
:<count>bnext  go to the next <count> buffer 

Try these: sbnext, bprevious, sbprevious, sNext, sbNext, blast, brewind, sblast, sbrewind, bmodified, sbmodified and use your imagination and find it's intersection with Vim programmers' imaginations.

Usually, when the last window of a file is closed, the buffer associated with the file becomes inactive unless the "hidden" option is not set, which if it's set, they automatically become hidden.

:set hidden

Tomorrow on Visual Modes...


Day 13

After all, let's talk about "visual mode"; Something that can make your vim-life easier or at least more visualized.

There are three different visual modes:

Press v for a character by character visual mode
Press V (shift-v) for a line by line visual mode
Press CTRL-v for block visual mode
And finally press ESC to exit a visual mode.

You can delete (d) or yank (y) or change (c) or join (J) the selected part just like before.
In fact, you can use the visual mode as an alternative to every command that takes a motion argument.

Extra: If you're a programmer and use Vim for your daily programming, you might find the K (shift-k) command pretty useful. It will show you the man page for the word under cursor. (Note that you might need to install the "manpages-dev" package under Debian based distros for a complete set of manpages needed for developers.)

Tomorrow will be a few more commands in visual mode...


Day 14

Few more commands on Visual Mode:

You can use I/A/C to insert/append/change (respectively) a block of text.
Note that at first you will only see it in the first line, but then press ESC and the change will affect the whole selected block.

I  to insert in all the selected lines
A to append to all the selected lines
C to change all the selected lines

r<char> to replace the whole selected block with <char>(s).

> to shift the block one shiftwidth spaces to right

< shift to left

:set shiftwidth?  to see what's the shiftwidth, usually 8
:set shiftwidth=<num>  to set the shiftwidth to <num> spaces

The fun part starts from tomorrow: Vim for Programmers... 


Day 15

Try these by yourself:

:syntax on   for syntax highlighting
:set background?   to see what is your background? (dark or light). Did you get the meaning
for '?' ? Use it with other options...
:set background=dark
:set background=light

"syntax" highlighting in Vim depends on the file extension or file type (not the file command in *nix) and so in case you're editing a file foo.bar which is actually a ASCII C source code file, Vim will not be able to show his intelligence! Lend him your own:
:set filetype=c

Use >> or << to indent a line one shift-width to right or left respectively.  

Hint: programmers tend to indent with tab, and tab looks like 8 spaces, and 8 is 8! Don't indent 2 spaces or 4 spaces or rand() % 8 spaces!

Vim is smart enough to indent your source file just like how you're supposed to indent it:

:set cindent
:set smartindent
:set autoindent

Difference is that cindent has IQ 100, smartindent 50 (just like those who try to be smart) and autoindent didn't even get to finish the test! There's another indentation mode:
indentexpr (Einstein's class mate) which we'll talk about it later...

autoindent uses the indent from the previous line.
smartindent works just like the autoindent with this advantage that in some cases recognizes C syntax and increase or decrease the indentation level. This is the indentation mode mainly used in Dev(il)-C++.
cindent is configurable to different indenting styles.

Tomorrow: more programmers' commands... 
 

Day 16

=<motion> is a command to automatically indent your code.
== to indent the current line.
%  jumps to the matching { [ ( or } ] )

So a combination of these can be =% which if your cursor is currently on the open bracket or close bracket, it will indent all the code inside that block according to the indentation mode specified before.

Example: type in the following dummy program in Vim.

int foo()
{
printf("A wise man can see more from the bottom of a "
"well than a fool can from a mountain top .");
int i;
for (i = 0; i != 10; i++)
if (i == 5)
printf("Politics is the art of looking for trouble, finding it whether it "
"exists or not, diagnosing it incorrectly, and applying the wrong remedy.");

}

Move your cursor to the first line, press =G and here is the result:

int foo()
{
    printf("A wise man can see more from the bottom of a "
            "well than a fool can from a mountain top .");
    int i;
    for (i = 0; i != 10; i++)
        if (i == 5)
            printf("Politics is the art of looking for trouble, finding it whether it "
                    "exists or not, diagnosing it incorrectly, and applying the wrong remedy.");

}

* to search for the word under cursor forward
# do * but backward
[CTRL-I do * in current file + all those brought in by #include
]CTRL-I backward
gd, and gD jump to the definition of a variable
]CTRL-D and [CTRL-D jump to the definition of a macro
]d, [d, ]D, [D to display the macro definition 
 
Tomorrow, more for programmers...


Day 17

Some notes on what we had in last part:

[d, ]d are different from [D, ]D in that the formers display the first definition of a macro while the laters display all definitions found for a macro.
And also, the difference between [ and ] is that [ starts searching for the definition of the macro from the beginning of file, while ] start from the current position of the cursor.

We've already mentioned %, use it in different locations and find out more about it:
() {} [] #ifdef #else #endif ...

i{ i} a{ and a} are motion commands, well not like hjkl but can be used with those commands that accept a motion command, and roughly what they do is to select the block you're currently inside, i{ and i} are for inner block, meaning that { and } of the beginning and end of block will not be included while a{ and a} are "a block" and will include so. To understand, use them combined with v to show the selected block in visual mode: vi{ va{. Note that again we can apply a counter, so that v2i{ will include: starting from the current location, two nested blocks...

For tomorrow, try to install "ctags"...
 

Day 18

I'm assuming you have already installed "ctags":

In your terminal, type in "ctags <list of filenames>", this will create a "tags" file, which keeps track of tags in your program.
Now "vim <filename>" and ...  

CTRL-] to jump to the declaration or definition of the word under cursor
CTRL-t to jump back
:tag  same as CTRL-]
:tags a list of tags you've visited so far
:tag /<regexp> to search for definition of a set of strings matching the given regular expression

":tag" can be proceeded by a [count] which makes it jump to the [count]th occurrence of expression.

:stag is same as :tag with the only difference that will split window and show the tag in the new one; So does CTRL-w].
:tselect returns a list of all tags matching given expression; so does g]
:help tag-priority if you find the FSC thing in tselect interesting enough.

:tnext
:tprevious
:tNext
:trewind
:tlast

(forward, backward, backward, first and last tag)

:tjump and gCTRL] are merely equal to tselect and g] with a small useless different, you would never remember, trust me.

:stselect is also available (to split)

Next one on Makefile and related stuff...


Day 19

Make is a Unix tool to facilitate program compilation and some related things.
For start, let's say you have a file named foo.c, how do you compile it?

$ gcc foo.c 

Now let's do it with "make": create a file in the same directory as foo.c, call it "Makefile" and save the following lines in it:

all:
          gcc foo.c

Note that, "all:" is the first line in Makefile, and gcc foo.c has ONE SINGLE TAB before it. Save it, and in your prompt, type in make and then enter! done!

Now let's do it with Vim:
:make makes the project which it's makefile is in directory you opened vim from. if $PWD == $HOME/bar/, and Vim, then in order to make :make work, Makefile must be saved in $HOME/bar/

Of course there might be some errors and warnings, vim can jump straight to the line that error or warning is reported from which is what exactly it does by default for the first error or warning.

:cc  show the error or warning
:clist  show a list of all errors and warnings
:cn  go to the next error or warning
:cprevious  previous
:crewind
:clast
:cNext

In case you're using Vim for your programming stuff, add the following line to your .vimrc or whatever else the configuration file is called:

:map <F5> :w<CR>:make<CR>

And from this moment onward, when you write a program, create a Makefile in it's own directory, and instead of each time going to shell and gcc blablabla, just press F5... (more about it, and much nicer commands with map, later)

BTW, use :grep just like how you use it as a program outside of vim, with the only difference that :grep will jump to the found occurrence of expression and note that all those c* command up there ^^ are able to work with :grep


Day 20

A small note on Makefiles: make is a very sensitive program, so if you're Makefile does not follow what exactly make expects, you'll get error, and one of these expectations is that there should be exactly ONE tab before a command line (e.g. at the beginning of gcc foo.c line) and this tab cannot
be expanded (replaced by spaces) so, one can use ":set list" to ask Vim to show you a $ at the end of each line and a ^I in place of a tab, so: 

all:
        gcc foo.c

will be shown like this: 

all:$
^Igcc foo.c$

BTW, you can set Vim to expand tabs or not:

:set expandtab
and
:set noexpandtab

Abbreviations:

:abbreviate <ABBREVIATE> <COMPLETE>

I use this:
:ab #D #define
:ab #I #include<

:ab lng oh my god, this is just so long to type every time, so I just type "lng" and a whitespace!

And Vim will replace the <ABBREVIATE> with the <COMPLETE> if a whitespace (space, tab, enter) is found after it. 

:ab  to list all abbreviations

I guess I mentioned the :map command in last tutorial, but a recap: 

:map <KEY> <SET OF COMMANDS>

Will map a key into a set of commands, so one can have something like this: 

:map <F10> :wall<CR>:q<CR> 

to map F10 to write all buffers and quit.

Here is a nice one:

:map <F9> :w<CR>:make<CR>:clist<CR>
 
Just remember to have a Makefile in the directory you used to open vim. 
 
:map <F5> :w<CR>:make -f Makefile.%<<CR>:clist<CR>

and now remember to have a Makefile.<file name with no extension> in that directory, so by pressing F5 in a file named foo.c, Vim tries to make with file Makefile.foo (allows several separate programs in a folder with a Makefile for each). 
 

Day 21

Did I mention that you can list all the abbreviations by:
:ab
or
:abbreviation

To write your current configuration of Vim on a vimrc file:

:mkvimrc <file>

And to load a vimrc file:

:source <file>

:version gives a list of compile time configurations of your Vim.

I alway use: 

:set textwidth=80

Since a tty has 80 columns and also, 80 is long enough for up to three nested loops, which if you have more, you'd better rewrite your program!
BTW, you might need to:

:set formatoption+=t or c to make it work

Substitute:
One can substitute or replace regexp using :s command, e.g.:

:s/X/Y/  will replace the first occurrence of X in the current line with Y
:1,5s/X/Y/   does the same thing for each line from 1 to 5
:%s/X/Y/    does it for the whole file
:s/X/Y/g   replace "every" occurrence of X with Y in the current line

So, basically, the s command has the following form:

:[range]s/<regexp>/<expression>/[flag]

range is mmm, is a range!
regexp is a regular expression like the one we talked few sections back.
flags are as follows:
g  for global
p  for print
c  for confirmation
i   for ignore case
I   for don't ignore case
:help su for more


I guess by now we have covered almost everything one needs to use vim easily and productively. Perhaps if you have already read this far, you can learn more advanced stuff on your own.

Peyman.