Vim Cheatsheet

Bash/Zsh vi mode

You can use vi mode in your shell by setting the mode. By default Bash uses emacs mode but you can update your .bashrc or set it manually. By default, it puts you in insert mode, so it doesn't feel very different from emacs mode. You can switch in to command mode when you need to manipulate or navigate the line.

  • Switch shell modes with set -o vi and back with set -o emacs.
  • In Zsh, there is a vi-mode plugin that can be enabled which allows themes to show an indicator if you are in command mode. For example, the avit theme.
  • Go through previous/next commands with j and k when in command mode. CTRL-P and CTRL-N may or may not still work since they are emacs binds. Up and down arrows usually still work.
  • Search history with /. CTRL-R and CTRL-S might still work.
  • Press v in command mode to pull up the full editor with the command in the open buffer. When you save and exit, the final output from the editor is dropped in your shell ready to run. Change the default editor that is opened when pressing v by changing EDITOR environment variable. For example, export EDITOR=vim.

Rebinding CAPS to ESC

I highly recommend remapping the CAPS LOCK key to ESC to make switching modes easier.

I have instructions on how to do this in Windows, Mac, and Linux in the post: Rebind Caps Lock key to Escape/Control.

Switch between modes

  • CTRL-[ or ESC to to command mode.
  • i, a, and o to go in to insert mode.
  • I, A, and O to go in to insert mode alternate ways.

Launching vim

  • Run vim by itself to open an unnamed buffer
  • Open a single file with vim filename
  • Open multiple buffers (single window) vim file1 file2 file3
  • Open multiple buffers (split windows)
    • Horizontally split: vim -o file1 file2
    • Vertically split: vim -O file1 file2

Managing windows

  • Split with current file using :vsplit, :split, CTRL-W S, CTRL-W V.
  • Optionally open new files like :vsplit filename.
  • Switch windows with CTRL-W W.
  • Close a window with :q or CTRL-W Q.
  • Resize windows with CTRL-W to intiate the chord, then follow up with one of:
    • Shrink and expand vertical with - or +.
    • Shrink and expand horizontal with < and >.
    • Maximize vertical with _.
    • Maximize width with | .
    • Split everything equally with =.
  • Resize using commands:
    • Horizontal resize with :resize 20, :res -3, or :res +3
    • Vertical resize with :vertical resize 20, :vertical res -3, or :vertical res +3

Buffers, reading & opening files

Buffers (open files) are separate from windows. You can have multiple windows all for the same buffer. You can also have one window with multiple buffers open in the background. Buffers are always in-memory. It is only when you write using a command that the changes are saved to disk.

Loading files in to buffers - Open a file for editing with :e filename - Split window w/ new unnamed buffer using :vnew or :new. - Use :enew to edit new buffer in current window. - Use :tabnew to open tab w/ new buffer.

  • List available buffers with :ls.
  • Create a new unnamed
  • Switch current window buffer with :b2 or :b!2, :bnext :bprevious.

Saving and exiting

  • Simple exit with q.
  • Force quit (ignore changes) with q!.
  • Save/write with :w
  • Save and quit with :wq or :x or ZZ.

Moving around

You can multiply any of these commands by pressing a number first.

  • General move with j, k, l, h
  • Scroll up and down full/half pages with CTRL-D, CTRL-U, CTRL-B, CTRL-F.
  • Go forward and backward with w, b, W, B.
  • Go to beginning and end of file with gg and G.
  • Go to specific lines (e.g. 33) with :33 or 33G.
  • Go to beginning and end of lines with $, ^, and 0.

Cut, paste, delete

  • Delete character with x.
  • Make visual selections with v or V.
  • Copy/yank selection with y.
  • Delete/cut selection with d.
  • Copy/yank line with yy.
  • Delete/cut a line with dd.
  • Paste with p or P.


  • Just press u in command mode.
  • Type :u command and press enter.
  • Redo a command with CTRL-R.
  • Repeat last command with .


Delete and change are similar but change will delete the item and switch in to insert mode. Delete will only delete. For both, you can work "inside" an element, or on "all" of the element, signified with the keys a or i. For example "delete inside )" will delete everything inside the parenthesis. "delete all-of )" will delete the everythign inside AND parenthesis. This works with words, quotation marks, parenthesis, brackets, braces, etc.

  • Change inside/all word with caw or ciw.
  • Change inside/all like ci) or ci".
  • Delete to something like dt) or dt".
  • Delete inside something like di} or di].
  • Delete a/all like daw, da), da".

Search, find, and replace

  • Search like /sometext.
  • Re-run last search with just a blank /
  • Search backwards with ?sometext

  • Repeat last search with n.

  • Repeat last search but backwards with N.

  • :s/old/new/ - Swap text (next occurence on current line)

  • :s/old/new/g - Swap text (globally on current line)

  • :%s/old/new/ - Swap text (next occurence in file)

  • :%s/old/new/g - Swap text (globally in file)
  • :%s/old/new/gc - Swap text with confirmation (globally in file)

Running shell commands

  • Execute commands like this :!ls.
  • Can also read output in to file with :r !ls


  • To start and stop a macro recording, press q in command mode.
  • The first letter pressed after hitting q is the register where the macro is stored. For example, qt would put the macro in the t register.
  • To replay the macro, enter @<register> for example @t.
  • Repeat a macro with @@.
  • Repeat a macro multiple times w/ a number prefix. E.g. 5@t.


  • Read file contents and output at cursor with :r filename
  • Open file explorer with :Explore


  • :help digraph to get more information
  • Run :digraph to see extended ASCII characters. Type CTRL-V + the characters in the digraph. E.g. CTRL-V + 172.

My ~/.vimrc

set number
syntax on

"" show existing tab with 4 spaces width
set tabstop=4
"" when indenting with '>', use 4 spaces width
set shiftwidth=4
"" On pressing tab, insert 4 spaces
set expandtab

set showcmd     "" Show (partial) command in status line.
set showmatch       "" Show matching brackets.
set ignorecase      "" Do case insensitive matching
""set smartcase      "" Do smart case matching
set incsearch       "" Incremental search
""set hlsearch
""set autowrite      "" Automatically save before commands like :next and :make
""set hidden     "" Hide buffers when they are abandoned
""set mouse=a        "" Enable mouse usage (all modes)

if filereadable("${HOME}/.vimrc.local")
  source ${HOME}/.vimrc.local

"" Show whitespace
set listchars=tab:>~,nbsp:_,trail:.
set list

"" Make semicolon act as colon
nnoremap ; :

"" Highlight lines that reach the limit
highlight ColorColumn ctermbg=magenta
call matchadd('ColorColumn', '\%80v', 100)

"" Show row/column in status bar
set ruler

# Make it so backspace/delete will delete end of
# a line to join two line w/o needing `J`
set backspace=indent,eol,start

# Let's the left/right navigation wrap up/down lines
set whichwrap+=<,>,[,]

# for gvim
set guifont=Hack:h16
colorscheme evening