After 9 years of TextMate, I’m switching to vim. I’m writing this cheat sheet as I learn. Check back often.

N.B. Keep in mind, everything in vim is case sensitive.

Modes

In vim there are six modes:

modedescription
NormalFor moving around and editing the file
InsertFor typing text
ReplaceBasically like INSERT mode from DOS, where you overwrite what’s on the screen
VisualFor selecting characters of text
Visual LineFor selecting lines of text
Visual BlockFor selecting rectangular blocks of text

Moving between modes

commanddescription
esc or ctrl+[Enter Normal mode
iInsert at cursor (enters Insert mode)
IInsert at the beginning of the line (enters Insert mode)
aInsert after cursor (enters Insert mode)
AInsert at the end of the line (enters Insert mode)
ROverwrite what’s on the screen (enters Replace mode)
vSelect characters of text, starting at the cursor (enters Visual mode)
VSelect lines of text, starting with the current line (enters Visual Line mode)
ctrl+vSelect rectangular blocks of text (enters Visual Block mode)
giJump to the last place you were in insert mode (enters Insert mode)

Saving & quitting in normal mode

commanddescription
:wSave (write)
:qQuit vim
:wqSave & quit
:q!Quit without saving changes
:qaClose all tabs and quit vim
:wqaWrite out all work, close all tabs, and quit vim
ZZSame as :wq
ZQSame as q!
:closeClose the current window (a.k.a., space allocated for a loaded buffer

Opening files

commanddescription
:e filepathOpen a file
:e!Reload the current file from disk, discarding changes in memory
:r filenameRead in and insert a file’s contents inside the current file, at the position of the cursor
:r !commandRead in the STDOUT of a shell command

Moving around

commanddescription
kUp
jDown
hLeft
lRight
ctrl+bPage up
ctrl+fPage down
ctrl+uHalf page up
ctrl+dHalf page down
HGo to the first line on the screen
MGo to the middle line on the screen
LGo to the last line on the screen
0Beginning of the line
^First non-whitespace character on the line
$End of the line
wGo to the beginning of the next word, where punctuation are considered their own word
WGo to the beginning of the next word, where spaces separate words
eGo to the end of the next word, where punctuation are considered their own word
EGo to the end of the next word, where spaces separate words
bGo to the beginning of the previous word, where punctuation are considered their own word
BGo to the beginning of the previous word, where spaces separate words
geGo to the end of the previous word, where punctuation are considered their own word
gEGo to the end of the previous word, where spaces separate words
(Go to the beginning of the previous sentence
)Go to the beginning of the next sentence
{Go to the beginning of the previous paragraph
}Go to the beginning of the next paragraph
fcGo to the next occurance of character c on the line
FcGo to the previous occurance of character c on the line
tcSame as fc, but one character before it
TcSame as Fc, but one character before it
;Next result from fc, Fc, tc, or Tc (don’t try typing these multiple times; use ; to repeat)
,Next result from fc, Fc, tc, or Tc in the opposite direction
%Jump between the beginning and end of paranthesis, brackets, braces, greater than/less than
ggBeginning of the file
GEnd of the file
:n or nGGo to line number n
'.Go to the last edit
oIn Visual or Visual Line mode, move your cursor to the other end of the selected area
OIn Visual Block mode, move your cursor to the other corner of the selected area

Editing in normal mode

commanddescription
x or deleteDelete the character under, and then after, the cursor
X or backspaceDelete the character before the cursor
oInsert line below
OInsert line above
rcReplace the character under the cursor with character c
xpSwap two letters (i.e., delete and paste)
sDelete the current character and switch to insert mode (Substitute)
dwDelete from the cursor to the end of the word, including the subsequent space
d)Delete from the cursor to the beginning of the next sentence
d}Delete from the cursor to the end of the current paragraph
da"Delete inside quotes, including the quotes
di"Delete inside quotes, but leave the quotes
dawDelete an entire word, including the subsequent space
diwDelete an entire word, but leave the spaces before and after it
dasDelete a sentence, including the space after the period .
disDelete a sentence, but leave the space after the period .
dapDelete a paragraph, including the blank line separating it from the next paragraph
dipDelete a paragraph, but leave the blank line separating it from the next paragraph
dab or da( or da)Delete an entire parenthetical () block, including the parentheses
dib or di( or di)Delete an entire parenthetical () block, but leave the parntheses
da< or da>Delete around an angle bracket’s contents <>, including the angle brackets themselves
di< or di>Delete inside an angle bracket’s contents <>, leaving the angle brackets
datDelete around an HTML/XML tag <this>and</this>, including the tags
ditDelete around an HTML/XML tag <this>and</this>, leaving the tags
daB or da{ or da}Delete an entire braces {} block, including the braces
diB or di{ or di}Delete an entire braces {} block, but leave the braces
da[ or da]Delete a brackets block, including the brackets
di[ or di]Dlete a brackets block, but leave the brackets
cwDelete from the cursor to the end of the word, excluding the subsequent space, and switch to insert mode
cawDelete an entire word, including the subsequent space, and switch to insert mode
ciwDelete an entire word, but leave the spaces before and after it, and switch to insert mode
...All of the above di* and da* commands work with c instead of d, which will switch to insert mode after the command is run
cc or SDelete the current line’s contents, but not the newline, and switch to insert mode (Substitute the current line)
c$Delete to the end of the line, but not the newline, and switch to insert mode
JJoin the next line to the end of the current line (it deletes the newline character at the end of the current line)
gThis is one of the hardest vim keystrokes to explain. The formula for using g is g + action + motion. g is useful because you can avoid going into visual mode. Think of it as “go.” For example, gu10j would make 10 lines below the cursor lowercase. If you did this using visual mode, you’d have to type shiftv, 10ju, escape.
g0, g^, or g$Like ‘0’, ‘^’, and ‘$’, but respects line wraps
~Toggle the case of the character under the cursor
uChange the selected text to lowercase
UChange the selected text to uppercase

Copying and pasting

  • Instead of “copying”, vim calls it “yanking”
  • Sometimes instead of “pasting”, vim calls it “putting”
  • I use these terms interchangably, herein
  • Unlike Windows, Mac, and Linux, which have one system clipboard for cut and copied text, vim has the concept of multiple clipboards called registers. Each register can be yanked into or pasted out of, and is identified with a single character. To accomplish this, prefix the yanking or pasting commands below with "c, where c is the register name you wish to yank into or paste out of. For example, "fdd will delete the current line into the register f. You could then paste the line by typing "fp.
commanddescription
DCuts from the current character to the end of the line to the clipboard
CCuts from the current character to the end of the line to the clipboard, and then switches to insert mode
ddCuts the entire line you’re on to the clipboard
yyCopies the entire line you’re on to the clipboard
y...Copy any block, like y3w for copy 3 words, or yip to yank inside a paragraph
pPaste on the line below the cursor
PPaste on the line above the cursor
ctrl+r, cPaste in insert mode, from the register c
"0p0 is a somewhat special register that refers to the last explicitly yanked item. This avoids text yanked with D, dd, and other actions that yank as a “secondary” function. "0p will paste the last explicitly yanked item.
".p. is another special register: it contains what you last typed. This command will paste from it
""p" is another special register: it is the “unnamed” register where text goes if you don’t specify otherwise. This command will paste from it
"+p+ is another special register: it is the system clipboard
:regView all of the different registers of yanked text
:set pasteTurn on “paste mode” before you paste from your operating system…
:set nopaste… and turn it off when you are done. (I never paste this way; I prefer to use the * register when pasting from OS X, i.e., paste with "*p)

Selecting text

commanddescription
shift+vEnter visual mode, selecting the current line; allows additional lines to be selected by using the up and down arrow keys, or j and k; to select with more granularity, press v
ctrl+vEnter visual block mode, where you can select a rectangle of text
gvRe-select last selected area

Indenting

commanddescription
=Fix indentation on selected text
==Fix indentation on current line
>indent in the selected text by one level
>>indent in the current line by one level
<indent out the selected text by one level
<<indent out the current line by one level
>a{indent a {} block
>i{Indent inside a {} block
...Any chunk (paragraphs p, parenthesis (, tags t, braces {, blocks [, etc.) can be indented with >a or >i

Undoing and redoing

commanddescription
uUndo
:undoUndo
:redoRedo
ctrl+rRedo

Marking (bookmarking)

vim marks let you mark (or “bookmark”) a character on a line, and return to it later. Each mark can be referenced by a character, like the yanking and macro registers.

commanddescription
mcMark the cursor’s character, and the line that it’s on, into the mark register represented by character c
'cGo to the line that mark c is on
``c`Go to the character that mark c is on
:marksShow all mark registers

Searching & replacing

The general formula of searching and replacing in vim is: range_to_operate_on/regex_to_find/regex_to_replace/regex_options

commanddescription
/querySearch from top to bottom. In Visual Mode, select up to the first character of query.
?querySearch from bottom to top. In Visual Mode, select up to the first character of query.
nThe “next” thing (i.e., when searching)
NThe “previous” thing
*Go to the next instance of the word under the cursor, or whatever the “next” thing is
#Go to the previous instance of the word under the cursor, or whatever the “previous” thing is
:%s/tofind/toreplace/gFind & replace in entire file (%s is a range specifying the entire file)
:%s/tofind/toreplace/Find & replace in entire file, but only the first occurance on each line (g at the end replaces all matches on a line)
:%s/tofind/toreplace/giFind & replace in entire file, ignoring case when finding
:%s/tofind/toreplace/gIFind & replace in entire file, not ignoring case when finding
:%s/tofind/toreplace/gcFind & replace in entire file, confirming before each change
:%s/tofind/toreplace/geFind & replace in entire file, ignoring errors
:1,10s/tofind/toreplace/gFind & replace in lines 1 through 10
:g/foo/ s/bar/fuzz/gOn lines that contain foo, replace bar with fuzz
\Turn off search highlighting (custom mapping)

Searching multiple files

commanddescription
:vimgrep /^I am/ ./*.markdownLook for any lines that start with I am in .markdown files in the directory vim was started from
:vimgrep /^I am/ ./**/*.markdownLook for any lines that start with I am in .markdown files in the directory, or any subdirectories, vim was started from (i.e., recursive search)
:cnNext result from :vimgrep
:cpPrevious result from :vimgrep

Repeating commands

In vim, you can repeat almost any command by prefixing it with a number. For example, k moves the cursor up by 1 line; 10k moves the cursor up 10 lines.

commanddescription
.Repeat the last command

History

  • When you open a history window, you can move through commands with arrow keys or hjkl
  • A history window is editable. This means you can use all of the vim commands you know and love, like i to insert or w to move forward by word. This is a great example of how badass vim is.
commanddescription
q:Show command history
q/ or q?Show search history
enterRun the selected command
ctrl+c, wClose the history window

Macros

Macros are a sequence of keystrokes that you can execute automatically.

commanddescription
qcStart recording keystrokes into the c macros register (you can use any character, not just c)
qStop recording
@cRun the macro c

Abbreviations

Abbreviations in vim are little snippets that expand when typed, much like TextExpander for OS X. I recommend you set abbreviations in your .vimrc file.

commanddescription
:abList all of your abbreviations
:una shortcutUnabbreviate (un-register) the shortcut (use this if the shortcut is something you literally wish to type)

Line numbers

commanddescription
:set numberTurn on line numbering
:set nonumberTurn off line numbering

What is the difference between buffers, panes, windows, and tabs?

  • A buffer is just that: a buffer of text in memory. When you load a file into vim, a buffer is created for it. A buffer may represent a file on disk.
  • A pane is an area on the screen to show a buffer.
  • A window is another word for a pane.
  • A tab holds one or more panes. vim can have multiple tabs.

Buffers

commanddescription
:lsList open buffers. % is the current buffer. # is the alternate buffer (see below). Any buffers with a + are modified and have not been saved to disk.
:b numberSwitch to the buffer with that number in the current pane
number, ctrl+6Switch to the buffer with that number in the current pane
:b#Switch to the alternate buffer
:bnSwitch to the next buffer
:bpSwitch to the previous buffer
:bd numberClose the buffer with that number

Panes

commanddescription
ctrl+w, sCreate a horizontal split
ctrl+w, vCreate a vertical split
ctrl+w, wGo to the “next” window
ctrl+w, arrow keyPut your cursor in the next pane to the left, right, top, or bottom
ctrl+w, qClose (quit) a window
ctrl+w, +Make the pane taller
ctrl+w, -Make the pane shorter
ctrl+w, >Make the window wider
ctrl+w, <Make the window narrower

Tabs

commanddescription
:tabsList all tabs, where you can also see which files (buffers) and panes are inside each tab
:tabnewMakes a new tab
:tabcloseCloses the current tab
:tabn or gtGo to the next tab
:tabp or gTGo to the previous tab
ngtGo to the tab in position n (1-based index)
:tabm nMove the current tab to the n‘th position at the top of the screen (0-based index)
:tabmMove the current tab to the last position at the top of the screen
ctrl+w, TMove the current pane into its own tab

Linux in vim

commanddescription
:!commandRuns a Linux command from inside vim

Using the mouse

commanddescription
hold optionWhen :set mouse=a is enabled, temporarily treats the mouse as if it wasn’t. (OS X only)

Plugins

vim is a masochistic venture without plugins. Here are the ones I strongly recommend:

CtrlP

CtrlP is a vim plugin that lets you “quick find” files, like command+t in Textmate and Sublime.

commanddescription
:CtrlPOpen CtrlP
ctrl+pOpen CtrlP
ctrl+vOpen the selected file in a vertical split (CtrlP must be active for this to work)
ctrl+xOpen the selected file in a horizontal split (CtrlP must be active for this to work)
:CtrlPClearCacheClear the CtrlP cache and rebuild; useful if the contents on disk change

NerdTree

NerdTree is a vim plugin that provides a Windows Explorer-style file list, like the file drawer in Textmate.

commanddescription
?Shows NerdTree help
rRefreshes the file list
CSet the selected directory as the new root
IShow/hide hidden files (toggle)
mSelect a file in NerdTree and press m to show the nerd tree menu. This menu lets you add, move, delete, or copy files.

.vimrc

Unfortunately, I cannot share my .vimrc file as it contains confidential techniques and information.