Thanks to the always awesome Tim Pope,
Rails.vim version 5 was
released
a month ago, and with it comes a new way to configure navigation
commands. The new projections.json
replaces editor.json
, which in
turn replaced Rnavcommand
.
Projections allow you to define custom ways to navigate to files, open related files, or create files with boilerplate if the file does not exist.
Here are some examples for predefined navigation commands that you may recognize:
Assuming we are in
app/models/user.rb
,:AV
will open upspec/models/user_spec.rb
in a vertical split.To create a new file
app/controllers/users_controller.rb
, simply enter:Rcontroller users!
and you will be taken to a file that looks like this:class UsersController < ApplicationController end
The !
is the magic which force-creates a new file.
Now that we know how to use them, let’s define some custom commands.
The four primary ways to define projections are:
- Per app, in
config/projections.json
. - Per bundled gem, in
g:rails_gem_projections
(requires bundler.vim). - Inside a bundled gem, in
lib/rails/projections.json
(requires bundler.vim). - Globally, in
g:rails_projections
.
Each projection can define a handful of options, including alternate (:A
) and
related (:R
) files or a template for new files. More are described in the
docs.
A complete example for Active Model Serializers navigations:
"app/serializers/*_serializer.rb": {
"command": "serializer",
"affinity": "model",
"test": "spec/serializers/{}_spec.rb",
"related": "app/models/{}.rb",
"template": "class {camelcase|capitalize|colons}Serializer < ActiveModel::Serializer\nend"
}
This will allow you to jump back and forth between the serializer’s tests and model, as well as create a new serializer based on the filename.
Rails.vim will capture the input, which you may use in your file name definitions and template code with the following transformations:
{}: original
{camelcase|capitalize|colons}: Ruby class names
{plural}: pluralized
{singular}: singularized
{underscore|capitalize|blank}: humanized
While it is possible to create projections inside of gems, it seems strange to
include editor specific code. Because we can’t count on every gem to include
them, I created my own global and gem specific
projections, defined by
g:rails_projections
and g:rails_gem_projections
respectively. Since this is
vimscript, they are defined in a butchered version of JSON by escaping line breaks.
Gem specific projections will only be availabile if the gem is bundled with the current project, and you have installed bundler.vim. The definitions for each are grouped by the gem’s name as seen in this example.
Project specific projections can be defined in config/projections.json
with
real JSON, like in these
Backbone.js and
Ember.js examples.
For a more in depth description of what projections can do,
read more online
or with :help rails-projections
.
What’s next
If you found this useful, you might also enjoy: