Vim Cheatsheet

Folds, Diff, and Git

Use this Vim reference while you build software engineering projects, review code, or refresh the syntax you reach for most.

Folding

Folds collapse regions so a long file fits on one screen.

KeyAction
zf{motion}Create a fold over the motion
zf in VisualFold the selection
zd / zDDelete the fold under the cursor / recursively
zEDelete every fold
zo / zOOpen the fold / all nested folds
zc / zCClose the fold / all nested folds
za / zAToggle the fold / recursively
zROpen every fold in the file
zMClose every fold
zvOpen just enough folds to see the cursor
zj / zkMove to the next / previous fold
[z / ]zStart / end of the current open fold
:set foldmethod=indent    " fold by indentation
:set foldmethod=syntax    " fold by language syntax
:set foldmethod=marker    " fold on {{{ and }}} in comments
:set foldmethod=expr      " fold with a custom expression
:set foldlevel=1          " how deep to leave folds open
:set foldlevelstart=99    " start with everything open
:set foldnestmax=3
:set foldcolumn=2         " show a fold gutter

Diff Mode

vimdiff a.txt b.txt          # two-way diff
vim -d a.txt b.txt c.txt     # three-way
git difftool                 # if configured to use vimdiff
:diffthis            " make this window part of the diff
:diffoff             " take it out
:diffoff!            " take every window out
:diffsplit other.txt " diff against another file
:diffupdate          " recompute after edits
:windo diffthis      " diff every window
KeyAction
]cNext change
[cPrevious change
do or :diffgetObtain: pull the other side's change into this buffer
dp or :diffputPut: push this change to the other buffer
:diffget LOCALIn a 3-way merge, take the local side
:diffget REMOTETake the remote side
:diffget BASETake the merge base
zROpen all folds (diff mode folds unchanged text)
:set diffopt+=vertical           " split side by side
:set diffopt+=iwhite             " ignore whitespace changes
:set diffopt+=algorithm:patience " a nicer diff algorithm

In a conflicted git mergetool session with vimdiff you get four windows: LOCAL, BASE, REMOTE, and the working copy in the middle. Navigate with ]c, pull the side you want with :diffget LOCAL or :diffget REMOTE, then :wqa.

Vim as the Git Editor

Git already uses your $EDITOR for commit messages, interactive rebases, and hunk selection.

git config --global core.editor "vim"
export EDITOR=vim
export VISUAL=vim
BufferWhat you are editing
COMMIT_EDITMSGThe commit message. :wq commits, :cq aborts.
git-rebase-todoThe rebase plan. Change pick to squash, reword, edit, drop.
MERGE_MSGThe merge commit message.
addp-hunk-edit.diffA hunk during git add -p + e.

:cq quits Vim with a non-zero exit code, which is how you tell git "abort this operation" rather than committing an empty or unwanted message.

" Nicer commit message editing
augroup GitCommit
  autocmd!
  autocmd FileType gitcommit setlocal spell textwidth=72 colorcolumn=51,73
  autocmd FileType gitcommit startinsert
augroup END

Reading Diffs and Patches

:e changes.patch     " syntax highlighted as a diff
:set filetype=diff
:%!git diff          " replace the buffer with the current diff
:r !git log --oneline -20

Comparing Against Git

Without plugins, a quick way to see what changed:

:vnew | r !git show HEAD:%    " the committed version in a split
:windo diffthis               " diff it against your working copy

The fugitive plugin turns this into :Gvdiffsplit, along with :Git blame, :Git, and :GBrowse.

Spell Check

:set spell spelllang=en_us
:set nospell
KeyAction
]s / [sNext / previous misspelling
z=Suggest corrections
1z=Take the first suggestion without the menu
zgAdd the word to your dictionary
zwMark the word as wrong
zug / zuwUndo zg / zw
:spellrRepeat the last correction through the file

Encoding and Line Endings

:set fileencoding?      " what this file is
:set fileencoding=utf-8 " change it on the next write
:set fileformat?        " unix, dos, or mac
:set fileformat=unix    " strip CRLF on write
:e ++enc=latin1 file    " reopen with a different encoding
:e ++ff=dos file        " reopen forcing CRLF
:%s/\r//g               " strip stray carriage returns
:set list listchars=eol:$,tab:>-,trail:~
:set bomb!              " toggle the byte order mark

Recovering a Swap File

When Vim crashes it leaves a .swp file, and the next open offers to recover.

vim -r file.txt        # recover from the swap file
vim -r                 # list recoverable swap files
:recover               " recover the current buffer
:e!                    " discard and reload from disk

After recovering, diff the recovered buffer against the file on disk before you write it, then delete the .swp file so the prompt stops appearing.