Vim is a terminal-based editor optimized for speed. Keys are hotkeys by default. Vim does not even use Ctrl for most of them. Maneuvering via hotkeys is so efficient mouse input is often disabled by default.
This guide focuses on the features I use most frequently. It has nothing about with native Vim windows because I use i3 or Spacemacs instead. If you feel I left out a valuable feature then please let me know about it in the comments.
Movement
The simplest way to move is via the hjkl keys.
key
action
h
moves the cursor one character left
j
moves the cursor one line down
k
moves the cursor one line up
l
moves the cursor one character right
The hl keys operate within a single line. Pressing h at the start of a line does nothing. Pressing l at the end of a line does nothing. By line I mean a string of characters ending with a carriage return. The fact that a long paragraph appears to wrap around on your screen is irrelevant.
The jk keys move the cursor down and up a single line. If the cursor is in the 3rd column of the 6th line then pressing j moves the cursor to the 3th column of the 7th line.
Most commands can be prefixed with a number.4h moves the cursor left 4 characters.101j moves the cursor down 101 lines.
A sequence of nonempty lines is called a paragraph. The {} keys move the cursor forward and back by paragraphs.
key
action
}
moves the curser forward one paragraph
{
moves the curser backward one paragraph
There are two kinds of “words” in Vim. A word is a sequence of alphanumeric characters. A Word is a sequence of non-whitespace characters. The wbe keys move the cursor around words. The WBE keys move the cursor around Words.
key
action
w
moves the cursor forward to the next start of a word
e
moves the cursor forward to the next end of a word
b
moves the cursor backward to the next start of a word
W
moves the cursor forward to the next start of a Word
E
moves the cursor forward to the next end of a Word
B
moves the cursor backward to the next start of a Word
The #* keys move the cursor forward and backward to the next “idenfitier”. If the cursor hovers over the word “marmot” then pressing * will move the cursor forward to the next instance of the word “marmot” and pressing # will move the cursor backward to the previous instance of the word “marmot”.
key
action
#
moves the cursor backward to the previous identifier
*
moves the cursor forward to the previous identifier
The f key takes a character as an argument and moves the cursor forward to that character. For example, fa moves the cursor forward to the next instance of a. The f key operates within a line. It will never take the cursor to another line. The F command is like f except it searches backward. The t and T commands are like f and F exvcept they move the cursor one fewer character.
The ; command repeats the most recent fFtT command. The , command is like ; except backwards. If you use an F command followed by a , then the double-backwardsness will cancel itself out.
key
action
f<char>
moves forward to <char>
F<char>
moves backward to <char>
t<char>
moves forward to the character before <char>
T<char>
moves backward to the character after <char>
;
repeats the previous fFtT command
,
repeats the previous fFtT command except reversed
The 0^$ keys move the cursor to the beginning and end of a line.
key
action
0
moves the cursor to the beginning of the line
^
moves the cursor to the beginning of the line, excluding whitespace
+
moves the cursor to the beginning of the next line, excluding whitespace
$
moves the cursor to the end of the line
The HLM keys move the cursor around relative to the viewing window itself.
key
action
H
moves the cursor the the start of the first visible line
M
moves the cursor the the start of the middle visible line
L
moves the cursor the the start of the last visible line
You can move the viewing window itself with z and Ctrl keys.
key
action
Ctrl-e
moves the viewing window down one visual line
Ctrl-y
moves the viewing window up one visual line
Ctrl-f
moves the viewing window forward by one viewing window
Ctrl-b
moves the viewing window backward by one viewing window
Ctrl-d
moves the viewing window forward by half of one viewing window
Ctrl-u
moves the viewing window backward by half of one viewing window
zz
moves the viewing window to position the cursor in the middle
zt
moves the viewing window to position the cursor at the top
zb
moves the viewing window to position the cursor at the bottom
You can move the cursor itself up and down visible lines with the g prefix.
key
action
gj
moves the cursor down one visual line
gk
moves the cursor up one visual line
The g key can also go to a particular line.
key
action
gg
jumps the cursor to the beginning of the buffer[1]
G
jumps the cursor to the end of the buffer
<num>gg
jumps the cursor to the specified line
<num>G
″
The | key is like g except for columns.
key
action
<num>|
moves the cursor to the <num>th column within a line
The / key performs search. You type / then the string you are searching for and then press Enter. The ?nN keys are analogous to F;n.
key
action
/
initiates a search
?
initiates a backwards search
n
repeats the previous search
N
repeats the previous search except reversed
The () characters move forward and backward one sentence.
key
action
)
moves forward to the next start of a sentence
(
moves backward to the next start of a sentence
The [] characters move the cursor forward and backward to a variety of things. My favorite uses of [] is to go forward and backward to matching parenthesis. For example, ]) moves forward to the next unmatched closing parenthesis. It is indispensable when writing Lisp. Inner quotes and tags behave similarly to parentheticals.
key
action
])
move forward to matching parenthesis
](
″
[)
move backward to matching parenthesis
[(
″
[[
jump to function start
]]
jump to function end
You can (invisibly) mark places in your buffer to return to later. You can set one mark per letter. Lowercase letters a-z are buffer-specific e.g. each buffer can have its own “a” mark. Uppercase letters A-Z are global e.g. only one buffer at a time can have an “A” mark.
key
action
m<a-z>
create a buffer-specific mark
m<A-Z>
create a global mark
’<mark>
jump to the beginning of the line with mark <mark>
`<mark>
jump to mark <mark>
Some marks are populated automatically. Of the automatic marks, I only use ''. You can find the others here.
mark
meaning
″
jump to last jump point
Editing
Now that you know how to move, we can edit some text. Most of the time you edit text you should use the dyp keys.
d stands for delete, which is similar to “cut”.
y stands for yank, which is similar to “copy”.
p stands for put, which is similar to “paste”.
The d key operates on text objects and movement commands. For example dtA deletes everything up to (but not including) the next “A” on the current line.
Every delete operation operates on characters or lines.dtA operates on characters and thus behaves similarly to other editors. A delete operation which operates on lines deletes an integer number of lines. Delete operations which operate on lines delete the current line and the destination line. Thus, dj deletes the current line and the next line.
y is identical to d except it leaves your buffer unchanged.
delete or yank key
action
d<char>
deletes every character from the starting character up to (and including) the destination character
d<line>
deletes every line from the starting line up to (and including) the destination line
dd
deletes the current line
y<char>
yanks every character from the starting character up to (and including) the destination character
y<line>
yanks every line from the starting line up to (and including) the destination line
yy
yanks the current line
p puts the selection before the cursor.P puts the selection after the cursor. “Before” and “after” refer to characters or lines depending on whether you deleted/yanked characters or lines.
key
action
p
put after the cursor
P
put before the cursor
By default, p and P will put the last text you deleted or yanked. You can save text into registers by prefixing "<register> before your delete or yank command. For example, "add deletes the current line and saves it into register “a”.
There is one register for each letter a-z. If you use a capital letter then your delete or yank command will append to the register instead of overwriting it. You can put from a register by prefixing your p or P command with the register. For example, "ap" will put from register “a”.
Remember how I said you could follow d and y with a movement command or a text object? Remember from earlier the concept of “words” and “paragraphs”? Here we put them together into a simple grammar.
da deletes a text object.
key
action
daw
delete a word
daW
delete a Word
das
delete a sentence
dap
delete a paragraph
da(
delete a parenthetical
da)
″
yaw
yank a word
yaW
yank a Word
yas
yank a sentence
yap
yank a paragraph
ya(
yank a parenthetical
ya)
″
You can replace the a with an i to delete an inner word, an inner paragraph, etcetera. An inner text object is just like the regular text object except it does not include any surrounding delimiters. In the case of a parenthetical, the “inner parenthetical” does not include the outside parenthesis. For words/sentences/paragraphs, the delimiter is whitespace.
key
action
diw
delete inner word
diW
delete inner Word
dis
delete inner sentence
dip
delete inner paragraph
di(
delete inner parenthetical
di)
″
yiw
yank inner word
yiW
yank inner Word
yis
yank inner sentence
yip
yank inner paragraph
yi(
yank inner parenthetical
yi)
″
Other text objects include '"[]{}<>. They all do what you would expect them to do.t refers to an HTML-like tag.
Insert Mode
You cannot write everything by yanking and putting pieces of existing text together. Sometimes you have to insert text into a document. Several different keys drop you into insert mode.
key
action
i
inserts text before the cursor
a
inserts text after the cursor
I
inserts text at the beginning of the line
A
inserts text at the end of the line
o
creates a newline below the current line and inserts text there
O
creates a newline above the current line and inserts text there
s
deletes the current character and inserts text
S
deletes the current line and inserts text
You can exit insert mode by pressing Escape but it is faster to remap your CapsLock key to Ctrl and then exit insert mode with Ctrl-[. Some hotkeys are valid only while in insert mode.
insert mode key
action
Escape
exits insert mode
Ctrl-[
″
Ctrl-F
moves cursor forward one character
Ctrl-b
moves cursor backward one character
Ctrl-w
deletes one word backward (without saving it to a register)
The c key is like d except it drops you into insert mode afterward.
key
action
c<movement>
clear text
c<text_object>
clear text
After you exit insert mode, the whole insertion counts as a single edit. So if you type ci( followed by an insertion then the entire replacement of text inside the parenthetical counts as a single edit. You can repeat an edit with the . operator.
key
action
.
repeat previous edit
The . key might be the most important key in all of Vim. Generally-speaking, the more you use the . operator the better you are at Vim.
Miscellaneous edit commands
key
action
x
delete the character under the cursor
X
delete the character before the cursor
~
toggle capitalization and move the cursor forward one character
r<char>
replace a single character
The Undo Tree
u and Ctrl-r operate like the undo and redo stack you are familiar with.
key
action
u
undo last edit
Ctrl-r
redo next edit
If you undo a long series of edits and then mistakenly make an edit you can undo the damage with g+ and g- which traverse the nodes of the tree in chronological and reverse-chronological order.
key
action
g+
traverse undo tree in chronological order
g-
traverse undo tree in reverse chronological order
Macros
A macro is a series of keystrokes. Macros are good for automating repetitive tasks, especially editing structured text.
To define a macro, start by pressing the q key. Then pick a letter a-z at which to save the macro. Then execute the macro manually. When you are done typing the macro, press q again.
Once you have a macro defined, you can press @ followed by the macro’s letter to execute the macro.
key
action
q
define a macro
@<a-z>
execute a macro
@@
execute previous macro
Macros are well-behaved. If a macro modifies a line and then goes down one line and you tell Vim to execute the macro 1000 times but your buffer only has 700 lines then Vim will stop when it gets to the end of your buffer.
Visual mode
Visual modes are similar to highlighting. Visual modes have their uses, but it is usually faster to avoid them.
key
action
v
enter visual mode
V
enter visual line mode
Ctrl-v
enter visual rectangle mode
Find and Replace
You can find and replace all the instances of a string by typing :%s/ followed by the original string followed by / followed by the replacement string followed by Enter…assuming you did not type any escape sequences. Find and replace is a complex subject I will not delve into here even though I do use it.
Enter and exit
You can enter Vim by typing vim into your terminal followed by the file you would like to create or edit. You can exit vim by typing : followed by a quit command.
If you are not from a Unix back then the term “buffer” may be unfamiliar. Just translate “buffer” to “file” or “document” in your head even though, technically, a buffer is more general than a document.
Vim
Vim is a terminal-based editor optimized for speed. Keys are hotkeys by default. Vim does not even use
Ctrl
for most of them. Maneuvering via hotkeys is so efficient mouse input is often disabled by default.This guide focuses on the features I use most frequently. It has nothing about with native Vim windows because I use i3 or Spacemacs instead. If you feel I left out a valuable feature then please let me know about it in the comments.
Movement
The simplest way to move is via the
hjkl
keys.The
hl
keys operate within a single line. Pressingh
at the start of a line does nothing. Pressingl
at the end of a line does nothing. By line I mean a string of characters ending with a carriage return. The fact that a long paragraph appears to wrap around on your screen is irrelevant.The
jk
keys move the cursor down and up a single line. If the cursor is in the 3rd column of the 6th line then pressingj
moves the cursor to the 3th column of the 7th line.Most commands can be prefixed with a number.
4h
moves the cursor left 4 characters.101j
moves the cursor down 101 lines.A sequence of nonempty lines is called a paragraph. The
{}
keys move the cursor forward and back by paragraphs.There are two kinds of “words” in Vim. A word is a sequence of alphanumeric characters. A Word is a sequence of non-whitespace characters. The
wbe
keys move the cursor around words. TheWBE
keys move the cursor around Words.The
#*
keys move the cursor forward and backward to the next “idenfitier”. If the cursor hovers over the word “marmot” then pressing*
will move the cursor forward to the next instance of the word “marmot” and pressing#
will move the cursor backward to the previous instance of the word “marmot”.The
f
key takes a character as an argument and moves the cursor forward to that character. For example,fa
moves the cursor forward to the next instance ofa
. Thef
key operates within a line. It will never take the cursor to another line. TheF
command is likef
except it searches backward. Thet
andT
commands are likef
andF
exvcept they move the cursor one fewer character.The
;
command repeats the most recentfFtT
command. The,
command is like;
except backwards. If you use anF
command followed by a,
then the double-backwardsness will cancel itself out.fFtT
commandfFtT
command except reversedThe
0^$
keys move the cursor to the beginning and end of a line.The
HLM
keys move the cursor around relative to the viewing window itself.You can move the viewing window itself with
z
andCtrl
keys.You can move the cursor itself up and down visible lines with the
g
prefix.The
g
key can also go to a particular line.The
|
key is likeg
except for columns.The
/
key performs search. You type/
then the string you are searching for and then pressEnter
. The?nN
keys are analogous toF;n
.The
()
characters move forward and backward one sentence.The
[]
characters move the cursor forward and backward to a variety of things. My favorite uses of[]
is to go forward and backward to matching parenthesis. For example,])
moves forward to the next unmatched closing parenthesis. It is indispensable when writing Lisp. Inner quotes and tags behave similarly to parentheticals.You can (invisibly) mark places in your buffer to return to later. You can set one mark per letter. Lowercase letters a-z are buffer-specific e.g. each buffer can have its own “a” mark. Uppercase letters A-Z are global e.g. only one buffer at a time can have an “A” mark.
Some marks are populated automatically. Of the automatic marks, I only use
''
. You can find the others here.Editing
Now that you know how to move, we can edit some text. Most of the time you edit text you should use the
dyp
keys.d
stands for delete, which is similar to “cut”.y
stands for yank, which is similar to “copy”.p
stands for put, which is similar to “paste”.The
d
key operates on text objects and movement commands. For exampledtA
deletes everything up to (but not including) the next “A” on the current line.Every delete operation operates on characters or lines.
dtA
operates on characters and thus behaves similarly to other editors. A delete operation which operates on lines deletes an integer number of lines. Delete operations which operate on lines delete the current line and the destination line. Thus,dj
deletes the current line and the next line.y
is identical tod
except it leaves your buffer unchanged.p
puts the selection before the cursor.P
puts the selection after the cursor. “Before” and “after” refer to characters or lines depending on whether you deleted/yanked characters or lines.By default,
p
andP
will put the last text you deleted or yanked. You can save text into registers by prefixing"<register>
before your delete or yank command. For example,"add
deletes the current line and saves it into register “a”.There is one register for each letter a-z. If you use a capital letter then your delete or yank command will append to the register instead of overwriting it. You can put from a register by prefixing your
p
orP
command with the register. For example,"ap"
will put from register “a”.You can find a list of special registers here.
Text Objects
Remember how I said you could follow
d
andy
with a movement command or a text object? Remember from earlier the concept of “words” and “paragraphs”? Here we put them together into a simple grammar.da
deletes a text object.You can replace the
a
with ani
to delete an inner word, an inner paragraph, etcetera. An inner text object is just like the regular text object except it does not include any surrounding delimiters. In the case of a parenthetical, the “inner parenthetical” does not include the outside parenthesis. For words/sentences/paragraphs, the delimiter is whitespace.Other text objects include
'"[]{}<>
. They all do what you would expect them to do.t
refers to an HTML-like tag.Insert Mode
You cannot write everything by yanking and putting pieces of existing text together. Sometimes you have to insert text into a document. Several different keys drop you into insert mode.
You can exit insert mode by pressing
Escape
but it is faster to remap yourCapsLock
key toCtrl
and then exit insert mode withCtrl-[
. Some hotkeys are valid only while in insert mode.The
c
key is liked
except it drops you into insert mode afterward.After you exit insert mode, the whole insertion counts as a single edit. So if you type
ci(
followed by an insertion then the entire replacement of text inside the parenthetical counts as a single edit. You can repeat an edit with the.
operator.The
.
key might be the most important key in all of Vim. Generally-speaking, the more you use the.
operator the better you are at Vim.Miscellaneous edit commands
The Undo Tree
u
andCtrl-r
operate like the undo and redo stack you are familiar with.If you undo a long series of edits and then mistakenly make an edit you can undo the damage with
g+
andg-
which traverse the nodes of the tree in chronological and reverse-chronological order.Macros
A macro is a series of keystrokes. Macros are good for automating repetitive tasks, especially editing structured text.
To define a macro, start by pressing the
q
key. Then pick a letter a-z at which to save the macro. Then execute the macro manually. When you are done typing the macro, pressq
again.Once you have a macro defined, you can press
@
followed by the macro’s letter to execute the macro.Macros are well-behaved. If a macro modifies a line and then goes down one line and you tell Vim to execute the macro 1000 times but your buffer only has 700 lines then Vim will stop when it gets to the end of your buffer.
Visual mode
Visual modes are similar to highlighting. Visual modes have their uses, but it is usually faster to avoid them.
Find and Replace
You can find and replace all the instances of a string by typing
:%s/
followed by the original string followed by/
followed by the replacement string followed by Enter…assuming you did not type any escape sequences. Find and replace is a complex subject I will not delve into here even though I do use it.Enter and exit
You can enter Vim by typing
vim
into your terminal followed by the file you would like to create or edit. You can exit vim by typing:
followed by a quit command.Typing
ZZ
does the same thing as the:wq
command.Cheatsheet
If you are not from a Unix back then the term “buffer” may be unfamiliar. Just translate “buffer” to “file” or “document” in your head even though, technically, a buffer is more general than a document.