Hashrocket.com / blog

Bg default article large

Vimscript And You!

posted on and written by in

Image 100x100 jonathan jackson

At Hashrocket we love configuring our development environments to be highly portable and customizeable. Occassionally, that necessitates rolling up our sleeves, busting out our editor, and cranking out some Vimscript. If you've ever implemented a plugin in Vimscript then you have undoubtedly ran into some pain trying to excercise the code. Pathogen gets you a long way by reloading your plugins conveniently, but what if there were a faster way? And wouldn't it be great to be able to test drive it? Well, as luck would have it, we can!

In this post we are going to cover:

  1. Setting up Vimrunner
  2. Writing a test using Rspec to exercise Vim
  3. Writing a plugin to satisfy the test

By the end you should have a solid foothold to start testing your own Vim plugins.

Setting up Vimrunner

Vimrunner is a project written by Andrew Radev that let's you leverage the scriptability of Vim. It's documentation is pretty great so if you have questions be sure to refer to the Vimrunner README.

First start by making a directory structure that looks something like this (simplified for post):

plugin
└── example_plugin.vim
spec
  ├── plugin
  │   └── example_plugin_spec.rb
  └── spec_helper.rb

Inside the spec/spec_helper.rb let's place the Vimrunner config block to get access to its built in vim helper and support modules.

require 'vimrunner'
require 'vimrunner/rspec'

Vimrunner::RSpec.configure do |config|
  config.reuse_server = false
  config.start_vim do
    vim = Vimrunner.start
    vim
  end
end

Above we set reuse_server to false to ensure it uses a new instance for each test. This is slower, but makes everything easier. The start_vim block gives us access to the vim runner inside our specs.

Now that we have Vimrunner set up for the most part we can open up spec/plugin/example_plugin_spec.rb and write a test.

Writing a test

This plugin is simply going to strip whitespace for ruby files. So let's start by setting up a file that has trailing whitespace so we can test our expectations.

require 'rspec'
require_relative '../spec_helper'

describe "Trim" do
  before do
    vim.add_plugin(File.expand_path('../../../',__FILE__), 'plugin/example_plugin.vim')
  end

  it "strips whitespace" do
    sample   = "class TestingWhitespaceStripping   "
    write_file("test.rb", sample)
    vim.edit "test.rb"
    vim.write
    expect(File.read(filename)).to eql(sample.strip + "\n")
  end
end

Alright, let's run that and make sure it fails how we expect it to fail.

Making it pass

Now that we are nice and red it is time to go green. Let's actually write the plugin. At this point, you may want to refer to Learn Vimscript the Hard Way by Steve Losh. It's a great way to get up and running in Vimscripting. Our example is naively simple, but it would be trivial to expand it into something more robust.

autocmd BufWritePre *.rb call s:Trim()

function! s:Trim()
  %s/\s\+$//e
endfunction

So there you have it, our plugin in all its glory. We are telling it to trim ruby files on BufWritePre, which means it will execute s:Trim() right before saving the file. Vioala, no more pesky trailing whitespace. Let's head over to the command line and test it out. Run the following commands

cd path/to/plugin/spec/dir
rspec --color example_plugin_spec.rb

And we've officially arrived at green.

Concerns

Vimrunner requires whichever vim you are using as the server to be compiled with +clientserver and +xterm-clipboard if you plan on using GUI vim. Once you have that you're ready to begin testing all your vim plugins. If you would like to see a more robust example refer to Vim-Spacejam, the plugin that inspired this post.

I hope this has inspired you to dive into Vimscript. Thanks for reading.

References

Image by Zimpenfish

  1. Vimrunner
  2. Vim-Spacejam example plugin
  3. Learn Vimscript the Hard Way
  4. Damien Conway's 5 Part Vimscript series /ty @telemachus

Posted in Development and tagged with Vim