Reading and sending mails from within Emacs: a tutorial for mu4e
There are several ways to handle (i.e., to read and send) all your emails directly from within Emacs. As you can read on this reddit thread, there are essentially three candidates: the built-in Emacs tools (Rmail and Gnus), mu4e and NotMuch. mu4e is a solution I find especially convenient and easy to use. In this post, I’ll propose a quick tutorial and a reasonable mu4e configuration. Another tutorials out there are really well done, such as this one (the present post is essentially a modified and extended version of this excellent tuto), but most of them are quite old, and do not necessarily play well with the latest versions of mu. This tutorial works for mu 1.4.x (and, I hope, later versions).
What are mu and mu4e?
This is a three-story building :
- “mu is a tool for dealing with e-mail messages stored in the Maildir-format, on Unix-like systems” (from the official mu website)
- mu4e is an Emacs-based client built on top on mu
- Both of them need a tool such as isync/mbsync to synchronise your emails between your remote email server and a local folder on your computer
1 Install all the necessary stuff
In this section, I’ll assume that you are a Linux user, but it should (?) be possible to find an équivalent of this for Mac OS or Windows.
First, you should install SSL development libraries, that are called slightly differently from one Linux distro to another. For instance, Linux Manjaro users can execute:
sudo pacman -S openssl
but this library may also be called
openssl-devel
orlibssl-dev
if you are using another distro.Then, you can install mu and isync/mbsync. Although they are available on Git repositories and can be manually installed, using the package manager of your Linux distro is the easiest way. Manjaro users can execute the following commands:
pacaur -S mu sudo pacman -S isync
The official manual of mu gives further instruction for other Linux distros.
2 Configure isync/mbsync
You need to store your login information in an encrypted file on your computer so that your server can (safely) recognize you.
2.1 Password info
- In your
.emacs.d/
folder, create a file.mbsyncpass
and simply write your password in it. This file needs to be encrypted, so that this private information can be safely stored on your computer. You can encrypt this file with
gpg2
by running the following command into the.emacs.d/
folder:gpg2 --output .mbsyncpass.gpg --symmetric .mbsyncpass
A new encrypted file
.mbsyncpass.gpg
has been created in this folder.But now, do not forget to remove the temporary file
.mbsyncpass
you had to create in step 1!rm .mbsyncpass
2.2 Mail account info
Create a file
~/.authinfo
directly in the root of your home directory. In this file, you’ll have to store your mail account info, by using in this template:machine smtp.example.com login myname port 587 password mypassword
Simply replace
smtp.example.com
by your SMTP server,myname
by your user name,mypassword
by your password, and keep the remaining characters unchanged.Let’s do it again: you’ll also need to encrypt this file, since it contains your password. You can run:
gpg2 --output ~/.authinfo.gpg --symmetric ~/.authinfo
to create an encrypted version of this file, and then simply remove the temporary file you had to create:
rm .authinfo
2.3 Configuration file for isync/mbsync
You’ll have to create a configuration file for isync. Let’s create a file .mbsyncrc
in your .emacs.d/
folder. Here is a template you can fill in:
IMAPAccount nameaccount Host your.imap.server User yourname PassCmd "gpg2 -q --for-your-eyes-only --no-tty -d ~/.emacs.d/.mbsyncpass.gpg" Port 993 SSLType IMAPS AuthMechs * CertificateFile /etc/ssl/certs/ca-certificates.crt IMAPStore nameaccount-remote Account nameaccount MaildirStore nameaccount-local Path ~/email/mbsyncmail/ Inbox ~/email/mbsyncmail/INBOX SubFolders Verbatim Channel nameaccount Master :nameaccount-remote: Slave :nameaccount-local: Patterns * Create Slave Sync All Expunge None SyncState *
The mbsync documentation is very complete and you should find easily the meaning of each parameter. But in particular, the following ones are important:
Path
is the name of the local folder mbsync will use your computer to store your emails. Here, I chose to store them in a folder called/email/mysyncmail
.Patterns *
means that I want to synchronise all the folders contained in my mailbox. If you want to synchronise only the folders INBOX, Sent and Trash (for instance), simply replace this line byPatterns "Sent" "INBOX" "Trash"
.PassCmd
is the command that mbsync must execute to retrieve your password. Here, I simply indicate that mbsync must decrypt the file~/.emacs.d/.mbsyncpass.gpg
you created in section 2.1, in which you stored your (encrypted) password. In you chose a different location for this file, adapt this instruction accordingly in your.mbbsyncrc
file.
Finally, run the following command (and adapt it: replace nameaccount
by the value you chose as the name account in your .mbsyncrc
file), so that this config file can take effect. All your emails will be downloaded from the server, and then indexed locally:
mbsync --config ~/.emacs.d/.mbsyncrc nameaccount mu init --maildir=~/email/mbsyncmail/ mu index
Now, you’re ready to use mu4e!
3 Basic configuration of mu4e
Here are some of the mu4e-related instructions I have in my Emacs init.el
file. They are convenient for me, they may not be convenient for you. You may want to dig into the mu4e manual to find the variables you would like to customize in a way you like.
The first thing to do is to ensure that mu4e can be found by Emacs. On my computer, mu4e has been installed in the folder
/usr/share/emacs/site-lisp/mu4e
. Therefore, I must add this folder to myload-path
, and load mu4e:;; Add mu4e to the load-path: (add-to-list 'load-path "/usr/share/emacs/site-lisp/mu4e") (require 'mu4e)
Configure some SMTP settings according to the information from tour mail provider. Modify the following template using your own information:
;; SMTP settings: (setq send-mail-function 'smtpmail-send-it) ; should not be modified (setq smtpmail-smtp-server "your.smtp.server") ; host running SMTP server (setq smtpmail-smtp-service 587) ; SMTP service port number (setq smtpmail-stream-type 'starttls) ; type of SMTP connections to use
Specify the name of the draft, sent and trash folders (they must exist and begin by a
/
):;; Mail folders: (setq mu4e-drafts-folder "/Drafts") (setq mu4e-sent-folder "/Sent") (setq mu4e-trash-folder "/Trash")
Specify how mu4e should get and display your incoming emails:
;; The command used to get your emails (adapt this line, see section 2.3): (setq mu4e-get-mail-command "mbsync --config ~/.emacs.d/.mbsyncrc nameaccount") ;; Further customization: (setq mu4e-html2text-command "w3m -T text/html" ; how to hanfle html-formatted emails mu4e-update-interval 300 ; seconds between each mail retrieval mu4e-headers-auto-update t ; avoid to type `g' to update mu4e-view-show-images t ; show images in the view buffer mu4e-compose-signature-auto-include nil ; I don't want a message signature mu4e-use-fancy-chars t) ; allow fancy icons for mail threads
Some possible other tweaks. For example, if you never want to include yourself when you choose “reply to all”, you can customize the variable `mu4e-compose-reply-ignore-address’:
;; Do not reply to yourself: (setq mu4e-compose-reply-ignore-address '("no-?reply" "your.own@email.address"))
If you do not want to use
auto-fill-mode
when writing your emails:;; Do not use auto-fill-mode for emails: (defun auto-fill-mode-off () (auto-fill-mode 0)) (add-hook 'mu4e-compose-mode-hook 'auto-fill-mode-off)
mu4e also allows to modify the expression used to introduce a quoted email. As a native french speaker, I chose this one:
;; Modify the expression introducing a quoted email: (setq message-citation-line-function 'message-insert-formatted-citation-line) (setq message-citation-line-format "Le %Y-%m-%d à %T %Z, %f a écrit :\n")
- It’s up to you ! :)
4 Launch mu4e
Simply execute M-x mu4e
(or bind this to a convenient shortcut): you’re done!
In the main *mu4e-headers*
buffer, you just have to become familiar with some shortcuts:
Key | Action |
---|---|
C | Compose a new email |
R | Reply to an email |
F | Forward an email |
j | Jump to a given folder |
RET | Open email in a new buffer |
C-c C-u | Manually retrieve incoming emails from the server |
5 Get desktop alerts for new emails
Thanks to the setting (setq mu4e-update-interval 300)
, mu4e is asked to retrieve emails every 300 seconds. But you’re not really notified in a very clear way. Users migrating from an email client such as Thunderbird for example, may like to have pretty desktop alerts. A very nice Emacs package, mu4e-alert, allows this kind of notification.
This package is clearly documented, and easy to customize. I wanted something a bit different from the standard behavior, that I found sometimes a bit intrusive. Most often, when I start Emacs for the first time on the morning, checking my incoming emails is one of the first things I do, and I’m happy to be notified when I have new emails. But in other contexts, when I need to focus and do not want to be disturbed, or simply when I’m working in a train with a bad connection, I simply want Emacs to stop with all the email stuff (retrieval, notifications and so on). I wanted an “on-demand” behavior: either automatic and periodic retrieval of new emails with desktop alerts, or nothing at all.
The following instructions allow me to do that. When I start Emacs, it will first consider that it should not handle all the email stuff, and will not behave at all as an email client, unless I press F2
. As soon as I press F2
, and until the end of the Emacs session, Emacs will retrieve emails and display nice desktop alerts.
May you be interested by such a customization, here are the required instructions. (Warning: they make use of use-package.)
;; Configure desktop notifs for incoming emails: (use-package mu4e-alert :ensure t :init (defun perso--mu4e-notif () "Display both mode line and desktop alerts for incoming new emails." (interactive) (mu4e-update-mail-and-index 1) ; getting new emails is ran in the background (mu4e-alert-enable-mode-line-display) ; display new emails in mode-line (mu4e-alert-enable-notifications)) ; enable desktop notifications for new emails (defun perso--mu4e-refresh () "Refresh emails every 300 seconds and display desktop alerts." (interactive) (mu4e t) ; start silently mu4e (mandatory for mu>=1.3.8) (run-with-timer 0 300 'perso--mu4e-notif)) :after mu4e :bind ("<f2>" . perso--mu4e-refresh) ; F2 turns Emacs into a mail client :config ;; Mode line alerts: (add-hook 'after-init-hook #'mu4e-alert-enable-mode-line-display) ;; Desktop alerts: (mu4e-alert-set-default-style 'libnotify) (add-hook 'after-init-hook #'mu4e-alert-enable-notifications) ;; Only notify for "interesting" (non-trashed) new emails: (setq mu4e-alert-interesting-mail-query (concat "flag:unread maildir:/INBOX" " AND NOT flag:trashed")))