Mutt, IMAP and elinks¶
![mutt](../_images/20110605-mutt_window.png)
I spent the last two nights figuring out how I can set up more than one e-mail account in the email client mutt.
For you who ask why spending several hours of reading manuals and trying different configurations while any other e-mail client would give access within five minutes: Stop reading this article. We do not share any common ground in this topic.
By default mutt can be configured for just one e-mail account at a time. If you start it with a different configuration file - no problem. But this is for amateurs and can be achieved within 5 minutes (as mentioned above). What we want is everything at the same time; all at once; all under full control.
Mutt¶
So account-hooks are the way to go in this scenario. In this example I configured two different accounts on the same IMAP server (on different ones it is easier). Since a couple of descriptions about configuring gmail accounts can be found on the Internet, I skip this part and will just point at unspecific IMAP serves. I also spared any password protection functions.
#.muttrc
account1@IMAPserver1 (Email-address1)
account2@IMAPserver1 (Email address2)
IMAPSERVERADDRESS (address of the imap server)
The basic configuration of each account has been stored in separate files in ~/.mutt/accounts:
#~/.mutt/accounts/account1.imapserver1
#
# Folders for account1@IMAPserver1
#
set folder="imap://account1@IMAPserver1@IMAPSERVERADDRESS/"
set spoolfile="imap://account1@IMAPserver1@IMAPSERVERADDRESS/"
set hostname="IMAPserver1"
set folder=imap://IMAPSERVERADDRESS/
set record=+Sent
set from="Firstname Secondname"
set postponed=+Skisser
set realname="Firstname Secondname"
#~/.mutt/accounts/account2.imapserver1
#
# Folders for account2@IMAPserver1
#
set folder="imap://account2@IMAPserver1@IMAPSERVERADDRESS/"
set spoolfile="imap://account2@IMAPserver1@IMAPSERVERADDRESS/"
set hostname="IMAPserver1"
set folder=imap://IMAPSERVERADDRESS/
set record=+Sent
set from="Firstname Secondname"
set postponed=+Skisser
set realname="Firstname Secondname"
Once this has been done the rest is a piece of cake.
#~/.muttrc
# General changes
# # # # # # # # # #
set date_format = "%Y-%m-%d ,%H:%M:%S"
# Mailboxes (the primary one last)
mailboxes "imap://account2@IMAPserver@IMAPSERVERADDRESS" "imap://account2@IMAPserver@IMAPSERVERADDRESS"
#
# Account Hooks
#
# Reset all variables to start from a know state.
account-hook . 'unset preconnect imap_user imap_pass imap_authenticators; set ssl_starttls=ask-yes'
# account1@IMAPserver
account-hook imap://account1@IMAPserver@IMAPSERVERADDRESS/ '\
set imap_user=account1@IMAPserver \
imap_pass=""'
# account2@IMAPserver
account-hook imap://account2@IMAPserver@IMAPSERVERADDRESS/ '\
set imap_user=account2@IMAPserver \
imap_pass=""'
#
# Folder Hooks
#
folder-hook 'imap://account2@IMAPserver@IMAPSERVERADDRESS' 'source ~/.mutt/accounts/account2.IMAPserver'
folder-hook 'imap://account1@IMAPserver@IMAPSERVERADDRESS' 'source ~/.mutt/accounts/account1.IMAPserver'
# Choose the first accounts that shall be used at startup
source ~/.mutt/accounts/account1.IMAPserver
# Other stuff
set header_cache ="~/.mutt/cache/headers_$imap_user"
set message_cachedir =~/.mutt/cache/bodies
set certificate_file =~/.mutt/certificates
set smtp_url = "smtp://account1@IMAPserver@SMTPSERVERADDRESS[:PORT]/"
set smtp_pass = ""
# Annoyances
set move = no #Stop asking "more read message to mbox"!
set imap_keepalive = 900
set mail_check = 0
# My Editor is VI
set editor='vi + -c "set textwidth=72" '
set attribution = "På %d, skrev %n:"
# Key Bindings/Macros
bind index "^" imap-fetch-mail
Limit¶
Instead of searching, you can limit (filter) the index list of mutt and display only the messages of a certain interest. Instead ‘/’ use ‘l’ (lowercase L). Per default it searches for subject, author and sender e-mailaddresses. If you are in your sent email folder, this does not help you when you want all mails to a certain recipient. I found the following additional parameters quite helpful:
~s party : messages with subject containing “party”
~d * *~t_ paulm : To: matches paulm (useful for sent-mail folders)
~O : old (i.e. unread but not new) messages. ~N is new unread. ~U is unread, i.e. both together.
~p : messages addressed to you (useful if your inbox is bombarded with mailing list or system report activity).
~p ~U : for messages to you you have not read yet.
. : matches everything. In effect, remove the limit.
~h Content-Type:.*html | ~h Content-Type:.*multipart : messages with HTML-attachments | all attachments
More in the mutt-documentation, section 4.2: patterns.
Switching folders¶
After a while it is getting quite boring, almost annoying to manually switch between often used folders of a account. Switching between Trash and Inbox and Send can really annoy the shit out of you, if you have to to it too often.
Instead you can assign key-bindings to perform the necessary actions for you when giving just one or two keystrokes:
#.muttrc
macro index gi "=INBOX" "Go to inbox"
macro index gs "=INBOX.Sent" "Go to Sent Mail"
macro index gd "=INBOX.Drafts" "Go to drafts"
macro index gt "=INBOX.Trash" "Go to Trash"
On pressing gs (maybe you should press before) mutt switches into the folder for the send mails. Addresses is this folder on IMAP by INBOX.Sent. This might not be correct in your case, but you figure out the right folder address when you switch to the folder manually (hopefully for the last time) and then you will see the current address in the bottom line of mutt.
ELinks (HTML-Emails)¶
For reading crappy HTML emails inside the interface of mutt, two changes are necessary. Using a .mailcap file you tell mutt to render all HTML mails as text and display them in links or any other console browser you like. If you do not have one already, create a .mailcap file in your home directory and put the following lines in it:
#.mailcap
text/html; links %s; nametemplate=%s.html
text/html; links -dump %s; nametemplate=%s.html; copiousoutput
Now tell mutt to automatically render HTML emails by putting this into your .muttrc file:
#.muttrc
auto_view text/html
If you get a couple of mails with problems displaying special characters like å, ø, æ. etc, you might consider W3M for the mails instead of links (or ELinks).
Update:
I have replaced links with ELinks in ~/.mailcap. Occasionally I get HTML-emails from systems, sending out logs and reports and marking errors with HTML color-tags. Reading them on the console costs much time when you have to try to spot the errors. Of course you could just search within ELinks after terms like “Error”, but that is to obvious.
You need to configure ELinks to be able to send the current URL to the external browser.
You need to configure a short cut for this action within ELinks.
So you do the following to configure ELinks
Within ELinks you go to Setup -> Options Manager -> Document -> URI passing.
There you add an option with a name like Opera or Firefox.
Edit this option and add the parameter for your Browser, e.g. : opera -backgroundtab %c.
Save this edit.
Within ELinks you got to Setup -> Key-binding Manager -> Main Mapping -> Pass URI of current frame to external command.
Add an option for a shortcut, e.g. CTRL-o.
Save this edit.
When you now press <CTRL>+o within ELinks your configured browser will open (or just open an additional Tab) and display the HTML document.
This will edit ~/.elinks/elinks.conf and add the following lines (if configured with Opera):
#~/.elinks/elinks.conf
set document.uri_passing.Opera = "opera -backgroundtab %c"
bind "main" "Ctrl-O" = "frame-external-command"
Mailcap¶
The small file .mailcap is your key to happy life. Mutt checks that file first to see if an attached file you want to open has been specified there and how to open it. Occasionally you stumble over some files or configurations that do not really work out.
Another experience you might make is that mutt waits until the started application terminates until you can continue using it. So just opening a PDF out of mutt and at the same time checking another file or email does not really work out.
Unless you fork a separate process for it. There are several ways of doing it, but I just implemented a tiny script which I found here to do that for me: And it works fine.
So instead opening an attached jpg-image with gthumb like this:
#~/.mailcap
image/jpg; gthumb %s
I will do it like this instead:
# ~/.mailcap
image/jpg; mutt_bgrun gthumb %s
mutt_bgrun needs to be available within the $PATH otherwise it is not gonna be found.
Encrypt Passwords¶
As known the passwords can be stored directly into the configuration file ~/.muttrc. And as also known this should not be the way to do it, since simple access to this file would grant all access to the whole e-mail folder.
One way to fix this security-issue is to store the passwords encrypted in a GPG file and source it directly into the configuration file. That way Mutt will ask when coming up for a password to decrypt the file. This will not be the password for the e-mail account, but the password for the pgp file. That way no password is stored in plain text on the local disk.
Create a text-file with the two parameters for defining the password in it:
# ~/.mutt/.muttrc.pw
set imap_pass="password"
set smtp_pass="password"
Encrypt the file with your pgp/gpg key:
$ gpg -r 'gpgid' -e ~/.mutt/muttrc.pw
$ ls ~/.mutt/.muttrc.pw*
/home/user/.mutt/.muttrc.pw /home/user/.muttrc.pw.gpg
Shred the plain-text file and delete it safely.
$ shred ~/.mutt/.muttrc.pw
$ rm ~/.mutt/.muttrc.pw
The remaining file ~/.mutt/.muttrc.pw.gpg is a binary and encrypted file that contains the parameters necessary for including them into the source-file. That file now needs to be imported into the mutt configuration file ~/.mutt/.muttrc
# ~/.mutt/.muttrc
source "gpg -d ~/.mutt/.muttrc.pw.gpg \|"
This will decrypt and import the encrypted file into the configuration file while reading it when Mutt fires up. The pipe at the end of the command is necessary for redirecting the output back to mutt.
When you now fire up Mutt you are gonna be asked for your pass-phrase for the PGP/GPG file once. As long Mutt is running it will grant you access to the file and you can send and receive e-mails as usual.
If you want to go even further search for information how to connect the gpg-agent to mutt.
Sending E-Mails as attachment¶
Occasionally I have to send e-mails attached to another email. This happens when I need to send some diagnostic e-mails the some vendor for instance. This is no problem at all if you know how to do it (and if you think about it)
Write your e-mail as usual.
Instead of lowercase ‘a’ you use the uppercase ‘A’ this time for attaching.
Mutt will open your mailbox and you tag the messages you want to attach with ‘t’.
Leave the attachment-dialog with ‘x’.
Send.
Forwarding attachments¶
When forwarding an e-mail, mutt tends to only forward the message part, but leave the attachments behind. This is actually considered to be the correct behavior, since you are forwarding usually exactly what is currently on the screen.
There are other convenient ways, to include the whole email into the forward, not only the currently displayed part.
Way:
Type v to get to the attachments screen.
Type t repeatedly to tag all the attachments, including the initial small text/plain attachment (that is the original message body).
When they are all tagged, type ;f (forward all tagged attachments). After you fill in the To: prompt, you will be able to edit the message body, and when you leave the editor, you will have the attachment list there to edit as you see fit.
Way: If that does not work (I have not tried it on HTML messages), there is a slightly more elaborate procedure:
Use Esc-e (resend-message), basically use the current message as a template for a new one. This calls up an editor on the current message, including headers.
Change the From to your name, the To to your intended recipient, and edit the message body to your hearts content. When you are done, you are being sent to the Compose screen, where you can adjust the attachment list and send the message. Forwarding is pretty clearly not what Esc-E was intended for … but it does the job and might be a handy trick to know.
Attachments, piping¶
Since we are already talking about attachments here: you can just pipe them as anything else (like the email, e.g.) to any command you like. So you can extract compress files on the file and save on step
Key: |
Command for a tar file to extract:
Pipe to: tar -C ~/ -x
URLS¶
For opening URLS just install urlview:
$ sudo apt-get install urlview
Then just CRTL+b will open the URL in your browser (or all URLS available you choose the one)
Spellchecking¶
Let’s just add some spellchecking to the mutt/vim editor.
Somewhere in my .muttrc or in one of the source-ed files I add the following line:
#.muttrc
set editor="vim -c 'set spell spelllang=nb,en,de' -c 1 -c 'set textwidth=72'"
Here are three parameters set. For the spellchecking only the first one is relevant. Supported languages are set to nb, en and de. If the dictionaries for the languages are missing, VIM will ask to download them and store them under ~/.vim.
This since change only is in the .muttrc and not in the VIM configuration file, this will not apply to all the other files we might edit with VIM (like configuration files).
Unknown or misspelled files are highlighted. In case we want to add a file to the spellchecking library/file, just put the cursor over the word, go in command-mode and type zg. This will put the word into the spellchecking-file, usually placed in ~/.vim/spell/<lang>.utf-8.add (you might want to put those files under your sync solutions to keep them aligned across your systems).
If you want to actually correct the word from the suggestions the command z= gives you a selection of suggestions.