I’ve been using Vim for a long time and I’m familiar with many of its commands but I’ve never had a good understanding of the underlying components of commands and their composition. Although there are many good Vim references, I felt that I was still not seeing the full picture. So, to try and dig a little deeper and educate myself, I’ve put together this reference, which details a subset of the command language. The approach I’ve taken was inspired by the grammar rules outlined in this blog post, and should be useful for anyone who is familiar with Vim.
A Vim command can be constructed from different rules, and below each rule is
specified with a EBNF-style
syntax, where <...>
is
another rule. {...}
represents some key presses, |
is an alternative and
[...]
is an optional component. Be warned that
since there are many special cases to Vim commands and I’ve not checked all the
combinations, some of the rules below may yield invalid compositions! As such,
these rules are better viewed as a way of remembering commands. For an
exhaustive treatment of the command language, please check the Vim
documentation, or use the :help
tags that I’ve given.
Motions
Motions change the position of the cursor and can be combined with a count to repeat the motion.
count := {digits}
motion := [<count>] <motion-keys>
command := <motion>
Examples:
2fx
- move to the second right-hand occurrence ofx
in the line (inclusive)2Tx
- move to the second left-hand occurrence ofx
in the line (exclusive)w
- move to the next word10j
or10_
- move down 10 lines10k
- move up 10 lines6w
- move to start of the sixth word forwards6E
- move to end of sixth word forwards4b
- move to start of the fourth word backwards2{
- move two paragraphs down3/foo
- move to the third occurrence offoo
later in the buffer3?foo
- move to the third occurrence offoo
earlier in the buffer
Text objects
Text objects are a collection of characters relative to the position of the
cursor. Compared to motions, text objects on a whole object, regardless of the
specific cursor position. The a
and i
modifiers augment text objects,
specifying whether the surrounding context should be included. The context may
be whitespace or delimiting characters.
text-object := <text-object-keys>
| <modifier> <text-object-keys>
Examples:
aw
- around word (includes surrounding whitespace)iw
- inner word (excludes surrounding whitespace)aW
- around WORD (where word is delimited by whitespace)as
- around sentenceis
- inner sentenceap
- around paragraphip
- inner paragrapha'
- a single-quoted stringi'
- inside a single-quoted stringa(
=a)
=ab
- a parenthesised block, from(
to)
i(
=i)
=ib
- inside a parenthesised block, contents of(...)
a<
=a>
- a tag, from<
to>
at
- around tag block, including matching start and end tags<tag>...</tag>
it
- inside tag block, excluding tagsaB
=a{
=a}
- around a{...}
blockiB
=i{
=i}
- inside a{...}
block
Operators on text objects
Operators can be applied to text objects. In some circumstances, a count can be applied to the text object to repeat its effect.
command := [<count>] <operator> <text-object>
text-object := <count> <modifier> <text-object-keys>
Examples:
cw
- change word from cursorciw
- change word under cursordw
- delete until end of word5dw
=d5w
- delete until end of right-hand sixth wordcaw
- change around word under cursor2d3w
- delete six words5gUw
- make the next five words uppercasedgg
- delete lines from cursor to beginning of bufferdG
- delete lines from cursor to end of buffer3d_
- delete three linesc$
- change until end of liney_
=yy
=Y
- yank the linec_
=cc
=C
- change the linegUap
- make paragraph uppercasegqap
- format paragraph text totextwidth
line lengthdit
- delete text between tags<tag></tag>
dat
- delete tag blockyi"
- yank text in"..."
blockyi<
- yank text in<...>
blockyiB
- yank text in{...}
blockyaB
- yank whole{...}
block
Operators on motions
A motion can be applied after an operator to apply the operator on the text that was moved over.
command := [<count>] <operator> <motion>
Examples:
dl
=x
- delete next characterdb
- delete backwards to the start of a worddtx
- delete untilx
character in line (exclusive)dfx
- delete untilx
character in line (inclusive)d/foo
- delete from cursor to next occurrence offoo
d3/foo
- delete from cursor until the third occurrence offoo
c$
=C
- change until end of lined$
=D
- delete until end of lined0
- delete until beginning of lined^
- delete until first non-blank character in linec{
- change from current line to beginning of paragraphgU}
- make paragraph uppercasec{
- change paragraph (same ascap
operator-text object)>}
- indent paragraphy%
- yank the entire{...}
blockcgg
- change lines from cursor to top of bufferggdG
- delete contents of buffer
Duplicate operators
Operators applied twice affect the entire line, a synonym for <operator>_
,
command := [<count>] <operator> <operator>
Examples:
dd
=d_
- delete linecc
=c_
- change lineyy
=y_
- yank line>>
=>_
=>l
- indent line<<
=<_
=>l
- unindent line
Note: duplication does not apply to ~
or two-character operators.
Aliases
Some commonly-used commands have aliases.
x
=dl
- delete next characterC
=c$
- change until the end of the lineD
=d$
- delete until the end of the lineY
=yy
- yank the lineS
=cc
- change the lineA
=$a
- append text to end of the lines
=cl
- substitute character (delete and insert)S
=cc
- substitute line
Filtering
Text lines can be filtered through an external program (see :help filter
).
command := ! <motion> <filter>
Examples, using some basic utilities found on Unix platforms:
!8jsort
- sort the next 8 lines!apsort
- sort lines in paragraph!apwc -l
- replace paragraph with word count!apfmt -s
- collapse whitespace in paragraph into single spaces!apfmt -c
- centre lines in paragraph!i(grep foo
- remove all lines in(...)
block that don’t containfoo
(similar to the Ex command:%v/foo/d
)gg!Gsort
- sort all lines in buffergg!Guniq -c
- remove all duplicate lines in buffer and prefix remaining with duplicate counts
Visual selection
Visual selection, character-wise v
, line-wise V
or block-wise Ctrl+v
(all
referred to below by {visual}
, see :help visual-start
), followed by a
motion or text object can be used to specify a character range. An operator can
then be used to transform the text. Note the operators gu
, gU
and g@
can’t be used in visual mode and text objects in visual mode, however, there
are additional ones that can (see :help visual-operators
). A visual block is
created by entering a visual mode, then providing a motion or text object to
set the selection, or alternatively by any sequence of movement commands
(referred to by {move-around}
).
visual-block := {visual} {move-around}
| {visual} <motion>
| {visual} <text-object>
command := <visual-block> <operator>
| <visual-block> <visual-operator>
| <visual-block> ! <filter>
Examples:
vtxd
=dtx
- delete untilx
vt.rx
- replace all characters withx
until.
v3as~
- make next three sentences uppercasevapU
- make paragraph uppercasevapd
- delete paragraph{Ctrl+v}{move-around}sfoo{Esc}
- replace each line of blockwise selection withfoo
{Ctrl+v}{move-around}Ifoo{Esc}
- prependfoo
to each line of blockwise selection{Ctrl+v}{move-around}Afoo{Esc}
- appendfoo
to each line of blockwise selectionvap!sort
- sort the lines of the current paragraphvap!fmt
- use thefmt
command-line tool to format selection into lines of 75 characters (similar to thegqap
command)ggvG!indent
- use theindent
command-line tool to apply automatic indentation all lines of a C-code buffer{visual}J
- join the highlighted lines on the current line{visual}gJ
- join the highlighted lines on the current line (removing whitespace)
Other command combinations
Beyond the above rules, there are further command keys and more restricted combination with motions, operators and text objects.
The .
command repeats the last change that was made.
command := [<count>] .
db.
- delete the previous two wordsdb4.
- delete the previous five words{insert text...}
then/{pattern}.
- insert text again before next text matching{pattern}
The gn
and gN
motions can be used with operators to move between matching
search patterns.
command := [<count>] <operator> gn
| [<count>] <operator> gN
cgn
- change the next search match3cgn
- change the third search matchcgN
- change the previous search match
Here are some other interesting and potentially useful commands that I’ve found in the Vim help:
gf
- goto file (when cursor is on a valid filesystem path)gF
- goto file and line number (line number following path)J
- Join the current line with the next one (with space in between)gJ
- Join the current line with the next one (without space in between)3J
- join the next three lines on the current line (removing indent)3gJ
- join the next three lines on the current linegv
- reselect previous visual areag~~
=g~g~
- switch case of linegUU
=gUgU
- make line uppercaseguu
=gugu
- make line lowercaser{char}
- replace character under cursor with{char}
10r{char}
- replace the next 10 characters with{char}
Summary of rules
Motions
<motion-keys>
References: :help motion
:help various-motions
Action | Effect |
---|---|
l ,h ,j ,k |
right, left, down, up |
w / W |
start of next word / start of next WORD |
b / B |
start of pevious word / start of previous WORD |
e / E |
end of next word / end of next WORD |
0 / $ |
start / end of line |
^ / g_ |
first / last non-blank character in line |
{ / } |
start / end of paragraph |
t{char} |
till - move to next character (inclusive) |
f{char} |
find - move to next character (exclusive) |
T{char} |
till - move to previous character (inclusive) |
F{char} |
find - move to previous character (exclusive) |
% |
move to matching character (default pairs: () , {} , [] ) |
[( , [) |
move to matching parenthesis |
[{ , [} |
move to matching curly brace |
/{pattern} |
search forward (must be followed by {CR} ) |
?{pattern} |
search backwards (must be followed by {CR} ) |
gg / G |
move to first / last line in buffer |
Operators
<operators>
Reference: :help operator
Key | Operator |
---|---|
c |
change |
d |
delete |
y |
yank |
~ |
swap case (or g~ ) |
> |
shift right (always linewise) |
< |
shift left (always linewise) |
gu |
make lowercase |
gU |
make uppercase |
gq |
format text |
g@ |
apply function (set by operatorfunc ) |
Visual operators
<visual-operators>
References: :help visual-operators
Key | Operator |
---|---|
r{char} |
replace every character in selection with {char} |
s , c |
substitute (inserted text replicated on each line for blockwise) |
J / gJ |
join / join (remove whitespace) |
p |
put (replace selection with contents of register) |
U |
make uppercase |
u |
make lowercase |
I |
insert (prepend, only on blockwise selection) |
A |
insert (append, only on blockwise selection) |
Text objects
<text-object-keys>
References: :help text-objects
, :help objects
Key | Text object |
---|---|
w |
word (delimited by non-keyword characters, see :help iskeyword ) |
W |
WORD (delimited by whitespace, includes empy line) |
s |
sentence |
p |
paragraph |
t |
tag |
[ , ] |
text block between square brackets |
{ , } |
text block between curly braces |
( , ) |
text block between parethesises |
' , ' |
text block between single quotes |
" , " |
text block between double quotes |
< , > |
text block between angle braces |
` , ` |
text block between back ticks |
b |
text block between ( and ) |
B |
text block between { and } |
Modifiers
<modifiers>
References: :help text-objects
Key | Movement |
---|---|
a |
a or around |
i |
inner |
count := {digits}
text-object := <text-object-keys>
| <modifier> <text-object-keys>
| <count> <modifier> <text-object-keys>
motion := [<count>] <motion-keys>
visual-block := {visual} {move-around}
| {visual} <motion>
| {visual} <text-object>
command := <motion>
| [<count>] <operator> <text-object>
| [<count>] <operator> <motion>
| [<count>] <operator> <operator>
| ! <motion> <filter>
| <visual-block> <operator>
| <visual-block> <visual-operator>
| <visual-block> ! <filter>
| [<count>] .
| [<count>] <operator> gn
| [<count>] <operator> gN
Some random commands
Just for fun, here are some random commands using the above rules to show the variety of actions you can perform. Some might not make sense or not work, but they might give you some ideas.
Motions
Text objects
Operators on text objects
Operators on motions
F{ch}
/{pat}
[}
t{ch}
9B
3/{pat}
b
T{ch}
{
j
w
[}
l
g_
5[(
%
{
0F{ch}
w
T{ch}
[}
10
k
[}
%
1G
[{
5k
0
/{pat}
1/{pat}
2l
?{pat}
g_
1h
h
t{ch}
4F{ch}
0$
t{ch}
$
B
l
g_
^
1{
2?{pat}
G
^
k
1[(
$
w
h
^
/{pat}
gg
w
g_
1e
[)
t{ch}
6/{pat}
t{ch}
iw
ab
a}
aw
it
i<
i[
i'
aw
i"
a"
ip
iB
i[
a]
a>
iW
i'
a{
i'
a[
a>
a"
i'
i{
i)
i)
it
ab
i>
iW
a'
at
i{
is
iW
aW
a>
i[
a{
i'
aB
ip
a}
a]
i"
a<
iW
ib
a(
iw
i"
a{
a<
at
a{
ip
a}
a"
as
i)
a{
ap
a<
<aW
5gua{
>4aW
<at
8>iW
gUis
>aW
3g@aw
g@i)
<0ap
~a(
y5a]
<0i)
>3ip
g@a}
da"
gUi[
gq1i{
<i]
2g~ib
g@i]
gua`
gUi(
~8a}
<is
d7a[
g~i(
d5aw
g~a}
4diW
gqiw
<4i{
<is
g~iW
daW
<aB
~a)
c5a<
gUaB
ca}
9g@as
gu0a(
~2a"
ya<
gUa'
~9a`
y2is
gU2i)
c4i'
7ya"
guaB
0<i'
c9i'
guib
g@a`
9g@a>
6c9ip
2g@2ab
yi[
1c3iW
c3ap
8gUi`
gqit
g@i[
0d{
9gu[)
2yT{ch}
8g~?{pat}
2ce
0gUb
8g~j
2c[(
3>}
3>gg
6>G
6~j
0d[{
8gU{
4c[}
4~h
7<l
7g@^
6~/{pat}
7yh
3<}
1<F{ch}
4cw
1gu[)
0cB
7g~[{
3g~[{
7yk
3~k
5g~[)
5g@G
8yt{ch}
0g@e
8>0
6g~[(
5dB
9>T{ch}
0gU{
3<w
1y?{pat}
4g@[{
5~b
2<^
4>w
4y{
1<e
8c[}
6c{
2g~/{pat}
3cj
8cT{ch}
3>%
0<F{ch}
4gqB
3gqT{ch}
3dk
5>[)
2gqh
8ce
7~gg
3cl
4c^
4c%
1gq$
References/further reading
- A vim Tutorial and Primer
- Best of Vim Tips
- Learn to speak vim — verbs, nouns, and modifiers!
- The compositional nature of Vim
- The grammar of Vim
- Vim Cheat Sheet for Programmers
- Vim Cheat Sheet
- Vim Commands Cheat Sheet
- Vim Grammar
- Vim Text Objects: The Definitive Guide
- Vim documentation
- Vim for PHP programmers
- Your problem with Vim is that you don’t grok vi