vim-from-scratch icon indicating copy to clipboard operation
vim-from-scratch copied to clipboard

Rico's guide for setting up Vim

trafficstars

Deprecated: Thanks for checking my project! The guide below was made for older versions of Vim. Today, you can try nvim-starter or kickstart.nvim for Neovim.



Vim from scratch

Rico's guide to setting up Vim for
everyday development


This guide will walk you through setting up a practical config that will work on Vim, Neovim, Macvim, and any other Vim implementation out there.

Getting started

  • Install Vim and Neovim
  • Back up your existing config
  • Create ~/.vim
  • Create your .vimrc
  • Set up symlinks

Customizations

  • Add vim-plug
  • Set up plugins
  • Set up additional options
  • Set up key bindings
  • Set up the leader key

Interoperability

  • With GUI Vim apps
  • Between Vim and Neovim
  • With Oni

Moving forward

  • Commit your config
  • Share your config
  • Learn more about Vim
  • Look at other configs

Install Vim and Neovim

(Skip this step if you've already installed Vim.)

There are many ways to acquire Vim. I suggest using Neovim, a fork of Vim with extra features--but regular Vim would work just fine.

  • Vim on Linux
    Most distributions come with vim and neovim packages. Some distributions have different versions available. When in doubt, pick the vim-gnome or vim-gtk3 or gvim package.

    sudo pacman -S gvim         # Arch Linux
    sudo apt install vim-gnome  # Ubuntu
    
  • Neovim on Linux
    If your distro ships with python-neovim, add it in too.

    sudo pacman -S neovim python-neovim
    
  • Neovim on MacOS
    The neovim package is available in Homebrew.

    brew install neovim
    # (todo: add more notes on python integration etc)
    
  • Vim on MacOS
    I recommend using Macvim with installed via Homebrew with --override-system-vim. This gets you a more updated version of Vim than if you used the vim package. You'll also get a GUI app, which can be nice.

    brew install macvim --with-cscope --with-lua --override-system-vim --with-luajit --with-python3
    

Back up your existing Vim config

(Skip this step if you're setting up a fresh installation of Vim.)

Want to try out this guide, but you already have Vim set up? You can rename them for now, and restore it later on.

mv ~/.vimrc ~/.vimrc~
mv ~/.vim ~/.vim~
mv ~/.config/nvim ~/.config/nvim~

Create your ~/.vim

The first obvious step is to create your config folder. Vim expects this in ~/.vim, and Neovim expects it in ~/.config/nvim. Since our goal is to make a Vim config that'll work everywhere, I suggest keeping it in ~/.vim and symlinking it as needed.

mkdir -p ~/.vim
cd ~/.vim

# Version it using Git
git init
git commit -m "Initial commit" --allow-empty

Create your init.vim (aka .vimrc)

Vim looks for your config in ~/.vimrc, and Neovim looks for it in ~/.config/nvim/init.vim. Let's create the file as ~/.vim/init.vim, which we will symlink to the proper locations later.

cd ~/.vim
touch init.vim

Set up symlinks

My preferred method is to create a Makefile which will set up symlinks as necessary. In ~/.vim, create a file called Makefile and add this in:

# Makefile
pwd := $(shell pwd -LP)

link:
	@if [ ! . -ef ~/.vim ]; then ln -nfs "${pwd}" ~/.vim; fi
	@if [ ! . -ef ~/.config/nvim ]; then ln -nfs "${pwd}" ~/.config/nvim; fi
	@ln -nfs "${pwd}/init.vim" ~/.vimrc

After creating it, just run make link. This should finally make your config available in both ~/.config/nvim/init.vim and ~/.vimrc.

# Before doing this, make sure you don't have ~/.vimrc (careful!)
rm ~/.vimrc

# Set up symlinks
cd ~/.vim
make link

Install vim-plug

vim-plug is the plugin manager I can recommend the most. It's ridiculously fast, and supports a lot of great features. This command will download plug.vim into your Vim config path:

curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
  https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

Edit your config file by doing vim ~/.vim/init.vim. Add the following:

set nocompatible
let g:mapleader=" "

call plug#begin('~/.vim/vendor')

if !has('nvim') && !exists('g:gui_oni') | Plug 'tpope/vim-sensible' | endif
Plug 'rstacruz/vim-opinion'

call plug#end()

Save it, restart Vim, then call PlugInstall.

" Save the file and exit vim
:wq

" Start vim again, then install the plugins
:PlugInstall

See: vim-plug usage (github.com)

Install plugins

The config above will install 2 plugins. Both are optional, but I recommend them:

  • vim-sensible enables some good "sensible" defaults, such as turning on syntax highlighting. This is superfluous in some vim forks like Neovim so I suggest to conditionally load it only when needed.

    if !has('nvim') && !exists('g:gui_oni') | Plug 'tpope/vim-sensible' | endif
    
  • vim-opinion enables some good "opinionated" defaults that I prefer (I'm the author of this plugin!). This has some settings that I think will do well for most setups, such as incremental search and so on.

    Plug 'rstacruz/vim-opinion'
    

More plugins

Here are some more that I can recommend to almost every developer:

  • fzf is a very fast file picker. I recommend this over alternatives like ctrlp.vim.

    Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
    Plug 'junegunn/fzf.vim'
    
  • ale verifies your files for syntax errors.

    Plug 'w0rp/ale'
    
  • vim-sleuth auto-detects if files use space or tabs, and how many spaces each file should have.

    Plug 'tpope/vim-sleuth'
    
  • vim-polyglot adds automatic language support for every language that Vim can support through 3rd party plugins.

    Plug 'sheerun/vim-polyglot'
    

Set up additional options

Our config so far has vim-sensible and vim-opinion, which has some great defaults. You may want to add more settings. Instead of dumping them into ~/.vimrc, I suggest adding them to your after-directory instead. This will keep your config file as clean as possible.

mkdir -p ~/.vim/after/plugin
vim ~/.vim/after/plugin/options.vim

Here are some stuff you can add. All of these are optional.

" Enable 256-color by default in the terminal
if !has('gui_running') | set t_Co=256 | endif

" Hide line numbers by default
set nonumber

" Wildignore
set wig+=vendor,log,logs

See: Keep your vimrc clean (vim.wikia.com), ~/.vim/after _(learnvimscriptthehardway.stevelosh.com)_

Set up additional key bindings

I suggest keeping most (all?) of your key bindings in one file in your after-directory. I prefer to keep them in ~/.vim/after/plugin/key_bindings.vim. This way, you can

vim ~/.vim/after/plugin/key_bindings.vim
" ctrl-s to save
nnoremap <C-s> :w<CR>

" ctrl-p to open a file via fzf
if exists(':FZF')
  nnoremap <C-p> :FZF!<cr>
endif

" SPC-f-e-d to edit your config file
nnoremap <leader>fed :cd ~/.vim<CR>:e ~/.vim/init.vim<CR>
" SPC-f-e-k to edit your kepmap file
nnoremap <leader>fek :cd ~/.vim<CR>:e ~/.vim/after/plugin/key_bindings.vim<CR>
" SPC-f-e-o to edit your options file
nnoremap <leader>feo :cd ~/.vim<CR>:e ~/.vim/after/plugin/options.vim<CR>

The leader keymaps at the end can be triggered with the Spacebar as the leader key. For instance, the first one is SPACE f e d. These are inspired by Spacemacs.

Change your leader key

The default init.vim above has a g:mapleader setting of spacebar. This is a great default that a lot of people use! I personally prefer the , key as a Dvorak user, but this is totally up to you. Common leader keys are <space>, <cr>, <bs>, - and ,.

" In your ~/.vim/init.vim
let g:mapleader=","

See: Leaders (learnvimscriptthehardway.stevelosh.com)

Interoperability with GUI Vim apps

There are many Vim GUI apps available today. Some popular ones include Macvim, VimR, vim-gtk and more are probably coming out everyday.

There are some settings you might only want to use on GUI. You can use if has('gui_running') to conditionally only apply settings when running in a GUI.

Like most settings, I suggest placing them in the after-directory, eg, ~/.vim/after/plugin/theme.vim. Here's an example that sets fonts for GUIs:

" ~/.vim/after/plugin/theme.vim

if has('gui_running')
  " Settings for when running in a GUI
  set transparency=0
  set guifont=Iosevka\ Medium:h16 linespace=-1
  set guioptions+=gme " gray menu items, menu bar, gui tabs
  set antialias
  color ir_black+
else
  " Settings for when running in the console
  color base16
endif

Interoperability between Vim and Neovim

TODO: talk about has('nvim'), config paths, etc

Interoperability with Oni

TODO: talk about exists('g:gui_oni')

More to come!

This guide is a work in progress, more stuff soon! But at this point you should have a working Vim config. Commit it, and share it!

Here are some more resources to look at:

Icon from Thenounproject.com