mu4e: by default, make changing to current context a no-op

Update mu4e-context-switch to not call the enter/leave functions when
'changing' to the current context. However, calling those functions (if
defined) can be force through a prefix arg. Document this.

Make mu4e-context-determine recognize 'policies', i.e. what to do when
no context matches. This part is WIP.
This commit is contained in:
djcb
2015-12-21 22:15:47 +02:00
parent 6bafb39960
commit 60192a60d2
3 changed files with 87 additions and 57 deletions

View File

@ -372,8 +372,8 @@ tempfile)."
(put 'mu4e-compose-parent-message 'permanent-local t) (put 'mu4e-compose-parent-message 'permanent-local t)
(let ((context (mu4e-context-determine mu4e-compose-parent-message))) (let ((context (mu4e-context-determine mu4e-compose-parent-message)))
(if context (if context
(mu4e-context-switch (mu4e-context-name context)) (mu4e-context-switch nil (mu4e-context-name context))
(when mu4e-contexts (mu4e-context-switch)))) (when mu4e-contexts (mu4e-context-switch nil))))
(run-hooks 'mu4e-compose-pre-hook) (run-hooks 'mu4e-compose-pre-hook)
;; this opens (or re-opens) a messages with all the basic headers set. ;; this opens (or re-opens) a messages with all the basic headers set.

View File

@ -59,22 +59,35 @@ for the message replied to or forwarded, and nil otherwise. Before composing a n
;; if it matches, nil otherwise ;; if it matches, nil otherwise
vars) ;; alist of variables. vars) ;; alist of variables.
(defun mu4e-context-switch (&optional name) (defun mu4e~context-ask-user (prompt)
"Let user choose some context based on its name."
(when mu4e-contexts
(let* ((names (map 'list (lambda (context) (cons (mu4e-context-name context) context))
mu4e-contexts))
(context (mu4e-read-option prompt names)))
(or context (mu4e-error "No such context")))))
(defun mu4e-context-switch (&optional force name)
"Switch context to a context with NAME which is part of "Switch context to a context with NAME which is part of
`mu4e-contexts'; if NAME is nil, query user." `mu4e-contexts'; if NAME is nil, query user.
(interactive)
If the new context is the same and the current context, only
switch (run associated functions) when prefix argument FORCE is
non-nil."
(interactive "P")
(unless mu4e-contexts (unless mu4e-contexts
(mu4e-error "No contexts defined")) (mu4e-error "No contexts defined"))
(let* ((names (map 'list (lambda (context) (let* ((names (map 'list (lambda (context)
(cons (mu4e-context-name context) context)) (cons (mu4e-context-name context) context))
mu4e-contexts)) mu4e-contexts))
(context (context
(if name (cdr-safe (assoc name names)) (if name
(mu4e-read-option "Switch to context: " names)))) (cdr-safe (assoc name names))
(mu4e~context-ask-user "Switch to context: "))))
(unless context (mu4e-error "No such context")) (unless context (mu4e-error "No such context"))
;; if new context is same as old one one switch with FORCE is set.
;; leave the current context (when (or force (not (eq context (mu4e-context-current))))
(when (and mu4e~context-current (mu4e-context-leave-func mu4e~context-current)) (when (and (mu4e-context-current) (mu4e-context-leave-func mu4e~context-current))
(funcall (mu4e-context-leave-func mu4e~context-current))) (funcall (mu4e-context-leave-func mu4e~context-current)))
;; enter the new context ;; enter the new context
(when (mu4e-context-enter-func context) (when (mu4e-context-enter-func context)
@ -84,7 +97,7 @@ for the message replied to or forwarded, and nil otherwise. Before composing a n
(set (car cell) (cdr cell))) (set (car cell) (cdr cell)))
(mu4e-context-vars context))) (mu4e-context-vars context)))
(setq mu4e~context-current context) (setq mu4e~context-current context)
(mu4e-message "Switched context to %s" (mu4e-context-name context)) (mu4e-message "Switched context to %s" (mu4e-context-name context)))
context)) context))
(defun mu4e-context-autoselect () (defun mu4e-context-autoselect ()
@ -95,19 +108,26 @@ match, return the first."
(mu4e-context-switch (mu4e-context-switch
(mu4e-context-name (mu4e-context-determine nil 'pick-first))))) (mu4e-context-name (mu4e-context-determine nil 'pick-first)))))
(defun mu4e-context-determine (msg &optional pick-first) (defun mu4e-context-determine (msg &optional policy)
"Return the first context with a match-func that returns t. MSG "Return the first context with a match-func that returns t. MSG
points to the plist for the message replied to or forwarded, or points to the plist for the message replied to or forwarded, or
nil if there is no such MSG; similar to what nil if there is no such MSG; similar to what
`mu4e-compose-pre-hook' does. `mu4e-compose-pre-hook' does.
If there are contexts but none match, return nil, unless POLICY determines what to do if there are contexts but none match. The following
PICK-FIRST is non-nil, in which case return the first context." are supported:
- 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 (when mu4e-contexts
(or (find-if (lambda (context) (or (find-if (lambda (context)
(and (mu4e-context-match-func context) (and (mu4e-context-match-func context)
(funcall (mu4e-context-match-func context) msg))) mu4e-contexts) (funcall (mu4e-context-match-func context) msg))) mu4e-contexts)
(when pick-first (car mu4e-contexts))))) ;; no context found
(case policy
(pick-first (car mu4e-contexts))
(ask (mu4e~context-ask-user "Select context: "))
(otherwise nil)))))
(provide 'mu4e-context) (provide 'mu4e-context)

View File

@ -1809,7 +1809,8 @@ Note - in the @ref{Headers view} you may see the 'friendly name' for a
list; however, when searching you need the real name. You can see the list; however, when searching you need the real name. You can see the
real name for a mailing list from the friendly name's tool-tip. real name for a mailing list from the friendly name's tool-tip.
@item Get messages with a subject soccer, Socrates, society, ...; note that the '*'-wildcard can only appear as a term's rightmost character: @item Get messages with a subject soccer, Socrates, society, ...; note that
the '*'-wildcard can only appear as a term's rightmost character:
@verbatim @verbatim
subject:soc* subject:soc*
@end verbatim @end verbatim
@ -2358,13 +2359,20 @@ when starting; see the discussion in the previous section.
Couple of notes: Couple of notes:
@itemize @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 You can manually switch the focus use @code{M-x mu4e-context-switch}, by default bound to @kbd{;} in headers, view and main mode.
@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. The current focus appears in the mode-line.
@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 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.
@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. However, with a prefix-argument (@kbd{C-u}), you can force @t{mu4e} to call
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}
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{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 @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. @item Finally, be careful to get the quotations right -- backticks, single quotes and commas and note the '.' between variable name and its value.
@end itemize @end itemize
@node Some context tricks @node Some context tricks
@ -3508,7 +3516,8 @@ five arguments, following @t{completing-read}. The default value is
@t{ido-completing-read}; to use emacs's default behaviour, set the @t{ido-completing-read}; to use emacs's default behaviour, set the
variable to @t{completing-read}. Helm users can use the same value, and variable to @t{completing-read}. Helm users can use the same value, and
by enabling @t{helm-mode} use helm-style completion. by enabling @t{helm-mode} use helm-style completion.
@item @emph{I have a lot of Maildir folders, so regenerating them each time makes things slow. What can I do?} @item @emph{I have a lot of Maildir folders, so regenerating them each time makes
things slow. What can I do?}
Set @code{mu4e-cache-maildir-list} to @code{t} (but make sure to read Set @code{mu4e-cache-maildir-list} to @code{t} (but make sure to read
its docstring). its docstring).
@ -3540,7 +3549,8 @@ messages}.
like Gmail does?} Yes -- see @ref{Including related messages}. like Gmail does?} Yes -- see @ref{Including related messages}.
@item @emph{There seem to be a lot of duplicate messages -- how can I get rid @item @emph{There seem to be a lot of duplicate messages -- how can I get rid
of them?} See @ref{Skipping duplicates}. of them?} See @ref{Skipping duplicates}.
@item @emph{How can I use the @t{eww} browser to view rich-text messages?} See @ref{Html2text functions}. @item @emph{How can I use the @t{eww} browser to view rich-text messages?}
See @ref{Html2text functions}.
@item @emph{Some messages are almost unreadable in emacs - can I view them in @item @emph{Some messages are almost unreadable in emacs - can I view them in
an external web browser?} Indeed, airlines often send messages that an external web browser?} Indeed, airlines often send messages that
heavily depend on html and are hard to digest inside emacs. Fortunately, heavily depend on html and are hard to digest inside emacs. Fortunately,