My Vim Setup
This is my Vim config. There are many like it, but this one is mine.
Overview
I intend for this post to be a living document that outlines my Vim setup so I can easily share new tips and tricks with my coworkers. Hopefully I don’t let it fall too far out of date :trollface:.
My config is highly personalized, and yours should be too! You should use this post and the vim directory in my dotfiles to learn and find ideas — not as a starting point for a new Vim setup.
I’m adverse to change, so I use Vim 8 over Neovim. Neovim has changed too much too quickly for my tastes and the community seems a bit hostile, at least on Reddit.
I also like defaults, so I use Terminal.app on macOS over iTerm. I’ve thought about switching to iTerm for better color support, but I haven’t found a new theme that’s made it worth making the change.
Installation
I use Homebrew to install Vim. One thing I don’t like about the default formula is that it installs a Homebrew version of Ruby. I manage my own Ruby environment, so I use a hacked version of their formula to allow me to build Vim using a custom Ruby.
It is installed with brew install itspriddle/brews/vim
. Updates come in
automatically with brew update
, and upgrades happen as normal with brew
upgrade [vim]
.
~/.vim/vimrc
I kept all of my settings in ~/.vim/vimrc
for a long time. I felt it got
unwieldy, so I split it into multiple files to try to organize things better.
My actual ~/.vim/vimrc
is mostly bare because I’ve split the
configuration into multiple files. It just loads the main files I’ve created
under ~/.vim/config/
— which I’ll outline below.
~/.vim/config/maps.vim — Maps
I keep non-plugin specific maps in a separate file — maps.vim. My favorites:
noremap <space> :
remaps the spacebar key to:
, letting you start a colon command with your left or right thumb instead of your right pinky.nnoremap gV `[v`]
: Visually selects the text that was last edited. I often use this when I paste a block of code and want to re-indent it.vnoremap <C-q> gq
: Formats the selected paragraph. I use this daily when writing documentation inside code or writing Markdown files. The main effect for me is to format paragraphs to be 78 columns wide, though other items from'formatoptions'
apply.nnoremap <C-q> gqap
andinoremap <C-q> <C-o>gqap
do the same in normal and insert modes.
~/.vim/config/settings-core.vim — Core Settings
I keep “core settings”, like my selected colorscheme and other set ...
settings, in a separate file — settings-core.vim. Most of these are
standard fare, but I’ll mention a few favorites.
If you want to print to paper from Vim (:help hardcopy
), make sure to check
out the printer settings. I don’t encounter such settings in the wild
often, so either people are unaware they can print from Vim, or they are just
accepting default values. As an aside, even if you don’t want to print to
paper, you can still generate a .ps
file for conversion to .pdf
.
Undo persistence (:help undo-persistence
) is a great feature that lets you
use u
to undo changes after closing a file. It can be enabled with these
settings.
These settings cleanup some of the messages that Vim displays when starting up, completing files, and entering insert mode.
I like 2 spaces instead of tabs, 78 character lines, and no line wrapping — these settings enable that behavior.
When using J
to join sentences, Vim will add two spaces after a period.
These settings make it use just a single space. I’m not using
a typewriter after all.
Some special characters are used to show “invisibles”, like hard-tabs, trailing whitespace, and soft line wrapping — enabled by these settings.
~/.vim/config/settings-plugins.vim — Plugin Settings
I keep plugin specific settings in a separate file — settings-plugins.vim. I won’t go into these here, the important parts are outlined below with their corresponding plugins.
~/.vim/config/plug.vim — Plugins
I use vim-plug to manage my plugins. I follow the recommended setup and
keep a full copy of the plugin in autoload/plug.vim
. I periodically run
:PlugUpgrade
and commit the updated autoload/plug.vim
.
My plugins are specified in plug.vim. Settings specific to those plugins are kept in settings-plugins.vim.
This is a big list, but that doesn’t mean you should jump to install 50
plugins yourself. Understand the shortcomings a plugin aims to solve before
you decide if you need to install it. The plugins I use all enhance Vim in a
useful way for my work, and when they no longer do, I’ll uninstall them. Take
the effort to learn how to work with a default Vim installation — it can be
invaluable when setting up servers or VMs via ssh
.
Notable plugins and their configs are outlined below.
Core Plugins
These “core” plugins are general ones that enhance Vim itself.
vim-colors-solarized: Solarized Dark is my preferred colorscheme, and has been for 6 years. I occasionally switch to Solarized Light.
vim-sensible: Sensible/minimal default config. Everyone should use this, and it is a great configuration for barebones or embedded systems.
vim-unimpaired: Handy pairs of maps, cob
to toggle 'bg'
from light to
dark, cos
to toggle :set spell
, col
to toggle :set list
, cow
to
toggle :set wrap
, etc. [b
and ]b
to navigate open buffers, and [q
and
]q
to navigate to Quickfix lines. yo
is shorthand for :set paste
, o
,
:set nopaste
. I’ve also mapped yp
to to the
same in the current line — these are super useful.
vim-scriptease: Provides some helpers for working with Vimscript. I
primarily use the :Vedit
and similar commands to quickly open Vim plugin
files when I have an idea or need to troubleshoot.
lightline.vim: A lightweight alternative to Powerline — in pure
Vimscript. Works out of the box with Solarized and other popular themes. I use
these customizations to change colors when switching
from light to dark (via unimpaired’s cob
, or :set bg=<dark|light>
and to
assign a custom filename in Quickfix windows.
QFEnter.vim: Maps to open files in the Quickfix window in splits, vsplits, etc. These are included in ack.vim and older versions of ag.vim (which I do not use).
vim-altscreen: Keeps the terminal clean when using :!
commands.
vim-togglecursor: Changes the cursor to a blinking |
in insert mode, and
a blinking _
in replace mode. Works great with Vim 8 and Terminal.app.
simple-url-browse: This plugin overrides gx
from NetRW to open URLs
under the cursor. The NetRW version breaks on URLs with “#” or “?” characters
in them.
simple-qf-toggle: Provides <Plugin>
maps to open and close the Quickfix
and Location List windows. I map these to coq
for the Quickfix List and coQ
for the Location List.
Unix Plugins
These plugins bring some frequently used Unix tools and behaviors to Vim.
vim-eunuch: Vim commands for common Unix utilities. :Chmod
, :Move
and
friends. New files with shebangs are automatically set executable.
:SudoWrite
is fantastic when you forget to sudo vim
.
vim-rsi: Gives you Readline keybindings, like <C-a>
and <C-e>
in
command mode to go to the start and end of the line.
Editing Plugins
These plugins enhance the editing experience in Vim.
simple-tab: A mini plugin that maps <Tab>
to <C-p>
and <S-Tab>
to
<C-n>
to complete words in the open file. I’ve tried SuperTab and other
alternatives in the past and found I don’t need most of their features. You
might not like this one unless you’re a minimalist.
splitjoin.vim: Simplifies the transition between multiline and single-line
code. In Ruby, press gS
on puts hi if true
or { key: val, key2: val }
to
split them into multiline statements, or gJ
to convert the multiline version
into the single-line one.
vim-easy-align: Plugin to help align code. I have several
maps that cover most of my usage (like aligning hash
keys on :
, or aligning multiple lines of method calls on ,
). I use these
daily to align code, typically I visually select a block and then use
<leader>a=
, <leader>a,
, or <leader>a:
.
vim-abolish: Abolish helps work with “word variants”. I use the coercion
commands the most: crs
in SomeClass
converts it to some_class
, or cr-
in some_class
converts it to some-class
.
vim-characterize: This plugin lets you press ga
on a UTF character to
see the character code. Very rarely used, but useful when I need it (and
remember to use it).
vim-commentary: A lightweight plugin to comment code based on Vim’s
'commentstring'
setting. I use the gcc
normal mode map and gc
in visual
mode to toggle comments.
vim-endwise: Smartly adds method endings when typing. Eg: def foo<cr>
will add an end
automatically. Includes multi-language support.
vim-repeat: This is a utility plugin that other plugins use (like
splitjoin.vim, vim-easy-align). It allows you to use .
to repeat
plugin commands.
vim-speeddating: Allows incrementing/decrementing dates using <C-a>
and
<C-x>
just like numbers. (Did you know <C-a>
and <C-x>
increment and
decrement numbers out of the box?)
vim-surround: Helps work with surrounding characters. For example, in
"foobar"
, press cs"'
to change surrounding from “ to ‘;
[blah]
, cs[{
changes it to {blah}
. I use this almost daily.
vim-stripper: Automatically strips trailing whitespace when saving
buffers. Files can be excluded, like Markdown, where trailing whitespace is
significant. Includes a :Stripper
command to manually strip trailing
whitespace.
File Browsing & Searching Plugins
These plugins help jump to files. I use a variety of these, and plain :e
path/to/file
depending on the context and my mood.
vim-filebeagle: Lightweight file browser, somewhere between :Explore
and
:NERDtree
. I like -
to call the browser, so I have these
settings in place. Press -
from a buffer to see
the parent directory, you can navigate around to open a new file with <cr>
or create files with +
. You can even create directories by pressing +
in
the FileBeagle browser and specifying a path ending in a /
(eg: foo/bar/
).
fzf.vim: I use the built in Vim plugin for fzf (not the
fuller-featured plugin). I have a few custom helpers and settings: :FZFBuffers
allows searching open
buffers and :FZFMRU
allows searching most recently used files.
vim-gutentags: Automatic ctags integration. I prefer to keep my tags files
under .git
, and I have some Gutentags customizations and Vim customizations in place to accommodate
that.
simple-ag: I use the_silver_searcher as a fast replacement for grep
.
I’ve used ack.vim and ag.vim in the past to integrate it with Vim, but I find
I don’t use many of their features. For that reason, I’ve implemented a simple
version that covers all of my needs. :Ag
searches for the current word under
the cursor and opens the results in the Quickfix list — :LAg
does the same
but places results in the Location List. :Ag <query>
and :LAg <query>
search for specific queries and allow options to be passed to ag
, eg: :Ag
-Q 'foo bar'
. If you use this, you probably want QFEnter.vim, which I
outlined above. Note that I wrote this over configuring 'grepprg'
because
I’ve not found a good way to silently run :grep
.
Git & GitHub Integration
I use Git and GitHub almost daily. These plugins help working with commit messages and browsing code on GitHub.
vim-git: Provides basic git integration for things like editing commit
messages or rebasing. I have a few customizations in place for commit
messages. For rebasing (eg git rebase -i
),
those same settings are included, and some handy maps are implemented to quickly change a line to “pick”, “squash”, etc.
vim-fugitive: Provides a lot more integration with Git. Some favorites are
:Gstatus
and :Gwrite
to stage things, and :Gcommit
to commit, all from
Vim.
vim-rhubarb: Provides GitHub integration. I only use :Gbrowse
— it is
a great way to browse and share code with coworkers. Use V
to make a visual
selection and :Gbrowse -
will open GitHub with those lines selected. Call
:Gbrowse!
to copy the URL to the clipboard.
simple-gist: Is a small plugin I made that allows posting buffers/lines to
GitHub Gist — basically a slightly smarter version of :w !gist
. There are
other more robust plugins out there if you want to manage Gists from Vim,
but I only need to create them.
Finally, I have an autocmd in place to update GitHub URLs to use the shorthand syntax, eg: “https://github.com/foo/bar/issue/1” becomes “foo/bar#1” when saving git commit or pull request messages.
Ruby on Rails
Ruby on Rails makes up the bulk of my day to day work. I have a bunch of plugins and customizations to help.
vim-rails: This plugin is an absolute must have if you work with Rails
projects in Vim — and the one in this list I couldn’t live without. I use
the file browsing maps daily, :Emodel
to open a model, :Econtroller
to
open a controller, :AS
to open an alternate file in a split. Using
vim-projectionist I have defined several others,
like :Eseed
to open db/seeds.rb
and :Efactory
to open factories under
spec/factories/
. It also provides enhanced syntax highlighting for Rails
specific classes and methods.
vim-ruby: Provides Ruby syntax and indentation. I use this version over
the one shipped with Vim itself because it is often more up to date. I have a
few customizations and maps setup, including <leader>d
to run the current test file and <leader>D
to run the current test line via
vim-test.
vim-test: A test runner (works for RSpec, MiniTest, lots of others). Errors are sent to the Quickfix list so you can navigate to offending tests easily. On Vim 8 I use vim-dispatch as the test strategy. Should work out of the box with Neovim. I test mostly with Ruby. My vim-test settings enable Ruby test runners and enable Dispatch as the runner.
vim-rake: Provides Rake integration for non-Rails projects. I mostly use
this for the :Elib
helper to browse files under lib/
, though I
occasionally use :Rake
.
vim-bundler: Provides Bundler integration. I’ve seen performance hits in the past with this, so I’ve installed and uninstalled it about 5 times. I’m trying it again 😀.
vim-haml: Provides syntax highlighting for HAML and SASS.
vim-ruby-minitest: Provides syntax highlighting for Minitest files.
vim-coffee-script: Provides syntax highlighting for CoffeeScript files.
Markdown, Liquid, and Jekyll
I write a ton of Markdown, for documentation at work and this blog. These plugins help.
vim-markdown: Provides Markdown syntax highlighting. This version is sometimes more up to date than the one that ships with Vim itself.
vim-marked: Integrates Marked — a Markdown viewer for macOS — with
Vim. It provides :MarkedOpen
, :MarkedClose
, and MarkedToggle
to handle
launching Marked with the current Markdown buffers loaded.
vim-liquid: Provides enhanced Markdown syntax highlighting for Liquid. Liquid is used in Jekyll/GitHub Pages, and I use it in some work projects.
vim-jekyll: Provides Jekyll integration. I use this to manage posts on this blog.
Other Syntax Plugins
Other syntax plugins I use:
nginx.vim: Provides syntax highlighting for Nginx config files.
ansible-vim: Provides syntax highlighting for Ansible config files.
vim-crystal: Provides syntax highlighting for Crystal Language files.
vim-css3-syntax: Provides extended syntax highlighting for CSS3 selectors and attributes.
html5.vim: Provides extended syntax highlighting for HTML5 tags and attributes.
vim-javascript-indent: Provides improved indentation in JavaScript files.
vim-jquery: Provides syntax highlighting for jQuery functions.
vim-bats: Provides syntax highlighting for Bats test files.
vim-applescript: Provides syntax highlighting for AppleScript files.
Supplemental
Since I’m using a package manager, I try to avoid random entries in
~/.vim/plugin
and friends. I keep a “plugin” of my own I call
supplemental under ~/.vim/plugged/supplemental
. It includes mini plugins
and other customizations. There are quite a few goodies in here if you look
around, some of which, the “simple” plugins, have been covered above.