Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

vim

Stow package for ~/.vimrc and ~/.vim/. Vim 8+ with vim-plug managing the plugin set.

Table of contents

Leader is , (let mapleader=',').

Plugins

Managed by vim-plug. Install/update with :PlugInstall / :PlugUpdate. Clean orphans with :PlugClean!.

Editing essentials (tpope stack)

PluginUse
vim-commentarygcc toggles a line, gc{motion} toggles a range
vim-surroundcs'" → change 'foo' to "foo"; ys{motion}{char}; ds{char}
vim-repeatmakes the above two .-repeatable
vim-sleuthauto-detect indent settings from the file
vim-fugitive:Git, :Gdiffsplit, :Gblame, :Git log
vim-dispatchasync build/test runner
vim-projectionistproject-aware :A-style file switching
vim-unimpairedbracket-pair mappings: ]q/[q quickfix, ]b/[b buffers, ]c/[c (shared with gitgutter), ]<Space> add blank line, etc.
vim-eunuchshell-command Ex wrappers: :Rename, :Move, :Delete, :SudoWrite, :Chmod

UI

PluginUse
vim-airlinestatusline with mode/branch/lint
bufexplorer<leader>be/bt/bs/bv — list/toggle/split buffers
preservim/nerdtree<leader>nt toggle, <leader>nf reveal current file
tagbar<leader>tt outline of symbols (needs ctags)
undotree<leader>u visualize undo branches (paired with undofile)

Fuzzy finder

PluginUse
junegunn/fzf + junegunn/fzf.vim:Files, :Rg, :Buffers, :GFiles?, :History

Editor integrations

PluginUse
editorconfig-vimhonor .editorconfig files
vim-tmux-navigator<C-h/j/k/l> jumps across vim splits and tmux panes
vim-gitguttergutter diff markers; ]c/[c next/prev hunk
splitjoin.vimgS/gJ split/join one-liners ↔ blocks
auto-pairsauto-close brackets/quotes
ultisnipssnippet engine
vim-snippetsthe snippet library ultisnips expands (engine ships none on its own)

Linting

PluginUse
dense-analysis/aleasync linting (pylint, shellcheck, yamllint). Go is owned by vim-go.

Languages

PluginUse
fatih/vim-goGo IDE-ish features. See Go workflow.
rust-lang/rust.vimRust filetype + rustfmt

Colors

dracula is the scheme for all filetypes, including Go.

Leader-key cheat sheet

(Leader = ,)

KeysAction
,<space>clear search highlight
,,switch to last file
,ev / ,svedit / source $MYVIMRC
,ln / ,nw / ,rntoggle number / wrap / relativenumber
,sctoggle spell check
,tn / ,tcnew / close tab
,bd / ,bdaclose current buffer / close all buffers
,dc / ,doclose diff / :DiffOrig (diff against unsaved)
,rtretab
,urlopen URL under cursor (OS default browser)
,ggtoggle gitgutter line highlights
,tttoggle tagbar
,nt / ,nftoggle / reveal NERDTree
,utoggle undotree
,f / <C-p>fzf :Files
,bfzf :Buffers
,afzf :Rg (prompt for pattern)
,*fzf :Rg word under cursor
,hfzf :History
,qclose quickfix
<C-n> / <C-m>:cnext / :cprevious

Other mappings

Non-leader bindings worth knowing:

KeysAction
jj (insert)<Esc> — escape without leaving home row
<Down> / <Up> (insert)move by visual line (gj/gk), so wrapped lines work intuitively
j / k (normal)move by visual line (gj/gk)
<M-j> / <M-k> (normal + visual)move the current line / selection down / up
< / > (visual)indent left / right and keep the selection (gv re-select)
<tab> (normal + visual)jump to matching bracket (rebinds %)
n / N / * / #re-center the screen on the match (Nzz)
/starts a “very magic” search (/\v — most punctuation is regex metachar)
Qgq — reformat with motion (the default Q ex mode is rarely useful)

Custom Ex commands:

CommandAction
:W / :SudoWritesudo-save the current buffer (:W is an alias for vim-eunuch’s :SudoWrite)
:DiffOrigvertical diff between the buffer and the on-disk file (,do triggers it)

Non-default settings

SettingReason
hiddenallow buffer switching with unsaved changes
clipboard=unnamed,unnamedplussystem clipboard on Mac (unnamed) and Linux (unnamedplus)
termguicolorstrue color; pairs with tmux terminal-overrides ",xterm-256color:Tc"
splitbelow, splitrightnew splits open in more intuitive positions
completeopt=menu,menuone,noselectdropdown without auto-selecting first match
mouse=amouse on
undofile, undolevels=500persistent undo across sessions
backup, backupdir=~/.vim/backupkeep backup files in a known place
directory=~/.vim/tmp, undodir=~/.vim/undomove swap/undo out of the working dir
colorcolumn="80," + range(120,999)line marker at 80, solid color from 120+
textwidth=200global default; overridden to 80 for FileType text
ignorecase + smartcasecase-insensitive unless query has uppercase
tags=tags;/walk up looking for ctags tags file

Trailing whitespace is highlighted in red and stripped on save for *.go/*.py/*.sh. The motion/search rebindings that pair with these settings (visual-line j/k, recentering n/*, <tab> for bracket matching) are listed under Other mappings.

Window/pane navigation across vim and tmux

<C-h/j/k/l> is bound in both. With vim-tmux-navigator and tmux’s matching keybindings, hitting <C-l> from a rightmost vim split jumps into the tmux pane to the right. Same in reverse.

Ripgrep integration

  • :Rg foo — interactive fzf picker over rg results (from fzf.vim).
  • ,*:Rg for the word under the cursor.
  • :grep foo — batch search; populates the quickfix list. Uses rg via:
    set grepprg=rg\ --vimgrep\ --smart-case\ --hidden
    set grepformat=%f:%l:%c:%m
    
  • For “live rg + fzf, open at line in editor” from outside vim, see the frg function in fzf/README.md.

Go workflow

vim-go is configured with:

  • g:go_fmt_command="goimports" — format + organize imports on save
  • g:go_metalinter_autosave=1 — run linter on save
  • g:go_auto_sameids=1, g:go_auto_type_info=1 — highlight same identifiers, show types
  • Many g:go_highlight_*=1 flags for richer syntax

Go-specific leader maps (active only in .go files):

KeysAction
,b:GoBuild or :GoTestCompile based on filename
,ctoggle coverage
,ttest
,rrun
,erename (gopls)
,iinfo under cursor
,simplements
,ds/,dt/,dvdef in split/tab/vsplit
,gd/,gv/,gbdoc / doc-vertical / doc-browser
,glmetalinter
,ga:GoAlternate (jump between code and test file)

Runtime directories

The repo includes empty .gitignore files in these dirs to keep them present in stow targets without committing the runtime data:

DirWhat goes there
~/.vim/backup*~ backup files (gitignored repo-wide)
~/.vim/tmpswap files
~/.vim/undopersistent undo blobs
~/.vim/pluggedvim-plug-managed plugins (not in repo)

Fresh-machine setup

stow vim                    # symlinks ~/.vimrc and ~/.vim/
vim +"PlugInstall --sync" +qall

For headless (CI/script) install, vim-plug needs a real pty — run inside a temporary tmux session (see CLAUDE.md at the repo root).