Code archaeology

When I returned to BBEdit last year after several years as a TextMate user, I found the Scripts and Text Filters menus filled with entries left over from 2005: little scripts that I’d written for some purpose or another—many of them clearly experimental or unfinished. They’d been sitting in the subfolders of BBEdit’s Application Support folder, a folder I’d copied over from one computer to the next on the off-chance that I’d need them one day.

One of them was my Capitalize script, which still worked but needed a little improvement. The others didn’t seem especially useful, but I decided I wouldn’t delete them until I’d had a chance to look them over thoroughly. That was a year ago, and they’re still there, mostly unexamined. I have, however, reviewed one of them and found a good idea that didn’t get taken to completion.1

The script is called Execute.pl, and it’s a Text Filter. When I opened it up, the source looked like this:

perl:
 1:  #!/usr/bin/perl
 2:  
 3:  use Cwd;
 4:  $here = `pwd`;
 5:  $cmd = join("\n", <>);
 6:  print "We are here: $here";
 7:  print "Here is the command:\n";
 8:  print "$cmd\n";
 9:  print "And here are the results:\n";
10:  print `$cmd\n`;

This is obviously not production code. Almost everything in it is exploration and debugging. Line 3 is worthless, as the Cwd library never gets used. Lines 4 and 6 are obviously my attempt to learn the script’s working directory, something I recently had to relearn. Lines 7–8 is a check to see if Line 5 did what it was supposed to—read every line of the selected text into a list and join them together with newlines. Line 10 is then supposed to run the command and replace the selected text with the result.

I’m pretty sure I abandoned this script because it never worked. It’s my understanding that BBEdit 8, which is what I was using in 2005, sent text to filters through argv[0], not standard input, so the <> operator in Line 5 wouldn’t get what it was supposed to.

Still, the idea is a good one. TextMate had a way (⌃R) to execute a line of text as a shell command and insert the result, and I’ve often wished for that in BBEdit. Neither Shell Worksheets nor the various Run commands from the #! menu work the way I want.

But this does:

perl:
1:  #!/usr/bin/perl
2:  
3:  undef $/;
4:  $cmd = <>;
5:  print `$cmd`;

Undefining the input record separator in Line 3 causes the angle operator in Line 4 to slurp in all of standard input as a single chunk of text. Line 5 then executes that text as a shell command and prints it to standard output.

To use this Execute filter, I type in the shell command I want to run, select it (usually via ⇧⌘←) and then select Text▸Apply Text Filter▸Execute (or use ⌃R, the keyboard shortcut I’ve assigned to it). The command is then replaced with its output. This is actually slightly better than TextMate’s ⌃R because it gets rid of the command, which is almost always what I want.

One of BBEdit’s unsung features is that it inherits the $PATH you’ve assigned your shell, so all the little scripts you’ve written to be used in Terminal are available in BBEdit without having to specify their full, absolute path. One of my most-used scripts is called addr: given a name, it searches my Contacts for that person and returns his or her full address in plain text. I use it to fill in the client information when I’m writing a report. Starting with this header,

Title: A report
Author: Dr. Drang
Date: September 4, 2013
Client: addr appleseed

I select the addr appleseed and hit ⌃R to get

Title: A report
Author: Dr. Drang
Date: September 4, 2013
Client: John Appleseed
Apple Inc.
1 Infinite Loop
Cupertino CA 95014

I need to indent the lines after Client:, but it’s still pretty fast.


  1. I’m assuming since the code is in such a sorry state that it’s mine. I’ve done some Googling and exploration at Bare Bones’s site and have found no evidence that it was written by someone else. If you know better, shoot me an email or a tweet, and I’ll make the appropriate amendments to this post.