Blog Tags: 

Introduction to Vim

Background

There are tons of tutorials and mountains of excellent documentation for Vim. There is also quite a bit of outdated mediocre material one could easily waste a lot of time on (like I have). Instead of reinventing the wheel and repeating all of it I'll just do the sensible thing and increase the signal to noise ratio by pointing you to the good stuff and giving you my perspective on what I think is most important for you to learn and understand. Hopefully this will speed things a long. The point isn't to try and learn everything about Vim, just whatever 10% of the features will be most useful to you. The problem is that 10% is different for each type of user and if you don't have a guide you won't necessarily know what features even exist.

Vim stands for Vi iMproved. Its basically an improved and extended version of Vi, the standard Unix editor. Vi itself is a bit weird and unintuitive at first, since it is a modal editor and most people are used to modeless editing nowadays. However after you get Vi, you'll understand why it was a natural choice for the standard Unix editor. Its design and user interface mirrors Unix philosophy perfectly: combining small and work simple well defined tools in flexible ways to achieve powerful results.

The modality of Vim that can cause so much initial confusion is also its source of power. You have to pay a price for that power because you can't just sit down with a modal text editor for the first time and get things done. If you're not in "easy mode" (evim or vim -y), and you don't anything about Vi or modality, Vim will not do what you expect and that will scare most people away, which is a shame, because modality is a great idea if you are a power user that does a lot of text editing, but to gain the benefits you have to be willing to invest in acquiring a new skill.

In a nutshell a modal text editor turns your entire keyboard into an insanely feature rich gamepad for sifting through, transforming and inputting text.

For example, in most modeless editors you'll move around with the cursor keys and maybe a page up, page down or the mouse. Vim users call this a hunt and peck motion. With Vim there is a much more powerful set of motion commands, and these motion commands can be combined with other commands to manipulate and transform text.

The keybindings for all of these commands seem somewhat arbitrary at first but as you start using them you'll find that they do in fact make sense from an ergonomics point of view, since your hands tend to stay in the same place and don't have to shift position for the cursor keys, or the mouse and so forth, or get twisted into uncomfortable positions like they do in Emacs and eventually develop Repetitive Strain Injury. I've read reports that for laptop users with cramped keyboard this can be an especially significant advantage.

Getting started

After you install the vim-python package, start the 30 minutes interactive vimtutor program. This will give you an understanding of how to perform basic text editing tasks.

Of course basic text editing is just the tip of the iceberg, but in order to develop more advanced skills you'll need to be properly motivated, so here are few links to wet your appetite:

http://www.viemu.com/a-why-vi-vim.html

http://www.moolenaar.net/habits.html

You'll want to read the manual, at least the Getting Started section:

|usr_01.txt|  About the manuals
|usr_02.txt|  The first steps in Vim
|usr_03.txt|  Moving around
|usr_04.txt|  Making small changes
|usr_05.txt|  Set your settings
|usr_06.txt|  Using syntax highlighting
|usr_07.txt|  Editing more than one file
|usr_08.txt|  Splitting windows
|usr_09.txt|  Using the GUI
|usr_10.txt|  Making big changes
|usr_11.txt|  Recovering from a crash
|usr_12.txt|  Clever tricks

After that my notes should provide a decent reference for the most important commands and features and with a little practice and the occasional query into the documentation you should be set to go. Naturally I may miss some things so if you have any questions after that you can send them my way. Don't try to do it all at once. Just switch to Vim, start using it and build up your skills by experience.

My experience was that the documentation was easy to skim/search through for the important/interesting stuff once I had a good overview understanding.

Random tips

  • Vim can open compressed files
  • Vim can open/save files directly from the network (multiple protocols)

Vim flavors

  • vim: console version

  • gvim: GUI version

    By default, forks into the background. If you want the process to stick around (e.g., needed when configured as an external editor) you'll need to use the --nofork option.

  • evim: easy version (behaves like a modeless editor)

For further information, see the vim(1) man page. Note that you don't have to install these separately. They are simply different front-ends to the same software and are packaged together.

Getting help

:h

Most commands in Vi have abbreviated forms for convenience. If you want to know what :h is short for:

:h :h

And it turns out that :h is short for :h[elp]

:help isn't the only command that starts with :h but its the author figured would be most commonly called so it got a really nice abbreviation.

What other commands start with :h?

:h :h<CTRL-D>

Gives you a nice list, like in the bash shell, but unlike the shell this form of listing (by default) is more like grepping through all available topics that contain your search term rather than topics that start with your search term.

So what help topics have the string help in them?

:h help<CTRL-D>

You'll notice different topics have different forms. This makes their type easy to identify:

'topic'     # a Vim configuration option
-topic      # a Vim command line flag
:topic      # a Vim command
topic()     # a Vim function
<Topic>     # a Vim key binding
i_topic     # an insert mode key binding
v_topic     # a visual mode key binding
topic.txt   # a help file

Of course you may not find what you're looking for if you don't know what it is and your just guessing according to keywords, so searching through the help can be extremely useful:

:h helpgrep gives you a description of the helpgrep command

You'll notice that it tells you that you can navigate through matches with the quickfix commands, and that quickfix is highlighted with a different color. Thats a tag. If you move the cursor to that tag and press CTRL-] it will take you to that topic. A double mouse click will also work, but isn't nearly as fun once you know how to move the cursor to any point in the document quickly and without taking your hands off the keyboard. A CTRL-T will take you back to the page where you came from.

Since the documentation can be at times very verbose, I'll spare you the suspense. To pop up a window with the results of your :helpgrep search do:

:copen

You can start out by navigating between windows with the mouse until you learn how to do it the proper way:

:h windows

When you find what you're looking for, close the search buffer with:

:cclose

You may find it useful to search through the quickref page listing the most commonly used commands:

:h quickref

Motion commands

:h motion.txt

The best way to understand what these motion commands do is to try and navigate a document with them.

The usual motion commands that work in any editor:

the cursor keys: left down up right

PageUp
PageDown

I find that often the easiest way to jump straight to a certain position in a file is by searching for a keyword. In the configuration I use I've turned on incremental search so the cursor shifts position as you are typing the search term. To make the current position stick, complete the search by pressing <Enter>.

If you jump to the wrong position CTRL-O will bring you back to where you started. CTRL-I will take you forward again.

search commands:

/keyword<Enter>     search forward
?keyword<Enter>     search backwards
*                   search forward for the word under the cursor

n   next match
N   previous match

hunt and peck commands:

h j k l: back down up forward

gj    down one screen line (not real line)
gk    up one screen line

Its bit weird at first, but you get used to it quickly and its very easy on your hands and fingers.

to a specific letter:

f<key>      forward to <key>
F<key>      back to <key>

t<key>      forward one character before <key>
T<key>      back one character after <key>

by word:

w       forward
W       forward including punctuation characters

e       forward to end of word
E       forward to end of word including punctuation characters

b       back
B       back including punctuation characters

by sentence:

)       forward
(       back

by paragraph:

}       forward
{       back

by line position:

0       start of line
^       start of line not counting whitespace
$       end of line

to a specific line:

gg      start of file
G       end of file

<N>G    specific line
        e.g., 10G # jump to line 10

by screen position:

H       top
M       middle
L       last

by mark:

:h mark-motions

m<letter>   sets a mark
`<letter>   jumps back to that mark

`.          jump to last line edited (very useful)

by parenthesis:

%       find next ([{}]) and jump to its match

Amplifying motion commands

Note that you can prefix any motion command with a number to multiply its effect, for example:

2)  # move 2 sentences forward
5w  # move 5 words forward

Scrolling commands

:h scrolling

scroll:

CTRL-E      scroll one line down
CTRL-Y      scroll one line up

CTRL-U      scroll up
CTRL-D      scroll down

redraw current line so that its:

zt          at the top of the screen
zz          at the middle of the screen
zb          at the bottom of the screen

Making changes

Vim has several basic operations for making changes. Inserting text, deleting text, cut and pasting text, indenting / unindenting text, etc.

A special command is '.' which repeats the last change whatever it was. This doesn't seem very interesting at first glance but it can be quite useful when you are making repetitive changes such as search and replace, or transforming text, etc.

Tiny changes:

x       delete one character
r<key>  replace one character
~       toggle lowercase/uppercase of letter under cursor

Replace mode

Usually you'll want to use insert mode. Use replace mode if you really want to overwrite the current text instead.

Entering replace mode:

R

Insert mode

You're not supposed to stay in insert mode. You move the cursor around in normal mode. You enter insert mode insert text and then exit it with <Escape> or <CTRL-C>. I prefer CTRL-C because I don't have to shift the position of my hands.

Entering insert mode:

i   current cursor
a   after cursor
o   insert new line below cursor
O   insert new line above cursor
I   insert at beginning of line
A   insert at end of line

Useful key bindings in insert mode:

CTRL-W  delete word
CTRL-U  delete entire line

Remember that you can/should combine motion commands with insert commands.

For example:

ea  move to end of word and append to it

Deleting

Commands:

dd              delete current line
D               delete until end of line

d + {motion}    delete from current cursor to where motion would take us

examples:

dw      delete next word
d2w     delete next two words
d2b     delete previous two words

d}      delete next paragraph
d{      delete previous paragraph

d)      delete until end of sentence
dG      delete until end of file

Delete + Insert

Change is usually more useful than delete because it does two things, and creates a useful repeatable operation.

Commands:

c + {motion}

C   Change till the end of line
S   Substitute entire line

Cut and Pasting

:h usr_04.txt

yanking and deleting copy/move text into registers. See :registers for a list and to examine their contents.

To move content out of the registers you use paste commands in normal mode: p paste after current line P paste before current line

You can also paste text without exiting insert mode:

:h i_CTRL-R

Indenting

How indenting works depends on Vim's particular configuration. I've configured it to indent 4 spaces when you press <Tab> and unindent by 4 spaces when you press <Backspace> (if 4 continuous spaces exist)

Also I've turned auto-indent on so that Vim starts the next line with the same indent as the current line.

Normal mode commands:

>>              indent this line
<<              un-indent

> + {motion}
< + {motion}

For example:

>}      indent paragraph
>G      indent to end of file
>/^\S   indent to first unindented line

In insert mode:

CTRL-T  indent current line
CTRL-D  unindent current line

How to insert a real tab (useful for Makefiles):

CTRL-V<Tab>

Format text

Commands:

J       join lines
gq      format lines

Repeating changes

The '.' command is one of the most powerful. It repeats the last previous change.

search and replace example:

/foo<Enter>

cbar<CTRL-C>

n   # next foo match
.   # repeat replace command if you want to replace this match

Note: at least in some cases you may find it easier to use the :substitute command instead, but the above example gives you more control in the sense that you can choose which matches to replace interactively.

Recording sequences of changes

:h recording :h usr_10.txt

Recording:

q<key>
    bunch of changes
q

Playback:

@<key>

Global changes

:h :global

Extremely powerful command, that applies arbitrary commands to any line that matches a regular expression.

For example, the following deletes all lines with 2007 in them:

:g/2007/normal dd

Visual mode

:h visual-mode

Entering visual mode:

V   # line visual mode (select whole lines)
v   # select arbitrary positions on screen

gv  # reselect the previous Visual area

Inside visual mode use motions commands to select text

Commands in visual mode:

d   # delete
y   # yank (I.e., copy)
>   # indent
<   # unindent

J   # join lines and paragraphs
gq  # format selected

Visual block mode

Note that there is also a strange but quite useful visual block mode that can be very useful but is a bit difficult to explain. You need to experiment and see the effect for yourself.

For further details see:

:h blockwise-operators
:h blockwise-examples

Gotcha: blockwise Insert and Append won't work if you escape with CTRL-C. You need to escape with the <Esc> key.

Saving and exiting

:h save-file

Commands:

ZZ      # save and exit
ZQ      # exit without saving

CTRL-S  # custom key binding I added to save file

Window management

:h windows

Like Emacs and screen, Vim support window splitting. You can split windows horizontally, vertically, resize windows, minimize them, maximize them, etc.

Even if you don't split your windows explicitly many commands (e.g., :help), split the window for you so you have to know how to control them.

To begin with, if you don't know or don't remember the key bindings, you can use the GUI "Window" menu. In GUI mode you can also resize the windows with the mouse by dragging their borders.

Commands:

:sp                 split current window
:sp path/to/file    split window by opening file

Key bindings:

CTRL-W S      split current window

CTRL-W o      keep only this window open (close all others)
CTRL-W c      close this window

CTRL-W _      maximize this window
CTRL-W =      make all windows equal in length

CTRL-W w      toggle between windows
CTRL-W p      switch to the previous window
CTRL-W t      switch to top most window
CTRL-W b      switch to the bottom window
CTRL-W hjkl   move to the window in the desired direction
CTRL-W HJKL   move window to the desired location
              e.g.,
                CTRL-W J will shift the position of a window to the
                bottom

Tabs

:h tabpage.txt

Tab commands:

:tabnew
:tabnew +Ex
:tabnew path/to/file

gt  next tab (also CTRL-<PageDown>)
gT  previous tab (also CTRL-<PageUp)

Folding

:h folding

:h 'foldmethod'

  • folds can be manually created or automatically created or a combination of both.
  • if you create folds manually, they will be lost when you abandon the file unless you save them explicitly with the :mkview command
  • folds can be nested (recursively)

manually creating a fold:

zf + {motion}
    e.g.,
        zf}     fold next paragraph

in visual mode: zf

mnemonic: z looks like a folded piece of paper (from the side)

Commands:

zo  # open fold
zc  # close fold

zr  # open one level of folds (globally)
zR  # open all folds
zM  # close all folds

File explorer

:h Explore
:h pwd
:h cd

I find the file explorer to be a very useful and efficient way to open files.

Opening a file explorer window:

gvim path/to/dir

:e path/to/dir

:Ex [ path/to/dir ]

    Without arguments, opens a file explorer in the same directory as the
    currently open file.

Explorer-mode commands:

F1 for commands

c chdirs to current open directory
<Enter> open in current window
o open in new split window
t open in new tab

Spell checker

:h spell

Underlines mis-spelled words (like Thunderbird).

:set spell

Commands:

z=
]s  move to next mis-spelled word
[s  move to previous mis-spelled word

Taglist extension

:h taglist.txt

Taglist is the most popular Vim extension. It depends on exuberant ctags package to scan source code (many languages are supported) for tags. What a tag is depends on the language being scanned. For example, in Python a tag is a class or function definition. In vimscript, this includes variable assignments.

Taglist uses ctags to generate a side-pane that lists all the tags in all buffers by default. This is a very convenient way to quickly jump between software structures in the same file or across multiple files.

Commands:

F8 # toggle side-pane

Taglist window commands:

<CR>    # jump to tag location
o       # jump to tag in new window
t       # jump to tag in new tab
        # (if tab already exists, jump to existing tab or window)

u       # update tags

+       # open fold
-       # close fold
*       # open all folds
=       # close all folds

Auto-completion

:h popupmenu-completion

Commands:

keywo<CTRL-P>

in completion popup
    CTRL-P  up one value
    CTRL-N  down one value

    CTRL-E  cancel auto-completion

    CTRL-H  remove character from completion (find more matches)
    CTRL-L  add character to completion (find less matches)

Omni-completion

:h new-omni-completion

A special form of auto-completion that understands context (e.g., Python context)

Usage example:

s = ""
s.<CTRL-X><CTRL-O>

CTRL-W z                # Close preview pane

Hidden buffers

:h buffer-hidden

If you open a file Vim keeps it in memory even if you subsequently move on to editing another file. This is called the hidden buffers list. You don't have to have the file open in a window or a tab. This is useful for moving between a history of last locations without having to keep all of these files open simultaneously in a bunch of windows or tabs.

Another way to populate your buffers is to specify multiple files on the command line.

You can move between buffers with the GUI menu or with keyboard commands:

:ls             # list buffers (not files)
:b[uffer] N     # jump to buffer N

Configuring Vim

:h set

Vim has too many configuration options to count. Most of these have reasonable defaults so you don't need to tweak them, but if you're interested in seeing whats configuration try:

:options

Take a look, consult the docs, and experiment with different settings to understand how they work.

Commands:

:set {option}?   # show value of {option}
:set {option}    # switch option on
:set no{option}  # switch option off
:set inv{option} # toggle option

Note that most options have short versions so if you are configuring your Vim session interactively to suit a particular file/session you can do that without too much trouble.

For example:

:set number      # switches on line numbering in the current buffer

Is equivalent to:

:set nu

If you want to find what the short version of an option is, simply query the help system:

:h 'number'

Extending Vim

:h usr_41.txt

:h if_pyth.txt

Vim, especially the most recent versions (7+) is highly extensible. Its native Vimscript is basically a real programming language you can do pretty much everything in, but its not nearly as powerful or easy to develop in as Python. For a specialized extension languages, its not too bad, but it kinds of a kludge when compared to a real programming language like Python (e.g., it doesn't support OOP).

Thankfully Vim can be embedded with Python as the extension language such that you can do most of the heavy lifting in native Python with only minor references to Vim API's itself in specialized glue code that interfaces your code with Vim's vimscript internals. This way you can call on the full power of Python's standard library, object oriented programming and interactive testing and development facilities for most of the development cycle and you only have to deal with the less elegant Vim parts in the glue code.

That doesn't mean you can ignore vimscript completely, but you don't have to deal with it much if you're careful about making your Python code logically independent.

File types

:h filetype

Vim doesn't have modes in the Emacs sense, but it does have a concept of a filetype that is recognized either by suffix (e.g., *.py), content, or location, and Vim can be configured to run special code when loading a particular type of file.

This special code can provide syntax highlighting, additional key bindings, change the behavior of indenting, etc.

Modelines

:h modeline

You can configure vim options on a per-file basis using a modeline. Thats a funny string at the start or the end of a document. You can use this to configure special indenting options, syntax highlighting, etc.

Example:

vim:noai:sw=3 ts=6

This sets turns off autoindent, sets shiftwidth to 3 and tabstop to 6.

Misc neat tricks

filtering text through a unix shell pipe:

visually select text (e.g., a list of numbers)
!sort -n

defining abbreviations:

:h abbreviations

text arithmetic (increment decrement numbers in place):

CTRL-A CTRL-X
You can get future posts delivered by email or good old-fashioned RSS.
TurnKey also has a presence on Google+, Twitter and Facebook.

Comments

Adrian Moya's picture

Thanks for condensing all this info in one post, I'll keep it on my bookmarks for future reference!

Greetings to the TKL team!

Liraz Siri's picture

I took notes when I was learning Vim and I figured it wasn't very useful if it was just sitting around in my computer.

Great to see you buddy.

Pages

Post new comment