For a long time I have managed email with Thunderbird and its awesome Nostalgy add-on. This add-on is what makes Thunderbird work for me – I cannot stand the point&click&drag&drop mentality of a program like Mac’s Mail.app.
I also like to separate private mails from work mail, so I don’t accidentally end up in my work inbox when reading my private mail. Hence I have a need for two mail clients that are at least acceptable.
Now I have finally plucked up enough courage to try a true text-based email client: Mutt. Besides the text interface, there are two other perks that makes Mutt attractive to me:
- I can use Vim (or any editor, really) to compose emails.
- The configuration files are in plain text.
This post is about the daunting task of setting up Mutt and its associates OfflineIMAP, msmtp and Notmuch. My setup is closely based on the excellent tutorial by Steve Losh and an updated version found here that uses multiple accounts.
In the setup Mutt serves only as an email reader/writer – it does not interact directly with any servers. OfflineIMAP makes a local copy of all emails on an account, msmtp sends mails and Notmuch indexes the local mails for fast searching.
My full configuration is part of my dotfiles repository and here I only explain selected parts.
The setup I describe here is tested on OS X Yosemite as this is runs on my primary home computer.
OfflineIMAP performs two-way syncing: Changes on the server (i.e. new mails) are transferred to the local machine and changes on the local machine (e.g. deletion of mails) are transferred to the server.
In order not to mess around with my regular email accounts I make a new account for testing my configurations:
After a while I got cocky, added one my real email addresses and experimented with this instead – that was a bad idea as I ended up deleting most of the emails on the server. At that point I really appreciated that the paid email service includes support and daily backups.
I haven’t had the guts to recreate the problem with mass deletion, but I am pretty sure that the trouble stems from me changing the
nametrans function between two syncs (as explained in the next section).
Therefore a note to self:
When changing the
nametrans function or deleting folders in the local copy the affected accounts should be deleted in
~/.offlineimap where OfflineIMAP saves configurations.
Supposedly, new versions of OfflineIMAP are not backwards compatible and my setup uses
It is possible to name folders differently on the server and the local computer by specifying a
nametrans function is needed for both the remote and local repository and they should be inverses.
For my private email I use a small modification of simple function suggested in the OfflineIMAP documentation that removes the leading
INBOX. from the server names:
- For the local repository:
- For the remote repository:
My work uses an Exchange server and I found Mutt help here for this situation.
Here I do not use
nametrans as the folder names do not have any weird leading phrases.
However, there are a bunch of folders on the server that I am not interested in, ruled out by the folderfilter under the remote repository:
When first running OfflineIMAP I was informed that SSL was needed and that a certain certificate did not match that of the server. Apparently Mac insists on dealing with certificates through its Keychain (unlike various GNU/Linux distributions where they can be installed with the package manager). I stopped the complaining by simply adding the line
under the remote repository with
XXX being the announced certificate of the server.
OfflineIMAP supports different ways of saving credentials for each account – entering my password on every run is not an option for me and neither is a clear text password in the config file.
On OS X I shamelessly copy from Steve Losh:
The passwords are saved in OS X’s Keychain and accessed by OfflineIMAP through a custom Python function.
The nice thing about this approach is that it is little hassle accessing the passwords – even if Keychain asks for permission it only takes a
Space to confirm.
Unfortunately, this approach is not applicable to GNU/Linux, but that will be a topic for later.
For both the IMAP and SMTP server a Keychain item is added with
- Keychain Item Name being the server (
http://imap.one.comfor my private email provider).
- Account Name being the login name
- Password being, well, you know, the password.
On the GNU/Linux distributions I have tried, the Mutt version available is compiled with the sidebar patch.
On Mac, Mutt is available through Homebrew – but the sidebar patch is unfortunately not included.
I found several guides claiming that running a
brew edit mutt and adding appropriate options would include the sidebar;
I was not able to make that approach work.
Which folders are shown in the sidebar can be customized with the following lines in
Mutt is made for viewing text emails.
Attachments are handled externally in the file
~/.mutt/mailcap by specifying rules based on file types.
For e.g. JPG images add the line
view_attachment.sh is found here.
Put it in the location specified in the mailcap file and make it executable.
For viewing HTML emails inside Mutt I use the browser elinks.
Add the following lines to
HTML emails are then dumped to the
tmpdir set in
muttrc and displayed with elinks in Mutt.
To open URL’s in mails without the interfering mouse, I use urlview which on OS X is available through Homebrew.
This command opens a URL in the default browser (on OS X), but assumes that the URL is correct, i.e., that the protocol is included.
Sloppy links like
www.something.com will not be opened correctly.
The script can be tested with
urlview <file> where
<file> contains URL’s.
Add the following line to
CTRL-u when reading an email runs
urlview on the mail and returns a list of the links in the mail.
I manage settings for the individual accounts by adding
muttrc and filling up the sourced file.
One particular difference is how my two mail providers handle sent mail.
For my private mail I do not save local copies – specified by
unset record – as the sent mail are saved on the served and downloaded with the next run of OfflineIMAP.
The Exchange server does not save the sent mail so here I specify where to save sent mail with
When running OfflineIMAP the sent messages are uploaded to the server.
As mentioned in the beginning I am a Mutt novice, so this is a collection of commands I find myself using repeatedly after a couple of days in Mutt’s company:
s: Move/save message to folder. If you want to write the folder use
?to see a file hierachy of folders; this is useful, but not very efficient for navigation (the folders are numbered and can be accessed as such, but the Vim-style with
xjwill not move you
xfolders down). Forward slash can be used for seaching though.
c: Open another folder. The navigation rules are the same as for
s. Note the shortcut
c!to go the spool directory (typically the inbox).
t: Tag messages. After tagging, the collection messages can be moved with
;s. The semicolon tells Mutt to apply the subsequent command to all tagged messages, not just the highlighted one.
Tto mark messages based on a pattern. To limit the search to a particular field like ‘from’ or ‘subject’, use
~s, respectively. The full list of fields can be found in the manual
TAB: After deleting messages they are still visible in the folder and a
TABmoves the messages to the
a: Attach file.
As mentioned in the beginning, msmtp is used for sending email.
On OS X Homebrew comes to the rescue once again:
brew install msmtp
Msmtp is configured with
For my private account I have:
Msmtp also looks in OS X’s Keychain for the password.
To tell Mutt which msmtp account and mail account that belongs together, I add the following lines to
To quote Steve Losh:
sendmail_waitline tells Mutt to wait for the msmtp program to finish sending the mail before returning control, instead of running it in the background.
Notmuch delivers fast indexing and searching.
Generate the config file
~/.notmuch-config by running
notmuch setup and build an index by running
The first run might be a little time consuming, but subsequent runs will be much faster as only new emails will be processed.
To invoke a search directly with notmuch, run
Integration with Mutt is available through the Perl script notmuch-mutt, but it has quite a number dependencies that I cannot figure out how to resolve on OS X.
Steve Losh suggests the Python script mutt-notmuch-py instead. The README for the script and the documentation in the source says that this script is exclusively for Gmail, but I have no problem running it from Mutt and get results for my non-Gmail accounts.
To call the script from within Mutt, add the following line to your
This temporarily returns you to the shell and prompts for a search phrase.
The emails matching the search criteria (if any) are symlinked to
I add this temporary folder to the sidebar for easy navigation.