Skip to content

Instantly share code, notes, and snippets.

@fredjoseph
Last active September 29, 2020 07:15
Show Gist options
  • Select an option

  • Save fredjoseph/ffff8673c58673a57095098b3d69a783 to your computer and use it in GitHub Desktop.

Select an option

Save fredjoseph/ffff8673c58673a57095098b3d69a783 to your computer and use it in GitHub Desktop.
Vim Cheat Sheet

Cheatsheet

Verbs

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)

Modifiers

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)

Nouns

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

Noun Combined with a modifier

Keys Signification
aw a (complete) word
as a (complete) sentence
ap a (complete) paragraph
iw inner word
is inner sentence
ip inner paragraph

Substitutions

:[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

Examples

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

Registers

  • The unnamed register ""
  • Ten numbered registers "0 to "9
  • The small delete register "-
  • Twenty-six named registers "a to "z or "A to "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 "/

Mappings

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

Shortcuts

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

Tips

Generating numbered lists

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.

Generating IP address list

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.

Increasing or decreasing numbers

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:

  1. Place your cursor at the first line, at 0 for which you want to become 1.
  2. Press Ctrl-v to enter Visual block mode, move the cursors down to select the rest of the zeroes, to the last line.
  3. Now, press g and then press Ctrl-a (the shortcut for increasing numbers)

Repeating characters

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>

Open and edit archives

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.

Open the last edited file

Simply start Vim, and press Ctrl-o-o.

Paste text while in Insert mode

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.

Copy lines without cursor movement

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.

Move lines without cursor movement

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 ''.

Delete lines without cursor movement

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.

Run the same command on multiple lines

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 '

External program integration

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

Navigation through cursor history

You want to move through Jumplist? Here’s how:

  • Ctrl-o - to move backwards
  • Ctrl-i - to move forwards To move through Changelist, use:
  • g; - to move backwards
  • g, - to move forwards

Inspect vim variable

:echo g:foo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment