Using Ruby one-liners with Quicksilver

· technology ·

Sometimes a Unix-based system can be a beautiful thing. Take a little problem and solution I came across today. I had been writing some notes on a paper I was reading in the Vim Outliner, and wanted to paste a paragraph or two into the notes section of Endnote (a reference manager). But there was immediately an irksome problem: Endnote doesn't understand Unix line endings, and my notes were also hard-wrapped to 72 characters, with a 'pipe' character (|) and tab before each line of text. Worse still, Endnote doesn't have a find and replace command^1^. I could have opened up BBEdit or something similar and constructed the appropriate find and replace there, but that seemed annoyingly long-winded. Then I remembered that you can access the contents of the system clipboard directly using the commands pbpaste and pbcopy. Because they work like standard Unix commands, you can pipe other commands to them, and so build up a useful tool from a chain of smaller commands. This example shows you how to filter the text on the clipboard through a command to munge it in some way, and then put it back on the clipboard ready for pasting — no intermediate files required!

So — as I'm learning Ruby — I thought I'd knock up a quick Ruby one-liner to strip out the line feeds, the pipes, tabs and superfluous space, and replace them with a single space:

pbpaste | ruby -00 -pe 'gsub!(/nt+|s+/, " ")' | pbcopy

That just passes the contents of the clipboard to the Ruby code which replaces all the unwanted gubbins with a single space, then puts the modified result back on the clipboard. Cool, isn't it? But not quite cool enough for me. I would have bring forward my Terminal window and type this lengthy command, which again seemed like too much work, particularly as I'm likely to need to do this many times in the future. I realized that I could select the command I'd just constructed in the Terminal and drag it onto Quicksilver's shelf to make a clipping. Then I could run the whole thing from the clipboard. Here's how it works:

  1. Copy the text you want to munge.
  2. Activate Quicksilver (Command-Space on my machine) and type a full stop (period) to put Quicksilver into text mode.
  3. Hover over the shelf to activate it, and drag the clipping of the command you made earlier onto the text box in the Quicksilver command window.
  4. Activate Quicksilver again — yes, your clipping is still there.
  5. Type Tab, then 'ru' to bring up the 'Run in Shell' action. Hit return.
  6. Switch to wherever you want to paste your modified text and type Command-V.

It's much more laborious to describe than do, and there's another benefit. Once you've dragged the clipping onto the command window, you can hit '.' again to edit the contents. This means that you can easily make slight modifications to the command, but you can use your stored command as a guide to remind you of the correct format.

There are many other commands you could use. Want to shout at people? Try:

pbpaste | ruby -00 -ne 'puts $_.upcase' | pbcopy

There are lots of great Ruby one-liners here, but you could just as easily use Perl, or any other scripting language or Unix command. I think it's a great demonstration of the way that you can blend traditional Unix tools with some of the newer MacOS X utilities like Quicksilver, which share much of the same philosophy, but work in a slightly different way.

^1^ In many ways, Endnote is unbelievably primitive — the developers seem only just to have realised that some people have scroll wheels on their mice, and that it would be nice to be able to use them.

Update: I forgot that there's another way to get the Shelf items into Quicksilver. In the Catalog, look under Modules > Quicksilver, and you'll find an item for Shelf & Clipboard. Make sure the the checkbox is checked and rescan. now you should be able to search for 'shelf' in Quicksilver, the press the right arrow to descend into the clipboard and choose your clipping. No dragging required! Or you could go the whole hog and set up a trigger for the whole sequence if there's a one-liner you use a lot.