June 25th, 2013

My Vim Setup With a Hint of Workflow

Everyone has their favorite text editor and their own workflow to go along with it. In this post I’m going to go over how I use Vim and what my workflow consists of when working on a Rails project. It can be interesting to look into how others work with their tools and compare it to your own workflow.

Foreword

If you’re just now looking into or diving into Vim you might not want to start with a lot of plugins or custom configuration options. I suggest slowly incorporating things into your workflow as you need them and you’ll find that you will have much better results.

Plugins

I have a fairly large amount of plugins and I will go over each of them briefly with the exception of language syntax plugins.

Vundle NERDTree ctrlp Ack Miscellaneous Plugins

Vundle

Vundle is what I use to manage my Vim plugins. You install this plugin and can add Github repo links in your .vimrc so that Vundle can install them for you.

Bundle 'tpope/vim-rails'
Bundle 'tpope/vim-rake'

Think of it as apt-get or homebrew for Vim plugins. All you do is call Bundle followed by Github Username/Repo. Then you can run :BundleInstall and Vundle will install all of the plugins specified in your vimrc.

NERDTree

NERDTree is probably the most important and useful plugin that I have. This is what I use to show all the files in the current project I’m working on. You can open NERDTree in the current directory or specify a directory using :NERDTree. I have Vim configured where I can run mvim . or any other directory, and it will open a new Vim window with NERDTree open in the specified directory. I do this with a little autocommand magic that checks if the first argument is a directory.

if isdirectory(argv(0))
    bd
    autocmd vimenter * exe "cd" argv(0)
    autocmd VimEnter * NERDTree
endif

Really simple, just cd’s to the directory and opens up a NERDTree there. From there I just use NERDTree to open files in current tabs with o, new tabs with t, and splits with i. You can also use it to create, rename and delete files with m.

There are a few cons to NERDTree that just require you working around them a bit. NERDTree won’t look for new files unless it creates or modifies them so you have to manage this yourself. You can reload a file or an entire directory with r, or all of them with R. NERDTree also doesn’t persist among tabs meaning if you create a new tab, you’ll have to create a new NERDTree in that window. I personally enjoy this so I can set a different part of the application to be the root in NERDTree in certain tabs, or just have more screen real estate.

ctrlp.vim

ctrlp is a nice “fuzzy finder” plugin for Vim. I have ctrlp bound to CMD+T in my .gvimrc.

if has("gui_macvim")
    macmenu &File.New\ Tab key=<nop>
    map <D-t> :CtrlP<CR>
endif

I use this when I’m too lazy to go through the files in my NERDTree or when it would just take too long. I just hit the shortcut and start typing out the file that I want to open and hit enter when I find the one I’m searching for.

Be sure to use let g:ctrlp_use_caching=0 if you want your files to be updated without having to reload.

Ack

Ack.vim, is basically a Vim wrapper around the perl script Ack. This is a very simple program where you can just run :ack <pattern> and it will recursively search files content in the current directory (The directory NERDTree is on) for your regex pattern. This is very useful for searching for phrases you need to replace, or even console.log lines that you want to remove from your Javascript.

I personally have this bound to <leader>a :Ack with an extra space on the end so that I can just hit space a <pattern> to search through my files.

Miscellaneous Plugins

These are plugins that have a decent use, but not enough to be part of their own writeup.

  • vim-rails is useful for creating migrations and for the Rails specific syntax highlighting.
  • Gitv is good for browsing your Git commits visually. A good gitk replacement.
  • Tomorrow-Night is my custom version of the Tomorrow-Night theme for vim. So far it’s my favorite colorscheme for Vim.
  • Fugitive is an amazing Git wrapper for vim.
  • Statuslight is my custom replacement for Powerline.vim since they deprecated the Vim version in favor of their new horrible Powerline scripts.

If you’re interested in all of the plugins that I use check out my .vimrc in my dotfiles repo.

Vim Shortcuts

Vim has a lot of shortcuts that can help out your workflow. Here are some of my most used shortcuts that don’t require plugins.

  • G goes to the end of the file
  • gg goes to the top of the file
  • gg=G indents the entire file
  • == indent the current line

There are also ways to map your own shortcuts using something called a leader key. I personally have my leader key mapped to space since it’s much easier than the default \. Some people enjoy , but I prefer the space key.

nnoremap <space> <Nop>
let mapleader = " "

Since I use splits quite often I have the navigation keys in combination with leader to navigate splits.

nnoremap <leader>h <C-w>h
nnoremap <leader>j <C-w>j
nnoremap <leader>k <C-w>k
nnoremap <leader>l <C-w>l

This way I can just hit <space><key> to go to whatever split is in that direction. This is much easier and faster than the default ctrl+w <direction>.

I also have <space><space> mapped to :noh so after doing a search I can easily stop highlighting the results.

nnoremap <leader><space> :noh<cr>

Finally, we have nnoremap <leader>a :Ack mapped to run :Ack since this is something I run fairly often.

File indents

For different languages we have different conventions for how we indent files. I always have vim using spaces via set expandtab rather than tabs.

autocmd FileType text setlocal textwidth=78
autocmd FileType markdown setlocal wrap
autocmd FileType ruby setlocal shiftwidth=2 tabstop=2
autocmd FileType javascript setlocal shiftwidth=2 tabstop=2
autocmd FileType coffee     setlocal shiftwidth=2 tabstop=2
autocmd FileType handlebars setlocal shiftwidth=2 tabstop=2
autocmd FileType scss  setlocal shiftwidth=2 tabstop=2
autocmd FileType css   setlocal shiftwidth=2 tabstop=2
autocmd FileType html  setlocal shiftwidth=2 tabstop=2
autocmd FileType eruby setlocal shiftwidth=2 tabstop=2
autocmd FileType eco   setlocal shiftwidth=2 tabstop=2

This just specifies which languages have what kind of indents. As you can see I really enjoy 2 indents on almost everything, but this is definitely personal preference.

My default in my vimrc is 4 space indents unless specified in the previous snippet.

set tabstop=4
set shiftwidth=4

Documentation

I suggest documenting everything in your vimrc as you go along. If you look at my Dotfiles vimrc you can see I documented almost everything that my vimrc does. This can help you and others out by being explicit about everything your vimrc does. I also suggest open sourcing and keeping your dotfiles on Github so you can easily git clone your dotfiles onto any computer or box you want them on with very little hassle.