Published on


Table of Contents




tTill (stop before)
fFind (put cursor on)




f{c}Jump forward and put cursor on {c}
F{c}Jump back and put cursor on {c}
t{c}Jump forward and put cursor before {c}
T{c}Jump back and put cursor after {c}
/{s}Search for {s}
/{s}/e(In visual mode) Select text up to and including {s}
*Search for other instances of the word under cursor
nNext occurrence
NPrevious occurrence
0Go to beginning of line
$Go to end of line
^Go to first non-blank character in line
_Go to first non-blank character in line
wMove forward one word
bMove back one word
eMove to the end of your word
ggGo to top of file
GGo to bottom of file
<C-i>Previous location
<C-o>Forward location
:{l}Move to line number {l}
%Go to block close


"${register}Access the content in the register (e.g. "a)
"${register}yYank into the register (e.g. "ay)
"${register}pPaste from the register (e.g. "ap)
<C-r> ${register}Paste from the register in insert/command mode (e.g. <C-r> a)


iInsert before cursor
aAppend after cursor
IInsert at the beginning of line
AInsert at the end of line
oNew line below
ONew line above
rReplace character
RReplace but keep typing
CChange rest of line
~Change case
xDelete under cursor
XDelete before cursor
ddDelete line
DDelete to end of line
JJoin the current line with the next
.Repeat command
yyYank line
{d}yyyank {d} lines
pPaste after cursor
PPaste before cursor
edit!Reload buffer
<n>df<x>Delete n number of occurrences of x


q{c}Record macro and store in {c}
qStop recording
@{c}Replay macro stored in {c}
:5,10norm! @{c}Execute the macro stored in {c} on lines 5 through 10
:5,$norm! @{c}Execute the macro stored in {c} on lines 5 through the end of the file
:%norm! @{c}Execute the macro stored in {c} on all lines
:g/pattern/norm! @{c}Execute the macro stored in {c} on all lines matching pattern
:'<,'>norm! @{c}Execute the macro stored in {c} on visually selected lines

Search and Replace

:%s/foo/bar/gFind each occurrence of foo (all lines), and replace it with bar
:s/foo/bar/gFind each occurrence of foo (current line), and replace it with bar
:%s/foo/bar/gcChange each foo to bar, but ask for confirmation first
:%s/\/bar/gcChange only whole words exactly matching foo to bar; ask for confirmation
:%s/foo/bar/gciChange each foo (case insensitive) to bar; ask for confirmation
:%s/foo/bar/gcIChange each foo (case sensitive) to bar; ask for confirmation
:'<,'>s/\%Vfoo/bar/gChange each foo to bar in visual selection
:'<,'>s/\%V\s/,/gChange each space to , in visual selection


:vspVertical split
:spHorizontal split
:resize 60Change height of window
:res +5Change height of window
:res -5Change height of window
:vertical resize 80Change width of window
:vertical resize +5Change width of window
:vertical resize -5Change width of window

Global Command

The global command is used to run a command-line command on multiple lines simultaneously. The syntax is :g/pattern/command

:g/pattern/dDelete all lines containing pattern
:g!/pattern/commandDelete all lines not containing pattern
:g/one|two/dDelete all lines containing either one or two
:g/[0-9]/dDelete all lines containing any single digits (alternative is :g/\d/d)
:g/./normal A;Add a ; to the end of each non-empty line
:g/pattern/execute "norm Ahello"Add hello to the end of each line containing pattern


:termOpen terminal
:vsp | termOpen terminal in a vertical split
:sp | termOpen terminal in a horizontal split

Tips and Tricks

:noautocmd wSave file without executing Autocommand events
"_dUse "black hole register" and delete
:mapShow mappings
:map <leader>rnShow mapping for <leader>rn
:map jShow mapping for j
:map <F5>Show mapping for <F5>
:help key-notationDisplay key notation-meaning
:e /path/to/fileOpen file
nvim -u /path/to/fileUse a custom vimrc file
export XDG_CONFIG_HOME="~/.config/minimal"Use a custom init.vim file (it looks for $XDG_CONFIG_HOME/nvim/init.vim)
vim --clean -u DEFAULTS -U NONE -i NONERun vim without any settings
%s/\s\+$//eDelete any trailing white space at the end of each line


d2wDelete two words
cisChange inside sentence
100i{s}Writes {s} one hundred times
3.Repeat command three times
:%!uniqRemove duplicate lines
:%!jq .Prettify a JSON file
{d}df{x}Deletes up to the {d}th character of {x}
$A,Add a comma to the end of the line
:g/^$/dDelete empty lines
:g/price/dDelete lines that contain the word "price"
:g!/price/dDelete lines that DON'T contain the word "price"
:v/price/dDelete lines that DON'T contain the word "price"
verbose set shiftwidthFind where a variable was last set (in this case set shiftwidth)
q:Open ex-command history in a vim buffer
:e existing/path/new_file.extCreate new file


Use argdo to update multiple files (in this case, set shiftwidth to 4 and then update the indenting with gg=G)

:args ~/path/to/project/**/* | argdo execute "set shiftwidth=4" | execute "normal gg=G" | update


Use norm mode to update multiple lines at once.

:norm 0f,x10i

# 0	-> Go to beginning of line
# f,	-> Go to first , symbol
# x	-> Delete the , symbol
# 10i 	-> Insert ten spaces (note there is a space after 10i)

Negative lookahead

Given the following input, how do we match the lines that have abc but do not also contain xyz somewhere else on the same line (i.e. it doesn't need to immediately precede it) -> /abc\(.*xyz\)\@!

The abc is the best // Should match
The first three letters are abc // Should match
The abc is the best but xyz is cheaper // Should not match
The first three letters are abc and the last are xyz // Should not match

Using Ack and cdo

Using the Ack package and built-in :cdo command, you can replace all instances of foo with bar easily:

:Ack foo
:cdo s/foo/bar/g | update

Yank and paste while incrementing

  • qa - begins the recording of a macro inside the register a (you could choose another letter).
  • Vyp - duplicates the current line, by selecting the whole line (V), copying it (y) and then pasting it below (p).
  • t) - move the cursor just before the next closed parenthesis, so that it's on the second number.
  • <C-a> - (Ctrl and a) increments the number.
  • q - ends the recording of the macro.
  • 135@a - replays the macro stored in the register a 135 times.

Yank all lines matching pattern

:g/^match/yank A

This runs the global command to yank any line that matches ^match and put it in register a. Because A is uppercase, instead of just setting the register to the value, it will append to it. Since the global command runs the command against all matching lines, you will get all lines appended to each other.

What this means is that you probably want to reset the register to an empty string before starting: :let @a="" or qaq (i.e., recording an empty macro).

You can use the same with any named register.

reference - StackOverflow