Vim Introduction and Tutorial

I often tried to learn the great Emacs editor/IDE/operating system. The last time I tried it, I spent some time getting comfortable with it until I wanted to customize my .emacs file.

That was the point when I entered vi .emacs. As soon as I realized what I’ve done, I knew that Vim has won me over a long time ago.

So, here I am – using Vim as my editor1 of choice.

Another big motivational boost came after I discovered that my preferred shell (ZSH) has an awesome vi-mode including the command mode (yes, you can switch between command and insert mode!).

Vim has a great deal of features, and learning them takes some time. Of course there are many online-tutorials and tips’n’tricks pages, but the help-files are very good too! There are overview-pages, summary pages and some comments at the commands.

I took the approach to start using some tutorial and let the help-system guide (type :help <command> to get help for the command) me through the rest. I like to try the commands in a test-file, and take a short note of important commands.

Another reason I like to use Vim is because it’s much more healthy than Emacs (using the default-keymappings). Healthy? Many commands are easily typed with a single keystroke – the virtue of a modal editor, instead of long command-chains with lots of modifier keys. Even if you have a natural keyboard, pressing Ctrl, Alt etc is certainly not natural at all.

Just remember: Vim’s basics are really very simple, but in combination the simple commands become very powerful.

Modes

You have 3 modes:

  1. Command mode: all keystrokes are interpreted as commands
  2. Insert mode: most keystrokes are inserted as text (leaving out those with
    modifier keys)
  3. Visual mode: helps to visually select some text, may be seen as a submode of
    the the command mode.

To switch from the insert or visual mode to the command mode, type <Esc>.

To switch from the command mode to the insert mode type one of

  • i …switch to insert mode before the current position
  • a …switch to insert mode after the current position (append)
  • I …jump to the first non-blank character in the current line and switch
    to the insert mode
  • A …jump to the last character of the current line and switch to the
    insert mode

To switch from the command mode to the visual mode type one of

  • v …switch to the visual mode (character oriented)
  • V …switch to the visual mode (line oriented)
  • Ctrl-v …switch to the block-visual mode (select rectangles of text)

All commands that take a range (for example subtitution, delete, copy or indentation) work with the visual mode too.

Movement

The simplest movement commands are

  • h …move left
  • l …move right
  • k …move up
  • j …move down

Obviously these commands work only in the command mode, of course you can also use the cursor keys (in all three modes).

There are a lot of movement commands available in Vim, I’ll only cover a few, but if you need something special very often take a look at the help, I’m sure you’ll find something usable.

Vim distinguishes between screen-lines (those shown on the monitor) and real lines (those ended with a new-line).

So here the most important commands

  • 0 …first column of the line
  • ^ …first non-blank character of the line
  • w …jump to next word
  • W …jump to next word, ignore punctuation
  • e …jump to word-end
  • E …jump to word-end, ignore punctuation
  • b …jump to word-beginning
  • B …jump to word-beginning, ignore punctuation
  • ge …jump to previous word-ending
  • gE …jump to previous word-ending, ignore punctuation
  • g_ …jump to last non-blank character of the line
  • $ …jump to the last character of the line

If you remember just a few of them, you’ll get very quickly from A to B! Another important fact is, that these commands give the range for other commands.

Editing

Inserting text is pretty simple in Vim, just type i and start typing. But Vim offers quite sophisticated text-editing commands.

  • d …delete the characters from the cursor position up the position given by the next command (for example d$ deletes all character from the current cursor position up to the last column of the line).
  • c …change the character from the cursor position up to the position indicated by the next command.
  • x …delete the character under the cursor.
  • X …delete the character before the cursor (Backspace).
  • y …copy the characters from the current cursor position up to the position indicated by the next command.
  • p …paste previous deleted or yanked (copied) text after the current cursor position.
  • P …paste previous deleted or yanked (copied) text before the current cursor position.
  • r …replace the current character with the newly typed one.
  • s …substitute the text from the current cursor position up to the position given by the next command with the newly typed one.
  • . …repeat the last insertion or editing command (x,d,p…).

Doubling d, c or y operates on the whole line, for example yy copies the whole line.

Please note, many commands are much more powerful than I describe them here. For example you can specify a buffer into some text is yanked. Typing "ayy copies the current line into register a, pasting the contents of register a is done by "ap. Vim remembers the last few yanks and deletions in automatic registers, to show the contents of the registers type :registers, you can also use them to paste some older text.

Visual Block

Using the visual block-mode it’s possible to insert characters on each line of the selection easily.

Suppose you have selected a rectangle (using Ctrl-v), you can insert text in front of it by typing I (switch to insert mode) and inserting your text. As soon as you leave the insert mode, the text will be added to all the other selected lines. Use A to enter text after the selection.

Another useful feature is to substitute the whole block with a new text. For that matter select a block and type s, Vim enters the insert mode and you can type. After you leave the insert mode, Vim inserts the text in the remaining lines.

If you’d like to append some text at the end of some lines, use Ctrl-v$ and select the lines. The difference between the former variant is, that the $ explicitly says “end of line” whereas a selection with Ctrl-v operates on the columns, ignoring the text.

Using Ctrl-v:

 This is a testNEWLY INSERTED
 This is a     NEWLY INSERTED
 This is       NEWLY INSERTED

Using Ctrl-v$:

 This is a testNEWLY INSERTED
 This is aNEWLY INSERTED
 This isNEWLY INSERTED

Text-objects

Vim commands operate on text-objects these are characters, words, characters delimited by parentheses, sentences and so on.

For me the most important one is the inner word: iw. To select the current word, just type viw (v for selection mode, and iw for the inner word), similar for deletion: diw.

The difference between inner-word/block and a-word/block etc is that the inner variant selects only the contents like the characters of the word (no blank afterwards) or the contents of the parentheses but not the parentheses. The a-variant selects the parentheses or a blank after a word too.

  • iw …inner word
  • aw …a word
  • iW …inner WORD
  • aW …a WORD
  • is …inner sentence
  • as …a sentence
  • ip …inner paragraph
  • ap …a paragraph
  • i( or i) …inner block
  • a( or a) …a block
  • i< or i> …inner block
  • a< or i> …a block
  • i{ or i} …inner block
  • a{ or a} …a block
  • i" …inner block
  • a" …a block
  • i` …inner block
  • a` …a block

Here a quick visualisation of the commands the color and the [ ] mark the selected text:

Command Text Object
iw This is a [test] sentence.
aw This is a [test ]sentence.
iW This is a […test…] sentence.
aW This is a […test… ]sentence.
is …sentence. [This is a sentence.] This…
as …sentence. [This is a sentence. ]This…
ip End of previous paragraph.

[This is a paragraph. It has two sentences.]

The next.
ap End of previous paragraph.

[This is a paragraph. It has two sentences.

]The next.
i( or i) 1 * ([2 + 3])
a( or a) 1 * [(2 + 3)]
i< or i> The <[tag]>
a< or i> The [<tag>]
i{ or i} some {[ code block ]}
a{ or a} some [{ code block }]
i" The "[best]"
a" The[ “best”]
i` The `[best]`
a` The[ `best`]

Try them out and remember the ones you need regularly (in my case iw and i() they are the real time-savers!

Undo and Redo

Don’t be afraid to try the various commands, you can undo almost anything using u in the command mode – even undo is undoable using Ctrl-r.

Vim 7.0 introduced undo-branches, but I didn’t have time to dig deeper.

External commands

In Vim it’s easy to include the output of external commands or to filter the whole line or just a part through an external filter.

To issue an external command type :!command, the output will be shown and that’s it.

To filter the text through an external command type :!sort %.

To insert the output of the external command in the current file type :r!command (for example :r!which ls).

Search for “filter” for more information :h filter.

Searching and Replacing

Searching in Vim is very easy. Type / in the command mode and insert the term you search, and Vim will search the file (in forward direction) for the term. Use ? for the backward direction. Using n or N you can repeat the search in the same or opposite direction.

If the option “incsearch” is set, Vim immediately jumps to the matching text when you enter something. If “hlsearch” is set, it highlights all matches. To remove the highlight type :nohl.

Replacing something isn’t very hard too, but you should have a good understanding of regular expressions.

To substitute a regular expression with some other text, type :%s/old/new/gc this command takes the whole file %, and substitutes s the word "old@ with “new” and looks for more than one occurrence within one line g and asks if it really should replace the shown one c.

To replace some text only in a selected area, select the area, and type :s/old/new/g. This should look like :'<,'>s/old/new/g in the command line. You’ll understand '< and '> after the “Marks” section.

Completion

While you are typing, it’s pretty common to use the same word over and over again. Using Ctrl-p Vim searches the currently typed text backwards for a word starting with the same characters as already typed. Ctrl-x Ctrl-l completes the whole line.

If you’re not sure how to type some word and you’ve enabled spell-checking (:set spell), you can type Ctrl-x Ctrl-k to do a dictionary lookup for the already typed characters. Vim’s completion system has much improved during the last major update (Vim 7.0).

Note the completion commands work only in the insert mode, they have other meanings in the command mode!

Marks

You can set marks within your documents to jump quickly between different positions of a document or even many documents.

Vim automatically sets various marks like

  • {0-9} are the last 10 positions of closed files (0 the last, 1 the last but one)
  • < and > are the left and right position of marked texts
  • ( and ) are the start or end of the current sentence
  • { and } are the start or end of the current paragraph
  • [ and ] are the first or last character of the last yanked or changed text
  • . position of the last change
  • ' or ` position before the last jump
  • " position before the last exit of the file (local to a file)
  • ^ position of the last insert-stop

To set a manual mark, use m{a-zA-Z} (m followed by either a,b..z or A,B,..Z), and to jump to one of the marks (manual or automatic) you can choose between ' and `

  • ' …sets the cursor to the first non-blank character in the marked line
  • ` …sets the cursor to the exact position where the mark was set

There is a little difference between lower-case and upper-case characters:

  • {a-z} are local to a file
  • {A-Z} are stored and available over sessions (associated with a file)

You can use L for your work-log and T for your time-table for example, and quickly update the information there.

For example you can jump to the last known position of a file before it was closed by typing `" (it’s easy to configure Vim to do it automatically at start).

To get a list of all marks Vim knows about type :marks. To delete marks use :delmarks (:delmarks a b c removes marks a and b and c, to delete all marks use :delmarks!).

Tabs, Buffers and Windows

Vim 7.0 has introduced tabs. We all know and love tabs, so it’s not much to say here. (Just a note: tabs in Vim are a bit different than in other programs, you could also think of them as many Vim instances in a tabbed terminal window. The difference is, that each tab-page can have it’s own layout. For example I could split my screen of the first tab, and view the same file in one window at the second tab… . So Vim-tabs are a bit more powerful.)

To open many files in tabs via the command line use vim -p *.txt.

To switch between tabs use the mouse (in gVim) or type gt.

To create a new empty tab type :tabnew, or open a file in a new tab :tabe xyz.

Buffers and Windows are a bit harder to understand. A window is what you see when you open Vim, when you open the help system (by typing :help buffers), you’ve got two windows. So they are no actual windows, but view-ports that Vim offers.

You can open a window and split the current one horizontally using :sp or vertically using :vsp. This way Vim shows you the same buffer in two different windows. You can open a new file too, using :sp file or :vsp file. To switch between windows use the mouse or type Ctrl-w {hjkl} in the command mode.

A buffer is a file (most of the time), but isn’t necessarily visible. So there are usually more buffers than windows. To show a different buffer in the current window, you can switch them using :b NUMBER, where the buffer number can be looked up using :buffers. In the standard configuration Vim forces you to save the currently shown buffer before it allows you to switch to another buffer, so don’t be frustrated by it’s complains. (Type :set hidden to enable unsaved buffers, but be careful).

Here my notes from the help-file:

  • :b N switch to buffer N
  • :buffers show buffer list. Explanation:
    • % current window
    • # alternate buffer (switch using :e# or :b#)
    • a active (loaded and visible)
    • h hidden (loaded but not visible)
    • + modified
  • :bd unload the buffer and remove it from bufferlist (don’t close Vim,
    even on the last buffer)
  • :bun unload the buffer but stay in bufferlist
  • :sp #N split current window and edit buffer N
  • :w write the current buffer to disk
  • :e file load a file from disk
  • :q closes current window (and Vim if it’s the last one)
  • :new new empty window
  • :on close all windows but the active one (Ctrl-W o)
  • Ctrl-W {h,j,k,l} move between windows

Allow modified buffers to be hidden when the option ‘hidden’ is set. Buffers are automatically saved if the option ‘hidden’ is not set, but ‘autowrite’ is set.

Macros

Vim allows to replay some commands using . (a dot). For more than one command use macros.

You can start macro-recording using q and one of {0-9a-zA-Z}, so for example qq records the macro to buffer “q”. Hit q when you are finished recording.

Now you can replay the macro at any time using @q.

This is the end

I hope I could get you started for mastering one of the most sophisticated editors out there. The last thing I can do now is to include my configuration file. Use :help ... to explore Vim’s powers further and write a tutorial for the next apprentice.

Place the vimrc into your home-directory (~/.vimrc), but make sure you don’t have one already.

1 Vim is an editor, no IDE or operating system. Don’t try to make an IDE out of it, if you like IDEs use one! Of course it’s possible to automate many tasks, like compiling and jumping to errors reported by the compiler, for that matter look at Vim’s plugins.

Emacs is a good operating system, but it lacks a good editor.
— Old saying.

Comments

comments powered by Disqus