Introduction to Vim

This tutorial is best viewed in vim for active practice. Click here to download it.

Basic vertical movement with vim bindings works on this page! Press j/k to try.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# Introduction to Vim

## Preface

This document seeks to provide an introduction to vim, from the basic foundation
of vim usage all the way to advanced usage, features, customization, and coding.

## Introduction to modes

The vim editor has several modes of operation: Normal (command), Insert, Visual,
and Replace. Normal mode is the default mode that vim will start in when opening
a file. It takes direct commands such as movement in the buffer (the file that's
open) or colon commands like `:q` that are run in the bottom of vim under status
line information. Insert mode is what you would expect from any editor -- typing
characters results in characters appearing in the buffer. Visual mode selects an
area of text, which could be the typical selection from the starting point until
the ending point, a selection of entire lines, or a rectangle of characters. The
last mode, Replace mode, is basically Insert mode but overwrites existing buffer
contents instead. Of these, the Normal and Insert modes will be the two primary.

The first priority when discovering vim is learning to switch between the modes,
as well as actually exiting vim. The table below will give a brief introduction.

| Current mode | Desired mode | Keystroke | Notes                              |
|--------------|--------------|-----------|------------------------------------|
| Normal       | exit vim     | `:q`      | Among many other exit commands.    |
| Normal       | Insert       | i         |                                    |
| Normal       | Visual       | v         | Selects like a normal text editor. |
| Normal       | Replace      | R         | Use `r` for just one character.    |
| Insert       | Normal       | <esc>     | Escape is your best friend in vim. |
| Visual       | Normal       | <esc>     |                                    |
| Replace      | Normal       | <esc>     |                                    |

As a quick note, in the following text the terms "under the cursor" and "left of
the cursor" are used interchangeably, which will make sense with a block cursor.

### Normal Mode

Normal mode is the home in vim, from which you run any command, do any movement,
or enter any other mode. The following bindings are the most important to usage:

| Command     | Action      | Notes                                            |
|-------------|-------------|--------------------------------------------------|
| `:q`        | exit vim    | Prompts before exiting if the buffer is unsaved. |
| `:q!`       | exit vim    | Doesn't prompt about unsaved buffers.            |
| `:w`        | save buffer |                                                  |
| `:e <file>` | open <file> | Replaces the current buffer by opening <file>.   |
| h, j, k, l  | movement    | left, down, up, right respectively.              |
| b, w        | movement    | left and right by one token.                     |
| e           | movement    | right by one token, to the end of token.         |
| B, W, E     | movement    | Same as lowercase versions, but space delimited. |
| ^b, ^f      | paging      | page up, page down.                              |
| gg, G       | paging      | beginning of buffer, end of buffer.              |
| u, ^r       | editing     | undo, redo.                                      |
| /<term>     | searching   | Search for <term>.                               |
| n, N        | searching   | next match, previous match.                      |

### Insert and Replace Mode

Insert mode is generally self-explanatory: you type something and something gets
typed in the buffer. Therefore, this section will how best to enter Insert mode.
The following commands make the assumption that you are starting in Normal mode.

| Command | Action                                                             |
|---------|--------------------------------------------------------------------|
| i       | Insert, at the left of the cursor.                                 |
| I       | Insert, at the beginning of the line.                              |
| a       | Insert, at the right side of the cursor (think "append").          |
| A       | Insert, at the end of the line (think "append", but for real now). |
| o       | Insert, in a new line before the current line.                     |
| O       | Insert, in a new line after the current line.                      |

Replace mode, as noted, is basically the same as Insert mode, but it overwrites.

| Command | Action                                                             |
|---------|--------------------------------------------------------------------|
| r       | Replace the single character under the cursor.                     |
| R       | Replace (overwrite) under the cursor until you leave Replace mode. |

### Visual Mode

This mode handles "visually" selecting regions of vim. This handles the expected
functionality like copying and pasting (within vim), but additionally enables an
operation across the entire selection, such as inserting rectangles of text or a
search constrained to just the highlighted region. Note, there are other ways to
accomplish these operations besides with "visual" mode, such as using the % sign
to operate on the entire file, but these won't be covered in this documentation.

The commands below generally assume Normal mode, but will report any exceptions.

| Command     | Action                                                         |
|-------------|----------------------------------------------------------------|
| v           | Start a selection from the left of the cursor.                 |
| V           | Start selecting lines, starting with the current line.         |
| y           | (Visual) Copy ("yank") the text that's been selected.          |
| yy          | Copy ("yank") the entire current line.                         |
| y<movement> | Copy from the left of cursor to the destination of <movement>. |
| P           | Paste, at left of cursor.                                      |
| p           | Paste, at right of cursor.                                     |
| I           | (Visual block) Inserts down the entire rectangle.              |

This introduces an important concept -- the interaction between various commands
forms something similar to a language. In the above table, `y<movement>` opens a
door to this language. Many editing commands can combine with a movement to give
a target to their action, and the functionality compounds to become a completely
natural flow of interaction with the editor. However, this is a topic for later.

## Editing

Now comes the time to discuss the editing power of vim. The previous sections do
their best to make vim a smooth simple experience, but if that was the goal then
something like Notepad could have been used, with far less reading and practice.

The basics, like moving around with h/j/k/l, have already been introduced. These
are great for avoiding mouse usage and keeping your hands on the home row of the
keyboard, but there is so much more to learn here. The pair of tables below give
a summary of more of the everyday indispensable bindings for advanced vim usage.

The Change commands put vim in Insert mode from Normal mode after text deletion.

| Command     | Action                                                         |
|-------------|----------------------------------------------------------------|
| c<movement> | Change from left of cursor until destination of <movement>.    |
| cc          | Change the entire line.                                        |
| C           | Change from left of cursor until the end of the line.          |
| ci<char>    | Change inside <char>, eg `ci[` will change contents of braces. |
| ca<char>    | Change around <char>, like above but also removes the chars.   |
| s           | Delete the character under the cursor; then enter Insert mode. |
| S           | Change the entire line.                                        |
| d<movement> | Delete from left of cursor until destination of <movement>.    |
| dd          | Delete the entire line.                                        |
| D           | Delete from left of cursor until the end of the line.          |
| x           | Delete the character under the cursor (like <delete>).         |
| X           | Delete the character behind the cursor (like <backspace>).     |
| . (period)  | Tells vim to do whatever it just did, again.                   |

The . command is quite powerful for repeating an action many times. For example,
if you wanted to put a - at the beginning of several lines, besides using Visual
mode, you could also walk down the lines in a sequence like `I-<esc>j.j.j.j.j.`.

And of course, below are a variety of commands for moving the cursor and buffer.

| Command | Action                                                             |
|---------|--------------------------------------------------------------------|
| zz      | Scroll the buffer to place the cursor in the center of the screen. |
| zb      | Scroll the buffer to place the cursor at the bottom of the screen. |
| zt      | Scroll the buffer to place the cursor at the top of the screen.    |
| H, M, L | Move the cursor to the top, middle, or bottom of the screen.       |
| t<char> | Move the cursor up to <char>, to the left by one.                  |
| T<char> | Move the cursor backward to <char>, to the right by one.           |
| f<char> | Move the cursor forward to <char>, on top of the char.             |
| F<char> | Move the cursor backward to <char>, on top of the char.            |
| 0, $    | Move the cursor to the beginning / end of the line                 |
| (, )    | Move the cursor to the beginning / end of the "paragraph"          |
| :<num>  | Move the cursor to line <num>, eg `:200` moves to line 200.        |

## Macros

A macro is a sequence of interactions with vim that can be played back to repeat
whatever was done. Macros are saved in letters, as chosen when recording. Saving
a macro follows the pattern `q<letter><interactions>q`, where the letter is what
the macro will be saved in, and the interactions are generally any normal usage.
A macro is replayed with `@<letter>`, and can be repeated by the shorthand `@@`.

## Registers

Text can be saved into registers, which are different clipboards that vim keeps.
Each register is saved into a character, and is referenced using `"<character>`.
To copy into a register ('a' for demonstration), select a region, then use `"a`.
To paste from a register ('a' again), use `"aP` (or another paste command). This
is how one can interact with the system clipboard, actually -- there are special
registers for this. On Linux it's the `+` register, on macOS it's in `*`, and on
Windows you come to a realization that you're using the wrong OS. These can only
work if vim was installed with support; this information can be found in version
information (`vim --version`) at `xterm_clipboard`. A `+` prefix means it should
work; a `-` prefix means it doesn't support it. Instructions on updating vim for
system clipboard support are online but generally you install graphical/GUI vim.

## Buffers, Windows

Vim can open multiple files at once, and view multiple buffers at the same time.
Vim refers to the multi-buffer view panes as "windows", but to avoid terminology
confusion they'll just be called panes. Below is an overview of useful commands.

### Buffers

| Command      | Action                                                        |
|--------------|---------------------------------------------------------------|
| `:e <file>`  | Already mentioned; opens <file>, and replaces current buffer. |
| `:bp`, `:bn` | Go to the next / previous buffer.                             |

### Panes (Windows)

| Command       | Action                                                       |
|---------------|--------------------------------------------------------------|
| `:sp <file>`  | Open <file> in a pane, horizontally split above this one.    |
| `:vsp <file>` | Open <file> in a pane, vertically split to the right.        |
| `:on`         | Only show this pane; short for "only" (which can also work). |
| ^w ^w         | Cycle which pane is focused.                                 |
| ^w =          | Equalize pane sizes.                                         |
| ^w r          | Rotate buffers in panes.                                     |

## Customization

Vim can be customized quite a bit, through two primary methods. The first way is
a short-term change, with colon commands, such as `:set number` to activate line
numbers in the current buffer. The second by editing the configuration file, the
vimrc. This will affect anything you open in vim. For Linux and macOS, the vimrc
will be at `~/.vimrc`. For Windows it might take some looking around to find it.

This document could cover a portion of what can be customized, but a potentially
better approach is to just search online for whatever you expect and want from a
text editor. Line numbers? `:set number`. Don't spellcheck capitalization of new
sentences? `:set spellcapcheck=`. These can be done both from Normal mode like a
command, or by putting them directly in the vimrc (which doesn't use the colon).

For options that are a simple toggle, there are two ways to set them: explicitly
enabling / disabling it (let's say "foo") with `:set foo` and `:set nofoo`, or a
toggle with `:set foo!`. The latter method is only useful as a command though; a
vimrc configuration should set things explicitly instead of relying on a toggle.

Any command that's unambiguous can be abbreviated, as was seen with `:on` as the
short form of `:only`. `:w` is short for `:write` and `:q` is short for `:quit`.
This even applies for any functions you write or commands from plugins -- if the
shortened form of some command can only be expanded one way, vim understands it.

### The vimrc

When you customize the vimrc, it's a good idea to make a backup first so that in
the case of errors you can restore the working version. Past that, you can check
your changes directly from vim with `:so .vimrc` (short for `:source`). Sourcing
the file will run all commands, just like how a bash shell does with its bashrc.

#### Plugins

A wide variety of plugins are available for vim, as well as package managers for
handling them all. Vundle is a good package manager which can be found on GitHub
at https://github.com/VundleVim/Vundle.vim and has documentation for installing.

#### Vim Scripting

If vim doesn't offer what you need and you can't find a plugin for it either, an
option is to script it. The vimscript language allows you to implement functions
and commands to call just like anything else you'd run from Normal mode; or, you
could choose something somewhat more sane and let it interface between vim and a
programming language of your choice. The latter option is likely the better one.

This brings up a good point -- vim can make system calls. There are not a lot of
common usages for this though. To do this, use `:!<command>` to run `<command>`,
for example `:!pwd` runs `pwd` in shell. To put the command result directly into
the buffer, prepend and `r`, eg `:r!pwd` outputs directly to the current buffer.

## Conclusion

Vim is a powerful text editor with a beautiful language of interaction, infinite
customizability, and a world of extensibility. We've only scratched the surface.

Introduction to Vim © 2023 Adam Sinck, licensed via CC BY SA.