Mailsmith



Thursday, 26 February 2004

One of Mailsmith’s most significant charms is that its text editing features are extraordinarily similar to those of BBEdit. They look similar, they feel similar, and they’re similarly scriptable.

It’s for this reason alone that I’ve been using Mailsmith ever since version 1.0 shipped in 1998. Mailsmith 1.0 was glacially slow at storing messages in mailboxes, and lacking in many features. “1.0” software tends to be that way. But its BBEdit-like text editing capabilities were its saving grace.

But while similar editors, they are not identical. Certain differences are necessarily inherent between a text file editor and an email client. One such difference, which has bitten me dozens of times in the past five years, is the menu key shortcut Cmd-E.

In BBEdit, Cmd-E is bound to Search → Enter Search String. If you select some text in the front window, then invoke Enter Search String, the selected text becomes the text in the Search For field of the Find dialog. Thus, you can use this command to enter a search string, then use commands like Find Again or Replace All, without actually opening the Find dialog itself.

  1. Pattern Playgrounds. Grep Cheat Sheets. Ready for macOS Big Sur and Apple Silicon. Millions. of new features and refinements. Even more productive. Still wicked fast. The professional’s choice for more than twenty-five years (and counting).
  2. Mailsmiths are Mailsmithing Profession Assets that can be acquired as necessary components for completion of Mailsmithing tasks from Forgotten Profession Level 14 and above, and/or as optional components in Rare tasks that will reduce the completion time for their armor pieces.

Mailsmith 1.5 is the latest version of Bare Bones Software’s professional e-mail application, and the first major update of the product since 1998. As I described in my review of Mailsmith 1.1.2, Mailsmith distinguishes itself with BBEdit-style text editing, powerful filtering and searching, and a clean interface.

Mail.smithbucklin.com

In Mailsmith, Cmd-E is bound to Message → Send Now.

Do you see how this could be a problem? I’m writing in Mailsmith; I select a word; I hit Cmd-E with the intention of entering a search string — but fuck, by hitting Cmd-E, I just sent the message before it was finished.

This happens to me rarely — I’d say maybe two or three times a year, tops. But it’s been happening to me two or three times a year for nearly six years. It’s not a catastrophe, but it’s embarrassing enough that I wanted to find a way to stop it from happening again.

BBEdit and Mailsmith both allow you to customize their menu keys, but I don’t want to change either of these shortcuts. Cmd-E has been the standard shortcut for Enter Search String in Mac text editors since before BBEdit existed, and it’s still a de facto standard shortcut. (It’s even supported in new editors like Xcode and SubEthaEdit, although they call the command “Use Selection for Find”; I think “Enter Search String” is a better name, since it makes mnemonic sense with the Cmd-E shortcut.)

There is no standard shortcut for a mail client’s Send command, but Cmd-E is as good a shortcut as any. The obvious shortcut would be Cmd-S, but of course that’s reserved for Save. (Even if your app doesn’t actually save or print anything, you should never reappropriate deeply ingrained shortcuts like Cmd-S or Cmd-P.) Cmd-E is certainly a better shortcut for sending a message than Apple Mail’s contorted Shift-Cmd-D. And, Eudora uses Cmd-E for Send, which makes it as close to an established standard for Mac email clients as you’re going to get.

The problem isn’t the shortcuts themselves — it’s the fact that I have muscle memory for both of them. 99.9 percent of the time when I hit Cmd-E in Mailsmith, I really do want to send the current message. What I want to defend against is that one time in a thousand when I hit Cmd-E in Mailsmith with the intention of invoking Enter Search String.

The Menu Script Solution

Last month, a solution finally occurred to me: I could attach a menu script to Mailsmith’s Send Now command, and in the script, try to detect if it has been invoked when I really meant to invoke Enter Search String.

To attach a menu script to a Mailsmith menu command, you save the script in the Menu Scripts folder inside your Mailsmith Support Folder. (Same for BBEdit.) The name of the script needs to be in the form Menu_name•Command_name; so in this case, the name will be “Message•Send Now”.

The question is, how can I detect when I’ve invoked this command with the intention of entering a search string? Well, to enter a search string, you need to select some text first. But when I’m actually ready to send a message, I almost never have a selection in the message window — just a blinking insertion point.

So, here’s the idea for how the script should work:

  • When “Send Now” is invoked, check to see if there is a range ofselected text in the current message window.

    • If not, tell Mailsmith to go ahead and send the message,as usual.

    • If there is a text selection, display a confirmationdialog to ask if I really want to send the message.

Here’s the script:

Mailsmithing

It would be nice if the confirmation dialog offered an “Enter Search String” button in addition to the “Send” and “Cancel” buttons, but Mailsmith’s search string properties are read-only from AppleScript.

Mail.smithbucklin.com

Admittedly, this is a bit esoteric. But it has completely solved a rare but highly annoying problem I’ve suffered for over five years. In the two months that I’ve had this script in place, it has saved me from prematurely sending a message once, and it has never gotten in my way when I actually wanted to send a message.

Update:Michael Tsai wrote a version of this script that can enter the search string if there is a text selection — by using Mac OS X’s new-fangled GUI Scripting. Neat trick.

Saturday, 7 May 2005

The new Dictionary app is one of my favorite new features in Mac OS X10.4. Dictionary’s primary advantage over online dictionaries —including Sherlock’s — is that its database is stored on yourcomputer, and thus is always available; online dictionaries areuseless to an offline laptop. Plus, I like the presentation, and Ilike the definitions. As a writer, Dictionary is pretty much exactlywhat I want.

But, since I do the vast majority of my writing in BBEdit andMailsmith, I was faced with a problem. To be truly useful as a writingaid, you need to be able to invoke your dictionary easily from the appin which you’re writing. What I want to do is select a word in BBEdit(or Mailsmith or TextWrangler) and tell Dictionary to look up thatword in one quick action. But:

  • Dictionary’s “Look Up in Dictionary” contextual menu itemcurrently only appears in Cocoa NSTextView and WebView controlfields. Thus it doesn’t appear in BBEdit, TextWrangler, orMailsmith.

  • Dictionary’s system-wide keyboard shortcut — Command-Control-Dby default, but configurable in the Keyboard & Mouse panel inSystem Preferences — also only works in Cocoa NSTextView andWebView fields.

    Update, 12 May 2005: BBEdit 8.2.1 now supports theCommand-Control-D shortcut and inline Dictionary panel. Very, verycool. I’m fairly certain Bare Bones is now the first third-partydeveloper to add support for these hooks.

  • Dictionary does not have an AppleScript dictionary. (Technically,it does have a scripting dictionary, but it’s just a defaultCocoa dictionary, and offers no scripting features for performingdefinition look-ups, which means it’s effectively useless.)

  • Dictionary ostensibly allows you to perform look-ups via thedict:// URL scheme, but, as I’ve documented on my Tiger Detailsreport, this feature is half-baked at best, and for some usersdoesn’t seem to work at all.

That leaves two options, both of which I’ve found to work very well.

‘Look Up in Dictionary’ Service

Dictionary’s menu command in the Services menu works just fine fromBBEdit/TextWrangler/Mailsmith. The only downside is that it doesn’thave a keyboard shortcut, and mousing into the Services sub-menu istoo inconvenient.

However, you can easily add a custom shortcut to the “Look Up inDictionary” Services menu item:

  1. Open the Keyboard & Mouse panel in System Preferences, then click onthe Keyboard Shortcuts tab.

  2. Click the “+” button to add a new shortcut.

  3. In the configuration sheet, you can either choose “All Applications”or just pick a single application. Even though it seems as thoughthere’s just one system-wide Services menu, the truth is that eachapp creates its own instance of the Services menu. So if you want,you can customize a Service menu item shortcut for just one particularapp. For consistency, though, I think it’s better to choose “AllApplications” and use the same shortcut everywhere.

  4. Type “Look Up in Dictionary” in the Menu Title field. This must matchexactly.

  5. Type your new shortcut in the Keyboard Shortcut field. You can prettymuch type whatever shortcut you want here, and it’s important to notethat the system does not perform any conflict checking, so you can use a shortcut that’s already used by other menu items (includinganother command in the Services menu itself).

  6. You’ll need to quit and relaunch any apps that are currentlyrunning to use this new shortcut.

Scripting the Dictionary App via GUI Scripting

I’m so lazy that I don’t even want to have to select a word beforedoing a look-up on it. If I don’t have a selection, I’d like mylook-up command to use whatever word the insertion point is touching.This means the Services menu command is out, because it’s only enabledwhen there’s a range of selected text.

Mailsmith Mcintosh

We can use AppleScript to get the “current word” adjacent to theinsertion point (cf. “‘Select Word’ Script for BBEdit”,published here back in 2003), but what can we do with it if Dictionaryisn’t scriptable and its support for dict:// URLs is broken? Weresort to GUI Scripting.

Here’s the script. (To use it with Mailsmith or TextWrangler, all youneed to do is change the tell application 'BBEdit' line.)

The first part of the script sets dict_query to the text of thecurrent selection. If there is no text selection, then it tries to getthe “current word” adjacent to the insertion point. If that fails(e.g. if the insertion point is currently on a blank line), it uses adialog box to prompt for a word to look up.

The GUI scripting part has two key steps (after making sure thedict_query variable isn’t empty and activating the Dictionary app):

  1. Set the tell target to the search field in Dictionary’s mainwindow’s toolbar.

  2. Simulate keystrokes to enter the dict_query string in the field.

  3. Simulate a “return” keystroke.

The script uses the GUI scripting keystroke command instead ofsetting the value of the search field and then simulating a click onthe magnifying glass search button; in my experience this worksbetter. Also, the script first sets the value of the search textfield to the empty string; without this step, the new query issometimes appended to the existing query instead of replacing it.

Save the script in your BBEdit (or Mailsmith or TextWrangler) scriptsfolder, then use the Scripts palette to assign a keyboard shortcut,and you’re set. (I’ve got mine bound to Control-D, which is super-easyto type.)

Remember that to use GUI Scripting, you need to turn it on; it’s offby default. On Mac OS X 10.4, the easiest way to turn it on is to usethe new AppleScript Utility app (in the “AppleScript” folder insidethe top-level “Applications” folder). If you try running this scriptwith GUI Scripting turned off, you’ll get strange“NSReceiverEvaluationScriptError” error messages.

Mailsmith Mac

A Brief Plug for PreFab UI Browser

Mailsmith

The GUI scripting part of the script looks fairly simple, but how didI know that the name of the magnifying-glass icon button was “search”?You need to know this, because simply setting the value of the textfield doesn’t initiate a look-up. For that matter, how did I know howto string together the chain of objects to address the search textfield in the first place — the “text field 1 of group 1 of tool bar1” bit?

Apple’s solution is the painfully stark UI Element Inspector app.

But the only good way to determine the syntax for addressing interfaceelements via GUI scripting is to use PreFab UI Browser, an excellentutility that puts Apple’s UI Element Inspector to shame. It costs$55, but has a lenient and generous demo period during which you cantry it for free.

Trying to accomplish something with GUI scripting without using UIBrowser is like trying to walk around blindfolded. If not for UIBrowser, I seriously doubt I would have even attempted this script.

Mailsmith

It’s a completely valid gripe that Dictionary ought to provide aproper AppleScript command for performing look-ups, and I hope thisgets addressed in a future update. But in the meantime, GUI scriptinggets the job done today.

Mailsmithing

Previous:The Tiger Details List
Next:I Suppose It Has to Be OK