Getting started with Mutt on OSX

7 minute read

20/08/2016 I wrote a short upgrade to this guide, that uses the newly released mutt 1.7.0.


Here are some notes on how to get started with mutt and Fastmail on OSX (Yosemite). Most of this stuff applies to Linux as well. You can actually skip this whole mutt-is-awesome rant and checkout the “mutt” section of my doftiles.

Why mutt

mutt is stable, solid, predictable and flexible mail client. Also, I like writing in Vim. And I spend a lot of time in the command line. In the past, mutt was a pain to setup. Just google for “mutt setup” and you will find some monster articles, like this one or this one. Scary shit, uh?

A “normal” setup would include mutt, offlineimap, some smtp client, like msmtp and notmuch for searching your emails. Enough to scare away even the most determined hacker.

My setup is way simpler, since mutt is able to send emails without a third-party smtp client (I don’t know exactly when that option has been introduced in mutt). Additionally, I don’t require to store my emails locally, I don’t need to reply when off-line and I can search using the excellent Fastmail web interface.

This is how mutt looks like:

mutt

Get mutt

Vanilla mutt lacks some of the essential stuff, which is only available through patches. One is the trash patch - as in, send message to trash - and a sidebar to show IMAP folders. Applying a patch is not complicated - get the source, get the patch, make. In OSX, I can simply use Homebrew and get it done with a simple command.

brew install kevwil/patches/mutt \
    --with-gpgme --with-trash-patch \
    --with-sidebar-patch --with-confirm-attachment-patch

Talking to fastmail

mutt is configured through a .muttrc file. It’s a good idea to keep your configuration well organized and commented, because it can get a messy.

This is the very basic configuration required to fetch and send email through Fastmail.

set my_server       =   mail.messagingengine.com
set my_smtp_server  =   mail.messagingengine.com
set my_user         =   xxx@fastmail.fm
set my_pass         =   "`security find-internet-password -g -a lfi@fastmail.fm 2>&1| perl -e 'if (<STDIN> =~ m/password: "(.*)"$/ ) { print $1; }'`"
    
set record          =   "imaps://$my_server/INBOX.Sent Items"
set postponed       =   "imaps://$my_server/INBOX.Drafts"
    
set from            =   "xxx@fastmail.fm"

# Account - SMTP

set smtp_url        = "smtp://$my_user:$my_pass@$my_smtp_server:587"
set smtp_pass       = $my_pass
set imap_user       = $my_user
set imap_pass       = $my_pass
set ssl_force_tls   = yes
set ssl_starttls    = no
    
#
# Default inbox
#
set spoolfile=imaps://$my_server/INBOX

#
# Default location of mailboxes
#
set folder=imaps://$my_server/INBOX

This is good enough to start reading and sending emails with Fastmail. If you use gmail, there are plenty of tutorials out there that shows an equivalent configuration. You may have noticed that the my_pass variable is using the security command to retrieve the password from the OSX Keychain. I figured it was a good idea to remove my password from the .muttrc file, since I store all this stuff publicly on github.

To add the password to the OSX Keychain, type:

sudo /usr/bin/security -v add-internet-password -a xxx@fastmail.fm -s mail.messagingengine.com -w your-password

Contacts

mutt uses aliases to map a name to an email address. Aliases are stored in a file using a simple format:

alias john John Doe <johndoe@email.com>

The default key binding to add an address from the currently opened mail is a.

I store my contacts in a OwnCloud instance running on my server. Initially, I used a script to convert the vCard contacts into an alias flie, but it has been a sub-optimal solution, because I had to download the vCard file and re-import periodically.

Enter pycarddav. pycarddav is a CardDav CLI client with built in support for mutt’s query_command.

The setup takes a couple of minutes:

Install pycarddav:

pip install pycarddav

Create a configuration file with the credentials of the CardDav server and syncronize:

pycardsyncer

Test:

pc_query Barack
...
Name: Barack Obama
TEL (CELL, VOICE, pref): 123446767
TEL (WORK, VOICE): 999999999
EMAIL (INTERNET, HOME, pref): barack@whitehouse.org

Now, it is possible to configure mutt to search the contacts database using TAB when composing. Add this entry to the mutt .muttrc file.

set query_command="pc_query -m '%s'"

auto completion

The sidebar

The sidebar it’s an handy right-side panel that shows a configurable number of IMAP folders and the number of messages that each folder contains. I keep it hidden by default, and display it when needed.

sidebar

The folders displayed in the sidebar must be specified in the .muttrc file, like so:

mailboxes "+-----------------" \
      imaps://$my_server/INBOX \
      "imaps://$my_server/INBOX.Sent Items" \
      "imaps://$my_server/INBOX.Drafts" \
      "+-- folders ------------" \
      "imaps://$my_server/INBOX.folder1" \
      imaps://$my_server/INBOX.folder2 \
      imaps://$my_server/INBOX.folder3.subfolder \
      "imaps://$my_server/INBOX.folder4" \
      "imaps://$my_server/INBOX.folder5" \
      "imaps://$my_server/INBOX.folder6" \
      "imaps://$my_server/INBOX.folder7" \
      "imaps://$my_server/INBOX.folder8" \ 

Fine-tuning

It’s easy to geek out with mutt’s configuration. There are tons on parameters. My approach is to start with a simple configuration and snoop at other’s people .muttrc files. These are some settings that I have been using since start using mutt.

set sort              = threads                     
set sort_aux          = reverse-last-date-received 

Gmail-style threading.

set pager_stop

Stop mutt showing the next message when we are at the end of the current message’s body.

set fast_reply
set include     

Quick reply, makes mutt to stop asking lots of questions.

set reverse_name 
set envelope_from

Pre-fills the “From” address when replying to emails, based on the email account that received the original mail. Useful in case of multiple accounts or multiple aliases (like in my case).

As I mentioned early, I like writing in Vim. This is how I tell mutt to open Vim when composing an email:

set editor = "vim +/^$ ++1 -c 'set tw=76 expandtab nosmartindent spell'""

Here are a bunch of mutt dotfiles that I have used for inspiration.

Bao Nguyen dot files

Jeff Waugh mutt configuration

Dave Pearson mutt configuration

Angelo Olivera dot files

Hong Shick Pak dot files

GPG

mutt and GPG works pretty much hand in hand, no biggie, given that you have your GPG stuff all setup (I assume that if you made it so far, you are probably an avid GPG user). My configuration is shamelessly copied from this 2014 article on mutt and GPG. Just remember to brew mutt with the --with-gpgme flag and install gpgme (brew install gpgme).

I like to sign all my outgoing mail. Easily done with this option set.

set crypt_autosign=yes

With recent version of GPG, mutt output an error on startup that says Using GPGME backend, although no gpg-agent is running. I think there is a patch floating around, but I didn’t bother applying it, because it works.

Markdown

I use Roguelazer’s muttdown to send HTML email written in markdown. Before muttdown, which is a quite recent project, I was using a mutt macro based on pandoc (something similar to what is described here). muttdown is a sendmail replacement that transparently compiles annotated text/plain mail into text/html.

I just need to start my message with !m to trigger the markdown compilation.

To use muttdown:

git clone https://github.com/Roguelazer/muttdown.git
cd muttdown
python setup.py install

Create a configuration file, .muttdown.yaml

smtp_host: mail.messagingengine.com
smtp_port: 587
smtp_ssl: false
smtp_username: xxx@fastmail.fm
smtp_password_command: security find-internet-password -w -a xxx@fastmail.fm        

In .muttrc add:

set sendmail = "muttdown -c /path/to/.muttdown.yaml" 

Bindings and macros

The default key binding for mutt is quite reasonable. mutt allows to bind the same keystroke to different action in each view (index, pager, browser, attach, etc. - mutt calls the views “menus”).

I favor a Vim-like binding, mostly for navigating the email list and the email body.

mutt offers rudimentary macros as well. Macros in mutt are essentially a way to automate keystrokes.

To get an idea of how a macro looks like, take a look at this macro. It is triggered by the TAB key and it’s only available in the index menu (the message list). When triggered, it shows the next unread message and press enter.

macro index   <tab>      <next-unread><enter> 

Here is my binding file.

This is an awesome, interactive mutt cheatsheet for getting started with the key binding.

HTML emails

You can throw any kind of attachment to mutt, as long as the type is specified in a mailcap file. My mailcap file looks like this:

application/msword; ~/.mutt/view_attachment.sh %s "-" '/Applications/TextEdit.app'
#
# # Images
image/jpg; ~/.mutt/view_attachment.sh %s jpg
image/jpeg; ~/.mutt/view_attachment.sh %s jpg
image/pjpeg; ~/.mutt/view_attachment.sh %s jpg
image/png; ~/.mutt/view_attachment.sh %s png
image/gif; ~/.mutt/view_attachment.sh %s gif
#
# # PDFs
application/pdf; ~/.mutt/view_attachment.sh %s pdf

#
# # HTML
text/html; ~/.mutt/view_attachment.sh %s html; copiousoutput
#
# # Unidentified files
application/octet-stream; ~/.mutt/view_attachment.sh %s "-"

The “mailcap” file is just a way to map a MIME type to an application that can handle it. I’m using the view_attachment.sh script, which is mentioned in the mother of all mutt articles. It works well for me.

Once the “mailcap” file is sorted, mutt can auto-open HTML emails with an entry in the .muttrc file:

  auto_view text/html                                      # view html automatically
  alternative_order text/plain text/enriched text/html     # save html for last

autoopen

Colors

I’m lazy, so I use the Solarized theme for mutt, available here.

Leave a Comment

Your email is used for Gravatar image and reply notifications only. Address will not be published. *

Loading...