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:

mode description
Normal For moving around and editing the file
Insert For typing text
Replace Basically like INSERT mode from DOS, where you overwrite what's on the screen
Visual For selecting characters of text
Visual Line For selecting lines of text
Visual Block For selecting rectangular blocks of text

Moving between modes

command description
esc or ctrl+[ Enter Normal mode
i Insert at cursor (enters Insert mode)
I Insert at the beginning of the line (enters Insert mode)
a Insert after cursor (enters Insert mode)
A Insert at the end of the line (enters Insert mode)
R Overwrite what's on the screen (enters Replace mode)
v Select characters of text, starting at the cursor (enters Visual mode)
V Select lines of text, starting with the current line (enters Visual Line mode)
ctrl+v Select rectangular blocks of text (enters Visual Block mode)
gi Jump to the last place you were in insert mode (enters Insert mode)

Saving & quitting in normal mode

command description
:w Save (write)
:q Quit vim
:wq Save & quit
:q! Quit without saving changes
:qa Close all tabs and quit vim
:wqa Write out all work, close all tabs, and quit vim
ZZ Same as :wq
ZQ Same as q!
:close Close the current window (a.k.a., space allocated for a loaded buffer

Opening files

command description
:e filepath Open a file
:e! Reload the current file from disk, discarding changes in memory
:r filename Read in and insert a file's contents inside the current file, at the position of the cursor
:r !command Read in the STDOUT of a shell command

Moving around

command description
k Up
j Down
h Left
l Right
ctrl+b Page up
ctrl+f Page down
ctrl+u Half page up
ctrl+d Half page down
H Go to the first line on the screen
M Go to the middle line on the screen
L Go to the last line on the screen
0 Beginning of the line
^ First non-whitespace character on the line
$ End of the line
w Go to the beginning of the next word, where punctuation are considered their own word
W Go to the beginning of the next word, where spaces separate words
e Go to the end of the next word, where punctuation are considered their own word
E Go to the end of the next word, where spaces separate words
b Go to the beginning of the previous word, where punctuation are considered their own word
B Go to the beginning of the previous word, where spaces separate words
ge Go to the end of the previous word, where punctuation are considered their own word
gE Go 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
fc Go to the next occurance of character c on the line
Fc Go to the previous occurance of character c on the line
tc Same as fc, but one character before it
Tc Same 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
gg Beginning of the file
G End of the file
:n or nG Go to line number n
'. Go to the last edit
o In Visual or Visual Line mode, move your cursor to the other end of the selected area
O In Visual Block mode, move your cursor to the other corner of the selected area

Editing in normal mode

command description
x or delete Delete the character under, and then after, the cursor
X or backspace Delete the character before the cursor
o Insert line below
O Insert line above
rc Replace the character under the cursor with character c
xp Swap two letters (i.e., delete and paste)
s Delete the current character and switch to insert mode (Substitute)
dw Delete 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
daw Delete an entire word, including the subsequent space
diw Delete an entire word, but leave the spaces before and after it
das Delete a sentence, including the space after the period .
dis Delete a sentence, but leave the space after the period .
dap Delete a paragraph, including the blank line separating it from the next paragraph
dip Delete 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
dat Delete around an HTML/XML tag <this>and</this>, including the tags
dit Delete 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
cw Delete from the cursor to the end of the word, excluding the subsequent space, and switch to insert mode
caw Delete an entire word, including the subsequent space, and switch to insert mode
ciw Delete 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 S Delete 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
J Join the next line to the end of the current line (it deletes the newline character at the end of the current line)
g This 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
u Change the selected text to lowercase
U Change 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.
command description
D Cuts from the current character to the end of the line to the clipboard
C Cuts from the current character to the end of the line to the clipboard, and then switches to insert mode
dd Cuts the entire line you're on to the clipboard
yy Copies 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
p Paste on the line below the cursor
P Paste on the line above the cursor
ctrl+r, c Paste in insert mode, from the register c
"0p 0 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
:reg View all of the different registers of yanked text
:set paste Turn 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

command description
shift+v Enter 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+v Enter visual block mode, where you can select a rectangle of text
gv Re-select last selected area

Indenting

command description
= 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

command description
u Undo
:undo Undo
:redo Redo
ctrl+r Redo

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.

command description
mc Mark the cursor's character, and the line that it's on, into the mark register represented by character c
'c Go to the line that mark c is on
`c Go to the character that mark c is on
:marks Show 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

command description
/query Search from top to bottom. In Visual Mode, select up to the first character of query.
?query Search from bottom to top. In Visual Mode, select up to the first character of query.
n The "next" thing (i.e., when searching)
N The "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/g Find & 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/gi Find & replace in entire file, ignoring case when finding
:%s/tofind/toreplace/gI Find & replace in entire file, not ignoring case when finding
:%s/tofind/toreplace/gc Find & replace in entire file, confirming before each change
:%s/tofind/toreplace/ge Find & replace in entire file, ignoring errors
:1,10s/tofind/toreplace/g Find & replace in lines 1 through 10
:g/foo/ s/bar/fuzz/g On lines that contain foo, replace bar with fuzz
\ Turn off search highlighting (custom mapping)

Searching multiple files

command description
:vimgrep /^I am/ ./*.markdown Look for any lines that start with I am in .markdown files in the directory vim was started from
:vimgrep /^I am/ ./**/*.markdown Look 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)
:cn Next result from :vimgrep
:cp Previous 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.

command description
. 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.
command description
q: Show command history
q/ or q? Show search history
enter Run the selected command
ctrl+c, w Close the history window

Macros

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

command description
qc Start recording keystrokes into the c macros register (you can use any character, not just c)
q Stop recording
@c Run 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.

command description
:ab List all of your abbreviations
:una shortcut Unabbreviate (un-register) the shortcut (use this if the shortcut is something you literally wish to type)

Line numbers

command description
:set number Turn on line numbering
:set nonumber Turn 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

command description
:ls List 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 number Switch to the buffer with that number in the current pane
number, ctrl+6 Switch to the buffer with that number in the current pane
:b# Switch to the alternate buffer
:bn Switch to the next buffer
:bp Switch to the previous buffer
:bd number Close the buffer with that number

Panes

command description
ctrl+w, s Create a horizontal split
ctrl+w, v Create a vertical split
ctrl+w, w Go to the "next" window
ctrl+w, arrow key Put your cursor in the next pane to the left, right, top, or bottom
ctrl+w, q Close (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

command description
:tabs List all tabs, where you can also see which files (buffers) and panes are inside each tab
:tabnew Makes a new tab
:tabclose Closes the current tab
:tabn or gt Go to the next tab
:tabp or gT Go to the previous tab
ngt Go to the tab in position n (1-based index)
:tabm n Move the current tab to the n'th position at the top of the screen (0-based index)
:tabm Move the current tab to the last position at the top of the screen
ctrl+w, T Move the current pane into its own tab

Linux in vim

command description
:!command Runs a Linux command from inside vim

Using the mouse

command description
hold option When :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.

command description
:CtrlP Open CtrlP
ctrl+p Open CtrlP
ctrl+v Open the selected file in a vertical split (CtrlP must be active for this to work)
ctrl+x Open the selected file in a horizontal split (CtrlP must be active for this to work)
:CtrlPClearCache Clear 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.

command description
? Shows NerdTree help
r Refreshes the file list
C Set the selected directory as the new root
I Show/hide hidden files (toggle)
m Select 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.