[ Home | About Me | Blog | Self Hosting | Vinyl ]

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.

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.

mu-home.png

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:

mu-search-mail.png

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
SSLType IMAPS
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 that is based on something I originally found on 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
    :init
    (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.

:config
(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
                       (mapcar
                        (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.


This post is day 12 of my #100DaysToOffload challenge.

If you want to get involved, you can get more info from https://100daystooffload.com.


SFC Supporter

FSF Member

SDF