Extending rails.vim Navigation Commands with projectionist.vim

One of my favorite Vim plugins is rails.vim by Tim Pope. And the reason it's one of my favorite Vim plugins is all of the navigation commands that it gives you for working with Ruby on Rails projects. So, rather than having to do :e app/models/product.rb to navigate to a model in your Rails app, you can just do :Emodel product instead. It also has commands for navigating to controllers, views, layouts, migrations, mailers, etc. And if you want to open something in a vertical split, you just use the V version of the navigation commands (:Vmodel product).

It's pretty great.

But something that happens as you get more experienced with Rails is you start adding folders to your app/ folder. So, in addition to the standard models, views, controllers, and mailers directories, you might add a presenters, workers, or serializers directory. This is actually a big step toward leveling up as a Rails developer; it's a sign that you're comfortable decomposing your app into more than just models, views, and controllers.

One of the downsides of doing this, though, is that it feels painful to work with these new types of classes, because rails.vim doesn't have handy navigation commands for them. But that's okay, because it's actually really easy to add those navigation commands. In addition to rails.vim, Tim Pope also makes projectionist.vim, which allows you to create custom Vim commands via a simple configuration file. And it's not limited to Ruby or Rails; it can be used for any kind of project.

To get started, you put a .projections.json file in your project root directory. Here's what that file looks like on one of my projects, where it's adding navigation commands for workers and presenters:

  "app/workers/*_worker.rb": {"type": "worker"},
  "app/presenters/*_presenter.rb": {"type": "presenter"}

You can see that it's pretty simple. You specify a pattern that matches certain types of files in your project, then you specify some options for files which match that pattern. In this case, the only option I'm specifying is "type", which is what creates the navigation commands. So, that first line creates the :Eworker and :Vworker commands (and some others, but those are the only ones I actually use) and then specifies that they will open files in the app/workers directory which have filenames ending in _worker.rb.

And that's it!

Well, I'll mention one more thing: I specified the "type" option in the configuration file above, but there are other options that you can specify as well, such as a "template" for creating new files or an "alternate" for navigating to related files. I'll leave you to peruse the documentation if you want to learn more about those, though.