Muto - Blog - Feed


Actually Using Emacs Rmail

I've been using rmail (an email client built-in to Emacs) on and off for some 5 years now. I have used mutt, thunderbierd, notmuch, m4ue, claws, gmail, geary, evolution, and a handful of others, but I like rmail. I have a healthy relationship with rmail and, although I have written sections on it, and made a few videos about it, I owe rmail at least one good article, so here we go!


Setting Things Up Right

I'll only be talking about how to access email from a generic remote inbox, since that's what I have.

You're going to want to add this code into your emacs configuration file (I have mine in ~/.emacs.d/init.el but yours might just be in ~/.emacs.

(setq
 rmail-primary-inbox-list
  (list (concat "imaps://bird%40muto.ca"
                ":Passw0rD"
                "@mail.gandi.net"))

 send-mail-function 'smtpmail-send-it
 rmail-preserve-inbox t
 rmail-file-name "~/.emacs.d/mymail/bird"
 user-mail-address "bird@muto.ca"
 user-full-name "Bird")

Looking good! First we tell Emacs what our email address is, which uses the same syntax as the MAIL environment variable! It looks like this:

Protocol://Username:Password@Host

I cut it up into multiple lines for readability using the concat function. Notice that I use %40 instead of @. This is how the MAIL environment variable works. It's not bad, but it's a quirk that we just have to live with.

Then we set some variables:

  • Use the smtp-mail-send-it function to send email.
  • Don't delete mail from the server after polling
  • Set the default name for our inbox file
  • Set our 'return to' address
  • Specify our full name

Looking good so far! Let's test it out to make sure it works.


Using Rmail

Start rmail with M-x rmail, then use h to view your inbox, and g to attempt to get new mail. (If you're stuck here, let me know. I want this guide to be straightfofrward)

Send an email with m to whoever you want (me, maybe?) and that should be it! In the inbox summary view you can use n and p to move up and down through your emails, and o to send an email to another file.

When you send an email to a different file via o, it appends it to (or creates a new) file that is exactly the same as your inbox file, so you can have different "folders" by creating different rmail files! I usually have files named conv and note to sort between conversational emails and website notification/junk emails! It's nice

Note that, when you copy an email to a new file, it remains in your inbox. You can safely delete it from your inbox, since the copy is in another file.


The Tickets File

Did you notice that we store our password in plaintext in the init.el file? That's probably not the coolest thing ever, is it?

Mailutils comes with something called a "Ticket File", a plaintext file at ~/.mu-tickets which lets you store mail account information in, like so:

# ~/.mu-tickets
# The Ticket file contains one MAIL account
# per line that rmail will look at.

imaps://bird%40muto.ca:Passw0rd@mail.gandi.net
imaps://skel%40muto.ca:password123@mail.gandi.net

Now you can remove the password section in your init.el file! You can see this in action in the "Multiple Accounts" section.


Don't Keep Your Mail On the Server!

Quick PSA, download your email and store them locally. If you set rmail-preserve-inbox to t (like in the example), every time you refresh your inbox, your entire local inbox will be duplicated! I added it just so you wouldn't be surprised to find all your mail gone while you're using rmail.

Remove the rmail-preserve-inbox line on your main machine, and keep it on your other compters. That way you can check your email when you're away from home, and then you can go home and download them all. (Be sure to have a backup, too!)

Some Advanced Configuration

Let's make Rmail more fun with a few extra variables and functions!

(setq
 rmail-default-file "~/.emacs.d/mymail/bird/bird"
 rmail-mime-prefer-html nil
 message-signature "Lots of love, -Bird\nhttps://muto.ca"
 mail-default-headers "FCC: ~/.emacs.d/mymail/bird/sent"
 message-default-mail-headers mail-default-headers)


;; Make a function that opens rmail
;; without checking for new mail!
(defun rmail-no-check ()
  (interactive)
  (rmail-input rmail-default-file))

;; Shortcut for rmail-no-check
(global-set-key "\C-cmc" 'rmail-no-check)

;; Make C-o move between the email & inbox buffers
(add-hook 'rmail-summary-mode-hook
          (lambda ()
            (local-set-key (kbd "C-o") 'other-window)))
(add-hook 'rmail-mode-hook
          (lambda ()
            (local-set-key (kbd "C-o") 'other-window)))

First we set rmail-default-file, which sets the default path for rmail to look when you use o to output a file (by default it's ~/xmail, but I set it to my inbox file so I can be in the right directory)

We tell rmail to use plaintext if possible (but use HTML if there is no plaintext option available), Then we add a mail signature (note that escapes like \n are supported)!

Then we set mail-default-headers to a string that says "When you send an email to someone, also put it in an rmail-readable sent file!"

Additionally, we set message-default-mail-headers to be the same value as mail-default-headers. Why? Because if you're using multiple accounts (see below), when you switch accounts, rmail won't change the FCC value unless it's set! Weird, but that's how it is.

We also add a shortcut for opening rmail without needing to check every time, and we defined C-o to be other-window, because I usually map C-o to other-window, but rmail re-defines it to be the same as o, which I don't need!


The Mailrc file

When you start writing an email (with C-x m), you have to write the recipient's email address in the TO: field. That's fine, but what's even more fine is the ability to create aliases for all your contacts!

Open / create the file ~/.mailrc and write something like this in it:

alias bird    "Bird <bird@muto.ca>"
alias skel    "Skeleton <skeleton@muto.ca>"
alias example "Another Friend <friend@example.com>"

Basically, the .mailrc file defines shortcuts that allow you to tab-complete your contacts in mail-mode!

Now, when you're writing an email, if you want to write an email to me, you would put bird in the TO: field, then press TAB, which would expand it to say Bird <bird@muto.ca>!

The mailrc file also acts as a contact list. It's just… It's…. Gosh it's handy!

Multiple Accounts!

So, I use more than one email account. I have an email for every website I own, I have a gmail that I have from the stone ages (I can't delete my gmail! It's linked to my Webkinz account!), I have a work email, and I have my main email, so I like to switch between them easily. I can do this with an emacs function!

;; Configure the first email account:
(defun mail-skel ()
  (interactive)
  (setq
   ;; Passwords can be ommitted from rmail-primary-inbox-list
   rmail-primary-inbox-list
    (list (concat "imaps://skeleton%40muto.ca"
                  "@mail.gandi.net"))
   rmail-preserve-inbox t
   rmail-default-file "~/.emacs.d/mymail/skel/skel"
   user-mail-address "skeleton@muto.ca"
   user-full-name "Skeleton"
   rmail-file-name "~/.emacs.d/mymail/skel/skel"
   rmail-default-headers "FCC: ~/.emacs.d/mymail/skel/sent"
   message-default-mail-headers rmail-default-headers
   message-signature "Boo! -Skel")
  (message "%s" (propertize "Email account: Skeleton")))

;; Configure the second account
(defun mail-bird ()
  (interactive)
  (setq
   rmail-primary-inbox-list
   (list (concat "imaps://bird%40muto.ca"
                         "@mail.gandi.net"))
   rmail-preserve-inbox t
   rmail-default-file "~/.emacs.d/mymail/bird/bird"
   user-mail-address "bird@muto.ca"
   user-full-name "Bird"
   rmail-file-name "~/.emacs.d/mymail/bird/bird"
   rmail-default-headers "FCC: ~/.emacs.d/mymail/bird/sent"
   message-default-mail-headers rmail-default-headers
   message-signature "Lots of love! -Bird")
  (message "%s" (propertize "Email account: Bird")))

;; Set the default mail account
(mail-bird)

;; Keybindings to switch between accounts:
(global-set-key "\C-cmm" 'mail-bird)
(global-set-key "\C-cms" 'mail-skel)

Looking good! We pretty much just took a bunch setq declarations, and slapped them inside a function, then copied them all into another function! We also used message, which lets us print a minibuffer message telling us which account we just switched to!


Videos

You can see videos where I talk about rmail here! :)

If you use rmail and have discovered any way to make it even nicer, or if you're having trouble following or understanding this article, please email me at shack att muto.ca!