Let’s explain how contexts work by looking at an example. We define two contexts, ‘Private’ and ‘Work’ for a fictional user Alice Derleth.
Note that in this case, we automatically switch to the first context when starting; see the discussion in the previous section.
(setq mu4e-contexts
`( ,(make-mu4e-context
:name "Private"
:enter-func (lambda () (mu4e-message "Entering Private context"))
:leave-func (lambda () (mu4e-message "Leaving Private context"))
;; we match based on the contact-fields of the message
:match-func (lambda (msg)
(when msg
(mu4e-message-contact-field-matches msg
:to "aliced@home.example.com")))
:vars '( ( user-mail-address . "aliced@home.example.com" )
( user-full-name . "Alice Derleth" )
( message-user-organization . "Homebase" )
( message-signature .
(concat
"Alice Derleth\n"
"Lauttasaari, Finland\n"))))
,(make-mu4e-context
:name "Work"
:enter-func (lambda () (mu4e-message "Switch to the Work context"))
;; no leave-func
;; we match based on the maildir of the message
;; this matches maildir /Arkham and its sub-directories
:match-func (lambda (msg)
(when msg
(string-match-p "^/Arkham" (mu4e-message-field msg :maildir))))
:vars '( ( user-mail-address . "aderleth@miskatonic.example.com" )
( user-full-name . "Alice Derleth" )
( message-user-organization . "Miskatonic University" )
( message-signature .
(concat
"Prof. Alice Derleth\n"
"Miskatonic University, Dept. of Occult Sciences\n"))))
,(make-mu4e-context
:name "Cycling"
:enter-func (lambda () (mu4e-message "Switch to the Cycling context"))
;; no leave-func
;; we match based on the maildir of the message; assume all
;; cycling-related messages go into the /cycling maildir
:match-func (lambda (msg)
(when msg
(string= (mu4e-message-field msg :maildir) "/cycling")))
:vars '( ( user-mail-address . "aderleth@example.com" )
( user-full-name . "AliceD" )
( message-signature . nil)))))
;; set `mu4e-context-policy` and `mu4e-compose-policy` to tweak when mu4e should
;; guess or ask the correct context, e.g.
;; start with the first (default) context;
;; default is to ask-if-none (ask when there's no context yet, and none match)
;; (setq mu4e-context-policy 'pick-first)
;; compose with the current context is no context matches;
;; default is to ask
;; (setq mu4e-compose-context-policy nil)
A couple of notes about this example:
M-x mu4e-context-switch,
by default bound to ; in headers, view and main mode. The current context
appears in the modeline by default; see Modeline for details.
M-x mu4e-context-switch does not call the enter or
leave functions if the ’new’ context is the same as the old one.
However, with a prefix-argument (C-u), you can force mu4e to
invoke those function even in that case.
mu4e-context-current returns the current-context;
the current context is also visible in the mode-line when in
headers, view or main mode.
mu4e-mu-home are not changeable after
they have been set without quitting mu4e first.
leave-func (if defined) for the context we are leaving, is invoked
before the enter-func (if defined) of the
context we are entering.
enter-func (if defined) is invoked before setting the variables.
match-func (if defined) is invoked just before mu4e-compose-pre-hook.
mu4e-context-policy and
mu4e-compose-context-policy to tweak what mu4e should do when
no context matches (or if you always want to be asked).