Emacs Mu4e
We can use Emacs to consult mails with the help of various programs. Among them, Mu4e
is a mail client for Emacs and it is considered as an Emacs interface for mu
the mail indexer. A typical example might be a mail sync program like isync
which downloads mail from the remote Maildir folder to the local Maildir folder and then the mu
indexer will be used to index the mail. Finally an Emacs mail client can read the mails.
Prerequisite
Install isync
using your package manager, and you should install mu4e
using the system package manager to avoid any compatibility issues. Here we are installing the apt
package manager, but use whatever package manager you are using:
sudo apt update && sudo apt install mu4e isync
Syncing Mails
We will use isync
program to download mails to local Maildir folder. We can also use a program called offlineimap
which is a bit slower but it can work on Windows. Download mails from remote Maildir folder using .mbsyncrc
configuration file with following settings:
Refer to "Offline Email with Isync" page for a more detailed explanation of Isync configuration.
Index mailbox
Once mails have been synced to local Maildir, run a initial indexing process by providing you e-mail address to mu
program:
mu init --maildir=~/Mail --my-address=vithurshanselvarajah@gmail.com
mu index
NOTE: You will need to use –my-address for every e-mail address you use in a multiple account setup.
Email Client
Mu4e
is an email client for Emacs and it's consider as Emacs interface for mu
mail indexer. A typical example could be a mail syncing program like isync
which download mail from remote Maildir folder to local Maildir folder and then mu
indexer will be used to index mail. Then an Emacs mail client can read mails.
;; Start - Mail ------------------------------------------------------
(use-package mu4e
;; Install mu4e using the distro's package manager to stay compatible with mbsync
:ensure nil
:defer 120 ; Wait until 2 min after startup
;; Path where the package manager is installed mu4e files
:load-path "/usr/share/emacs/site-lisp/mu4e/"
:config
;; Avoid mail syncing issues when using "mbsync"
(setq mu4e-change-filenames-when-moving t)
;; Configure the function to use for sending mail
(setq message-send-mail-function 'smtpmail-send-it)
;; Shortcut to Mu4e dashboard
(global-set-key (kbd "C-c m") 'mu4e)
;; Distroy message buffers on exit
(setq message-kill-buffer-on-exit t)
;; Disable prompt when quitting
(setq mu4e-confirm-quit nil)
;; Refresh mail using isync every 10 minutes
(setq mu4e-update-interval (* 10 60))
(setq mu4e-get-mail-command "/usr/bin/mbsync -Va -c ~/.config/isync/mbsyncrc")
(setq mu4e-maildir "~/.local/share/mail")
;; Set first context ("Laposte") as default
(setq mu4e-context-policy 'pick-first)
;; Prompt for context when composing mail if a context hasn't been previously picked
(setq mu4e-compose-context-policy 'ask-if-none)
;; Ask user to select a key when signing/encrypting
(setq mm-sign-option 'guided)
(setq mm-encrypt-option 'guided)
;; Common setting for all mail accounts
;; Use "flowed" format to display mails to recipient
(setq mu4e-compose-format-flowed t)
;; Disable colors for HTML mails.
(setq shr-use-colors nil)
;; Enable spell checking
(add-hook 'mu4e-compose-mode-hook 'flyspell-mode)
;; Don't include related messages in queries
(setq mu4e-search-include-related nil)
(setq user-full-name "Vithurshan SELVARJAH")
;; If your Gmail is set up with a different lanugage you also need
;; to translate the names of these folders. For Norwegian
;; "[Gmail]/Corbeille" would be "[Gmail]/Papirkurv".
(setq mu4e-contexts
(list
;; Laposte - vithurshan@laposte.net
(make-mu4e-context
:name "Laposte"
:match-func
(lambda (msg)
(when msg
(string-prefix-p "/vithurshan@laposte.net" (mu4e-message-field msg :maildir))))
:vars '((user-mail-address . "vithurshan@laposte.net")
(mu4e-compose-signature . "Vithurshan SELVARAJAH\n* Mon site web – www.atomicl.net\n* LinkedIn – www.linkedin.com/in/vithurshan-selvarajah\n* RSS Feed - www.atomicl.net/index.xml")
;; The SMTP password will be retrieved from the file
;; defined in the "auth-sources" variable
(smtpmail-smtp-server . "smtp.laposte.net")
(smtpmail-smtp-service . 465)
(smtpmail-stream-type . ssl)
(mu4e-drafts-folder . "/vithurshan@laposte.net/DRAFT")
(mu4e-sent-folder . "/vithurshan@laposte.net/Sent Items")
(mu4e-refile-folder . "/vithurshan@laposte.net/Archives")
(mu4e-trash-folder . "/vithurshan@laposte.net/Deleted Items")
(mu4e-maildir-shortcuts . (("/vithurshan@laposte.net/Inbox" . ?i)
("/vithurshan@laposte.net/Sent Items" . ?s)
("/vithurshan@laposte.net/Deleted Items" . ?t)
("/vithurshan@laposte.net/DRAFT" . ?d)))
))
;; Gmail - vithurshanselvarajah@gmail.com
(make-mu4e-context
:name "Gmail"
:match-func
(lambda (msg)
(when msg
(string-prefix-p "/vithurshanselvarajah@gmail.com" (mu4e-message-field msg :maildir))))
:vars '((user-mail-address . "vithurshanselvarajah@gmail.com")
(smtpmail-smtp-server . "smtp.gmail.com")
(smtpmail-smtp-service . 465)
(smtpmail-stream-type . ssl)
(mu4e-drafts-folder . "/vithurshanselvarajah@gmail.com/[Gmail]/Brouillons")
(mu4e-sent-folder . "/vithurshanselvarajah@gmail.com/[Gmail]/Messages envoy&AOk-s")
(mu4e-refile-folder . "/vithurshanselvarajah@gmail.com/[Gmail]/Tous les messages")
(mu4e-trash-folder . "/vithurshanselvarajah@gmail.com/[Gmail]/Corbeille")
(mu4e-maildir-shortcuts . (("/vithurshanselvarajah@gmail.com/Inbox" . ?i)
("/vithurshanselvarajah@gmail.com/[Gmail]/Messages envoy&AOk-s" . ?s)
("/vithurshanselvarajah@gmail.com/[Gmail]/Corbeille" . ?t)
("/vithurshanselvarajah@gmail.com/[Gmail]/Brouillons" . ?d)
("/vithurshanselvarajah@gmail.com/[Gmail]/Tous les messages" . ?a)))
))
))
;; Empty the initial bookmark list
(setq mu4e-bookmarks '())
(setq mu4e-bookmarks
'((:name "All Inboxes" :query "maildir:/vithurshan@laposte.net/Inbox OR m:/vithurshanselvarajah@gmail.com/Inbox" :key ?i)
(:name "Sent Items" :query "m:/vithurshan@laposte.net/Sent\\ Items OR m:/vithurshanselvarajah@gmail.com/[Gmail]/Messages\\ envoy&AOk-s" :key ?s)
(:name "Deleted Mails" :query "m:/vithurshan@laposte.net/Deleted\\ Items OR m:/vithurshanselvarajah@gmail.com/[Gmail]/Corbeille" :key ?t)
(:name "Draft Mails" :query "m:/vithurshan@laposte.net/DRAFT OR m:/vithurshanselvarajah@gmail.com/[Gmail]/Brouillons" :key ?d)
(:name "Today's messages" :query "(m:/vithurshan@laposte.net/Inbox OR m:/vithurshanselvarajah@gmail.com/Inbox) AND date:today..now" :key ?n)
(:name "Last 7 days" :query "(m:/vithurshan@laposte.net/Inbox OR m:/vithurshanselvarajah@gmail.com/Inbox) AND date:7d..now" :hide-unread t :key ?w)
(:name "Messages with images" :query "mime:image/*" :key ?p)))
;; Start mu4e in the background when Emacs starts and periodically sync mail at the interval defined above
(mu4e t))
;; End - Mail --------------------------------------------------------
SMTP Conf
Now we need to set SMTP credentials in ~/.local/share/emacs/authinfo.gpg
file as defined earlier for Mu4e to send mails. Whenever we save a file with ".gpg" extension, Emacs uses the epa (Easy PGP Assistant)
library to encrypt the password using GnuPG:
machine smtp.gmail.com login vithurshanselvarajah@gmail.com password <your-password> port 465
Passwords set in the file can also be extracted manually using (auth-source-search:host "smtp.gmail.com")
Emacs-lisp function.
Do Not Wrap Lines
Traditional emails have a width limit of 79 characters for each line in the email body and by default Mu4e will use this limit to wrap lines in the email body. Instead, we can use the "flowed" format which tells the recipient's email client to adjust the width of line based on their screen size:
;; Use "flowed" format to display mails to recipient
(setq mu4e-compose-format-flowed t)
Refer to this article for more details on "flowed" format.
Mu4e Dashboard [Optional]
Controlling the number of messages that will get displayed to user by mu4e
by default:
mu4e-headers-results-limit
: The number of messages to display in mail listings (default 500)mu4e-headers-full-search
: Ift
, shows all messages, ignoring limit.
You can toggle mu4e-headers-full-search
with M-x mu4e-headers-toggle-full-search
!
Search queries
Run the function mu4e-search
or press letter s
from within mu4e to start searching:
something
- General text search for "something".from:stallman
- Emails from a particular sender.date:today..now
- Date range.flag:attach
- Emails with an attachment.maildir:/Inbox
- Search in a specific mail directory.
You can also use logic statements like and , not:
maildir:/Inbox and from:eli and docs
Documentation: https://www.djcbsoftware.nl/code/mu/mu4e/Queries.html
Keybinding
Run mu4e
to see the landing page or email dashboard mu4e
. When reading mail, you start out in the Headers
buffer and when you select an email with RET
, the View
buffer is displayed in a window below the Headers
buffer window.
Keybinding on Headers
mode/buffer:
Key | Evil | Command | Description | |
---|---|---|---|---|
Movement | ||||
C-n | j | next-line | Moves to the next header line | |
C-p | k | previous-line | Moves to the previous header line | |
[[ | [[ | mu4e-headers-prev-unread | Moves to previous unread message | |
]] | ]] | mu4e-headers-next-unread | Moves to next unread message | |
j | J | mu4e~headers-jump-to-maildir | Jump to another mail directory | |
Toggles | ||||
P | zt | mu4e-headers-toggle-threading | Toggles threaded message display | |
W | zr | mu4e-headers-toggle-include-related | Toggles related message display | |
Marking | ||||
d | d | mu4e-headers-mark-for-trash | Marks message for deletion | |
m | m | mu4e-headers-mark-for-move | Marks message for move to folder | |
+ | + | mu4e-headers-mark-for-flag | Marks message for flagging | |
- | - | mu4e-headers-mark-for-unflag | Marks message for unflagging | |
? | mu4e-headers-mark-for-unread | Marks message as unread | ||
! | mu4e-headers-mark-for-read | Marks message as read | ||
% | % | mu4e-headers-mark-pattern | Marks based on a regex pattern | |
u | u | mu4e-headers-mark-for-unmark | Removes mark for message | |
U | U | mu4e-mark-unmark-all | Unmarks all marks in the view | |
x | x | mu4e-mark-execute-all | Executes all marks in the view | |
Searching | ||||
s | s | mu4e-headers-search | Search all e-mails | |
S | S | mu4e-headers-search-edit | Edit current search (useful!) | |
/ | / | mu4e-headers-search-narrow | Narrow down the current results | |
b | b | mu4e-headers-search-bookmark | Select a bookmark to search with | |
B | B | mu4e-headers-search-bookmark-edit | Edit bookmark before search | |
g | gr | mu4e-rerun-search | Rerun the current search | |
Composing | ||||
C | C , cc | mu4e-compose-new | Compose a new e-mail | |
R | R , cr | mu4e-compose-reply | Compose a reply to selected email | |
F | F , cf | mu4e-compose-forward | Compose a forward for selected email | |
C-c C-d | message-dont-send | Save the composed mail as draft | ||
E | E , ce | mu4e-compose-edit | Edit selected draft message | |
C-c C-a | mml-attach-file | Attach a file | ||
C-c RET s p | mml-secure-message-sign-pgpmime | Sign the message | ||
C-c RET C p | mml-secure-encrypt-pgpmime | Encrypt the message | ||
Other Actions | ||||
q | q | mu4e~headers-quit-buffer | Quit the headers view |
Many of the same keybinding in Headers
mode/buffer will work in View
mode/buffer:
Key | Evil | Command | Description |
---|---|---|---|
Movement | |||
C-n | j | next-line | Moves to the next line in message |
C-p | k | previous-line | Moves to the previous line in message |
n | C-j | mu4e-view-headers-next | Moves to next email in header list |
p | C-k | mu4e-view-headers-prev | Moves to previous email in header list |
[[ | [[ | mu4e-headers-prev-unread | Moves to previous unread message |
]] | ]] | mu4e-headers-next-unread | Moves to next unread message |