Press "Enter" to skip to content

Learning Vim through Web Development, A Top Down Approach. Part 3: Ruby and Rails

In my last post I said that I would be looking at configuring my Vim setup for JavaScript. The intent was to come up with a viable setup React, since I work with it professionally. I switched gears this week for two reasons:

    1. Given that JSX is kind of a mesh between JavaScript and XML, I didn’t reach a point where I felt comfortable with some of the snippets and keybindings available.
    2. I really wanted to focus on getting a decent Ruby/Rails setup so I can start using it at work.




The star of of the configuration is the vim-rails plug-in. It provides enhanced syntax highlighting for Rails specific method calls and simplified navigation through the Rails directory structure. For instance, entering

in normal mode will open the Articles controller. It also has tab completion, so entering
:Econ followed by tab will expand to :Econtroller.


The next important plugin in this configuration is vim-ruby. It provides improved syntax highlighting, and shortcuts for navigating and selecting text. For example, ]m and ]M will go to the start and end of the next method definition respectively. In visual mode, typing am selects the entire method, and im selects the inner method, excluding the def and end parts.


Supertab is a great plugin for code completion. Hitting tab after entering partial text will render a contextual menu based on the context of the surrounding code, as illustrated below.

Vim-test and Vimux

For running tests, I’m using the vim-test plugin. My current configuration uses the vimux strategy.

let test#strategy = "vimux"

Vimux is a plugin that allows easy interaction with tmux. When running vim inside of a tmux session, vim-test will open a tmux split pane and execute the test inside of it. This is convenient for maintaining a visual representation of the test being executed, and nicely replicates the functionality of a dedicated test view that you will find in most IDEs. Note that this particular strategy will only work inside a tmux session. If tmux is not being used, another strategy would make the most sense.

In order to enable executing tests with the click of a button, I mapped a single key, preceded by the leader key, to vim-test’s execution commands.

" Test config
nnoremap  t :TestFile
nnoremap  s :TestNearest
nnoremap  l :TestLast
nnoremap  a :TestSuite
nnoremap  gt :TestVisit


A great plugin for linting your code is ALE, an asynchronous linter that supports several languages and tools. In the snapshot shown below, ALE detects the rubocop, configuration, and marks the offending lines of code, and provides the error message in the bottom margin that rubocop raises, depending on the position of the cursor.


In my current role, we use slim for authoring our server-side templates, and vim-slim is a great plugin for adding syntax highlighting to your slim files.

One of the things I love about slim is the minimal syntax necessary to edit rails templates. Nesting is determined by indentation, which is perfectly suited for an editing tool like Vim.

Vim-Rake, Vim-Bundler, and Vim-Dispatch

vim-rake and vim-bundler provide access Rake and Bundler respectively via Vim’s command mode. With vim-dispatch installed, the tasks can execute asynchronously in the background, allowing you to continue to edit or run other tasks without Vim being blocked (Note: vim-test also has a strategy for using vim-dispatch for test execution).


One thing to note about my current configuration is the removal of the nerdtree plugin. I haven’t worked with it enough to determine if it was an actual hindrance to my workflow, but being cognizant of the number of plugins being pulled in, and looking for opportunities to trim down whenever possible, I learned of vim’s built in file management system netrw in this blog post by George Ornbo.

vim-vinegar is a plugin that enhances netrw. Pressing - key opens the directory listing, which can be navigated with the j and k keys.

Pressing - again will bring you to the parent of the current directory. Pressing enter will open either the current file or directory of the cursor position.

Vim-Commentary, Vim-Sensible, Vim-Surround, and Vim-Repeat

vim-commentary has replaced nerdcommenter as the code comment plugin in my current configuration. This was motivated purely by experimentation.

vim-sensible is a plugin that provides a universal set of defaults for Vim. What I’ve primarily noticed when using it while it is installed is the ability to backspace through tabs.

vim-surround provides the ability to surround or remove quotations, parentheses, braces and brackets from the selected text. I installed this because it seemed useful, but I haven’t trained my muscle memory to make heavy use of it yet.

vim-repeat allows the . command to repeat actions from a number of supported plugins.

Current Configuration

" General config
set nocompatible
set number
syntax on

let mapleader = " "

" Plug config
call plug#begin('~/.vim/plugged')
  Plug 'morhetz/gruvbox'
  Plug 'ctrlpvim/ctrlp.vim'
  Plug 'vim-scripts/'
  Plug 'mileszs/ack.vim'
  Plug 'vim-airline/vim-airline'
  Plug 'vim-airline/vim-airline-themes'

  " code plugins
  Plug 'tomtom/tlib_vim'
  Plug 'MarcWeber/vim-addon-mw-utils'
  Plug 'garbas/vim-snipmate'
  Plug 'honza/vim-snippets' 
  Plug 'mattn/emmet-vim'
  Plug 'ap/vim-css-color'
  Plug 'ervandew/supertab'
  Plug 'tpope/vim-bundler'
  Plug 'tpope/vim-commentary'
  Plug 'tpope/vim-dispatch'
  Plug 'tpope/vim-endwise'
  Plug 'tpope/vim-eunuch'
  Plug 'tpope/vim-rails'
  Plug 'tpope/vim-rake'
  Plug 'tpope/vim-repeat'
  Plug 'tpope/vim-sensible'
  Plug 'tpope/vim-surround'
  Plug 'tpope/vim-vinegar'

  " Javascript plugins
  Plug 'pangloss/vim-javascript'
  Plug 'mxw/vim-jsx'

  " Ruby and Rails plugins
  Plug 'slim-template/vim-slim'
  Plug 'vim-ruby/vim-ruby'
  Plug 'janko-m/vim-test'

  Plug 'benmills/vimux'
  Plug 'w0rp/ale'
call plug#end()

" Colorscheme
colorscheme gruvbox

" key mappings
noremap  :!open %

" tab settings
set tabstop=2
set softtabstop=2
set shiftwidth=2
set expandtab

" ignore
set wildignore+=*/node_modules/*,*/tmp/*

" Test config
nnoremap  t :TestFile
nnoremap  s :TestNearest
nnoremap  l :TestLast
nnoremap  a :TestSuite
nnoremap  gt :TestVisit

let test#strategy = "vimux"


My next post will discuss JavaScript and JSX. A special thanks to Hashrocket, Thoughtbot, and Brian P. Hogan, whose vimrc files provided a ton of guidance for this configuration, and to Tim Pope for authoring so many awesome plugins.


Hashrocket Dotmatrix
Thoughtbot Dotfiles
Brian P. Hogan Dotfiles
Vim: You don't need NERDTree or (maybe) netrw