dctrud's Random Road

Occasional unimportant nonsense.

2020-05-13 - Email on Emacs - mu4e

Keeping on the theme of Emacs today, let's talk about email in Emacs. There are various options out there, but you're most likely to come across people talking about Gnus, Wanderlust, Notmuch, and mu4e. I've ended up with the latter, after trying the others (and also experimenting with mutt a few times). mu4e is pretty easy to use, and powerful. It sits on top of the 'mu' command line tool that will index and deal with mail that's in the Maildir format on a local machine.

EmacsWiki category covering mail options on Emacs

mu4e's home page

As with most things in Emacs you probably should take a look at different options to see what fits you best. I found that mu4e was just simpler for the way I use email.

On starting up mu4e with 'M-x mu4e' (bound to 'Spc a M' for me) you'll be greeted with this home screen.

mu4e home screenshot

If you *J*ump into a Maildir, search, or use the bookmarks then you'll enter the index view and mail you open from thre displays in a lower pane. Here I did a *s*earch for 'emacs' and opened up a mail:

mu4e search screenshot

Mu4e also does a half decent job of showing HTML email in an intelligible way with w3m.

Getting email down to mu

My main email account is hosted with Zoho. To sync that down to a Maildir on my computer so that 'mu' can index it I'm using isync.


I have an '.mbsyncrc' in my '$HOME' that is configured to pull down from Zoho over IMAP:

Create Both
Expunge Both
SyncState *

IMAPAccount zoho
Host imappro.zoho.com
User xxxxxxxxxxxxxxxxx
CertificateFile /etc/ssl/certs/ca-bundle.crt

IMAPStore zoho-remote
Account zoho

MaildirStore zoho-local
Subfolders Verbatim
Path '/Mail/
Inbox '/Mail/INBOX

Channel zoho
Master :zoho-remote:
Slave :zoho-local:
Patterns *

Running 'mkdir /Mail && mbsync -a' will get the Maildir setup properly the first time. In future we can have mu4e call that from within emacs to update things.

Initialize mu

Once the Maildir is in place it needs to be initially indexed with mu. This is pretty painless once you have mu installed. Because mu is such a short name, the package is likely called 'maildir-utils' in your distro. Once you have that installed then run...

mu init --maildir='/Mail --my-address=myemail@example.com

Add as many '--my-address' options as you need to cover all of the email addresses that you use.

Emacs Config

I'm running Emacs with a config called spacelite that is based on something I hzenginx/spacelite from GitHub, which has now been archived by the original creator. It has spacemacs type keybindings, but is much less comprehensive / complicated.

The config I have to use mu4e is fairly straightforward. First we setup some of the keybindings specific to the spacelite thing I am using.

(defun spacelite/init-mail ()

  (use-package mu4e
    :ensure nil
    :commands mu4e
    (spacelite/set-leader-keys "a M" 'mu4e)
    (global-set-key (kbd "C-x m") 'mu4e-compose-new)
    (spacelite/set-leader-keys-for-major-mode 'mu4e-compose-mode
        "c" 'message-send-and-exit
        "k" 'message-kill-buffer
        "a" 'message-kill-buffer
        "s" 'message-dont-send              ; saves as draft
        "f" 'mml-attach-file)


This 'remove-hook' is important to avoid a bug that affects 'evil-collection' on newer versions of mu.

    (remove-hook 'mu4e-main-mode-hook 'evil-collection-mu4e-update-main-view)

Next set some nice-to-haves. Easy access to view in a browser, use fancy UTF characters for check marks etc, show images in mail, download locations.

    (add-to-list 'mu4e-view-actions
                '("View in browser" . mu4e-action-view-in-browser) t)
    (setq mu4e-completing-read-function 'completing-read
        mu4e-use-fancy-chars 't
        mu4e-view-show-images 't
        message-kill-buffer-on-exit 't)
  (let ((dir "'/Downloads"))
    (when (file-directory-p dir)
      (setq mu4e-attachment-dir dir)))

Now we setup the location of my Maildir, and the names of the common folders... which often vary between providers and may depend on what other clients you might use.

Note that the 'mu4e-get-mail-command' is set to call 'mbsync -a', which is what I setup previously to fetch my mail from Zoho via IMAP.

;;; Set up some common mu4e variables
  (setq mu4e-maildir "'/Mail"
        mu4e-sent-folder "/Sent Mail"
        mu4e-drafts-folder "/Drafts"
        mu4e-trash-folder "/Trash"
        mu4e-refile-folder "/Archive"
        mu4e-get-mail-command "mbsync -a"
        mu4e-update-interval nil
        mu4e-compose-signature-auto-include nil
        mu4e-view-show-addresses t)

On the sending side of things we have to give the SMTP server details.

;;; Email sending settings
  (setq  user-mail-address "xxxxxxxxxxx"
         smtpmail-default-smtp-server "smtp.zoho.com"
         smtpmail-smtp-server "smtp.zoho.com"
         smtpmail-smtp-user "xxxxxxxxxx"
         smtpmail-smtp-service 587)

Now we configure shortcuts and bookmarks to access the most useful mail directories, or searches. These were just taken right from a guide on the web I've lost - and I've not felt the need to customize them yet. Note how the bookmarks specify searches, not locations. 'mu' is all about searching email, and then working on views of these search results.

;;; Mail directory shortcuts
  (setq mu4e-maildir-shortcuts
        '(("/INBOX" . ?z)))
;;; Bookmarks
  (setq mu4e-bookmarks
        `(("flag:unread AND NOT flag:trashed" "Unread messages" ?u)
          ("date:today..now" "Today's messages" ?t)
          ("date:7d..now" "Last 7 days" ?w)
          ("mime:image/*" "Messages with images" ?p)
          (,(mapconcat 'identity
                        (lambda (maildir)
                          (concat "maildir:" (car maildir)))
                        mu4e-maildir-shortcuts) " OR ")
           "All inboxes" ?i)))

Finally, this setting will send any notifications from mu to the *Messages* buffer by default. You can change this to use libnotify or similar to get desktop notifications. I have 'mu4e-update-interval nil' though, so it's not really interesting here. I check my email manually when I want to, so notifications aren't really a consideration.

  (setq mu4e-enable-notifications t)))

(provide 'spacelite-mail)

And that's it. I use mu4e for most of my email activities now. It has stuck in a way that previous flirtations with mutt, and the other Emacs approaches, haven't. It's simple and very effective.

Index of Posts