My QuickCursor replacement

Dan Frakes, TJ Luoma, and I had a Twitter conversation yesterday about a Keyboard Maestro macro TJ wrote a couple of years ago to replace the late, lamented QuickCursor. QuickCursor was a little menu bar utility written by Jesse Grosjean that let you use your favorite text editor to edit text in virtually any Mac application. In effect, what QuickCursor did was automate the process of

  1. Cutting the text from the application you’re working in (Mail, for example).
  2. Pasting it into a new document in your favorite text editor (BBEdit, Sublime Text, TextMate, etc.).
  3. Cutting the final version of the text from the text editor.
  4. Pasting it back into the original application.
  5. Cleaning up any temporary files.

It was, in effect, an OS X version of the old Unix $EDITOR and $VISUAL environment variables. Unfortunately, QuickCursor didn’t survive Apple’s new sandboxing rules.

TJ’s two-year-old macro had stopped working for mysterious reasons that can probably be traced to an update of either OS X or Keyboard Maestro, and he decided to come up with an improved version. He wrote about it today on MacStories and has posted the new macro on GitHub.

In parallel, I worked on my own macro for doing the same thing, using TJ’s original as my model. TJ likes using notifications and other signals to let the user know whether things are working correctly or not; I prefer to just let’er rip—if the macro isn’t working, I’ll get an error message from Keyboard Maestro. More important, though, is that TJ’s macros, both the original and the new one, rely on a significant chunk of zsh shell scripting. I hate shell scripting in general and don’t know much about zsh, so I’d have a hard time making repairs to it if another OS X update breaks it. TJ’s a nice guy, but he can’t be expected to drop everything to fix an old script just so I can edit my emails in BBEdit.

Here’s a brief rundown of how my macro works. Let’s say I’m writing a new email message in MailMate, and I realize that it’s going to be long enough that I’d really rather write it in BBEdit.

MailMate before editing

I hit the ⌃⌥⌘⇧B key combination, and the text is cut out of MailMate and opened in a new BBEdit document.

BBEdit at start of editing

I finish writing the text of the message,

BBEdit at end of editing

save the document (⌘S), and close it (⌘W). MailMate comes back to the front, and the new text is pasted into the message window.

MailMate after editing

If text is selected in the original application, only that text is cut out and replaced with the new text. If the original application has no text in it—if, for example, I knew right away I was going to write a long email—BBEdit opens with a blank document. Basically, it works the way you want it to, assuming BBEdit is your editor of choice.

The macro can be downloaded from here. When the steps are collapsed, it looks like this:

Edit in BBEdit macro

The logic of most of the steps is pretty obvious, but I do think a few things are worth mentioning.

In the first step, I use Keyboard Maestro’s %CurrentApplication% token to save the name of the original application (MailMate in the example above) so the macro knows what to return to at the end.

The shell script in the third step is this:

bash:
 1:  #!/bin/bash
 2:  TSTAMP=`date "+%Y%m%d-%H%M%S"`
 3:  TEMPFILE="$HOME/Desktop/$TSTAMP-BBTMP.txt"
 4:  
 5:   pbpaste > "$TEMPFILE"
 6:  /usr/local/bin/bbedit --wait "$TEMPFILE"
 7:  
 8:  cat "$TEMPFILE" | pbcopy
 9:  mv "$TEMPFILE" $HOME/.Trash/

Lines 2–3 set the name of the temporary file that BBEdit will open and edit. It sits on the Desktop and has a name like 20150806-071423-BBTMP.txt. The first two parts are a date and time stamp, and the final part is in ALL CAPS so it stands out. If I see a file like this on my Desktop after I’m done editing, I know something’s gone wrong. If you want a different name or location for the temporary file, these are the lines to edit.

Line 5 puts the text cut from the original application into the temporary file, and Line 6 opens it in BBEdit. If you’re like Dan Frakes, you might find that the bbedit command is in /usr/bin instead of /usr/local/bin. Line 6 is where you can fix that. The --wait option stops the execution of the script until the BBEdit file is closed.

If you use a text editor other than BBEdit, Line 6 is also where you need to specify that editor. I know both TextMate and Sublime Text have commands analogous to bbedit. If you’re an Emacs or Vim user, you probably already have something that works like this macro, so why have you bothered to read this far?

Line 8 puts the contents of the temporary file onto the clipboard, and Line 9 moves it to the Trash, where you can retrieve it if necessary. When the script finishes, control goes back to Keyboard Maestro.

Step 4 of the macro is this short AppleScript, which retrieves the saved name of the original application and activates it:

applescript:
1:  tell application "Keyboard Maestro Engine"
2:    set p to value of variable "previouslyActiveApp"
3:  end tell
4:  tell application p to activate

Keyboard Maestro has some built-in commands for activating applications, but none of them (as far as I could tell) have a way of working with a variable—they require you to know the name of the application when you write the macro. Since the whole point of the macro is to work with virtually any application, I had to resort to AppleScript.

If you’re interested in this kind of macro, you should check out TJ’s article, where you can get links to his implementation and others by Patrick Welker and Chauncey Garrett. It’s a good bet that at least one of them will fit your style of working (or can be jiggered to fit).

And thanks to Jesse Grosjean for inspiring all of us.