December 12, 2006

Training your Mutt

Author: Joe 'Zonker' Brockmeier

Mutt is a great mail client, in large part because it is extremely customizable. You can tweak Mutt's behavior and have it do tricks that are nearly impossible to do with other mail clients -- but it can be a bit daunting to get started with. Let's take Mutt on a short trip to mail client obedience school and see how easy it can be to make Mutt handle mail just the way you want it to.

To do that, we'll take a look configuring your Mutt configuration file. Mutt reads the system-wide configuration under /etc/Muttrc and looks for a file called .muttrc under your home directory for its configuration. We'll focus on modifying the .muttrc configuration here.

In the .muttrc file, you can tell Mutt where to look for mail, define or redefine Mutt's keybindings, set up macros to speed up actions that you perform frequently, and a lot more. Let's start by telling Mutt where your mail is.

Getting mail

You can get mail in a couple of ways with Mutt. Mutt supports POP3, IMAP(S), and reading the local mail spool. Mutt requires little, if any, configuration to read a local mail spool. By default, Mutt looks for the $MAIL environment variable and reads mail there. If your mail is in a non-standard place, or if you don't want Mutt to use $MAIL as your mail spool, you can set it manually:

set spoolfile=/path/to/spool

Remote mail is slightly trickier. You could combine Mutt with fetchmail, Getmail, or another program to retrieve mail from remote machines, but I'm going to assume most users would rather maintain one program than several.

Let's start by looking at a basic POP configuration. If you want to retrieve email from a POP server, you'll need to set the following in your .muttrc:

set pop_user = "username"
set pop_delete = no
set pop_pass = "password"
set pop_host = ""

The pop_user parameter is the name of the user that will be collecting mail.

The pop_delete directive is a quadoption; you can set this to yes, no, ask-yes, or ask-no. Setting the parameter to yes or no will tell Mutt to delete or leave mail on the POP server without prompting the user, while ask-yes and ask-no tell Mutt to provide a prompt each time it grabs mail via POP, but set to default action to yes or no.

The pop_pass parameter is optional, and it's not really advisable to include it in the .muttrc if you're on a multiuser system. If you leave this out, Mutt will prompt you for the password the first time that you retrieve mail in a session, so you don't need to keep entering the password to grab mail if you leave Mutt running.

The pop_host parameter tells Mutt the hostname of the system to poll for new mail. The default is to poll the server on port 110, without encryption. If you want to use encryption or a different port, you can set that by modifying the server URL a bit. For example, here's what you'd want to use for Gmail:

set pop_host = "pops://"

The pops prefix tells Mutt to use SSL, and you can append a port number. You can specify pop:// for regular unsecured POP3, but there's no need to do so -- if you don't specify pops:// or the port number, Mutt assumes POP3 on port 110.

The IMAP configuration isn't any more difficult. I use IMAPS, and have Mutt use the remote folder as my mail spool:

set spoolfile=imaps://
set imap_user=username
set imap_pass=password

By setting the spoolfile to your IMAP inbox, Mutt will read the mailbox on the IMAP server. Note, again, that you may not want to save the password in your .muttrc file unless you're on a single-user system. If you omit the imap_pass parameter, Mutt will prompt you for your IMAP password.

Defining mailbox type

Mutt supports several mailbox types: mbox, MH, Maildir, and MMDF. By default, Mutt will use the mbox format, but you can override this with the mbox_type directive in the Mutt configuration file. For example, to set to MH, you'd use:

set mbox_type=MH

The mbox format is most widely used, but Maildir is often touted as a superior format. For example, if two programs try to manipulate the user's inbox at the same time, the mbox format has problems; because it's a single file, if two programs are successful at accessing the mbox file at the same time, you can wind up with a corrupted mailbox. Some programs use a locking mechanism to claim the mailbox, but that doesn't mean that another program will honor the lock.

Configuring keybindings

Switching to a new mail client, or new application of any sort, usually requires a retraining period. With Mutt, you can opt to retrain yourself or retrain Mutt. The first time I tried Mutt, I was migrating from Pine. Instead of adapting to Mutt, I decided to see if I could adapt Mutt to my way of doing things.

I could. A bit of searching, and I found this page, with a .muttrc contributed by Tobias v. Koch that configures Mutt to use most of Pine's keybindings, circa version 4.33. If you're using Ubuntu or Debian, you will have several sample Mutt config files under /usr/share/doc/mutt/examples that make for good references.

You can reconfigure Mutt's keybindings to suit your habits. The syntax for a custom keybinding is simple:

bind menukeyfunction

The menu can be one of several menus of functions available within Mutt; the index menu where you view messages, the editor menu where messages are composed, the pager menu which is where you read messages, or any of several others. Mutt also has a generic menu that comprises functions that are available in most menus, except the pager and editor menus.

Let's look at a few examples. The default key for sorting messages in Mutt is o, which brings up the list of options to sort messages by. If you wanted to change that to $ instead, you could use the following directive:

bind index $ sort-mailbox

This tells Mutt to use $ for the sort-mailbox function when in the message index menu. I usually sort messages by the From header, so I've set up a macro to do that in one step rather than two:

macro index $ of

Now, instead of pressing o to bring up the sort menu, and then f to sort by the From header, typing $ does it all in one shot.

Saving messages

If you subscribe to mailing lists, you may want to set up one or more save-hook directives in your .muttrc file. A save-hook provides a default folder for Mutt to save messages in if a message matches a simple pattern. Here's a good example:

save-hook "~C devel-list@" +devel-list

This tells Mutt if a message has the string "devel-list@" in the To or CC field of a message to default to saving it in the devel-list folder. If you wanted to match the user the message was sent from instead, you'd use "~f user. A full list of patterns can be found in the Mutt manual.

If you want to save messages going out to a list to the same folder, you could use the fcc-save-hook directive instead:

fcc-save-hook "~C devel-list@" +devel-list

That would save outgoing and incoming messages with devel-list@ in the To or CC field to the devel-list folder.

The save-hook method doesn't work so well if you have to sort a lot of messages that have almost no common characteristics. For example, I get tons of press releases to my work email address. Setting a save-hook triggered by mail email address wouldn't help, so I use a macro instead:

macro index \co s+OSTG
macro index \cp s+Work/PR

Let's walk through the syntax of the first line to make sure it's clear. The macro directive declares a macro, and index tells Mutt that it's to be used in Mutt's index view. The shortcut for the operation will be Ctrl-o, and when you press that key combination, Mutt will then execute the save command s with the parameter +OSTG, which tells Mutt to save the file in the OSTG folder under my mail directory.

This way, when I get a press release to my work address, I can press Ctrl-p to save it in the PR subfolder. If I get a work email that I want to save to the OSTG folder, I hit Ctrl-o.

Sane header display

Mutt likes to display headers, probably more than you'd care to see. Since I usually care about only a few message headers, I tell Mutt to "ignore" all headers except the From, To, Subject, Date, and CC headers in a message, like so:

ignore headers *
unignore headers from to subject date cc

The headers are still there, of course, but they're hidden from view when you're reading your messages. Since it's not unusual for a message to have more than 20 or more header fields, this saves some valuable screen real estate. If you need to see headers, you can toggle the full view with h, or whatever you have display-toggle-weed set to in your .muttrc file.

To specify what order headers should appear in, use the hdr_order directive:

set hdr_order to from subject date

Look at the pretty colors!

You can customize Mutt's color scheme to whatever makes your eyes happy. I tend to stick to minimal color modifications, but you can go crazy if you want to and customize almost every aspect of Mutt's interface and message displays. The syntax is simple:

color object foreground background expression

The object name, foreground, and background are required fields, while the expression is optional. If you add an expression, then the colorization will take effect only when an object matches the expression. You can find a list of objects and color usage in the Mutt manual.

Mutt has a special object called index that allows you to set colors for messages by pattern in the index. For instance, if you want to highlight any message that is sent by your boss:

color index brightred black boss

Any message in the index that matches the pattern "boss" will have a bright red foreground and a black background.

Here's a short example, with some of my colorization options:

color header brightred black subject
color hdrdefault brightwhite black
color quoted brightgreen black
color status black cyan
color indicator default green

This is mostly self-explanatory, but I'll break the first one down to be sure it's clear. The first item in the configuration tells Mutt to check the header object for a pattern that matches "subject." If it does match, it should set the foreground color to bright red, and the background color to black.

Next: More useful settings

Miscellaneous useful settings

When you're reading a message that has long lines, Mutt will automatically display a "+" marker at the beginning of each wrapped line. This is a bit ugly, but it's easy to get rid of by setting the markers directive to no:

set markers=no

As we've already covered, you can change Mutt's sort order on the fly. You can also configure Mutt to use a different sort order by default, if sorting by date isn't your cup of tea. Mutt allows you to sort by the from header, by threads, the date mail was received (as opposed to the date sent), by size, and several other categories. You'll see the full list of options in the muttrc manpage. To sort by thread, you would use this directive in your .muttrc file:

set sort=threads

If you just want to see messages in the order that they appear in your mailbox, you can use:

set sort=mailbox-order

To bypass Mutt's prompt for To: and Subject: when composing messages, I set two options in my .muttrc file:

set edit_headers=yes
set autoedit

This will put you directly into your editor of choice, and you can edit the header fields directly in your editor rather than entering the To: and Subject: fields at Mutt's prompt. Of course, it's possible to set the editor you wish to use as well. For instance, if you prefer the Pine feel, you can set the editor to nano:

set editor="nano"

Mutt isn't picky -- you can even set the editor to gEdit or Kate if you'd like to use a GUI editor.

When I'm plowing through a large amount of mail, I get annoyed at being asked whether I really want to append a message to a mailbox every time I try to file a message. Mutt's behavior here can be overridden by setting noconfirmappend:

set noconfirmappend

On the other hand, I'd actually like a prompt before Mutt exits, so that if I hit the exit command accidentally, I can tell Mutt not to exit. So, I set the quit option to ask-yes.

set quit=ask-yes

If this isn't set, the default is for Mutt to exit without any confirmation from the user.

Finally, you might want to set the program that Mutt uses to send mail off the local machine. For instance, I use the simple SMTP application to send mail off of my machine to an actual mail server. To configure Mutt to use that, I set the sendmail directive:

set sendmail="~/bin/account"

Here, I've set the sendmail directive to a shell script that calls ssmtp with the authentication information for my server.

Keeping things organized

After a while, your .muttrc file might start to get large. If you'd likes to keep it organized, you can split the configuration out into multiple files and use the source directive in your .muttrc, like so:

source "~/.mutt/save-hook"
source "~/.mutt/headers"
source "~/.mutt/colors"

You might also want to use an alternate configuration file to keep multiple mail accounts separate. Mutt can source different configurations on the fly -- all you need to do is to set up appropriate macros to call the profiles' configurations:

macro index <F9> ":source ~/.mutt/work"
macro index <F10> ":source ~/.mutt/home"

After setting the macros, just press F9 or F10 to switch your profiles on the fly. This can be useful for managing multiple mail accounts, mail signatures, and anything else you might want to configure on the fly.

Obviously, Mutt has many configuration options. The odds are, if there's something in Mutt's behavior that you want to change, you can change it. Poke through the muttrc manpage, and check out the Mutt manual, and you should be able to find your way.

Click Here!