Let’s get this out of the way. The default vi editor is horrible. I think I first used it on my Raspberry Pi and, like many other people, had no clue what was going on.

Default Vim setup
A memory of my first Vim experience

It’s only after taking the time to experiment and explore the flexibility Vim offers can I believe that it’s the best text editor out there. This post is meant to show off some things in my Vim setup that I think can be useful to you. Also, this post assumes you have some understanding of Vim (modes, movement, basic editing). Although my vimrc is on Github, I don’t recommend copy and pasting all of it. It’s too personalized to me, instead read this post first and build up your own. My vimrc can be used as an example of how to create a unique vimrc for one’s needs.

The default version of Vim that ships on Macs is out of date so I recommend using Homebrew to brew install vim and use that latest version. Some of the plugins below require newer versions of Vim.

Make Vim Great Again

I’d seen countless people on the internet praise Vim and show off some pretty terminal screenshots of Vim. How do they do it? It’s all in their magical Vim configuration file, vimrc, which is usually placed as a hidden file in the home directory (~/.vimrc).

The Basics

The very first thing I have in my vimrc is

set nocompatible             " be iMproved
filetype plugin on

" Set utf8 as standard encoding 
set encoding=utf-8

" Use Unix as the standard file type
set ffs=unix,dos,mac

" enables syntax highlighting
syntax on 

" always show status line
set laststatus=2

" show line numbers
set number

" relative line numbers are helpful for hjkl movements
set relativenumber

" Enable mouse support in console
set mouse=a

set ruler
set showcmd


Doing this sets up the basics. Next, an awesome feature of Vim is backups. Make sure you have a .vim/tmp and a .vim/backup directory setup to make use of Vim backups.

set backup
set writebackup
set backupdir=~/.vim/backup
set directory=~/.vim/tmp

You can set it and forget it and Vim will automatically make backups of the file you edit. Having these backups has saved me on more than one occasion.

Mappings

Mappings take one Vim command and direct them to another. Some commands, like enabling spell check, can be cumbersome to type out everytime :setlocal spell spelllang=en_ca in Vim.

It is easier to create a kind of shortcut key to activate our own commands in Vim. This key is called the Leader. I define my Leader as the Space key.

let mapleader = "\<Space>"

So we can remap the spelling command seen above to something much simpler using a mapping command. There are a couple different mapping commands and you can read about the differences between them here. I prefer to use nnoremap because it keeps my commands restricted to normal mode and non-recursive.

nnoremap <Leader>sp :setlocal spell spelllang=en_ca<CR> 
au BufRead *.txt,*.md setlocal spell

When it hit <Space>sp or when I open a .txt or .md file, spell check is enabled. The <CR> at the end represents the <Enter> key and makes sure the command gets executed. To disable it, I also use a custom mapping.

nnoremap <Leader>nsp :set nospell<CR>

Once you learn the features and commands of Vim and other plugins, see which ones you use the most and remap them to quicker commands. In the long run, it will save you plenty of time.

Plugins

Plugins are programs that integrate and interface with Vim. To be able to use plugins, you need a plugin manager. I use and recommend Vundle. Other options are Pathogen and NeoBundle. This post will use Vundle as the plugin manager and will use commands specific to Vundle. For any of the following plugins, you can read about their usage and settings by typing :help [Plugin Name] in Vim after being installed.

" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
" alternatively, pass a path where Vundle should install plugins
"call vundle#begin('~/some/path/here')

" let Vundle manage Vundle, required
Plugin 'gmarik/Vundle.vim'

" Brief help
" :PluginList       - lists configured plugins
" :PluginInstall    - installs plugins; append `!` to update or just :PluginUpdate
" :PluginSearch foo - searches for foo; append `!` to refresh local cache
" :PluginClean      - confirms removal of unused plugins; append `!` to auto-approve removal

Airline

Definitely the greatest Vim plugin. Airline is a “lean & mean status/tabline for Vim that’s light as air.” The default Vim status bar leaves a lot to be desired and Airline fills this void. It integrates with a bunch of other plugins and is very customizable. If you’re looking for a first plugin, Airline is the place to start.

Airline Demo

With Vundle, add the plugin like so:

Plugin 'bling/vim-airline'

To get the nice symbols to appear, a patched font is required called powerline. You can read more about it here. Enabling the fonts, after being installed, requires these option to be set:

let g:airline_powerline_fonts = 1
let g:Powerline_symbols = 'fancy'

YouCompleteMe

YouCompleteMe is “a fast, as-you-type, fuzzy-search code completion engine for Vim.” If you’re used to writing code in an IDE, autocomplete is a logical, and sometimes essential feature to boost your productivity. YouCompleteMe currently works with C-family languages, Go, Rust, JavaScript, and Python.

YCM Example

Plugin 'Valloric/YouCompleteMe'

" Settings for integration with Airline
let g:ycm_error_symbol = '!!'
let g:ycm_warning_symbol = '>>'

" Additional autocomplete settings
let g:ycm_complete_in_comments = 0
let g:ycm_complete_in_strings = 1

" What's this?
let g:ycm_global_ycm_extra_conf = '~/.ycm_extra_conf.py'

There are plenty of customizable settings for YCM and I encourage you to read through the help menu to see them all. For YCM to complete C-family languages, it requires an addtional configuration file to function, .ycm_extra_conf.py. There is an addtional Vim plugin that will generate this file for you, provided that there is a Makefile for your current code project in the current directory. I also remap this generation command.

" For generating file required for YouCompleteMe
Plugin 'rdnetto/YCM-Generator' 
" Remap to Control-Y
nnoremap <C-y> :YcmGenerateConfig <CR>

Ok…but what about the Makefile? I still have to generate that for each project. This is where a project of mine started from. Pymake will automatically generate the Makefile for you based on the files in your current working directory. The global config file you see in the code snippet above is a fallback config file that may not always be the right fit for the project I’m working in. To tie everything together, it made complete sense to script the whole thing in my vimrc:

function SetupDevEnvironment()
	" make sure dev environment hasn't already been setup
	if !empty(glob("./Makefile")) || !empty(glob(".ycm_extra_conf.py"))
		echom "It appears that your dev environment is already setup."
		return
	endif
	" save existing file
	silent write 
	" generate Makefile in background
	silent !pymake	
	" generate YCM config in background
	silent YcmGenerateConfig 
	" Restart YCM so it detects new config
	silent YcmRestartServer
	redraw! 
	echom "Developer environment created!"
endfunction

nnoremap <Leader>sd :call SetupDevEnvironment() <CR>

nnoremap <Leader>f :YcmCompleter FixIt <CR>
nnoremap <Leader>d :YcmCompleter GetDoc <CR>
nnoremap <Leader>t :YcmCompleter GetType <CR>

In addition to the function, I have a few YCM specific mappings. The first is the most useful. When YCM and detects a syntax error or another minor error, I can place my cursor on that current line, hit <Leader>f and it will automatically correct the error for me!

Syntastic

Syntastic is a syntax checking plugin for Vim that utilizes external syntax checkers and displays any errors to to the user with tight integration with Airline. Syntastic can also automatically check your syntax everytime you write to disk. You can customize the feedback mechanism and have it display error messages in your statusline.

Plugin 'scrooloose/syntastic'
set statusline+=%#warningmsg#
set statusline+=%{SyntasticStatuslineFlag()}
set statusline+=%*

Syntastic Example

Fugitive

There is no other plugin that comes close to Fugitive for a git wrapper for Vim. My entire workflow in git can be done through Fugitive, without leaving the comfort of Vim.

Plugin 'tpope/vim-fugitive'
" Sample of my fugitive-specific mappings
nnoremap <Leader>gc :Gcommit<CR>
nnoremap <Leader>gd :Gdiff<CR>
nnoremap <Leader>gb :Gblame<CR>
nnoremap <Leader>gs :Gstatus<CR>

NERD Tree

NERD Tree is a plugin to help you explore your filesystem and open files in Vim. Its very helpful for quickly switching between files and directories.

Plugin 'scrooloose/nerdtree'
" Close NERDTree if its only window open
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType") && b:NERDTreeType == "primary") | q | endif 
" These two open NERDTree on start if no file specified on launch
autocmd StdinReadPre * let s:std_in=1 
autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif
" Toggle NERDTree on and off
nnoremap <C-n> :NERDTreeToggle <CR> 

The long command is too tedious to type everytime. Mappings to the rescue. Sometime I start Vim, but don’t specify the file, so I have NERD Tree start if no file is specified and I can quickly find my way around my file system.


Color Schemes

VimColors.com highlights a wide variety of colorschemes for Vim. Take a look and choose one that fits you. I use Molokai and like it (it’s the scheme in the gif above). Choosing the right color scheme can brighten up your Vim setup and make it more enjoyable to work in.

Vim Jokes

Here’s a collection of some great Vim jokes I’ve seen around the Internet. Quitting Vim





The plugins, mappings, and configurations you see above just scratch the surface. I encourage you to tinker and experiment with Vim and the numerous plugins out there. I’ve tried to cover the basics of Vim customizations that will work for almost everybody, but there are many more customizations that can help you and your workflow, you just need to find them. :wq