mirror of https://github.com/djcb/mu.git
mu4e: implement context-policies
Allow setting a policy about what context to choose when starting mu4e and composing a message. Basically: When you have defined contexts and you start mu4e it decides which context to use based on the variable `mu4e-context-policy'; similarly, when you compose a new message, the context is determined using `mu4e-compose-context-policy'. These policies can be one of the following: - a symbol always-ask: unconditionally ask the user what context to pick The other choices only apply if none of the context matches (i.e., if none of the contexts' match-functions returns t: - symbol ask: ask the user - a symbol pick-first: pick the first context - nil: don't change the context
This commit is contained in:
parent
4bca0d0739
commit
113c024632
|
@ -112,12 +112,34 @@ for example:
|
|||
|
||||
The various `message-' functions from `message-mode' are available
|
||||
for querying the message information."
|
||||
:type '(choice (const :tag "move message to mu4e-sent-folder" sent)
|
||||
(const :tag "move message to mu4e-trash-folder" trash)
|
||||
(const :tag "delete message" delete))
|
||||
:type '(choice (const :tag "move message to mu4e-sent-folder" sent)
|
||||
(const :tag "move message to mu4e-trash-folder" trash)
|
||||
(const :tag "delete message" delete))
|
||||
:safe 'symbolp
|
||||
:group 'mu4e-compose)
|
||||
|
||||
|
||||
(defcustom mu4e-compose-context-policy nil
|
||||
"Determines how mu4e should determine the context when composing a new message.
|
||||
|
||||
If POLICY is
|
||||
'always-ask, we ask the user unconditionally.
|
||||
|
||||
In all other cases, if any context matches (using its match
|
||||
function), this context is returned. If none of the contexts
|
||||
match, POLICY determines what to do:
|
||||
|
||||
- pick-first: pick the first of the contexts available
|
||||
- ask: ask the user
|
||||
- otherwise, return nil. Effectively, this leaves the current context in place."
|
||||
:type '(choice
|
||||
(const :tag "Always ask what context to use" 'always-ask)
|
||||
(const :tag "Ask if none of the contexts match" 'ask)
|
||||
(const :tag "Pick the default (first) context if none match" 'pick-first)
|
||||
(const :tag "Don't change the context when none match" nil)
|
||||
:safe 'symbolp
|
||||
:group 'mu4e-compose))
|
||||
|
||||
(defcustom mu4e-compose-pre-hook nil
|
||||
"Hook run just *before* message composition starts.
|
||||
If the compose-type is either 'reply' or 'forward', the variable
|
||||
|
@ -370,10 +392,9 @@ tempfile)."
|
|||
;; message being forwarded or replied to, otherwise it is nil.
|
||||
(set (make-local-variable 'mu4e-compose-parent-message) original-msg)
|
||||
(put 'mu4e-compose-parent-message 'permanent-local t)
|
||||
(let ((context (mu4e-context-determine mu4e-compose-parent-message)))
|
||||
(if context
|
||||
(mu4e-context-switch nil (mu4e-context-name context))
|
||||
(when mu4e-contexts (mu4e-context-switch nil))))
|
||||
;; maybe switch the context
|
||||
(mu4e~context-autoswitch mu4e-compose-parent-message
|
||||
mu4e-compose-context-policy)
|
||||
(run-hooks 'mu4e-compose-pre-hook)
|
||||
|
||||
;; this opens (or re-opens) a messages with all the basic headers set.
|
||||
|
|
|
@ -100,13 +100,13 @@ non-nil."
|
|||
(mu4e-message "Switched context to %s" (mu4e-context-name context)))
|
||||
context))
|
||||
|
||||
(defun mu4e-context-autoselect ()
|
||||
(defun mu4e~context-autoswitch (&optional msg policy)
|
||||
"When contexts are defined but there is no context yet, switch
|
||||
to the first whose :match-func return non-nil. If none of them
|
||||
match, return the first."
|
||||
(when (and mu4e-contexts (not (mu4e-context-current)))
|
||||
(mu4e-context-switch
|
||||
(mu4e-context-name (mu4e-context-determine nil 'pick-first)))))
|
||||
match, return the first. For MSG and POLICY, see `mu4e-context-determine'."
|
||||
(when mu4e-contexts
|
||||
(let ((context (mu4e-context-determine msg policy)))
|
||||
(when context (mu4e-context-switch (mu4e-context-name context))))))
|
||||
|
||||
(defun mu4e-context-determine (msg &optional policy)
|
||||
"Return the first context with a match-func that returns t. MSG
|
||||
|
@ -114,20 +114,27 @@ points to the plist for the message replied to or forwarded, or
|
|||
nil if there is no such MSG; similar to what
|
||||
`mu4e-compose-pre-hook' does.
|
||||
|
||||
POLICY determines what to do if there are contexts but none match. The following
|
||||
are supported:
|
||||
POLICY specifies how to do the determination. If POLICY is
|
||||
'always-ask, we ask the user unconditionally.
|
||||
|
||||
In all other cases, if any context matches (using its match
|
||||
function), this context is returned. If none of the contexts
|
||||
match, POLICY determines what to do:
|
||||
|
||||
- pick-first: pick the first of the contexts available
|
||||
- ask: ask the user
|
||||
- otherwise, return nil. Effectively, this leaves the current context in place."
|
||||
(when mu4e-contexts
|
||||
(or (find-if (lambda (context)
|
||||
(and (mu4e-context-match-func context)
|
||||
(funcall (mu4e-context-match-func context) msg))) mu4e-contexts)
|
||||
;; no context found
|
||||
(case policy
|
||||
(pick-first (car mu4e-contexts))
|
||||
(ask (mu4e~context-ask-user "Select context: "))
|
||||
(otherwise nil)))))
|
||||
(if (eq policy 'always-ask)
|
||||
(mu4e~context-ask-user "Select context: ")
|
||||
(or (find-if (lambda (context)
|
||||
(and (mu4e-context-match-func context)
|
||||
(funcall (mu4e-context-match-func context) msg))) mu4e-contexts)
|
||||
;; no context found
|
||||
(case policy
|
||||
(pick-first (car mu4e-contexts))
|
||||
(ask (mu4e~context-ask-user "Select context: "))
|
||||
(otherwise nil))))))
|
||||
|
||||
(provide 'mu4e-context)
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
(declare-function mu4e~proc-mkdir "mu4e-proc")
|
||||
(declare-function mu4e~proc-running-p "mu4e-proc")
|
||||
|
||||
(declare-function mu4e-context-autoselect "mu4e-context")
|
||||
(declare-function mu4e~context-autoswitch "mu4e-context")
|
||||
|
||||
(declare-function show-all "org")
|
||||
|
||||
|
@ -737,9 +737,9 @@ first.
|
|||
If mu4e is already running, execute function FUNC (if non-nil).
|
||||
Otherwise, check various requirements, then start mu4e. When
|
||||
successful, call FUNC (if non-nil) afterwards."
|
||||
|
||||
;; auto-select some account
|
||||
(mu4e-context-autoselect)
|
||||
;; maybe switch the context
|
||||
(mu4e~context-autoswitch mu4e-compose-parent-message
|
||||
mu4e-compose-context-policy)
|
||||
;; if we're already running, simply go to the main view
|
||||
(if (mu4e-running-p) ;; already running?
|
||||
(when func ;; yes! run func if defined
|
||||
|
|
|
@ -114,7 +114,6 @@ better with e.g. offlineimap."
|
|||
:group 'mu4e
|
||||
:safe 'booleanp)
|
||||
|
||||
|
||||
(defcustom mu4e-attachment-dir (expand-file-name "~/")
|
||||
"Default directory for saving attachments.
|
||||
This can be either a string (a file system path), or a function
|
||||
|
@ -218,6 +217,29 @@ Suggested possible values are:
|
|||
:options '(completing-read ido-completing-read)
|
||||
:group 'mu4e)
|
||||
|
||||
(defcustom mu4e-context-policy 'ask
|
||||
"Determines how mu4e should determine the context when starting up.
|
||||
|
||||
If POLICY is 'always-ask, we ask the user unconditionally.
|
||||
|
||||
In all other cases, if any context matches (using its match
|
||||
function), this context is returned. If none of the contexts
|
||||
match, POLICY determines what to do:
|
||||
|
||||
- pick-first: pick the first of the contexts available
|
||||
- ask: ask the user
|
||||
- otherwise, return nil. Effectively, this leaves the current context in place.
|
||||
|
||||
Also see `mu4e-compose-context-policy'."
|
||||
:type '(choice
|
||||
(const :tag "Always ask what context to use" 'always-ask)
|
||||
(const :tag "Ask if none of the contexts match" 'ask)
|
||||
(const :tag "Pick the default (first) context if none match" 'pick-first)
|
||||
(const :tag "Don't change the context when none match" nil)
|
||||
:safe 'symbolp
|
||||
:group 'mu4e))
|
||||
|
||||
|
||||
;; crypto
|
||||
(defgroup mu4e-crypto nil
|
||||
"Crypto-related settings."
|
||||
|
|
|
@ -37,7 +37,7 @@ Documentation License.''
|
|||
|
||||
@dircategory Emacs
|
||||
@direntry
|
||||
* mu4e: (mu4e). An email client for Emacs.
|
||||
* mu4e: (Mu4e). An email client for GNU/Emacs.
|
||||
@end direntry
|
||||
|
||||
@contents
|
||||
|
@ -1990,8 +1990,8 @@ also match this extra search pattern. @key{\} takes you back to the previous
|
|||
query, so, effectively 'widens' the search. Technically, narrowing the results
|
||||
of query @t{x} with expression @t{y} implies doing a search @t{(x) AND y}.
|
||||
|
||||
Note, messages that were not in your in your original search results because
|
||||
of @code{mu4e-headers-results-limit}, may show up in the narrowed query.
|
||||
Note that messages that were not in your original search results because
|
||||
of @code{mu4e-headers-results-limit} may show up in the narrowed query.
|
||||
|
||||
@subsection Including related messages
|
||||
@anchor{Including related messages}
|
||||
|
@ -2256,16 +2256,15 @@ example:
|
|||
|
||||
@menu
|
||||
* Defining a context::
|
||||
* Default context::
|
||||
* Context policies::
|
||||
* Contexts example::
|
||||
* Contexts notes::
|
||||
* Some context tricks::
|
||||
@end menu
|
||||
|
||||
It can be useful to be able to switch between different sets of settings
|
||||
in @t{mu4e}; typical examples include the case where you have different
|
||||
e-mail accounts for private and work email, each with their own settings
|
||||
for e-mail addresses, mailservers etc.
|
||||
for folders, e-mail addresses, mailservers etc.
|
||||
|
||||
The @code{mu4e-context} system is a @t{mu4e}-specific mechanism to allow
|
||||
for that; users can be define different contexts, and either manually
|
||||
|
@ -2307,19 +2306,34 @@ an alist of variable settings for this account.
|
|||
@t{mu4e} uses a variable @code{mu4e-contexts}, which is a list of such
|
||||
objects.
|
||||
|
||||
@node Default context
|
||||
@section Default context
|
||||
@node Context policies
|
||||
@section Context policies
|
||||
|
||||
When you have defined contexts and you start @t{mu4e}, it automatically
|
||||
switches to the first context whose @code{match-func} returns
|
||||
non-nil. If none of them do, it picks the first. So, put your 'default'
|
||||
context as the first in @code{mu4e-contexts}.
|
||||
When you have defined contexts and you start @t{mu4e} it decides which
|
||||
context to use based on the variable @code{mu4e-context-policy};
|
||||
similarly, when you compose a new message, the context is determined
|
||||
using @code{mu4e-compose-context-policy}.
|
||||
|
||||
These policies can be one of the following:
|
||||
@itemize
|
||||
@item a symbol @t{always-ask}: unconditionally ask the user what context to pick
|
||||
@end itemize
|
||||
|
||||
The other choices only apply if none of the context matches (i.e., if
|
||||
none of the contexts' match-functions returns @code{t}:
|
||||
|
||||
@itemize
|
||||
@item a symbol @t{ask}: ask the user
|
||||
@item a symbol @t{pick-first}: pick the first context
|
||||
@item @t{nil}: don't change the context
|
||||
@end itemize
|
||||
|
||||
@node Contexts example
|
||||
@section Example
|
||||
|
||||
Let's look at an example; we define two contexts, 'Private' and 'Work'
|
||||
for a fictional user Alice Derleth.
|
||||
Let's explain how contexts work by looking at an example. We define two
|
||||
contexts, 'Private' and 'Work' for a fictional user @emph{Alice
|
||||
Derleth}.
|
||||
|
||||
Note that in this case, we automatically switch to the first context
|
||||
when starting; see the discussion in the previous section.
|
||||
|
@ -2354,16 +2368,13 @@ when starting; see the discussion in the previous section.
|
|||
"Miskatonic University, Dept. of Occult Sciences\n"))))))
|
||||
@end lisp
|
||||
|
||||
@node Contexts notes
|
||||
@section Context notes
|
||||
|
||||
Couple of notes:
|
||||
A couple of notes about this example:
|
||||
@itemize
|
||||
@item You can manually switch the focus use @code{M-x mu4e-context-switch}, by default bound to @kbd{;} in headers, view and main mode.
|
||||
The current focus appears in the mode-line.
|
||||
@item Normally, @code{M-x mu4e-context-switch} does not call the enter/leave functions if the 'new' context is the same as the old one.
|
||||
However, with a prefix-argument (@kbd{C-u}), you can force @t{mu4e} to call
|
||||
those function even in that case.
|
||||
@item Normally, @code{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 (@kbd{C-u}), you can force @t{mu4e} to
|
||||
invoke those function even in that case.
|
||||
@item The function @code{mu4e-context-current} returns the current-context; the current context is also visiable in the mode-line when in
|
||||
headers, view or main mode.
|
||||
@item You can set any kind of variable; including settings for mail servers etc. However, settings like @code{mu4e-maildir}
|
||||
|
@ -2378,13 +2389,13 @@ context we are entering.
|
|||
@node Some context tricks
|
||||
@section Some context tricks
|
||||
|
||||
|
||||
It is possible to automatically fill @code{mu4e-user-address-list} by
|
||||
concatenating the @code{user-mail-address} fields of all contexts:
|
||||
|
||||
@lisp
|
||||
;; This sets `mu4e-user-mail-address-list' to the concatenation of all `user-mail-address' values
|
||||
;; for all contexts. If you have other mail addresses as well, you'll need to add those manually.
|
||||
;; This sets `mu4e-user-mail-address-list' to the concatenation of all
|
||||
;; `user-mail-address' values for all contexts. If you have other mail
|
||||
;; addresses as well, you'll need to add those manually.
|
||||
(setq mu4e-user-mail-address-list
|
||||
(delq nil
|
||||
(mapcar (lambda (context)
|
||||
|
@ -2906,6 +2917,7 @@ two days, you could add this to @code{org-capture-templates}:
|
|||
|
||||
If you use the functionality a lot, you may want to define key-bindings
|
||||
for that in headers and view mode:
|
||||
|
||||
@lisp
|
||||
(define-key mu4e-headers-mode-map (kbd "C-c c") 'org-mu4e-store-and-capture)
|
||||
(define-key mu4e-view-mode-map (kbd "C-c c") 'org-mu4e-store-and-capture)
|
||||
|
|
Loading…
Reference in New Issue