¶How mu4e manages e-mail accounts
mu4e
is a frontend for memu
mail indexermu
just scans mail folders and indexes them- You tell
mu4e
about your mail folders and what searches you want to use - You can also tell
mu4e
how to change its configuration for different “contexts”
¶Laying the ground work
Since we will have two accounts under ~/Mail
now, we need to move the existing mail under a subfolder.
But first, we need to stop mu4e from syncing! Run M-x mu4e-quit
to stop the background sync timer.
Now we can move the Gmail folders into ~/Mail/Gmail
:
cd ~
mv Mail Gmail
mkdir Mail
mv Gmail Mail
We also need to update our .mbsyncrc
to use the new folders:
Path ~/Mail/Gmail/ Inbox ~/Mail/Gmail/Inbox
Test with mbsync
to make sure everything syncs correctly:
mbsync -a
Lastly, reindex with mu
:
mu index --maildir=~/Mail [email protected]
¶Setting up our first context
We will update our configuration to configure the Gmail account using mu4e-contexts:
(use-package mu4e :ensure nil :config ;; This is set to 't' to avoid mail syncing issues when using mbsync (setq mu4e-change-filenames-when-moving t) ;; Refresh mail using isync every 10 minutes (setq mu4e-update-interval (* 10 60)) (setq mu4e-get-mail-command "mbsync -a") (setq mu4e-maildir "~/Mail") (setq mu4e-contexts (list ;; Work account (make-mu4e-context :name "Work" :match-func (lambda (msg) (when msg (string-prefix-p "/Gmail" (mu4e-message-field msg :maildir)))) :vars '((user-mail-address . "[email protected]") (user-full-name . "System Crafters Gmail") (mu4e-drafts-folder . "/Gmail/[Gmail]/Drafts") (mu4e-sent-folder . "/Gmail/[Gmail]/Sent Mail") (mu4e-refile-folder . "/Gmail/[Gmail]/All Mail") (mu4e-trash-folder . "/Gmail/[Gmail]/Trash"))))) (setq mu4e-maildir-shortcuts '(("/Gmail/Inbox" . ?i) ("/Gmail/[Gmail]/Sent Mail" . ?s) ("/Gmail/[Gmail]/Trash" . ?t) ("/Gmail/[Gmail]/Drafts" . ?d) ("/Gmail/[Gmail]/All Mail" . ?a))))
Docs: https://www.djcbsoftware.nl/code/mu/mu4e/Contexts.html Example: https://www.djcbsoftware.nl/code/mu/mu4e/Contexts-example.html
Try out the new context by evaluating the new configuration and run M-x mu4e
.
You can change how the default context is picked by setting mu4e-context-policy
to one of the following values:
ask-if-none
- Ask the first time you enter the view (default)pick-first
- Pick the first context in themu4e-contexts
listalways-ask
- Always ask when entering the main view
¶Syncing the second account
We’ll be using a Fastmail account (https://ref.fm/u7703101) for this example. It requires an App Password to connect to the IMAP endpoint:
https://www.fastmail.com/settings/security/devicekeys/new
Now we can add the IMAP configuration for the Fastmail account to our .mbsyncrc
file:
... Gmail configuration from previous video ... IMAPAccount fastmail Host imap.fastmail.com Port 993 User [email protected] PassCmd "cat ~/.oh-no-another-insecure-password" SSLType IMAPS SSLVersions TLSv1.2 CertificateFile /etc/ssl/certs/ca-certificates.crt IMAPStore fastmail-remote Account fastmail MaildirStore fastmail-local Path ~/Mail/Fastmail/ Inbox ~/Mail/Fastmail/INBOX/ Trash ~/Mail/Fastmail/Trash/ SubFolders Verbatim # With mbsync 1.4.0 and later: Use 'Far' instead of 'Master', and # 'Near' instead of 'Slave'. Channel fastmail Master :fastmail-remote: Slave :fastmail-local: Patterns * Expunge None CopyArrivalDate yes Sync All Create Both SyncState *
Now you can sync the new account:
mkdir ~/Mail/Fastmail mbsync -a
When using a
mu
version prior to version 1.4.0:You’ll also need to reindex with
mu
to add the new address:mu index --maildir=~/Mail \ [email protected] \ [email protected]
When using
mu
version 1.4.0 or later:You’ll need to rerun
mu init
to add the new address:mu init --maildir=~/Mail \ [email protected] \ [email protected] mu index
NOTE: It’s possible you will see an error like this -
mu: mu_store_new_writable: xapian error 'Unable to get write lock on /home/daviwil/.mu/xapian: already locked' (11)
Just kill the running mu
process and run mu index
again:
pkill mu # run mu index again
¶Adding the second account to mu4e
Now we can add a new context for the account to mu4e-contexts:
(setq mu4e-contexts (list ;; Work account (make-mu4e-context :name "Work" :match-func (lambda (msg) (when msg (string-prefix-p "/Gmail" (mu4e-message-field msg :maildir)))) :vars '((user-mail-address . "[email protected]") (user-full-name . "System Crafters Gmail") (mu4e-drafts-folder . "/Gmail/[Gmail]/Drafts") (mu4e-sent-folder . "/Gmail/[Gmail]/Sent Mail") (mu4e-refile-folder . "/Gmail/[Gmail]/All Mail") (mu4e-trash-folder . "/Gmail/[Gmail]/Trash"))) ;; Personal account (make-mu4e-context :name "Personal" :match-func (lambda (msg) (when msg (string-prefix-p "/Fastmail" (mu4e-message-field msg :maildir)))) :vars '((user-mail-address . "[email protected]") (user-full-name . "System Crafters Fastmail") (mu4e-drafts-folder . "/Fastmail/Drafts") (mu4e-sent-folder . "/Fastmail/Sent") (mu4e-refile-folder . "/Fastmail/Archive") (mu4e-trash-folder . "/Fastmail/Trash")))))
After evaluating this configuration, we can launch mu4e
again and switch contexts using the ;
(semicolon) character.
¶How to use contexts
Examples:
- Compose new mail in a context
- Archive a message in a context (show which folder it goes to)
- Reply to a message in a merged search
You can create bookmarks to show merged views of folders across accounts:
In mu4e 1.2.0:
(add-to-list 'mu4e-bookmarks '("m:/Fastmail/INBOX or m:/Gmail/Inbox" "All Inboxes" ?i))
As of mu4e 1.3.7:
(add-to-list 'mu4e-bookmarks '(:name "All Inboxes" :query "m:/Fastmail/INBOX or m:/Gmail/Inbox" :key ?i))
This is your e-mail client to build!
¶What’s next?
- Composing e-mails
- Displaying unread mail count and notifications
- Even more uses for contexts and search queries
- Org Mode integration
¶Complete Configuration
Here’s the complete configuration for this episode:
Emacs.org
(use-package mu4e :ensure nil :config ;; This is set to 't' to avoid mail syncing issues when using mbsync (setq mu4e-change-filenames-when-moving t) ;; Refresh mail using isync every 10 minutes (setq mu4e-update-interval (* 10 60)) (setq mu4e-get-mail-command "mbsync -a") (setq mu4e-maildir "~/Mail") (setq mu4e-contexts (list ;; Work account (make-mu4e-context :name "Work" :match-func (lambda (msg) (when msg (string-prefix-p "/Gmail" (mu4e-message-field msg :maildir)))) :vars '((user-mail-address . "[email protected]") (user-full-name . "System Crafters Gmail") (mu4e-drafts-folder . "/Gmail/[Gmail]/Drafts") (mu4e-sent-folder . "/Gmail/[Gmail]/Sent Mail") (mu4e-refile-folder . "/Gmail/[Gmail]/All Mail") (mu4e-trash-folder . "/Gmail/[Gmail]/Trash"))) ;; Personal account (make-mu4e-context :name "Personal" :match-func (lambda (msg) (when msg (string-prefix-p "/Fastmail" (mu4e-message-field msg :maildir)))) :vars '((user-mail-address . "[email protected]") (user-full-name . "System Crafters Fastmail") (mu4e-drafts-folder . "/Fastmail/Drafts") (mu4e-sent-folder . "/Fastmail/Sent") (mu4e-refile-folder . "/Fastmail/Archive") (mu4e-trash-folder . "/Fastmail/Trash"))))) (setq mu4e-maildir-shortcuts '(("/Inbox" . ?i) ("/Gmail/[Gmail]/Sent Mail" . ?s) ("/Gmail/[Gmail]/Trash" . ?t) ("/Gmail/[Gmail]/Drafts" . ?d) ("/Gmail/[Gmail]/All Mail" . ?a))))
~/.mbsyncrc
IMAPAccount gmail Host imap.gmail.com User [email protected] PassCmd "cat ~/.oh-no-insecure-password" SSLType IMAPS CertificateFile /etc/ssl/certs/ca-certificates.crt IMAPStore gmail-remote Account gmail MaildirStore gmail-local Subfolders Verbatim Path ~/Mail/Gmail/ Inbox ~/Mail/Gmail/Inbox # For mbsync 1.4.0 and later: Use 'Far' instead of 'Master', and # 'Near' instead of 'Slave'. Channel gmail Master :gmail-remote: Slave :gmail-local: Patterns * ![Gmail]* "[Gmail]/Sent Mail" "[Gmail]/Starred" "[Gmail]/All Mail" "[Gmail]/Trash" Create Both SyncState * IMAPAccount fastmail Host imap.fastmail.com Port 993 User [email protected] PassCmd "cat ~/.oh-no-another-insecure-password" SSLType IMAPS SSLVersions TLSv1.2 CertificateFile /etc/ssl/certs/ca-certificates.crt IMAPStore fastmail-remote Account fastmail MaildirStore fastmail-local Path ~/Mail/Fastmail/ Inbox ~/Mail/Fastmail/INBOX/ Trash ~/Mail/Fastmail/Trash/ SubFolders Verbatim # With mbsync 1.4.0 and later: Use 'Far' instead of 'Master', and # 'Near' instead of 'Slave'. Channel fastmail Master :fastmail-remote: Slave :fastmail-local: Patterns * Expunge None CopyArrivalDate yes Sync All Create Both SyncState *