Background
You should be more or less a fan of command line email if reading this.
Having been using mutt for several years, I have to say my mutt configuration evolves, either following changes in new technology or concepts with email processing.
In early days when POP3 was still the go-to option, mutt was setup to hook up
with fetchmail to get email from server, then procmail/maildrop would do some
processing, including piping to spamassassin or bogofilter, before finally
messages reaches my local inbox. Multiple accounts was easy, because there
was no synchronization of my local mailboxes back to remote server, basically
messages all messages from different servers were put in the same directory,
the local inbox. When a reply message was composed, its header from
field was
usually set using a send-hook
based on the to
field of the message replied
to, so that I would reply from a wrong email account.
Now, IMAP dominates mainstream email servers, and it enables user to sync back their local mailboxes to remote server. It certainly benefits user more by allowing user to have the same view of email directories across different devices, but at the same time breaks the way multiple accounts could be used in mutt.
-
An IMAP client that does two way synchronization to server is required. Popular options are offlineimap and isync. Personally I prefer isync, and it is more stable according to my experience. Mutt’s built-in IMAP functionality is not recommended; it is just too slow.
-
Messages from different servers should be no more put in the same local mailbox. You do not want love letters from your girlfriend to be uploaded to your employer’s mail server.
-
MDA like procmail is no more possible because neither offlineimap or isync will work with it. This as well means spamassassin or bogofilter should be removed from your configuration as well. In IMAP environment, you should pretty much leave spam identification to the server. This also means it becomes harder to hook up a small script to procmail to do automated email processing like auto-reply and etc.Now there is imapfilter, and you can pipe your emails for further processing.
Okay, so much for background knowledge. Below is how I make an easy to use multi-account mutt configuration for two IMAP accounts.
Sync email with isync / mbsync
The following is a ~/.mbsyncrc
section for a gmail account, it stores all
emails in subdirectories of ~/.mail/
. For another account, a separate mailbox
folder should be chosen, for example ~/.business_mail/
.
Here I group several sync channels together, and each channel defines a pair
of remote and local directories to sync. For example, [Gmail]/Sent Mail
is
paired with ~/.mail/sent
. Doing this enables me to have simpler directory
names locally.
IMAPAccount gmail
Host imap.gmail.com
User XXXXXXX@gmail.com
Pass XXXXXXX
SSLType IMAPS
AuthMechs LOGIN
CertificateFile /Users/roylez/.root.crt
IMAPStore gmail-remote
Account gmail
MaildirStore gmail-local
# The trailing "/" is important
Path ~/.mail/
Inbox ~/.mail/inbox
Channel gmail-default
Master :gmail-remote:
Slave :gmail-local:
Patterns INBOX
Channel gmail-sent
Master :gmail-remote:"[Gmail]/Sent Mail"
slave :gmail-local:sent
Channel gmail-trash
Master :gmail-remote:"[Gmail]/Trash"
slave :gmail-local:trash
Channel gmail-archive
Master :gmail-remote:"[Gmail]/All Mail"
slave :gmail-local:all
# Automatically create missing mailboxes, both locally and on the server
Create Both
# Automatically delete messages on either side if they are found deleted on the other.
Expunge Both
# Save the synchronization state files in the relevant directory
SyncState *
Group gmail
Channel gmail-default
Channel gmail-trash
Channel gmail-archive
Channel gmail-sent
After setting up all accounts, I can use the following command to test synchronization.
mbsync -a
To automate it, a crontab entry is used. Since if network is down during synchronization will cause mbsync to hang indefinitely, I make it first try to kill any existing processes.
*/15 * * * * killall mbsync &>/dev/null; /usr/local/bin/mbsync -a -q
Setup Account Profiles
Now I have two accounts, say, one personal and one business. I then create separate account profiles for mutt to load.
The following is for ~/.mutt/account.personal
, and there should be another similar one, namely ~/.mutt/account.business
.
# vim: ft=muttrc
set folder = "~/.mail"
set mbox = "+inbox"
set record = "+inbox"
set postponed = "+inbox"
set spoolfile = "~/.mail/inbox"
set from = 'me@roylez.info'
set sendmail = "~/.mutt/do_sendmail msmtp"
set signature = 'fortune -s|cowsay -f small -W 70|'
set status_format="===[ 个人: %f ]---[ 邮件:%?M?%M/?%m%?n? 新:%n?%?o? 旧:%o?%?d? 删除:%d?%?F? 星:%F?%?t? 标记:%t?%?p?? ]----%>-(%P %l)==="
macro index,pager d "<save-message>=trash<enter>" "Trash"
macro index,pager y "<save-message>=all<enter>" "Archive"
You can see in this profile, every mailbox points to a directory under
~/.mail/
. Also you should notice I have a customized sendmail
command.
Because we should select different SMTP server for different accounts, this is
almost a must. Luckily msmtp allows to select a profile from command line.
Here the my script do_sendmail
does some extra things, like attachment
checking and collecting recipient email address for future query_command
look
up. You do not have to worry about this script, and it is perfectly okay if you
put simply set sendmail="msmtp -a gmail"
here.
Also, for this account I have tailed signature and mutt status_format
. The
latter is especially useful, because it enables me to tell which account I am
dealing with.
The last two macro definitions are critcal. The first mimics “moving to trash” action on the server, and the second mimics an “archive” operation, which nowadays almost everyone cannot live without.
Attention: You may discover duplicated emails in “all” directory after an archive operation, but do not panic. After two more synchronization the extra copy will be gone because Gmail identifies and takes care of duplications on the server.
Switch profiles with ease
In my ~/.muttrc
I have the following
# make c contextual according to archlinux wiki
macro index 'c' '<change-folder>?<change-dir><home>^K=<enter>'
source ~/.mutt/account.business
macro index <f2> '<enter-command>source ~/.mutt/account.personal<enter><change-folder>!<enter>'
macro index <f3> '<enter-command>source ~/.mutt/account.business<enter><change-folder>!<enter>'
# use tab to switch between accounts, inspired by
# http://msmtp.sourceforge.net/doc/msmtp.html#Using-msmtp-with-Mutt
macro generic \Cx| "<enter-command>source"
macro generic \Cx& "<enter-command>macro index \\t \"\\Cx"
macro index <tab> "\Cx0" # default change to account 1, this will be redefined once pressed
macro generic \Cx0 "\Cx| ~/.mutt/account.business\"\n\Cx&1\"<enter><change-folder>!<enter>"
macro generic \Cx1 "\Cx| ~/.mutt/account.personal\"\n\Cx&0\"<enter><change-folder>!<enter>"
In the first section, macro c
redefinitions is required to force a
<change-dir>
reload after sourcing a new profile and changing mailbox folder.
Macro <f2>
and <f3>
are defined to be shortcuts to different accounts,
respectively. However, it turns out that I do not use them much.
The last section defines <tab>
to be the key to toggle between two different
accounts. The selection of keymappings of \Cx|
and alike is to make sure
these utility macros would not be trigger by mistake. If you have more than two
accounts, then you would have to add additional macros, say \Cx2
and etc to
chain them up.