Effective Rails Development with Vim

Islam Wazery
Share

Vimlogo.svg

If you are new to Vim, be sure to read my introduction as it will help prepare you for this article. Here, I am focusing on using Vim for effective Rails development.

Rails Plugin

Tim Pope wrote a very useful Vim plugin called [Rails.vim][1] that provides a lot of great functionality, including enhanced syntax highlighting, partial extraction, and easier navigation in a Rails project.

Installation Using Vundle

As we saw in the previous tutorial, it’s very easy to install any plugin using Vundle. Just add the following line inside the call vundle#begin() and call vundle#end() block:

Plugin 'tpope/vim-rails'

After that, type :PluginInstall, hit enter, and Vundle will do the rest. Restart Vim and Rails.vim will be ready to use. Actually the plugin URL is https://github.com/tpope/vim-rails but as we have seen in the previous tutorial we don’t need to add the Github URL because Vundle will add it automatically, as it uses Github by default for the plugin sources.

All of the commands in Rails.vim are namespaced under the letter R. As such, to access any of the commands while browsing any Rails (.rb, .erb, ..etc) file, type :R and hit tab twice to view a list of them. You can browse the documentation typing :help Rails

Jumps Using gf

There is an exception to the rule that every Rails.vim command begins with the letter :R, which is gf (short for Go to File). The default behavior of Vim when typing gf with the cursor on a file name is to open up that file. However, when using Rails.vim this behavior is modified, so if you type gf on any identifier it will take you to the file where it’s specified. For example, when typing gf with the cursor positioned on the word “company”, Vim will take you to the Company model:

has_one    :company

Also, if you try this on any method, Vim will also take you to the file where the method is defined, even if it is a Rails built-in method. Browse the routes file, hit gf on any identifier, and you will find that Vim now understands where it’s defined.

get "home",    to: "pages#home",    as: "home"

If the cursor is on home, Vim will take you to the PagesController and place the cursor on the home action inside it. This also works on partials, named routes, and many other Rails identifiers.

NOTE:
1- In order for this to work, make sure you open Vim from the Rails project directory.
2- To go back to the previous file, hit CTRL + o in command mode.
3- To jump forward in files visited, hit CTRL+ i.
4- To view the list of visited files, hit :jumps.

Navigation in project files

Rails.vim allows easy navigation through different project files, like models, view, or controllers. You can easily jump to any one of them, as well as to a specific line or method. Let me explain how to do that.

Navigation Command Value
Rcontroller Jump to relevant controller, as if you are in a model file, and you want to jump to its controller.
Rmodel Jump to the model
Rview Just add the name of the view like (index, show, edit) to jump to the relevant view.
Runittest Jump to the relevant unit test.
Rfunctionaltest Jump to the relevant test.
Rintegrationtest Jump to the integration test, integration spec, or cucumber feature specified.
Rspec Jump to the given spec.
Rmigration Use tab completion to choose from the available migrations and jump to one of them.
Rschema Jump to the project schema.
Rmailer Jump to the given mailer.
Rhelper Jump to the given helper.
Rjavascript Jump to given JavaScript or CoffeScript file.
Rstylesheet Jump to given stylesheet.
Rtask Jump to given task.
Rlib Jump to given lib, if no arguments specified it jumps to the Gemfile.
Rlayout Jump to the layout of the current controller.

NOTE:
You can specify the controller, model, view, or test file you want to open by typing its name. Also, Vim provides tab completion while typing file names.

Open Files in Split Windows

If you want to open a file in a split window, just type :RV, instead of :R, and the item you wish to open (model, view, controller, etc.) This opens the file in a vertical split. If you want to a horizontal split, use :RS

Open Files in New Tabs

You can open any Rails file in a new window just use :RT instead of :R.

Open Files in Current Buffer

You can open any file in the current buffer (which means appending its content to the current cursor position in the current file) using :RD.

Running Tests

Why leave the text editor just to run the tests? Rails.vim gives you the ability to run tests directly from the editor, by simply typing :Rake. You can also run subsets of tests, like functional tests, unit tests, integration tests, Cucumber features, RSpec specs.

Generating Migrations

Why to leave Vim to run a migration? Just type :Rgenerate migration add_something_to_tablename. It will not only generate the migration, but also takes you to the file, which is really useful and saves time.

Inverting a Migration

What if you want to invert a migration, use :Rinvert.

Running, Restarting, and Killing the Server

  • You can run the server process from Vim using :Rserver.
  • You can stop the existing process and run a new one (restart the server) with :Rserver!.
  • You can kill the running server with :Rserver!-.

Viewing the Current Relevant Path

If you want to open the correct URL for the current file, like app/controllers/companies_controller.rb, type :Rpreview. It will open “/companies”, provided the server is running.

NOTE:
This command is context aware, so if you issued it on the index action of the CompaniesController, it will take you to the relevant route /companies/index

Partial Extraction

Rails.vim plugin offers a very handy feature called partial extraction. It is a bit tedious to extract some ERB to a partial, because that involves steps like cutting some text, creating a new file with a name that begins with _, and pasting that text, then refactoring the original view to include the partial. Why not let Vim handle that for you in an easy command.

If this is your file, in app/views/user/show.html.erb:

20   <div>
   21     <h2><%= @user.name %></h2>
   22     <p><%= @user.email %></p>
   23   </div>

And you issue this command:

:21,22Rextract profile

Your file changes to this:

20   <div>
   21     <%= render 'profile' %>
   22   </div>

A new file will be created with the relevant code in the relevant path. app/views/user/_profile.html.erb now contains:

1    <h2><%= @user.name %></h2>
   2    <p><%= @user.email %></p>

The Rextract command will behave differently depending on the file in which it is issued. If you are in a view, it will extract the code to a partial. If you are in a helper, it will create a helper with the extracted code. If you are in a model or controller, it will create a new concern with the extracted code.

SnipMate

SnipMate is a very useful plugin for managing code snippets. It saves a lot of time when writing code and you will find yourself using its shortcuts to create large code snippets. SnipMate also supports other languages, like JavaScript and HTML.

Installation

Using Vundle just add the following line inside the call vundle#begin() and call vundle#end() blocks:

Plugin 'garbas/vim-snipmate'

Call :PluginInstall and restart Vim.

Ruby Snippets

Now you can use the snippets. Open up a controller file, type def, then hit the tab key. Vim will insert the def end block, highlight the method name, and enter insert mode for you. After typing the method name, hit the tab key again and the cursor will jump inside the method definition. Pretty useful, right?

There are many other useful snippets, like:

Code block Shortcut
if end block if
if else end block ife
Each block ea
Each with index eawi
Map map
Collect col
Select sel
Scan sca
Class cla

To view the full list of available Ruby snippets, open the ~/.vim/snippets/ruby.snippets file.

You can also add your own snippets to that file, just follow the format. Let’s take the if end snippet as an example:

snippet if
        if ${1:condition}
                ${2}
        end

The word if after snippet is the snippet name. The next line is the snippet itself. ${1 is the first place the cursor will land and the word “condition” will be there highlighted and ready for replacement. ${2} is the next cursor position after the user hits the tab key. I recommend you to add your own snippets to enhance your editing efficiency.

CTags

Another useful tool is Exuberant Ctags. It enables you to navigate easily through your project source code. It indexes the source code objects to tags, which makes it easy for the editor to locate any source code object and jump to its definition.

Installation

First, you need to make sure that Ctags is not installed on your system. Type which ctags, if it returns with a result like ctags: aliased to /usr/local/bin/ctags, then you don’t need to install it.

If you do need to install it, here are instructions for various platforms. If you are using Fedora Linux, download the RPM package. If you are using MacOSX, use Hombrew to install it by typing brew install ctags. On Ubuntu, there is a package called exuberant-ctags which you can install with the apt-get package manager.

Running Ctags

To run Ctags on your project source code, type ctags -R --exclude=.git --exclude=log * from the root of your Rails directory. The capital R argument here makes it recursive. We exclud the .git directory, for obvious reasons.

A file named tags is now generated, which you should add it to the .gitignore file.

The final step is to add the following line to the vimrc file to tell Vim where to look for the tags file.

set tags=./tags;

Ctags is now ready. Go to any source file, position the cursor on any method, and hit CTRL + ]. Vim will jump to the definition.

For example:

flash[:alert] = 'alert'

If the cursor is on flash and you hit CTRL + ], Vim will jump to its source definition. This is very handy for viewing Rails source and learning more about it.

NOTE:
You can jump to definitions by typing tag method_name. To jump to has_many type :tag has_many.
You can use regular expressions like :tag /validate*

Ack

Ack is an awesome replacement for grep. Ack searches files for lines containing a match to the given pattern. With no file selected, Ack searches through regular files that are not explicitly excluded by the --ignore-dir and --ignore-file options, either present in the ackrc files or on the command line.

Installation

On MacOSX you can install Ack using Hombrew by typing brew install ack in the terminal. On Ubuntu you can do that by sudo apt-get install ack-grep, also you can refer to this [site][2] for other supported operating systems.

Easy Searching Source Code

You can use Ack from the terminal and from Vim. To use it from Vim as a replacement for grep just add the following line to the vimrc file:

" Use ack instead of grep
set grepprg=ack

You can use Ack from the terminal by typing ack --ruby controller, which will print all the lines with the word “controller”.

Now, if you type :grep controller in Vim, it will use Ack to search the project files for the occurrences of “controller” and print the lines where it is found.

Editing .ackrc config

We probably want to ignore the log and assets files, right? We can do so with a config file called ackrc placed in the project directory. It can also be placed in your home directory for global configuration.

Ignore the log and assets files with the following lines:

--ignore-dir=log
--ignore-dir=public/assets

Quick Navigation Through Results

When using grep some_text in Vim, it will print the lines of its occurrences. When you hit Enter, it will jump to the first occurrence. How do you move to the next one?

Simply type :cn to go to the next result, and :cp to jump to the previous.

tComment

There is a useful plugin for commenting and uncommenting Ruby code called tComment. It works like a toggle, allowin the selection of large chuncks of code to be commented/uncommented with a single shortcut.

Installation

Just like the previous examples, installation is easy with Vundle. Just add the following line to your vimrc inside the call vundle#begin() and call vundle#end() blocks:

Plugin 'tomtom/tcomment_vim'

Call :PluginInstall and restart Vim.

Usage

Here is a list of shortcuts provided by the tComment plugin:

Shortcut Description
gc{motion} Toggle comments
gcc Toggle comment for the current line
gC{motion} Comment region
gCc Comment the current line

Vim RSpec

Thoughtbot created a very handy plugin for running RSpec tests from Vim. It’s a big time saver, allowing RSpec specs to be fired off from inside Vim. The Vim RSpec plugin is strongly influenced by Gary Bernhardt’s Destroy All Software screencasts.

Installation

Add the following line to your vimrc inside the call vundle#begin() and call vundle#end() blocks:

Plugin 'thoughtbot/vim-rspec'

Call :PluginInstall and restart Vim.

Usage

Here are the default key mappings that RSpec plugin provide. You can customize it and add your preferred key mappings to the .vimrc file.

" RSpec.vim mappings
map <Leader>t :call RunCurrentSpecFile()<CR>
map <Leader>s :call RunNearestSpec()<CR>
map <Leader>l :call RunLastSpec()<CR>
map <Leader>a :call RunAllSpecs()<CR>

Ruby Refactoring

Ruby Refactoring is a plugin written by Enrique Comba Riepenhausen to make refactoring Ruby easier. As he states in the readme, Ruby Refactoring is inspired by some refactoring patterns that Gary Bernhardt presented at the Software Craftsmanship User Group UK.

Installation

Add the following line to your vimrc inside the call vundle#begin() and call vundle#end() blocks:

Plugin 'ecomba/vim-ruby-refactoring'

Call :PluginInstall and restart Vim.

Usage

Have a look at the excellent documentation Justin provides, which covers everything you need to use this plugin.

Learning Resources

1- Using Vim as a Complete Ruby on Rails IDE
2- Ruby autocomplete
3- Intro – Rails Vim
4- Vim Bundler plugin
5- Endwise plugin

Summary

In this tutorial, we covered some of the most useful Vim plugins for writing Rails. If you followed all my suggestions, your Vim editor is now an effective RoR IDE. Good luck!

CSS Master, 3rd Edition