Vim Keyboard Shortcuts
Vim is a modal editor: you move with motions, change text with operators, and enter insert mode only to type. This track drills those keyboard shortcuts — hjkl, text objects, splits, tabs, search, vimdiff, and quickfix — as real key sequences, not trivia. The same bindings transfer to Neovim and most Vim emulation layers.
Command Reference
motion
| Command | Description |
|---|---|
$ | Move to the end of the current line. |
gg | Go to the first line of the file. |
G | Go to the last line of the file (or line number with a count). |
w | Jump to the start of the next word. |
b | Jump to the start of the previous word. |
e | Jump to the end of the current or next word. |
j | Move the cursor one line down. |
k | Move the cursor one line up. |
0 | Move to the beginning of the current line. |
l | Move the cursor one character to the right. |
h | Move the cursor one character to the left. |
W | Jump to the start of the next WORD (whitespace-delimited). |
B | Jump to the start of the previous WORD (whitespace-delimited). |
^ | Move to the first non-blank character on the line. |
Ctrl+f | Scroll down one screen (page forward). |
Ctrl+b | Scroll up one screen (page backward). |
Ctrl+d | Scroll down half a screen. |
Ctrl+u | Scroll up half a screen. |
{ | Jump to the beginning of the previous paragraph or block. |
} | Jump to the beginning of the next paragraph or block. |
% | Jump to the matching bracket, brace, or parenthesis. |
f<char> | Find the next occurrence of a character on the current line. |
; | Repeat the last f, F, t, or T motion in the same direction. |
H | Move to the top line visible on screen. |
L | Move to the bottom line visible on screen. |
ge | Jump to the end of the previous word. |
F<char> | Find the previous occurrence of a character on the current line. |
t<char> | Move to just before the next occurrence of a character on the line. |
, | Repeat the last f, F, t, or T motion in the opposite direction. |
| | Move to the first column of the current line. |
zz | Center the current line in the window. |
M | Move to the middle line visible on screen. |
T<char> | Move to just after the previous occurrence of a character on the line. |
zt | Scroll the current line to the top of the window. |
zb | Scroll the current line to the bottom of the window. |
insert
| Command | Description |
|---|---|
o | Open a new line below and enter insert mode. |
Escape | Return to normal mode from insert or visual mode. |
i | Enter insert mode before the cursor. |
a | Enter insert mode after the cursor. |
I | Enter insert mode at the beginning of the line. |
A | Enter insert mode at the end of the line. |
O | Open a new line above and enter insert mode. |
s | Substitute: delete the character under the cursor and enter insert mode. |
S | Delete the current line and enter insert mode. |
gi | Resume insert mode at the last insert position. |
ex
| Command | Description |
|---|---|
:wq | Write the buffer and quit. |
:q | Quit the current buffer (fails if there are unsaved changes). |
:help | Open Vim's built-in help documentation. |
:w | Write (save) the current buffer to disk. |
:set number | Show line numbers in the margin. |
:q! | Force quit without saving changes. |
:e <file> | Edit a file in a new buffer, or reload the current file. |
:sp | Split the window horizontally and edit a file. |
:vs | Split the window vertically and edit a file. |
:qa | Close all files (fails if any buffer has unsaved changes). |
:qa! | Force quit all files without saving. |
:wqa | Write all changed buffers and quit. |
:sort | Sort lines in the current range or whole buffer. |
:ter | Open a terminal window. |
edit
| Command | Description |
|---|---|
x | Delete the character under the cursor. |
dd | Delete the current line. |
yy | Yank (copy) the current line. |
p | Put (paste) the yanked text after the cursor or below the line. |
D | Delete from the cursor to the end of the line. |
cc | Change the entire line: delete it and enter insert mode. |
C | Change from the cursor to the end of the line. |
r<char> | Replace the character under the cursor with the next typed character. |
J | Join the current line with the line below. |
P | Put (paste) the yanked text before the cursor or above the line. |
>> | Indent the current line one level to the right. |
<< | Unindent the current line one level to the left. |
. | Repeat the last change. |
~ | Toggle the case of the character under the cursor. |
R | Enter Replace mode and overwrite characters as you type. |
xp | Swap the character under the cursor with the next character. |
ddp | Swap the current line with the line below. |
Ctrl+a | Increment the number under or after the cursor. |
Ctrl+x | Decrement the number under or after the cursor. |
X | Delete the character before the cursor. |
dw | Delete from the cursor to the start of the next word. |
"+y | Yank the current selection or motion into the system clipboard. |
& | Repeat the last substitute command. |
"+p | Paste after the cursor from the system clipboard. |
tab
| Command | Description |
|---|---|
gt | Go to the next tab page. |
gT | Go to the previous tab page. |
:tabe | Open a file in a new tab page. |
:tabc | Close the current tab page. |
:tabo | Close all other tab pages and keep the current one. |
:tabs | List all tab pages and the windows they contain. |
visual
| Command | Description |
|---|---|
v | Start character-wise visual mode. |
V | Start line-wise visual mode. |
Ctrl+v | Start block-wise visual mode. |
o | In visual mode, move the cursor to the other end of the selection. |
gv | Reselect the last visual selection. |
search
| Command | Description |
|---|---|
n | Go to the next search match. |
/ | Start a forward search for a pattern. |
? | Start a backward search for a pattern. |
N | Go to the previous search match. |
* | Search forward for the word under the cursor. |
# | Search backward for the word under the cursor. |
:noh | Clear search highlighting without changing the search pattern. |
undo
| Command | Description |
|---|---|
u | Undo the last change. |
Ctrl+r | Redo the last undone change. |
U | Undo all changes on the current line. |
textobject
| Command | Description |
|---|---|
ciw | Change inner word: delete the word under the cursor and enter insert mode. |
diw | Delete inner word: remove the word under the cursor. |
caw | Change a word including surrounding whitespace. |
daw | Delete a word including surrounding whitespace. |
ci" | Change inside double quotes. |
di" | Delete inside double quotes. |
ci( | Change inside parentheses. |
dis | Delete the sentence under the cursor (inner sentence). |
dip | Delete the paragraph under the cursor (inner paragraph). |
cip | Change the paragraph under the cursor and enter insert mode. |
yip | Yank the paragraph under the cursor (inner paragraph). |
yap | Yank a paragraph including surrounding blank lines. |
dit | Delete inside an HTML/XML tag. |
cit | Change inside an HTML/XML tag. |
da" | Delete a quoted string including the quote characters. |
buffer
| Command | Description |
|---|---|
:bp | Go to the previous buffer. |
:bn | Go to the next buffer. |
:bd | Remove the current file from the buffer list. |
:ls | List all open buffers. |
:b <num> | Open the buffer with the given number. |
fold
| Command | Description |
|---|---|
zc | Close one fold under the cursor. |
za | Toggle the fold under the cursor. |
zM | Close all folds in the buffer. |
zR | Open all folds in the buffer. |
zo | Open one fold under the cursor. |
diff
| Command | Description |
|---|---|
do | Obtain the current difference from the other diff buffer. |
dp | Put the current difference into the other diff buffer. |
[c | Jump to the previous difference in vimdiff. |
]c | Jump to the next difference in vimdiff. |
:dif | Re-scan buffers and refresh vimdiff highlighting. |
quickfix
| Command | Description |
|---|---|
:copen | Open the quickfix window. |
:cclose | Close the quickfix window. |
:cnext | Go to the next error or location in the quickfix list. |
:cprevious | Go to the previous error or location in the quickfix list. |
:clist | List all errors or locations in the quickfix list. |
jump
| Command | Description |
|---|---|
Ctrl+o | Jump to the older position in the jump list. |
Ctrl+i | Jump to the newer position in the jump list. |
gf | Open the filename under the cursor. |
Ctrl+] | Jump to the definition of the tag under the cursor. |
case
| Command | Description |
|---|---|
gUU | Uppercase the entire current line. |
guu | Lowercase the entire current line. |
gUiw | Uppercase the word under the cursor. |
guiw | Lowercase the word under the cursor. |
marks
| Command | Description |
|---|---|
`a | Jump to the exact position of mark a. |
ma | Set mark a at the current cursor position. |
'a | Jump to the line containing mark a. |
:marks | List all current marks. |
'' | Jump back to the line of the previous position before the last jump. |
`` | Jump back to the exact previous position before the last jump. |
replace
| Command | Description |
|---|---|
:s/<pattern>/<str>/g | Replace every match on the current line. |
:%s/<pattern>/<str>/g | Replace every match in the whole file. |
:%s/<pattern>/<str>/gc | Replace every match in the file, confirming each change. |
:g/<pattern>/d | Delete every line that matches a pattern. |
:v/<pattern>/d | Delete every line that does NOT match a pattern. |
window
| Command | Description |
|---|---|
Ctrl+w s | Split the window horizontally. |
Ctrl+w v | Split the window vertically. |
Ctrl+w h | Move focus to the window on the left. |
Ctrl+w j | Move focus to the window below. |
Ctrl+w k | Move focus to the window above. |
Ctrl+w l | Move focus to the window on the right. |
Ctrl+w o | Close all other windows and keep only the current one. |
Ctrl+w c | Close the current window. |
Ctrl+w q | Quit the current window (same as close when last window). |
Ctrl+w w | Cycle focus to the next window. |
Ctrl+w = | Make all window heights and widths equal. |
Ctrl+w x | Swap the current window with the next one. |
Ctrl+w _ | Maximize the current window's height. |
macro
| Command | Description |
|---|---|
qa | Start recording a macro into register a. |
q | Stop recording the current macro. |
@a | Play back the macro stored in register a. |
@@ | Repeat the last executed macro. |
Key Use Cases
- Jump a file with word, line, and f/t character motions without the mouse
- Edit with operators and text objects (change inner word, delete a paragraph, yank quotes)
- Split windows and tabs to compare files or keep a second buffer visible
- Search, substitute, and clear highlights without leaving the keyboard
- Walk vimdiff hunks and compiler errors in the quickfix list
Frequently Asked Questions
What is the difference between a Vim motion and an operator?
A motion only moves the cursor (w, $, %, f). An operator waits for a motion or text object and then acts (d, c, y). dw deletes to the next word; ci" changes inside quotes.
Should I learn hjkl or just use arrow keys?
hjkl keeps your hands on the home row so counts, operators, and repeats stay in one place. This track still names the observable move — left, down, up, right — so either habit can be tested.
Do these shortcuts work in Neovim?
Yes. Motions, operators, text objects, windows, tabs, vimdiff, and quickfix are shared. Neovim-only Lua mappings are not in this dataset.
Why practice :w and ZZ if I already use a GUI save?
Ex commands and normal-mode aliases still matter in a terminal, in vimdiff, and when a plugin drops you in Vim. Muscle memory for :q! / ZQ avoids losing a buffer — or accidentally keeping one.
Ready to master Vim commands?
Test your muscle memory with our spaced-repetition quiz system. Free forever.
