I'm struggling to get mu4e to work with different (private and work) email accounts. The behaviour is different from what I expected, and I am not sure whether this is due to an issue in my configuration or in my expectation :-)
Learning how to install, configure and use offlineimap
, mu
and mu4e
took an hour or two for my Private account, and since then I've been struggling for about a whole day to get it to work with a second, Work, account. Syncing and indexing the Work email is no problem, but presenting and in particular separating emails from the two accounts. I think I've read every post on SO mentioning mu4e
and context
, the mu4e
manual, FAQ, and GitHub issues, many blogs, and seen many example inits, but no combination of any of them seems to work. I may still have missed something obvious though.
Current settings
My directories are set up as follows:
~/.emacs_mail
├── PrivateEmail
│ ├── Drafts
│ ├── Sent
│ ├── Trash
│ └── INBOX
└── WorkEmail
├── Drafts
├── INBOX
├── Sent
└── Trash
offlineimap
is asked to sync email from my private server and account to the PrivateEmail
subfolder, and from my work server and account to WorkEmail
. mu4e
is instructed that the mu4e-maildir
is ~/.emacs_mail/
and I'm trying to use contexts to separate the two. The mu4e part of my emacs init is shown here (the two context blocks are nearly identical in structure, and have some identical overlap, because I want to add more email accounts later on):
(require 'mu4e)
(setq mail-user-agent 'mu4e-user-agent)
(setq message-kill-buffer-on-exit t)
(require 'smtpmail)
(setq mu4e-headers-skip-duplicates t)
(setq mu4e-compose-format-flowed t)
(setq mu4e-headers-date-format "%Y-%m-%d %H:%M")
(setq mu4e-headers-fields
'( (:date . 25) ;; use :date / :human-date
(:flags . 6)
(:from . 22)
(:subject . nil) ;; use :subject / :thread-subject
)
)
(setq mu4e-user-mail-address-list '("[email protected]"
"[email protected]")
)
(setq mu4e-maildir "~/.emacs_mail")
(setq mu4e-contexts
`(
;; Private context:
,(make-mu4e-context
:name "Private"
:enter-func (lambda () (mu4e-message "Entering Private context"))
:leave-func (lambda () (mu4e-message "Leaving Private context"))
:match-func (lambda (msg)
(when msg
(mu4e-message-contact-field-matches msg
:to "[email protected]")
)
)
:vars '(
( mu4e-drafts-folder . "/PrivateEmail/Drafts" )
( mu4e-sent-folder . "/PrivateEmail/Sent" )
( mu4e-trash-folder . "/PrivateEmail/Trash" )
( mu4e-maildir-shortcuts .
(
("/INBOX" . ?i)
("/Sent" . ?s)
("/Trash" . ?t)
)
)
( user-mail-address . "[email protected]" )
( user-full-name . "My Name" )
( mu4e-compose-signature .
(concat
"My Name\n"
"http://private.org\n"
)
)
( mu4e-sent-messages-behavior . 'delete )
( mu4e-get-mail-command . "offlineimap" ) ;; Alternatives: fetchmail, getmail, isync, ...
( message-send-mail-function . 'smtpmail-send-it )
( smtpmail-stream-type . 'starttls )
( smtpmail-default-smtp-server . "smtp.email.com" )
( smtpmail-smtp-server . "smtp.email.com" )
( smtpmail-smtp-service . 587)
) ;; vars
) ;; Private
;; Work context:
,(make-mu4e-context
:name "Work"
:enter-func (lambda () (mu4e-message "Entering Work context"))
:leave-func (lambda () (mu4e-message "Leaving Work context"))
:match-func (lambda (msg)
(when msg
(mu4e-message-contact-field-matches msg
:to "[email protected]")
)
)
:vars '(
( mu4e-drafts-folder . "/WorkEmail/Drafts" )
( mu4e-sent-folder . "/WorkEmail/Sent" )
( mu4e-trash-folder . "/WorkEmail/Trash" )
( mu4e-maildir-shortcuts .
(
("/INBOX" . ?i)
("/Sent" . ?s)
("/Trash" . ?t)
("/Drafts" . ?d)
)
)
( user-mail-address . "[email protected]" )
( user-full-name . "My Full Name" )
( mu4e-compose-signature .
(concat
"Visiting address:\n"
"Room B2.70\n"
)
)
( mu4e-sent-messages-behavior . 'delete )
( mu4e-get-mail-command . "offlineimap" )
( message-send-mail-function . 'smtpmail-send-it )
( smtpmail-stream-type . 'starttls )
( smtpmail-default-smtp-server . "smtp.work.com" )
( smtpmail-smtp-server . "smtp.work.com" )
( smtpmail-smtp-service . 587)
) ;; vars
) ;; Work
)
)
(add-to-list 'mu4e-bookmarks
(make-mu4e-bookmark
:name "PrivateEmail unread inbox"
:query "flag:unread AND maildir:/PrivateEmail/INBOX AND NOT flag:trashed"
:key ?p)
)
(I used sed to anonimise this file and to remove blank lines (many, for readability) and lines starting with ;;
).
Current behaviour
When I (re)start emacs (with or without using -q and manually loading my mu4e.el) and start mu4e, I have to choose between the Private and Work contexts as expected. However, when I then press ji
, I get a list of email headers from both my Private and Work contexts, where I would expect only headers from the current context. Hence, I get identical results, independent of the current context.
Or, perhaps, I would expect to see nothing at all, since according to my init the ji
shortcut refers to /INBOX
w.r.t. the mu4e-maildir
, i.e. to the directory ~/.emacs_mail/INBOX/
, which does not exist. In fact, I originally set up the maildir-shortcuts
to "/PrivateEmail/INBOX", etc., but that doesn't work at all — I get an empty header list — I suppose mu4e
thinks that the directory ~/.emacs_mail/PrivateEmail/INBOX/
doesn't exist. Also, pressing s
to search for maildir:/INBOX
'works' (though I still get headers from both accounts, contrary to my desire) while maildir:/PrivateEmail/INBOX
doesn't (empty list).
Probably for the same reason, the bookmark I defined at the bottom of the file also produces an empty list. When I remove the /PrivateEmail
part, the header list is full of emails from both accounts...
Understanding contexts
What doesn't help is the fact that from the mu4e
manual, I don't understand what exactly the contexts, and central in that I think, the :match-func
, are supposed to achieve. Is the :match-func
supposed to filter emails for me, so that when listing my Inbox headers, I only see those from the current context? Or should the :match-func
only (help to) determine which account to use when e.g. replying to an email? The obvious variable I wanted to set differently in my different contexts was mu4e-maildir
, but according to the docs I'm not supposed to do that (and I'd have to restart mu4e
or even emacs, which I'd like to avoid (in that case, I could write a script to rename email dirs before starting mu4e
)).
Desired behaviour
Ideally, I would like to achieve that when I'm at work, I'd switch to the Work context and only deal with Work email (incoming, outgoing, other boxes I sedded out here, whatever). When I would press ji
, I'd see my Work inbox, and when I'd press bu
, I'd get only unread Work emails. When I'd go home, I'd press ;p
and I'd never see a work email again. And I'd be able to add another ~3-5 email accounts which wouldn't get mixed up. Are these realistic wishes? How would I achieve them, or get as close as possible? Have I just missed one vital setting in my init?
Curiouser and curiouser
With my shortcut ("/Private/Sent" . ?s)
, when I try to move an email to that box using ms
and x
, I get an error that the mail could not be moved to ~/.emacs_mail/Private/Private/Sent/...
. Hence, I changed the shortcut to ("/Sent" . ?s)
which throws the error that the mail could not be moved to ~/.emacs_mail/Sent/...
. I'm not sure how to get a single /Private
in there, rather than zero or two. Leading slashes don't make a difference...
Environment
Gentoo Linux, GNU emacs 26.1, mu(4e) 1.3.1.
offlineimap
tombsync
at some point because the former requires Python 2 which is being phased out.