From a1d0071dd0f60ff2ef314a7fbf3a50508fec3fbd Mon Sep 17 00:00:00 2001 From: djcb Date: Tue, 15 Dec 2015 18:20:31 +0200 Subject: [PATCH] mu4e: contexts: auto select one at startup, document When contexts have been defined, automatically select one at startup -- either the first whose match-function returns non-nil, or simply the first one. Document this, too. --- mu4e/mu4e-context.el | 24 +++++++++++----- mu4e/mu4e-utils.el | 17 +++++++---- mu4e/mu4e.texi | 68 ++++++++++++++++++++++++++++++-------------- 3 files changed, 76 insertions(+), 33 deletions(-) diff --git a/mu4e/mu4e-context.el b/mu4e/mu4e-context.el index c21c99c0..11014fe1 100644 --- a/mu4e/mu4e-context.el +++ b/mu4e/mu4e-context.el @@ -87,17 +87,27 @@ for the message replied to or forwarded, and nil otherwise. Before composing a n (mu4e-message "Switched context to %s" (mu4e-context-name context)) context)) -(defun mu4e-context-determine (msg) +(defun mu4e-context-autoselect () + "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))))) + +(defun mu4e-context-determine (msg &optional pick-first) "Return the first context with a match-func that returns t. MSG 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. If no context matches, return - nil." + `mu4e-compose-pre-hook' does. + +If there are contexts but none match, return nil, unless + PICK-FIRST is non-nil, in which case return the first context." (when mu4e-contexts - (find-if (lambda (context) - (and (mu4e-context-match-func context) - (funcall (mu4e-context-match-func context) msg))) - mu4e-contexts))) + (or (find-if (lambda (context) + (and (mu4e-context-match-func context) + (funcall (mu4e-context-match-func context) msg))) mu4e-contexts) + (car mu4e-contexts)))) (provide 'mu4e-context) diff --git a/mu4e/mu4e-utils.el b/mu4e/mu4e-utils.el index 6ac79add..08ba2e87 100644 --- a/mu4e/mu4e-utils.el +++ b/mu4e/mu4e-utils.el @@ -46,6 +46,8 @@ (declare-function mu4e~proc-mkdir "mu4e-proc") (declare-function mu4e~proc-running-p "mu4e-proc") +(declare-function mu4e-context-autoselect "mu4e-context") + (declare-function show-all "org") @@ -148,8 +150,6 @@ see its docstring)." (mu4e-error (mu4e-error "mu4e-attachment-dir evaluates to nil"))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun mu4e~guess-maildir (path) "Guess the maildir for some path, or nil if cannot find it." @@ -163,8 +163,6 @@ see its docstring)." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun mu4e-create-maildir-maybe (dir) "Offer to create maildir DIR if it does not exist yet. @@ -722,9 +720,18 @@ list of contacts we use for autocompletion; otherwise, do nothing." (mu4e-parse-time-string mu4e-compose-complete-only-after))))))) (defun mu4e~start (&optional func) - "If mu4e is already running, execute function FUNC (if non-nil). + "If `mu4e-contexts' have been defined, but we don't have a +context yet, switch to the matching one, or none matches, the +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) + + ;; (when (and mu4e-contexts (not (mu4e-context-current))) + ;; (mu4e-switch-context (mu4e-context-determine nil 'pick-first)) ;; if we're already running, simply go to the main view (if (mu4e-running-p) ;; already running? (when func ;; yes! run func if defined diff --git a/mu4e/mu4e.texi b/mu4e/mu4e.texi index 58f58b4c..7ac9f854 100644 --- a/mu4e/mu4e.texi +++ b/mu4e/mu4e.texi @@ -2255,13 +2255,14 @@ example: @menu * Defining a context:: +* Default context:: * Contexts example:: * Contexts notes:: +* Some context tricks:: @end menu - It can be useful to be able to switch between different sets of settings -in mu4e; typical examples include the case where you have different +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. @@ -2293,6 +2294,11 @@ an optional function that is invoked before replying to or forwarding a message with the given message plist as parameter, or @t{nil} when composing a brand new message. The function should return @t{t} when this context is the right one for this message, or @t{nil} otherwise. + +The function is also invoked when starting @t{mu4e} to determine the +starting context; in that case, the message-parameter is nil. You can +use e.g. the host you're running or or perhaps the time of day or even +your location to determine the context. @item @t{vars}: an alist of variable settings for this account. @end itemize @@ -2300,18 +2306,29 @@ 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 + +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}. + @node Contexts example @section Example Let's look 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. + @lisp (setq mu4e-contexts `( ,(make-mu4e-context :name "Private" - :enter-func (lambda () (mu4e-message "Private mail")) - ;; no leave-func + :enter-func (lambda () (mu4e-message "Switch to the Private context")) + ;; leave-func not defined :match-func (lambda (msg) (when msg (mu4e-message-contact-field-matches msg :to "aliced@@home.com"))) :vars '( ( mail-reply-to . "aliced@@home.com" ) @@ -2323,7 +2340,8 @@ for a fictional user Alice Derleth. "Lauttasaari, Finland\n")))) ,(make-mu4e-context :name "Work" - :enter-func (lambda () (message "Work")) + :enter-func (lambda () (mu4e-message "Switch to the Work context")) + ;; leave-fun not defined :match-func (lambda (msg) (when msg (mu4e-message-contact-field-matches msg :to "aderleth@@miskatonic.edu"))) :vars '( ( mail-reply-to . "aderleth@@miskatonic.edu" ) @@ -2333,10 +2351,31 @@ for a fictional user Alice Derleth. (concat "Prof. Alice Derleth\n" "Miskatonic University, Dept. of Occult Sciences\n")))))) +@end lisp -;; Set default context -(mu4e-context-switch "Private") -;; Set mu4e-user-mail-address-list to reflect the contexts' addresses +@node Contexts notes +@section Context notes + +Couple of notes: +@itemize +@item You can manually switch the focus use @code{M-x mu4e-context-switch}, by default bound to @code{;} in headers, view and main mode. The current focus appears in the mode-line. +@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} and @code{mu4e-mu-home} are not changeable after they have been set without quiting @t{mu4e} first. +@item @code{leave-func} (if defined) for the context we are leaving, is invoked before the @code{enter-func} (if defined) of the context we are entering. +@item @code{enter-func} (if defined) is invoked before setting the variables. +@item @code{match-func} (if defined) is invoked just before @code{mu4e-compose-pre-hook}. +@item Finally, be careful to get the quotations right -- backticks, single quotes and commas and note the '.' between variable name and value. +@end itemize + +@section Some context tricks +@node 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. (setq mu4e-user-mail-address-list (delq nil (mapcar (lambda (context) @@ -2345,19 +2384,6 @@ for a fictional user Alice Derleth. mu4e-contexts))) @end lisp -@node Contexts notes -@section Notes - -Couple of notes: -@itemize -@item You can manually switch the focus use @code{M-x mu4e-context-switch}, by default bound to @code{;} in headers, view and main mode. The current focus shows in the mode-line. -@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} and @code{mu4e-mu-home} are not changeable after they have been set without quiting @t{mu4e} firts. -@item @code{leave-func} (if defined) for the context we are leaving, is invoked before the @code{enter-func} (if defined) of the context we are entering. -@item @code{enter-func} (if defined) is invoked before setting the variables. -@item @code{match-func} (if defined) is invoked just before @code{mu4e-compose-pre-hook}. -@item Finally, be careful to get the quotations right -- backticks, single quotes and commas and note the '.' between variable name and value. -@end itemize @node Dynamic folders