2008-12-22

Beyond basic Vim usage

I have used Vim for about 8 years now, but for quite a while I didn't use the "vee-eye" key mapping the way it should be used. All I did was press i to go to Insert mode, type the text and then Esc:wq to save and quit. That's completely the wrong way to use this wonderful text editor. If you are in that situation I hope this Vim introduction can get you past it. After an overview of some settings for the configuration file I will list the commands everyone should know (and some you probably don't really need to know).

Basic configuration

To be able to use Vim efficiently you have to have some basic configuration set up. In Linux or Unix you should edit
~/.vimrc (Windows specifics last in the post) to include at least the following lines:
set nocompatible      " This is vim, not vi (Put this line first!)
colorscheme koehler " Optional, but I like a black background
set smartcase " Only do case sensitive match on Upper Case
syntax on " Syntax highlight on
set showcmd " Show the command you have typed in
set showmatch " Show matching brackets or parentheses
set wildmenu " Show possible command tab completions
set ruler " Show useful information on the command line
set incsearch " Incremental searching
set hlsearch " Highlight search results. Clear with :nohl
Besides these settings I have some more things, mostly related to tabs and indentation:
set expandtab         " Expand tabs to spaces
set tabstop=4 " 4 spaces is one tab
set shiftwidth=4 " Should be the same as tabstop
set softtabstop=4 " Makes the spaces feel like real tabs
set smarttab " Backspace over expandtab
set autoindent " Use current indentation on next line
set nocindent " Don't use cindent
set nosmartindent " Don't break filetype indent scripts
filetype on " Try to figure out the right filetype
filetype plugin on " Filetype specific plugins
filetype indent on " Filetype specific intenting
There's a lot more you can configure in the rc-file and there are plenty of good examples on the net, just search.

File handling

The file handling commands you need to know are:
:w         " Write changes to disk
:w newfile " Write changes to newfile
:w! " Force write
:q " Quit
:q! " Really quit!
:wq " Save and quit
:wqa! " Really save all files and quit.
Also, opening a file with vim + filename will position you at the end of the file.

Movements


A great way to getting started with vim is the built in
vimtutor, a text file tutorial you can follow to learn all basic commands in Vim. But to get you up to speed I'll list the basic moves here. Just one comment first. Even though the arrow keys probably work, don't use them! They are slow and you have to move your fingers from the keyboard.
h      " Left - Moves the cursor one step
j " Down
k " Up
l " Right

gg " Go to the start of the file
G " Go to the end, just like in less

w " Move one word forward
W " Move to next blank delimited word
b " Move one word backwards
B " Move to previous blank delimited word

0 " Go to the beginning of the line
$ " Go to the end of the line

H " Move to the top of the visible screen (Head)
M " Move the cursor to the middle of the screen
L " Move to the end of the screen (Last)

fc " Forward onto the character c on this line
Fc " Backwards onto the character c on this line
tc " Forward to the character c on this line but not on it
Tc " Back to the character c but not on it
nfc " Forward onto the nth c character on this line
All these moves can be used together with the commands I will describe below and will be referred to with a m. Most moves and actions can be performed with a number in front. 5w means move five words forward. I'll note that number n and a single char with c.

Normal mode and Insert mode


Vim has six basic modes, the most important two being Normal och Insert. Normal mode is the default where you do all the commands and movements and Insert is when you actually type in text
. There are many commands related to changing between these two modes:
i      " Go to insert mode before the cursor position
I " Go to insert mode at the beginning of the line
a " Go to insert mode after the cursor position
A " Go to insert mode at the end of the line
o " Insert a new line below and go to insert mode
O " Insert a new line above and go to insert mode
c
m " Delete from the cursor to m and go to insert mode
cc " Delete the whole row and go to insert mode (Change)
C " Change from current position to the end of the line
rc " Replace the character under the cursor with c
Esc " Go back to Normal mode
Ctrl-c " Go back to Normal mode
Ctrl-o " Do one command in normal mode, i.e Ctrl-o$
Search and Replace

Usually the fastest way to navigate the cursor is to search for the text you want to go to:

/regex " Search for a word or a regular expression
* " Search forward for the word under the cursor
# " Search backwards for the word under the cursor
n " Next search match
N " Previous search match
'' " Two back ticks; Move cursor to where you were before the search

:n " Go to line number n
:%s/oldtext/newtext/g " Replace oldtext with newtext in the whole file
:%s/oldtext/newtext/gc " The same, but confirm each replace
When doing a replace the %s means search every line in the file and the /g means replace all occurrences on the line. Omitting the g means you will only change the first occurrence on the line and. Without the % you only search the current line.

Cut, Copy and Paste


As expected there are many ways to copy and paste text in Vim. The "must know" ones are:
x   " Delete the character under the cursor
dd " Delete the current line and put it in the clip board
dw " Delete the word under the cursor
ndj " Delete n rows down and put them in the clip board
D " Delete from here to the end of the line
yy " Yank a line, meaning to copy it
yw " Yank a word
ym " Yank from the cursor to m
p " Paste below or after the cursor
P " Paste before or above the cursor
np " Paste
n copies of what you have in the clip board
Undo and Redo

Another great feature with vim is that you can do multiple undo or redo. The commands are:
u            " Undo once
uu " Undo two times
Ctr-r " Redo

:earlier n " Go to older text state n times
:earlier ns " Go to about n seconds before
:earlier nm " Go to about n minutes before
:earlier nh " Go to about n hours before

:later n " Go to newer text state n times
:later ns " Go to about n seconds later
:later nm " Go to about n minutes later
:later nh " Go to about n hours later
If all these normal mode commands is too much to remember at once there's a great printable cheat sheet at viemu.com that can help you practice them. There's a good quick reference available here.

Fun tricks

A fun thing about vim is that there's always more to learn and a quicker way to do the kind of edit you are trying to do. Some of my favorite tricks are:
.            " The simple dot replays your last command. Very powerful!

r[enter] " Insert linebreak without going into insert mode
J " Append the line below to the current line

qq[do stuff]q " Record the stuff you do in command register q
@q " Replay the action saved in q
@@ " Replay last used action

ci> " Delete between previous <> and go to insert mode
da> " Delete from previous <>, including the tags

^r=(3+4)*5 " Use when in insert mode. Will insert 35 at the cursor
Ctrl-A " Increase the number closest to the cursor with one
Ctrl-X " Decrease the number closest to the cursor with one

~ " Toggle case of the character under the cursor
gu
m " Lowercase from the cursor to m
gUi> " Uppercase between the previous <>

:TOhtml " Generate html that looks exactly like what you see in vim

g?
m " Do rot13 on the movement

z[Ret] " Scroll the window so that the cursor is at the top
zz
" Scroll the window so that the cursor is in the middle
z- " Scroll the window so that the cursor is at the bottom

gf " Go to the file under the cursor
K " Look up man page for the word under the cursor

!ls " Run ls in the current working directory
!!date " Replace the current line with the date. Use date /T on Windows
:set number " Show line numbers

:reg " Show what you have in the registers (The clip boards)

Ctrl-g " Show filename and position in file

:Ctrl-r Ctrl-w " Copy the word under the cursor to the : line
Split windows

In vim you can have more than one file visible in the editor at the same time, either by opening a file in split view or by using
vimdiff.
:split       " Split the windows horizontally
:sp myfile " Open myfile in a split view
:vsplit " Split the window vertically (:vs works as well)
Ctrl-ww " Move the cursor to the other window
Ctrl-w= " Resize the windows as equally as possible
Ctrl-wc " Close the current window
Custom mappings

Vim has a lot of key mappings available and it is easy to add your own to your vimrc-file. An example to make pasting text into Vim easier when you have autoindent/smartindent on:
map <C-s> :w<CR>
nnoremap <F2> :set invpaste paste?<CR>
imap <F2> <C-O><F2>
set pastetoggle=<F2>
The first line sets a mapping so that pressing in normal mode will invert the 'paste' option, and will then show the value of that option. The second line does the same in insert mode (but insert mode mappings only apply when 'paste' is off). The third line allows you to press when in insert mode, to turn 'paste' off. This tip and lots of others can be found at the great Vim Wikia.

Vim on Windows

On windows the configuration file is called _vimrc and can be found in your Vim install directory. By default it has some settings already, but you can still add the basic settings mentioned in the beginning of this post. In addition to that you should set nobackup and for fun, remap Ctrl-A and Ctrl-X key bindings to be Ctrl-+ and Ctrl-- on the numpad so that they work. They are used to increase and decrease numbers:
set nobackup
noremap <C-kPlus> <C-A>
noremap <C-kMinus> <C-X>
Thanks for reading this far. These settings have been found during a long time and from all kinds of sources and there are almost infinitely many to be found.

After this post I understand why the Daily Vim blog has a black background everywhere. It is a pain to get black block quotes in blogger to show your nice vim highlights. (Hint; edit the html to use <blockquote style="font-family: courier new; background-color: black; color: white;"><pre></pre></blockquote> around the html generated by TOhtml. Also, remember to remove the superflous tags, :s%/
<br>//g.)

(The post has been updated after graywh's comment.)

5 comments:

LosManos said...

hejdig.
If it is so fast to navigate in VI, why on earth did they decide to use hjkl as navigation keys instead of jkl; where I already have my fingers?
/OF

Claes Mogren said...

The reason is the actual hardware that Bill Joy used to write the first version of vi. It was a LSI ADM3A Terminal and they had arrows printed on the HJKL keys. More details here and the actual keys can be seen here. That page also explains why ~ is the home directory in Unix. :-)

Claes Mogren said...

While I'm adding comments, forgot these two favourite Vim commands:

r[enter] " Insert linebreak without going to Insert mode

J " Append the line below to the end of the current line.

qq<do stuff>q "Records the stuff you do in command register q

@q " Replay the action saved in q

@@ " Replay the last action

graywh said...

I believe you've misunderstood what "smartindent" does--it's like "cindnet"--and it doesn't play nicely with filetype indent scripts.. I recommend using "nocindent nosmartindent" and "filetype plugin indent on". Also, "autoindent" is safe to use as it just uses the indent from the current line when starting a new line and no other indenting is taking over.

I see bad advice all over the internet about using "smartindent". Please help stop the confusion.

Claes Mogren said...

Thanks graywh. I have noticed some odd behavior with smartindent some times, but wasn't sure why. Updated the post.