Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
248 lines (184 sloc) 12.1 KB
layout: post
title: The Mutt e-mail client
date: 2015-03-12 11:00:00
updated: 2015-03-12 11:00:00
coordinates: 50.725696 4.576064
proofread: yes
<figure class="extended-col">
<img src="../../assets/mutt.jpg" alt="Mutt" />
<blockquote class="vcard narrow-col">
All mail clients suck. This one just sucks less.
<cite class="fn">
<span class="given-name">Michael</span>
<span class="additional-name">R.</span>
<span class="family-name">Elkins</span>
<div class="narrow-col">
<p><a href="">Mutt</a> is a text-based e-mail client for UN*X systems. It doesn't do nicely formatted <abbr title="HyperText Markup Language">HTML</abbr> emails or images, but it's extremely customizable and completely keyboard-driven.</p>
<p>I have been using Mozilla's <a href="" title="Thunderbird open source e-mail client">Thunderbird</a> for a while now and I'm not completely satisfied with the way it handles mailboxes. It's time to try something 'new': Mutt. The plan is to use Mutt for all things e-mail for a full month.</p>
<p>A word of warning: Mutt is known for its complicated setup (there are literally hundreds of configuration commands), and I had to stitch together quite a few blog posts before I got a working setup. If you don't like braking and rebuilding stuff or hunting down a missing comma for half an hour, Mutt is probably not for you.</p>
<h2>Fetching emails with isync</h2>
<p>I use <a href="" title="IMAP and MailDir mailbox synchronizer">isync</a> to synchronize my e-mail locally and Mutt to read and send emails. <abbr title="Internet Message Access Protocol">IMAP</abbr> only. Mutt can do more, much more, but you will have to look elsewhere for that.</p>
<p>Mutt comes with <abbr title="Internet Message Access Protocol">IMAP</abbr> support built-in. This works superbly but is a bit slower when dealing with larger mailboxes. Mutt's built-in <abbr title="Internet Message Access Protocol">IMAP</abbr> support fetches your e-mail as soon as you start the program. There is a cache that is quite fast but requires a bit of patience every time you open the program. It also means you can't read your e-mail offline. I want a little more and use isync to download or better, synchronise, my e-mail locally via a crontab.</p>
<p>isync syncs your different e-mail accounts to a local folder structure. As much as it can be used outside of Mutt, they work together nicely and it makes Mutt faster and available on the go.</p>
<p>Be careful because isync doesn't download but <strong>synchronizes</strong> your mailbox! If you mess up the configuration, you could easily delete all your mail from the mail server. Play with a test account first and/or make sure you have a <strong>backup</strong> before you try this. You do have a backup, right?</p>
<p>The executable isync is called 'mbsync' and can be configured with a '.mbsyncrc' configuration file in your home dir. Let's configure our different <abbr title="Internet Message Access Protocol">IMAP</abbr> accounts and add a crontab to fetch our new e-mail.</p>
<p>Create a '~/.mbsyncrc' file with the following:</p>
{% highlight bash %}
SyncState *
Create Both
IMAPAccount john-account
Pass secret_password
UseIMAPS yes
RequireSSL yes
IMAPStore john-remote
Account john-account
MaildirStore john-local
Path ~/.mail/john/
Inbox ~/.mail/john/INBOX
Channel john-inbox
Master ":john-remote:INBOX"
Slave ":john-local:INBOX"
Channel john-sent
Master ":john-remote:Sent"
Slave ":john-local:sent"
Group john
Channel john-inbox
Channel john-sent
{% endhighlight %}
<p>Repeat this for every account you wish to synchronize. The example will only synchronize your inbox and sent mailbox, add other folders you might need, like a trash or spam folder. I had to create each of the account directories in '~/.mail' manually as well.</p
<p>Now add a crontab command to fetch all e-mail every 5 minutes:</p>
{% highlight bash %}
*/5 * * * * mbsync -a
{% endhighlight %}
<p>The 'mbsync -a' command fetches all configured e-mail accounts. You can define different schedules with 'mbsync john', for example, which only synchronizes the account in our configuration example.</p>
<p>Once done, you will see a folder for each channel in the ~/.mail/john directory with all your emails. You now have an offline copy, which is great.</p>
<h2>Installing Mutt</h2>
<p>Mutt time! Mutt doesn't come with a sidebar folder view out-of-the-box, but you probably want one. There is a patch, but you need to instruct Homebrew to include it when installing Mutt.</p>
{% highlight bash %}
brew edit mutt
{% endhighlight %}
<p>to modify the Homebrew formula and add</p>
{% highlight bash %}
option "with-sidebar-patch", "Apply sidebar patch"
{% endhighlight %}
<p>at the bottom of the block with all the options and add</p>
{% highlight bash %}
patch do
url ""
sha1 "1e151d4ff3ce83d635cf794acf0c781e1b748ff1"
end if build.with? "sidebar-patch"
{% endhighlight %}
<p>at the end of the section with all the patches.</p>
<p>And, finally, install Mutt:</p>
{% highlight bash %}
brew install mutt --with-sidebar-patch
{% endhighlight %}
<h2>Configuring Mutt</h2>
<p>Muttt's config lives in the '.muttrc' file in your home dir, right next to the isync config file. However, I prefer a '.mutt' folder with a 'muttrc' (no dot here) file to have all the Mutt dependencies in a single place.</p>
<p>Let's start by telling Mutt where to look. Add the following to the '~/.mutt/muttrc' file:</p>
{% highlight bash %}
set folder = ~/.mail # mailboxes
set alias_file = ~/.mutt/alias
set header_cache = ~/.mutt/cache/headers
set message_cachedir = ~/.mutt/cache/bodies
set certificate_file = ~/.mutt/certificates
set mailcap_path = ~/.mutt/mailcap # filetypes
set tmpdir = ~/.mutt/temp
{% endhighlight %}
<p>and set some nicer defaults:</p>
{% highlight bash %}
set wait_key = no # shut up, mutt
set mbox_type = Maildir # mailbox type
set timeout = 3 # idle time before scanning
set mail_check = 0 # minimum time between scans
set markers = no # no + sign for wrapped lines
unset move # gmail does that
set delete # don't ask, just do
unset confirmappend # don't ask, just do
set quit # don't ask, just do
unset mark_old # read/new is good enough
set beep_new # bell on new emails
set pipe_decode # strip headers and eval
set thorough_search # also when searching
color status cyan default # while instead of black
bind index gg first-entry # cursor to first a la vim
bind index G last-entry # cursor to last a la vim
{% endhighlight %}
<p>Moving on to the sidebar. The following configures the up and down arrows to select a mailbox in the sidebar and the right arrow to open the selected mailbox. It also highlights the mailboxes with new emails.</p>
{% highlight bash %}
set sidebar_delim = " │"
set sidebar_visible = yes
set sidebar_width = 20
macro index,pager <up> "<sidebar-prev>" "previous folder in sidebar"
macro index,pager <down> "<sidebar-next>" "next folder in sidebar"
macro index,pager <right> "<sidebar-open>" "open folder in sidebar"
color sidebar_new color221 color233
set status_chars = " *%A"
set status_format = "───────────────────[%r%m messages%?n? (%n new)?%?d? (%d to delete)?%?t? (%t tagged)? ]───%>─%?p?( %p postponed )?───"
{% endhighlight %}
<p>Let's configure an account. I created a file for each account and used the folder hooks to trigger the right config for the selected mailbox:</p>
{% highlight bash %}
folder-hook example/* source ~/.mutt/accounts/example
folder-hook gmail/* source ~/.mutt/accounts/gmail
{% endhighlight %}
<p>And the 'example' file in the accounts folder:</p>
{% highlight bash %}
set realname = "John Doe"
set from =
set use_from = yes
set my_smtp_user =
set smtp_pass = password
set smtp_url = smtps://$my_smtp_user:$
set ssl_force_tls = yes
set smtp_authenticators = login
set spoolfile = +example/INBOX # inbox
set record = +example/sent # sent folder
mailboxes Example \ # fake mailbox as divider
+example/INBOX \
{% endhighlight %}
<p>Note that the password is <strong>not encrypted</strong> here. Therefore, only use this if you know what you are doing and make sure the file is only readable for your user. There are some ways around this if this scares you, but that's beyond the scope of this post.</p>
<p>If your password contains special characters ($, &amp;, %, #, * and the like), you'll need to URL encode them. This took me a while to figure out. The password will be used in the 'smtp_url' setting so it makes sense you URL encode the special characters like you would in any URL. I used <a href="" title="Interactive Ruby Shell">irb</a> to quickly encode my password:</p>
{% highlight ruby %}
require "uri"
{% endhighlight %}
<p>The mailboxes section at the end of the file sets the mailboxes you will see in the sidebar. These have to match the mailboxes you defined earlier in the 'mbsync' configuration file. The first "Example" line is not a real mailbox, but a little hack to have a visual separation between the accounts.</p>
<p>You'll find plenty of Gmail example files if you want to add one of those. They are basically the same as the example above, but with Google's <abbr title="Simple Mail Transfer Protocol">SMTP</abbr> server and your Gmail address.</p>
<h2>Quick Look</h2>
<p>By default, Mutt saves attachments you open within Mutt to disk. This works but is cumbersome if you simply want to look at a photo someone sent you or quickly scan an attached <abbr title="Microsoft">MS</abbr> Word document. OS X has this awesome <a href="" title="OS X Quick Look @ Wikipedia">Quick Look</a> feature that quickly opens most files without having to install separate applications. Why not use Quick Look for e-mail attachments in Mutt?</p>
<p>Did you know you can run Quick Look from the command line with 'qlmanage -p file'? We''ll use this trick to tell Mutt to run Quick Look when opening attachments. Add a 'mailcap' file in the '~/.mutt' folder you created earlier with the following:</p>
{% highlight bash %}
text/html; qlmanage -p %s; nametemplate=%s.html
text/html; lynx -dump %s; nametemplate=%s.html; copiousoutput
application/pdf; qlmanage -p %s; nametemplate=%s.pdf
image/jpg; qlmanage -p %s; nametemplate=%s.jpg
image/jpeg; qlmanage -p %s; nametemplate=%s.jpg
image/pjpeg; qlmanage -p %s; nametemplate=%s.jpg
image/png; qlmanage -p %s; nametemplate=%s.png
image/gif; qlmanage -p %s; nametemplate=%s.gif
text/*; open %s
application/*; open %s
{% endhighlight %}
<p>Run Mutt; search for an e-mail with an attachment; press enter with the attachment selected and voila, quick previews without saving.</p>
<p>I obviously didn't find this all by myself so here are some of the most useful snippets I stole:</p>
<li class="vcard">
<a class="url" href="">The Homely Mutt</a> by <span class"fn">Steve Losh</span>.
<a class="url" href="">Quick Look and mailcap</a> tweet by <span class="fn">Paul Betts</span>.