This is a remix of http://vimsheet.com.
This cheat sheet assumes that you already know how Vim works, conceptually speaking, but want a quick reference for the default key mappings and a way to remind yourself of some of the more clever things that Vim is capable of.
In light of that, this sheet aims to be fairly thorough in its coverage, but also to illustrate patterns in Vim's design that can make commands easier to remember.
Everything here should be compatible with stock Vim, and assumes that the reader
is more interested in maintaining compatibility with any given server they SSH into
than they are in having a super-tricked-out local development environment.
In practice, this means that plugins and .vimrc
hacks are suggested to be used
only when they would not conflict with the muscle memory one builds up
making edits using stock vim.
From the author: I add content and revise sections of the original cheat sheet as I delve into each feature and absorb those parts of the manual. As you might expect, I am making this to be a useful reference for myself first and foremost.
The notational convention here is to use the same syntax for combination shortcuts
as would be used when writing a key mapping or macro.
That is, instead of Ctrl+r
or CTRL-R
, we will write <C-r>
.
See also :help key-notation
.
<C-...>
- Control-key<S-...>
- Shift-key<A-...>
- Alt-key<M-...>
- Meta-key<D-...>
- Command-key (macOS)Any motion (or command) can be prefixed with a number [count]
to iterate it that many times.
Words separated by: | punctuation | whitespace |
---|---|---|
Start of next word | w |
W |
End of next word | e |
E |
Beginning of previous word | b |
B |
End of previous word | ge |
gE |
H
, M
, L
- Screen-relative line navigation: Home (top), Middle, Last (bottom)zt
, zz
, zb
- Scroll cursor location to top, middle, bottom0
(zero) - start of line^
- first non-blank character of line (similar to 0w
and _
, but don't forget about I
!)$
- end of lineg_
- last non-blank character of linef[char]
- Seek forwards to the next instance of [char]
F[char]
- Seek backwards to the next instance of [char]
t[char]
- Seek forwards until adjacent to the next instance of [char]
T[char]
- Seek backwards until adjacent to the next instance of [char]
;
- Repeat the latest seek command once, or twice if the cursor would not move.,
- As above, but in the reverse direction.
f
or t
!(
)
- go backward/forward by sentences{
}
- go backward/forward by paragraph (blank lines)%
- go to next (or matching) ()
, []
, {}
-
- Like k
, but on the first non-blank char of the line+
- Like j
, but on the first non-blank char of the line_
- Like +
, but with -1 to [count]
<C-d>
- move down half a page<C-u>
- move up half a page[num]G
, :[num]<Enter>
- go to line number [num]
G
- go the bottom of the pagegg
- go to the top of the page<C-o>
- Jump to previous (older) cursor position<C-i>
or <Tab>
- Jump to newer cursor position:ju
- Show jumplistBe sure to see Registers below for how they work with yanked and deleted text.
p
- Put (paste) the unnamed register after the cursor (or current line)P
- Put (paste) the unnamed register before the cursor (or current line)Put cursor/line behavior depends on whether the the register contains characterwise or linewise text.
lowercase | uppercase | |
---|---|---|
Insert (i) | i - insert in front of cursor |
I - ... in front of the first non-whitespace in the line |
Append (a) | a - insert after the cursor |
A - ... at the end of the line |
Open (o) | o - insert to a new line below the cursor |
O - ... above the cursor |
Substitute (s) | s - remove char at the cursor first |
S - Clear entire line first (same as cc ) |
x
- Remove the character under the cursorX
- Remove the character to the left of the cursorr[char]
- replace a single character with the specified [char]
(does not use Insert mode)R
- Enter REPLACE mode, which is like INSERT mode but with overtypeJ
- Join current line to the line belowr<CR>
- "Split line" at cursor, assuming space selecteds<CR>
- As above, but remain in insert mode<C-a>
- Increment the number under the cursor<C-x>
- Decrement, as above
g
to affect a range, with increments increasing linewise.Yank (y) | Delete (d) | Change (c) - Delete and enter insert mode | |
---|---|---|---|
[noun] |
y[noun] |
d[noun] |
c[noun] |
entire line | yy or Y |
dd |
cc |
from cursor to the end of the line | y$ |
D |
C |
A noun can be a motion, like 2W
(two whitespace-delimited words) or a text object like it
(inner tag block).
See also Text Objects.
>[noun]
, <[noun]
- Shift [noun]
forward/backward by one 'shiftwidth'
.>>
, <<
- Shift line forward/backward by one 'shiftwidth'
.u
- undoU
- Undo entire line<C-r>
- redo.
- repeat last change<C-[>
or <Esc>
- exit insert mode<C-r>[register]
- Insert at the cursor from the register indicated (no "
prefix)v
- starts visual mode
h
, j
, k
, l
etc.) and can then do a command (such as y
, d
, or c
)V
- starts linewise visual mode<C-v>
- start visual block modegv
- After doing a command that leaves you in normal mode, return to the same visual mode with the same selection<C-[>
or <Esc>
- exit visual modeo
- Move cursor to opposite corner of the visual selectionO
- In VISUAL BLOCK mode, move cursor to opposing corner within the same lineType any of these while some text is selected to apply the action
v
, V
, <C-v>
- Switch to a different visual mode, as above. Match current mode to return to normal mode.y
- yank (copy) selected textd
- delete selected textc
- delete the selected text and go into insert mode (like c does above)p
- Replace with registerr[char]
- Replace selection with [char]
I
- Block insertA
- Block appendU
, u
- Uppercase/lowercaseJ
- Join lines>
, <
- Shift right/left by one 'shiftwidth'
(don't forget about [count]
prefix):
- Enter command mode with '<,'>
already prepended,
which is a range of automatic marks representing the current selection.:norm [commands]
- Execute a normal mode command sequence on the visual selection.
This can include inserts!<C-v>[keystroke]
- While in command mode (or insert mode),
prefix a control character that you want inserted literally.:norm I"<C-v><Esc>A"
:'<,'>norm I"^[A"
.
The ^[
sequence will appear in a different color if your terminal supports it.:
) on the range defined by the start and end
of visual selection marks ('<,'>
), run a normal mode command on each line (norm
);
that command says: enter insert mode at the start of the line (I
), insert a quote character ("
),
enter the escape control character (^[
) to leave insert mode
(remember <Esc>
and <C-[>
are synonymous, and ^
is a shorthand for Control-key),
append to line (A
), and insert a quote character ("
).:norm
technically adds the final <Esc>
at the end of the insert automatically,
so after running the command, you will not remain in insert mode.Prefix most yank/delete/change commands with "[reg]
where [reg]
is a specific register to copy to or from.
:reg
- View the current registers".
- Last-inserted text. Useful when you don't want to repeat an entire edit, but you do want to reuse its content.""
- The unnamed register: default source of puts (p, P), acts like a pointer to the most recently written register"-
- Default register for deletes less than a full line"0
- Default destination of yanks"1
- Default destination of deletes of at least a full line; also some specific motion nouns"[2-9]
- Numbered history registers; shifted into from "1
whenever it is written to"[a-z]
, "[A-Z]
- Named registers. Use uppercase variants to append."+
- System pasteboard; access to copy/paste from the system.Objects must be prefixed with a
or i
, for "a" ("an") object or "inner" object.
w
, W
- word or Word (as above)s
- Sentencep
- Paragraph"
, '
, `
- Quoted strings (only works within one line)(
, )
, or b
- Parenthesized block[
or ]
- Bracketed block{
or }
- Braced blockt
- XML-style tag block<
or >
- XML-style tag itselfIn practice, use these objects in context of another command, with the a/i prefix, like cib
.
:w
- write (save) the file, but don't exit:wq
- write (save) and quit:q
- quit (fails if anything has changed):q!
- quit and throw away changes:wqa
- Write and quit all open tabs (thanks Brian Zick):x
- Write and exit, but only write if there are changes:!<shell command>
- Run a shell command on the default shell. Output will appear in a new window:<some command>|<some other command>
- Run multiple vim commands by separating them with the |
character%
- Represents the current file path
:w|util %
:nnoremap <Leader>r :w|util %<CR>
- Set a leader-r command to save the file and run a shell command on it*
- Search forward for the word nearest to the cursor#
- Search backward for the word nearest to the cursor/pattern
- search for pattern?pattern
- search backward for patternn
- repeat search in same directionN
- repeat search in opposite direction:%s/old/new/g
- replace all old with new throughout file (gn is better though):%s/old/new/gc
- replace all old with new throughout file with confirmations:e filename
- Edit a file:tabe
- Make a new tabgt
- Go to the next tabgT
- Go to the previous tab:vsp
- vertically split windowsctrl+ws
- Split windows horizontallyctrl+wv
- Split windows verticallyctrl+ww
- switch between windowsctrl+wq
- Quit a window:enew
- edit a new, unnamed buffer:ls
- list all open buffers:bn
- go to the next buffer:bp
- go to the previous buffer:b[N]
- goto buffer numbered N
:b2
will bring buffer numbered 2 to your tab:b filename-prefix
- goto buffer with the corresponding filename-prefixCtrl+^
- Toggle between current and last bufferCtrl+o
- Go to the previous buffer you were inCtrl+i
- Reverse the effect of Ctrl+o
Marks allow you to jump to designated points in your code.
m[a-z]
- Set mark [a-z]
at cursor position[A-Z]
sets a global mark and will work between files
'V
as a shortcut to your .vimrc
file.'[a-z]
- move the cursor to the start of the line where the mark was set''
- go back to the previous jump location:help [topic]
- Search help pages for topic
[topic]
can be a keystroke like CTRL-R
(shorthand like ^r
is also accepted)v_
- Visual mode prefixi_
- Insert mode prefixc_
- Command mode prefix<C-]>
- Jump to keyword<C-t>
- Jump back (uses tag-stack
):help help-summary
for more tipsOn macOS, Vim's included .vimrc
file turns on a lot of convenient features like mouse support.
You might want to make some of the following tweaks.
Remember that the <Leader>
key, by default, is \
.
.vimrc
on Saveif has("autocmd")
autocmd BufWritePost .vimrc source $MYVIMRC
endif
set number
set relativenumber
set listchars=tab:\|\ ,space:ยท
set list
" Set a shortcut to toggle visible whitespace on and off.
nmap <Leader>l :set list!<CR>
" Must be double-escape to avoid conflicting with mouse scroll
nmap <Esc><Esc>:noh<CR><Esc>
No, not Escape. You don't actually need to use escape if you use <C-[>
instead.
On the machine that Bill Joy originally used to write vi
,
the control key was placed where caps lock is on most keyboards today.
Escape was placed where the tab key is today, so if you want to be totally based,
you could try swapping those.
Some people also like mapping jk
to exit insert mode.
The problem with this is that you would have to accomplish it in your .vimrc
,
and this would violate our stated intention of not messing with muscle memory
when remoting into other machines.
The Caps Lock/Tab remaps above can be accomplished on the operating system level,
or better yet on the keyboard hardware level, so they don't depend on the particular
.vimrc
file in the environment you are interacting with.