All Projects → rstacruz → Vim From Scratch

rstacruz / Vim From Scratch

Rico's guide for setting up Vim

Labels



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

Customizations

Interoperability

Moving forward

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

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].