| Key | Signification |
|---|---|
x |
Delete character under the cursor to the right |
X |
Delete character under the cursor to the left |
r |
Replace character under the cursor with another character |
s |
Delete character under the cursor and enter the Insert mode |
y |
yank (copy) |
c |
change |
d |
delete |
v |
visually select (not really a verb, but used with verbs) |
| Key | Signification |
|---|---|
i |
inner (inside) |
a |
around |
n |
number (e.g.: 1, 2, 10) |
t |
searches for something and stops before it (search until) |
f |
searches for that thing and lands on it (find) |
/ |
find a string (literal or regular expression) |
| Key | Signification |
|---|---|
w,W |
start of next word or WORD |
b,B |
start of previous word or WORD (start of word before) |
e,E |
end of word or WORD |
s |
sentence |
p |
paragraph |
t |
tag (in context of HTML/XML) |
b |
block (in context of programming) |
h,j,k,l |
left, down, up, right |
$ |
end of line |
^,0 |
start of line |
| Keys | Signification |
|---|---|
aw |
a (complete) word |
as |
a (complete) sentence |
ap |
a (complete) paragraph |
iw |
inner word |
is |
inner sentence |
ip |
inner paragraph |
:[range] s[ubstitute]/pattern/string/[flags] [count]
Flags can be:
- c - to confirm each substitution
- g - to replace all occurrences in the line
- i - ignore case for the pattern
- I - don’t ignore case for the pattern
| Range | Description | Example |
|---|---|---|
28 |
line 28 | :28s/bad/good/g |
1 |
first line | :1s/bad/good/g |
$ |
last line | :$s/bad/good/g |
% |
all lines in a file (same as 1,$) | :%s/bad/good/g |
6,28 |
lines 6 to 28 inclusive | :6,28s/bad/good/g |
11,$ |
lines 11 to end of the file | :11,$s/bad/good/g |
.,$ |
current line to end of the file | :.,$s/bad/good/g |
.+1,$ |
line after current line to end | :.+1,$s/bad/good/g |
.,.+4 |
current to current+5 line, inclusive) | :.,.+4s/bad/good/g |
- The unnamed register
"" - Ten numbered registers
"0to"9 - The small delete register
"- - Twenty-six named registers
"ato"zor"Ato"Z- lowercase : replace the register content
- uppercase : append to the register
- Four read-only registers
":,".,"%and"# - The expression register
"= - The selection and drop registers
"*,"+and"~ - The black hole register
"_ - Last search pattern register
"/
| Recursive | Non-recursive | Unmap | Modes |
|---|---|---|---|
:map |
:noremap |
:unmap |
normal, visual, operator-pending |
:nmap |
:nnoremap |
:nunmap |
normal |
:xmap |
:xnoremap |
:xunmap |
visual |
:imap |
:inoremap |
:iunmap |
insert |
:cmap |
:cnoremap |
:cunmap |
command-line |
:omap |
:onoremap |
:ounmap |
operator-pending |
| Shortcut | Action |
|---|---|
Esc |
Go back to normal mode |
:!<command> |
run a shell commands like :!ls |
| Configuration | |
:set <param> |
Display the current value of parameter param |
:verbose set <param> |
Find the last location where the parameter is changed |
:set all |
Display all parameters with their values |
:nmap |
List all nmap mappings |
:xmap |
List all xmap mappings |
:imap |
List all imap mappings |
| Tab | |
:tabnew <filename> |
create new tab |
:tabc |
close the current tab and all its windows |
:tabo |
close all tabs except the current one |
:tabr |
go to first tab |
:tabl |
go to last tab |
:tabm |
move the current tab to the last position |
:tabm # |
move the current tab to the #th position |
#gt |
Move to tab number # |
Ctrl-w t |
Move the current split window into its own tab |
gt OR :tabnext OR :tabn |
Move to the next tab |
gT OR :tabprev OR :tabp |
Move to the previous tab |
#gt OR :tabn # |
go to #th tab |
| Buffers | |
Ctrl-6 |
Switch back and forth between your current and previous buffer (doesn't work on all Vim implementations/versions) |
:ls OR :buffers |
List all buffers |
:#b OR :buffer # |
Go to buffer # |
| Navigation | |
h |
Move cursor left |
j |
Move cursor down |
k |
Move cursor up |
l |
Move cursor right |
H |
Move to home (top) of screen |
L |
Move to last line of screen |
M |
Move to middle of screen |
w |
Go to the start of the next word (delimited by non-keyword characters) |
W |
Go to the start of the next WORD (non-blank characters delimited by white space) |
e |
Go to to the end of the current word |
E |
Go to to the end of the current WORD |
b |
Go to the start of the previous word |
B |
Go to the start of the previous WORD |
0 |
Move to the start of the line |
^ |
Move to the first non-blank character of the line |
$ |
Move to the end of the line |
g_ |
Move to the last non-blank character of the line |
Ctrl-d |
Scroll down half page |
Ctrl-u |
Scroll up half page |
Ctrl-f |
Scroll down full page |
Ctrl-b |
Scroll up full page |
Ctrl-e |
Move screen down one line |
Ctrl-y |
Move screen up one line |
zz |
Center screen on cursor |
zt |
Align top of screen with cursor |
zb |
Align bottom of screen with cursor |
) |
Move forward one sentence |
( |
Move backward one sentence |
} |
Move to next paragraph |
{ |
Move to previous paragraph |
gg OR [[ |
Go to the top of the file |
G OR ]] |
Got to the end of the file |
% |
Go to the matching pair of (), [], {} |
n% |
Go to the line at the n% of the file |
nG OR :n |
Go to the line n |
' |
Go to the position before the latest jump, / where the last m' / m` command was given. |
f# |
Move to next occurrence of character # |
t# |
Move to one character before the next character # |
T# |
Move to one character before the previous character # |
; |
Go to the next instance when you've jumped to a character (repeat previous f,F,t,T) |
, |
Go to the previous instance when you've jumped to a character (repeat previous f,F,t,T movement) |
3f# |
Move to 3rd instance of character # forward from cursor on current line. |
3F# |
Move to 3rd instance of character # back from cursor on current line. |
g; |
Move backwards to a previous change |
g, |
Move forwards (use the changeList) |
Ctrl-o |
Jump back to a previous cursor location (can open a previously closed file) |
Ctrl-i |
Jump forwards (use the jumpList) |
| Editing a File | |
yy OR Y |
Yank (copy) a line |
#yy |
Yank (copy) # lines |
y# |
Copy motion (w: word, y: line, $: position to end of line, G: position to end of file) |
yt# |
Copy from the current position to the following character # |
:%y+ |
Copy all the lines of the current buffer |
dd |
Cut (delete) a line |
D |
Delete from the current position to the end of line |
#dd |
Delete # lines |
:#d |
Delete line # ('' : come back to the original location) |
d# |
Delete motion (w: word, d: line, $: position to end of line, G: position to end of file) |
dt# |
Delete from current position to the following character # |
p |
Paste the content of the buffer after the cursor position |
P |
Paste the content of the buffer before the cursor position |
ddp |
Switch 2 lines (cut the first one and paste it one line below) |
J |
Join line below to the current one |
gJ |
Join line below to the current one with no separator |
cc OR S |
Change (replace) entire line |
cw |
Change (replace) to the end of the word |
c$ |
Change (replace) to the end of the line |
s |
Delete character and substitute text |
x OR <Del> |
Delete the character at the current cursor position |
X |
Delete the character before the current cursor position |
xp |
Transpose two letters (delete and paste) |
. |
Repeat last command which changed the buffer content |
r# |
Replace the character under the cursor by # and go back in Normal mode |
R |
Replace the character under the cursor and stay in Replace mode |
== |
Indent current line |
=% |
Indent a block, the cursor must be placed at one of the braces |
gg=G |
Fix indentation of the entire file |
=G |
Fix indentation from the current line to the end of the file |
Ctrl-a |
Increment number (the cursor must be on a number or to the left of the number) |
Ctrl-x |
Decrement number (the cursor must be on a number or to the left of the number) |
:m# |
Move the current line to the line # |
:#1m#2 |
Move line #1 to the line #2 (relative range available) |
:#co. |
Copy line # one line below the current cursor position |
:%norm <command> |
Execute command on all the lines (:%norm di' : remove all text inside single quotes) |
| Undo/Redo | |
:earlier 2d |
Undo changes in last two days |
:ea 3h |
Undo changes in last three hours |
:ea 1m |
Undo changes in last one minute |
:later 5m |
Redo all the changes in last 5 minutes |
:lat 15s |
Redo all the changes in last 15 seconds |
:earlier 3f |
Undo last three file states (last three buffer writes) |
g- |
Undo branches (undo through all intermediate text states) |
g+ |
Redo branches (redo through all intermediate text states) |
u |
Undo changes |
U |
Undo all recent changes on the current line |
Ctrl-r |
Redo changes |
| Search and Replace | |
* |
Search forwards for word under cursor (exact search) |
# |
Search backwards for word under cursor (exact search) |
g* |
Search forwards including no exact work (search on 'master' will find 'mastering') |
g# |
Search backwards including no exact work (search on 'master' will find 'mastering') |
/pattern |
Search for pattern |
?pattern |
Search backward for pattern |
n |
Repeat search in same direction |
N |
Repeat search in opposite direction |
:noh |
Remove highlighting of search matches |
:match <color> /<pattern>/ |
Highlight all matches in the current buffer (color : ErrorMsg, WarningMsg, MoreMsg) |
:s/old/new/g |
Replace all instances of old with new on the current line |
:%s/old/new/g |
Replace all instances of old with new on the entire file |
cgn <new><Esc> THEN . |
Repeatable changes on search matches (search then change with cgn then change the next occurrence with .) |
| Change Case | |
~ |
Toggle case (Case => cASE) |
gU |
Uppercase |
gu |
Lowercase |
gUU OR gUgU |
Uppercase current line |
guu OR gugu |
Lowercase current line |
| Go to Insert Mode | |
i |
Enter insert mode |
I |
Insert at the beginning of the line |
a |
Insert (append) after the cursor |
A |
Insert (append) at the end of the line |
o |
Append (open) a new line below the current line |
O |
Append (open) a new line above the current line |
ea |
Insert (append) at the end of the word |
c# |
Change/Replace motion (w: word, c: line, iw:inside word) |
#cc OR #S |
Change/Replace # entire lines |
ct# |
Change up to the following character # |
C |
Change from cursor position to the end of the line |
| Insert Mode | |
Ctrl-o |
Switch to Normal mode for 1 command then go back to Insert mode |
Ctrl-r <register> |
Paste the content of the specified register |
Ctrl-r Ctrl-p <register> |
Paste the content of the specified register and fix the indentation issues |
Ctrl-h |
Delete back one character |
Ctrl-w |
Delete back one word |
Ctrl-u |
Delete back to the start of the line or the start of current insert |
Ctrl-c |
Go back to Normal mode |
Ctrl-n |
Autocomplete the current word by searching forwards for a matching word through the file |
Ctrl-p |
Autocomplete the current word by searching backwards for a matching word through the file |
| Go to Visual Mode | |
v |
Start visual mode, mark lines, then do a command (like y-yank) |
V |
Start linewise visual mode |
Ctrl-v |
Start visual block mode |
gv |
Re-select the previous visual selection |
| Visual Mode | |
= |
Indent selection |
<< |
Shift current line left by shiftwidth |
>> |
Shift current line right by shiftwidth |
> |
Shift text right |
< |
Shift text left |
y |
Yank (copy) selected text |
d |
Delete selected text |
a# |
Mark a motion |
aw |
Mark a word |
ab |
Mark a block with () |
aB |
Mark a block with {} |
i# |
Mark innner motion |
ib |
Mark inner block with () |
iB |
Mark inner block with {} |
o |
Move to the other end of the selected area (vertically) |
O |
Move to the other end of the selected area (horizontally) |
~ |
Switch case |
:fold |
Fold the selected lines |
Ctrl-c |
Go back to Normal mode |
| Folding Commands | |
zf# |
Fold the lines represented by the specified motion |
zf#j |
Fold the current line with the # following lines |
zfa{ |
Fold block delimited by curly braces |
zfap |
Fold a paragraph |
zf/<pattern> |
String creates a fold from the cursor to string |
zj |
Move the cursor to the next fold |
zk |
Move the cursor to the previous fold |
za |
Toggle a fold under cursor |
zo |
Open a fold at the cursor |
zO |
Open all folds at the cursor |
zc |
Close a fold under cursor |
zm |
Increase the foldlevel by one |
zM |
Close all open folds |
zr |
Decrease the foldlevel by one |
zR |
Decrease the foldlevel to zero—all folds will be open |
zd |
Delete the fold at the cursor |
zE |
Delete all folds |
[z |
Move to start of open fold |
]z |
Move to end of open fold |
| Working With Multiple Files | |
:e <filename> |
Edit a file in a new buffer |
:ene |
Open a blank file for editing |
:bnext OR :bn |
Go to the next buffer |
:bprev OR :bp |
Go to the previous buffer |
:bd |
Delete a buffer (close a file) |
:sp <filename> |
Open a file in a new buffer and split window |
:new <filename> |
Open a new buffer and split window |
:vsp <filename> |
Open a file in a new buffer and vertically split window |
:vnew <filename> |
Open a new buffer and vertically split window |
Ctrl-w w |
Switch to next pane |
Ctrl-w q |
Quit a window/pane |
Ctrl-w s |
Split window horizontally |
Ctrl-w v |
Split window vertically |
Ctrl-w c |
Close the current pane |
Ctrl-w h OR Ctrl-w ← |
Move cursor to window left |
Ctrl-w l OR Ctrl-w → |
Move cursor to window right |
Ctrl-w k OR Ctrl-w ↑ |
Move cursor to window above |
Ctrl-w j OR Ctrl-w ↓ |
Move cursor to window below |
Ctrl-w r |
Rotate windows clockwise |
Ctrl-w T |
Move current window to a new tab |
:on |
Close all windows except current window |
Ctrl-w #+ |
Increase size of the current split by # lines |
Ctrl-w #- |
Decrease size of current split by # lines |
Ctrl-w = |
Equalize the size of windows |
Ctrl-w | |
Maximize width of active window |
Ctrl-w 1| |
Minimize width of active window |
Ctrl-w _ |
Maximize height of active window |
Ctrl-w 1_ |
Minimize height of active window |
gf |
Open a file whose name (or path) is under or after the cursor |
:vimgrep <pattern> <filePattern> |
Search through multiple files in the specified directory (:vimgrep error **/*.log) |
:cn |
Jump to the next match |
:cN |
Jump to the previous match (:cN : jump to the previous match) |
:clist |
List all the files that contain the matched string |
:cc # |
Jump to specific match number, which you get from :clist output |
| Exiting a File | |
:w |
Write (save) the file, but don't exit |
:wq |
Write (save) and quit (write even if file is not changed) |
:x OR ZZ |
Write (save) current file (only if modified) and quit |
:q |
Quit (fails if there are unsaved changes) |
:q! |
Quit and discard unsaved changes |
:qa |
Quit all buffers and windows |
ZQ |
Quit without checking for changes |
| File Manager | |
:Ex <dir> |
Open specified directory (current directory if blank) in current Vim window (i to switch between view types). |
:Sex |
Open current directory in horizontal split window. |
:Vex |
Open current directory in vertical split window. |
:Tex |
Open current directory in a new tab. |
:Lexplore |
Open current directory in vertical split on the left. |
:40vs +Ex |
Open current directory in vertical split window with width of 40 columns |
| Spell Checking | requires :set spell spelllang=en_us |
z= |
get suggestions on a misspelled word |
1z= |
replaced mispelled word by the first suggestion |
zg |
Mark a misspelled word as correct |
zw |
Mark a good word as misspelled |
For example, to insert a list of ascending numbers, you can run a command like this:
:put =range(1,10)
You can also insert numbers after a particular line number, for example command:
:28put =range(6,87)
inserts list of numbers from 6 to 87 after line number 28.
In this example, we want to generate a list of IP addresses, starting from 192.168.0.1 to 192.168.0.100:
:for i in range(1,100) | put ='192.168.0.'.i | endfor
The result will be list of IP addresses in the mentioned range, with one IP address per line.
It’s one of those features you’ll use regularly. In Normal mode, hitting Ctrl-a will increment the next number. Hitting Ctrl-x will decrement the next number. In order for this to work, the cursor can be at the number, or to the left of the number, on the same line.
These keys work with a count. For example, pressing 4 then Ctrl-a will increment the following number four times.
Let’s say you have something like this in your code:
array[0] = 0;
array[0] = 0;
array[0] = 0;
array[0] = 0;
array[0] = 0;
and you want to get something like this:
array[1] = 0;
array[2] = 0;
array[3] = 0;
array[4] = 0;
array[5] = 0;
Best way to do it:
- Place your cursor at the first line, at 0 for which you want to become 1.
- Press
Ctrl-vto enter Visual block mode, move the cursors down to select the rest of the zeroes, to the last line. - Now, press
gand then pressCtrl-a(the shortcut for increasing numbers)
You want to add 8 new lines under the current line? Don’t even think of hitting Enter 8 times.
Instead, run:
8i<Enter><Esc>
You need to insert 20 “-” (dash) characters? Please, don’t hit - twenty times. Run:
20i-<Esc>
You need to edit a file inside an archive? Without Vim, you’d have to extract the archive, edit the file and save changes, then create a new archive with the updated file. Not anymore!
With Vim, you can open and edit files inside archive files without previously extracting them.
Multiple archive types are supported, like .zip, .tar, .tar.gz, .jar, etc.
For example, you could run:
$ vim my_archive.tar.gz
and you’d see all the files and directories inside my_archive.tar.gz. You’d be able to browse through them, open, edit and save them.
Simply start Vim, and press Ctrl-o-o.
You’re in Insert mode and you want to paste yanked text without moving to Normal mode. You can do that with Ctrl-r 0. If yanked text contains new line characters, Ctrl-r Ctrl-p 0 will fix the indentation issues.
Your cursor is on line 10. You want to paste line 20 to one line below your current cursor position.
Here’s how to do that using co[py] command:
:20co.
You can also use ranges. Let’s say your cursor is on line 10. You want to paste text from line 20 to 25 under line 10. Here’s how:
:20,25co10
It gets even better: :t is an alias of the co[py] command.
You could run the commands from above and achieve the same result if you’d replace co with t in them.
This command works with relative line numbers as well. For example, to paste the line, which is 10 lines above your current line, to a line below your current position:
:-10t.
One last example: if you’re at line 45, :35,t. will make a duplicate of lines 35 to your cursor (that is, from 35 to 45 inclusive) and put it after your current cursor.
You also have relative line numbers enabled. You see that the function starts 15 lines above your current line.
To make a copy of an entire block and place it after your current line, you could run
:-15,t.
The usage of command m[ove] is similar to co[py] command. For example, to move a line 6 to line 28, you’d run:
:6m28
It also supports ranges and relative lines. Here’s an example using both:
:-10,-5m+7
This command would take five lines which are located between lines 10 and 5 above your current position, and move them to 7th line under your current position. After this command, the position of your cursor will change. In order to come back to the original location where your cursor was before running this command, simply press ''.
Similar to :copy and :move commands, you can also run :delete command to delete lines without jumping to those lines.
For example, to delete lines 5 to 10, run:
5,10d
However, this command would leave the cursor at the deleted line location, so you’d need to use '' to jump back to the previous position.
Using the norm command, you can run the same command on multiple lines at once. Let’s say you want to delete all strings inside the single quotes ' on all the lines. Here’s what you’d need to do:
:%norm di'
- % - defines range: all lines.
- norm[al] - command which tells Vim to repeat the following command in Normal mode
- di' - delete inside single quotes
'
Vim has a great integration with system CLI (command-line interface) programs, which you can use to modify the current buffer. Here’s how to do it:
:%!<command>
Here are few examples to give you an idea on how powerful this feature can be:
:%!sort -k3- sort the buffer based on column 3:%!column -t- format the text in columns (useful when working with tabular data):%!ls|grep .txt- insert the list of txt files from the current directory
You want to move through Jumplist? Here’s how:
Ctrl-o- to move backwardsCtrl-i- to move forwards To move through Changelist, use:g;- to move backwardsg,- to move forwards
:echo g:foo