Mutt () is a mail user agent. It facilitates the composition and the reading of mail. That’s all it does. It doesn’t do things normally associated with MUAs, like spell check, checking mailboxes (though, in imap mode, it can do that), filtering of messages, and address books. Why doesn’t mutt do that? Because there are other tools that do those jobs, quite well. With mutt, as in the true Unix fashion, you can take all the little tools that you love, and string them together, in this case, for email. I use vim as my mail editor. If I spellcheck (which I rarely do), there’s aspell. Grabbing messages and filtering them are left to fetchmail and procmail, respectively.
I’ve not used an address book with a MUA since I’ve moved to mutt. Sure, there’s the ~/.mail_aliases file which holds shortcut names for people I mail often, but it’s really not the same thing. Address books imply holding a lot more information, and, honestly, I don’t need such things. I don’t know that many people, surely not so many that I need help remembering them.
Still, Address books are cool, and are now coming with all sorts of meta-data about people, including hooking in to and the like for maps of street addresses. Nifty. Ok, maybe address books could be useful. And Mac OS X ships with a very nice one.
So, how to get the information from it into mutt?
Mutt has two types of addresses. One is the mail aliases file I mentioned earlier. The other is a call to an external query to look for addresses, in one of two modes: an out-and-out query (from the pager, the default key is ‘Q’), and an auto-complete when typing an address (default key ‘^T’). The actual command run when a query is performed can be specified by a mutt configuration variable, ‘query_command’.
Fink is an excellent amalgum of open source software for Mac OS X, including mostly packages from the Debian distribution of GNU/Linux but also some specialty packages. One such specialty package is ‘contacts’, which offers a command-line view of the records in your Mac OS X Address book. Promising.
So, the magic command is:
set query_command = "contacts -Sf '%eTOKEN%n' '%s' | sed -e 's/TOKEN/\t/g'"
somewhere in your mutt configuration. One of these days I’ll document my mutt configuration in more detail, but I’ve got it split over several files. In this instance, it’s going in ~/.mutt/main.conf, where I put global configuration settings. Let’s look at the command in a bit more detail.
The contacts program takes a bunch of command line arguments (see man contacts for the whole list), but we’re going to use two here: the -S tells contacts to not pad the output with spaces. the -f and following is a formatting string. (The '%s' at the end of the contacts part of that command line will hold the partial name or address as it comes from mutt, and isn’t a part of the formatting string). The formatting string is '%eTOKEN%n', which says to place the email address (the one you’ve marked as preferred in the address book), followed by the word TOKEN, then the full name. No spaces, so it looks like this:
someone@somewhere.comTOKENFirstname Lastname
jeffersonstarship@crappybands.comTOKENJefferson Starship
and so on. One per line. There’s also a header line, which we could take out of the output, but mutt is smart enough to ignore it, so we’re fine the way it is.
The “TOKEN” and the sed part following is pure Unix. mutt wants tab-delimited records, but I couldn’t see how to have contacts put tabs in there; it wanted to pad with spaces or nothing (we pad with nothing by using the -S). So, we’ll write something in there and use sed to replace it with tabs.
If you happen to have someone in your address book or an email address in your address book that contains ‘TOKEN’, you’ll have to call TOKEN something else. I’d say that’s rare, and it works for our exercise here.
So the output of the contacts part of the command is piped into sed for processing. Sed is one of those really nifty commands that it pays to spend some time with. I’ll confess to not knowing sed that well, but this example is thankfully quite simple. Sed commands look like the stuff you type at the vim command “:” (purists everywhere are shaking their heads and snapping their suspenders in disbelief, but that’ll do for this example. For the sake of completeness, both sed and vim are much more complex than that.)
When sed gets the output of contacts, it runs the s (substitute) command on it, looking for things that look like “TOKEN” and replacing them with “\t,” which is the Unix shell way of saying “tab.” So, when it comes out of sed, it’s in the format that mutt wants.
What could be simpler?
At this point, everything’s working. Now, when I press “Q” to do a lookup, or hit Ctrl-T when entering an email address, the possible matches are displayed from my Mac OS X address book. Chocolatey. Man, Unix is cool.