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:
- Setting up Vimrunner
- Writing a test using Rspec to exercise Vim
- 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
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
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.
Vimrunner requires whichever vim you are using as the server to be compiled with
+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.
Image by Zimpenfish