Module 3, Topic 5
In Progress

xmpfilter

Module Progress
0% Complete

By far the most common question I get about RubyTapas is… "how do you get VIM to insert the result of expressions right in the buffer like that?" To which my first answer is "Silence, heathen! Can't you see you are in the presence of Emacs?!" But religious wars aside, how do I accomplish this magical feat?

The answer is that I use the venerable rcodetools gem. This gem, as its name suggest, contains a number of useful tools for working with Ruby code. The tool that concerns us today is xmpfilter. xmpfilter is a command-line utility which executes Ruby code. As it executes the code, it replaces specially-formatted comments with the value of the previously-executed expression.

For instance, here's a little Ruby file that adds two numbers and tells xmpfilter to show the result.

2 + 2 # =>

When I run the file through xmpfilter, it outputs the same code, with the result filled in.

$ xmpfilter math.rb

2 + 2 # => 4

xmpfilter also captures STDOUT and adds what it captures to the end of the output. To demonstrate, I'll add a line that prints some text and then run xmpfilter on it again.

puts "hello, world"
2 + 2 # =>
$ xmpfilter output.rb 

puts "hello, world"
2 + 2 # => 4
# >> hello, world

xmpfilter can pretty-print larger datastructures. For instance, here's a Ruby struct with a number of attributes. When I put the special hashrocket comment on the same line, the object is presented all on one line. But when I put it on the next line, it is printed out with newlines and indentation to make it easier to read.

Beer = Struct.new(:brewery, :name, :abv, :ipu)
hopback = Beer.new("Troegs", "Hopback Amber Ale", "6.0%", 55)
hopback # => #
Beer = Struct.new(:brewery, :name, :abv, :ipu)
hopback = Beer.new("Troegs", "Hopback Amber Ale", "6.0%", 55)
hopback
# => #

OK, now you know about xmpfilter, but you're probably still wondering how I integrate it with my editor. As it happens, the rcodetools gem actually contains an rcodetools.el file which adds Emacs commands for rcodetools utilities, including xmpfilter. I simply bind C-c C-c in ruby-mode to run the xmp command. The Emacs extension also modifies the "comment" keybinding so that hitting it twice adds an xmp-style comment.

Vim users will be happy to hear that rcodetools also contains a Vim extension. For users of other editors: you'll just need to write a script or macro which feeds the current buffer as STDIN into the xmpfilter command, and then replaces the contents of the buffer with the output.

Oh and if you're wondering: The "XMP" in the name is for "example".

And there you have it! Now you know my trade secrets. Happy hacking!

Responses