Mutt is the best e-mail client.

There's really not much more that I need to say. I've been using it for years and it's never let me down. You may be reading this and chuckling under your breath because you've never heard of Mutt or you've heard of it and dismissed it. Well, that's a mistake.

Screenshot of Mutt, reading mail

Mutt is a text-based e-mail client, or MUA if you want to be technical about it. Since e-mail is a text-based medium, that makes the most sense in my eyes. The beauty of it is that you can read all your e-mail without moving your hands from the keyboard! Got a bunch of crap that you don't want to read? Bounce on that "d" key until it's gone. No need to even open the messages. Mutt has a bunch of nice "hooks" as well that let you pipe mail through other programs. For example, I've got a hook for GnuPG so that my mail can be signed or encrypted with a few keystrokes. I've also got it set up so that HTML e-mails are converted to plaintext, since marketers love HTML so much that they feel the need to include it where it just doesn't need to be. I've considered just writing a procmail script to put HTML e-mails straight in the trash, but unfortunately some important mail comes as HTML. That's life these days.


My .muttrc, annotated

set folder = "$HOME/Mail" # My home mailboxes are stored here
set mbox = "+Archive" # the plus sign means it's relative to ~/Mail
set record = "+Sent Messages" # sent mail is saved here
set sort = "threads" # Mail is shown threaded as opposed to chronologically
set sort_browser = "date" # oldest shown on top, newest at the bottom
set use_domain = no  # if I address a mail to "mike", don't add @coddington.us
set signature = "/usr/bin/fortune -s|" # random pithy .signature file

# These are mailing lists that I'm subscribed to. Adding them to my .muttrc
# allows me to be able to easily reply to the list rather than the sender.
subscribe postfix-users
subscribe mutt-users
subscribe dev@suckless.org

# Prefer plaintext, but if we get html, use mailcap to shunt it to a viewer.
# I have my mailcap set to dump output to text using elinks.
auto_view text/html
alternative_order text/plain text/enriched text/html

# Command formats for gpg. I snagged this stuff from some other website.
# 
# This version uses gpg-2comp from 
#   http://70t.de/download/gpg-2comp.tar.gz
#
# $Id$
#
# %p    The empty string when no passphrase is needed,
#       the string "PGPPASSFD=0" if one is needed.
#
#       This is mostly used in conditional % sequences.
#
# %f    Most PGP commands operate on a single file or a file
#       containing a message.  %f expands to this file's name.
#
# %s    When verifying signatures, there is another temporary file
#       containing the detached signature.  %s expands to this
#       file's name.
#
# %a    In "signing" contexts, this expands to the value of the
#       configuration variable $pgp_sign_as.  You probably need to
#       use this within a conditional % sequence.
#
# %r    In many contexts, mutt passes key IDs to pgp.  %r expands to
#       a list of key IDs.

# Note that we explicitly set the comment armor header since GnuPG, when used
# in some localiaztion environments, generates 8bit data in that header, thereby
# breaking PGP/MIME.

# decode application/pgp
set pgp_decode_command="gpg --status-fd=2 %?p?--passphrase-fd 0? --no-verbose --quiet --batch --output - %f"

# verify a pgp/mime signature
set pgp_verify_command="gpg --status-fd=2 --no-verbose --quiet --batch --output - --verify %s %f"

# decrypt a pgp/mime attachment
set pgp_decrypt_command="gpg --status-fd=2 %?p?--passphrase-fd 0? --no-verbose --quiet --batch --output - %f"

# create a pgp/mime signed attachment
# set pgp_sign_command="gpg-2comp --comment '' --no-verbose --batch --output - %?p?--passphrase-fd 0? --armor --detach-sign --textmode %?a?-u %a? %f"
set pgp_sign_command="gpg --no-verbose --batch --quiet --output - %?p?--passphrase-fd 0? --armor --detach-sign --textmode %?a?-u %a? %f"

# create a application/pgp signed (old-style) message
# set pgp_clearsign_command="gpg-2comp --comment '' --no-verbose --batch --output - %?p?--passphrase-fd 0? --armor --textmode --clearsign %?a?-u %a? %f"
set pgp_clearsign_command="gpg --no-verbose --batch --quiet --output - %?p?--passphrase-fd 0? --armor --textmode --clearsign %?a?-u %a? %f"

# create a pgp/mime encrypted attachment
# set pgp_encrypt_only_command="pgpewrap gpg-2comp -v --batch --output - --encrypt --textmode --armor --always-trust -- -r %r -- %f"
set pgp_encrypt_only_command="pgpewrap gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --always-trust -- -r %r -- %f"

# create a pgp/mime encrypted and signed attachment
# set pgp_encrypt_sign_command="pgpewrap gpg-2comp %?p?--passphrase-fd 0? -v --batch --output - --encrypt --sign %?a?-u %a? --armor --always-trust -- -r %r -- %f"
set pgp_encrypt_sign_command="pgpewrap gpg %?p?--passphrase-fd 0? --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --always-trust -- -r %r -- %f"

# import a key into the public key ring
set pgp_import_command="gpg --no-verbose --import %f"

# export a key from the public key ring
set pgp_export_command="gpg --no-verbose --export --armor %r"

# verify a key
set pgp_verify_key_command="gpg --verbose --batch --fingerprint --check-sigs %r"

# read in the public key ring
set pgp_list_pubring_command="gpg --no-verbose --batch --quiet --with-colons --list-keys %r" 

# read in the secret key ring
set pgp_list_secring_command="gpg --no-verbose --batch --quiet --with-colons --list-secret-keys %r" 

# fetch keys
# set pgp_getkeys_command="pkspxycwrap %r"

# pattern for good signature - may need to be adapted to locale!

# set pgp_good_sign="^gpgv?: Good signature from "

# OK, here's a version which uses gnupg's message catalog:
# set pgp_good_sign="`gettext -d gnupg -s 'Good signature from "' | tr -d '"'`"

# This version uses --status-fd messages
set pgp_good_sign="^\\[GNUPG:\\] GOODSIG"