mu4e-context: make it a minor-mode

Add mu4e-context-minor-mode, for re-use in other parts of mu4e.

Update those parts + documentation.
This commit is contained in:
Dirk-Jan C. Binnema 2021-08-28 14:56:31 +03:00
parent bfd0618e58
commit 035977a89a
7 changed files with 68 additions and 53 deletions

View File

@ -447,7 +447,6 @@ removing the In-Reply-To header."
(setq mu4e-compose-mode-map (setq mu4e-compose-mode-map
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))
(define-key map (kbd "C-S-u") 'mu4e-update-mail-and-index) (define-key map (kbd "C-S-u") 'mu4e-update-mail-and-index)
(define-key map (kbd "C-c C-;") 'mu4e-compose-context-switch)
(define-key map (kbd "C-c C-u") 'mu4e-update-mail-and-index) (define-key map (kbd "C-c C-u") 'mu4e-update-mail-and-index)
(define-key map (kbd "C-c C-k") 'mu4e-message-kill-buffer) (define-key map (kbd "C-c C-k") 'mu4e-message-kill-buffer)
(define-key map (kbd "M-q") 'mu4e-fill-paragraph) (define-key map (kbd "M-q") 'mu4e-fill-paragraph)
@ -508,7 +507,12 @@ buffers; lets remap its faces so it uses the ones for mu4e."
\\{message-mode-map}." \\{message-mode-map}."
(progn (progn
(use-local-map mu4e-compose-mode-map) (use-local-map mu4e-compose-mode-map)
(mu4e-context-in-modeline)
(mu4e-context-minor-mode)
(define-key mu4e-context-minor-mode-map (kbd ";") nil)
(define-key mu4e-context-minor-mode-map (kbd "C-c C-;")
#'mu4e-compose-context-switch)
(set (make-local-variable 'message-signature) mu4e-compose-signature) (set (make-local-variable 'message-signature) mu4e-compose-signature)
;; set this to allow mu4e to work when gnus-agent is unplugged in gnus ;; set this to allow mu4e to work when gnus-agent is unplugged in gnus
(set (make-local-variable 'message-send-mail-real-function) nil) (set (make-local-variable 'message-send-mail-real-function) nil)
@ -710,8 +714,8 @@ are optional."
(set (make-local-variable 'mu4e-compose-type) compose-type) (set (make-local-variable 'mu4e-compose-type) compose-type)
(put 'mu4e-compose-type 'permanent-local t) (put 'mu4e-compose-type 'permanent-local t)
;; maybe switch the context ;; maybe switch the context
(mu4e~context-autoswitch mu4e-compose-parent-message (mu4e--context-autoswitch mu4e-compose-parent-message
mu4e-compose-context-policy) mu4e-compose-context-policy)
(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

@ -27,11 +27,10 @@
;;; Code: ;;; Code:
(require 'cl-lib) (require 'mu4e-helpers)
(require 'mu4e-utils)
(defvar smtpmail-smtp-user)
(defvar mu4e-view-date-format) ;;; Configuration
(defvar mu4e-contexts nil (defvar mu4e-contexts nil
"The list of `mu4e-context' objects describing mu4e's contexts.") "The list of `mu4e-context' objects describing mu4e's contexts.")
@ -39,16 +38,23 @@
(defvar mu4e-context-changed-hook nil (defvar mu4e-context-changed-hook nil
"Hook run just *after* the context changed.") "Hook run just *after* the context changed.")
(defvar mu4e~context-current nil (defface mu4e-context-face
"The current context; for internal use. '((t :inherit mu4e-title-face :weight bold))
Use `mu4e-context-switch' to change it.") "Face for displaying the context in the modeline."
:group 'mu4e-faces)
(defvar mu4e--context-current nil
"The current context.
Internal; use `mu4e-context-switch' to change it.")
(defun mu4e-context-current (&optional output) (defun mu4e-context-current (&optional output)
"Get the currently active context, or nil if there is none. "Get the currently active context, or nil if there is none.
When OUTPUT is non-nil, echo the name of the current context or When OUTPUT is non-nil, echo the name of the current context or
none." none."
(interactive "p") (interactive "p")
(let ((ctx mu4e~context-current)) (let ((ctx mu4e--context-current))
(when output (when output
(mu4e-message "Current context: %s" (mu4e-message "Current context: %s"
(if ctx (mu4e-context-name ctx) "<none>"))) (if ctx (mu4e-context-name ctx) "<none>")))
@ -58,7 +64,7 @@ none."
"Propertized string with the current context name. "Propertized string with the current context name.
An empty string \"\" if there is none." An empty string \"\" if there is none."
(if (mu4e-context-current) (if (mu4e-context-current)
(concat "[" (propertize (mu4e~quote-for-modeline (concat "[" (propertize (mu4e-quote-for-modeline
(mu4e-context-name (mu4e-context-current))) (mu4e-context-name (mu4e-context-current)))
'face 'mu4e-context-face) "]") "")) 'face 'mu4e-context-face) "]") ""))
@ -83,7 +89,7 @@ An empty string \"\" if there is none."
vars) ;; alist of variables. vars) ;; alist of variables.
(defun mu4e~context-ask-user (prompt) (defun mu4e--context-ask-user (prompt)
"Let user choose some context based on its name with PROMPT." "Let user choose some context based on its name with PROMPT."
(when mu4e-contexts (when mu4e-contexts
(let* ((names (cl-map 'list (lambda (context) (let* ((names (cl-map 'list (lambda (context)
@ -108,13 +114,13 @@ non-nil."
(context (context
(if name (if name
(cdr-safe (assoc name names)) (cdr-safe (assoc name names))
(mu4e~context-ask-user "Switch to context: ")))) (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. ;; if new context is same as old one one switch with FORCE is set.
(when (or force (not (eq context (mu4e-context-current)))) (when (or force (not (eq context (mu4e-context-current))))
(when (and (mu4e-context-current) (when (and (mu4e-context-current)
(mu4e-context-leave-func 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)
(funcall (mu4e-context-enter-func context))) (funcall (mu4e-context-enter-func context)))
@ -122,14 +128,14 @@ non-nil."
(mapc (lambda (cell) (mapc (lambda (cell)
(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)
(run-hooks 'mu4e-context-changed-hook) (run-hooks 'mu4e-context-changed-hook)
(mu4e-message "Switched context to %s" (mu4e-context-name context)) (mu4e-message "Switched context to %s" (mu4e-context-name context))
(force-mode-line-update)) (force-mode-line-update))
context)) context))
(defun mu4e~context-autoswitch (&optional msg policy) (defun mu4e--context-autoswitch (&optional msg policy)
"Automatically switch to some context. "Automatically switch to some context.
When contexts are defined but there is no context yet, switch to When contexts are defined but there is no context yet, switch to
@ -161,7 +167,7 @@ match, POLICY determines what to do:
- otherwise, return nil. Effectively, this leaves the current context as it is." - otherwise, return nil. Effectively, this leaves the current context as it is."
(when mu4e-contexts (when mu4e-contexts
(if (eq policy 'always-ask) (if (eq policy 'always-ask)
(mu4e~context-ask-user "Select context: ") (mu4e--context-ask-user "Select context: ")
(or ;; is there a matching one? (or ;; is there a matching one?
(cl-find-if (lambda (context) (cl-find-if (lambda (context)
(when (mu4e-context-match-func context) (when (mu4e-context-match-func context)
@ -170,9 +176,9 @@ match, POLICY determines what to do:
;; no context found yet; consult policy ;; no context found yet; consult policy
(cl-case policy (cl-case policy
(pick-first (car mu4e-contexts)) (pick-first (car mu4e-contexts))
(ask (mu4e~context-ask-user "Select context: ")) (ask (mu4e--context-ask-user "Select context: "))
(ask-if-none (or (mu4e-context-current) (ask-if-none (or (mu4e-context-current)
(mu4e~context-ask-user "Select context: "))) (mu4e--context-ask-user "Select context: ")))
(otherwise nil)))))) (otherwise nil))))))
(defun mu4e-context-in-modeline () (defun mu4e-context-in-modeline ()
@ -182,6 +188,18 @@ global-mode-line."
(make-local-variable 'global-mode-string) (make-local-variable 'global-mode-string)
'(:eval (mu4e-context-label)))) '(:eval (mu4e-context-label))))
;;; _ (define-minor-mode mu4e-context-minor-mode
"Mode for switching the mu4e context."
:global nil
:init-value nil ;; disabled by default
:group 'mu4e
:lighter ""
:keymap
(let ((map (make-sparse-keymap)))
(define-key map (kbd";") #'mu4e-context-switch)
map)
(mu4e-context-in-modeline))
;;;
(provide 'mu4e-context) (provide 'mu4e-context)
;;; mu4e-context.el ends here ;;; mu4e-context.el ends here

View File

@ -38,6 +38,7 @@
(require 'mu4e-proc) (require 'mu4e-proc)
(require 'mu4e-vars) (require 'mu4e-vars)
(require 'mu4e-mark) (require 'mu4e-mark)
(require 'mu4e-context)
(require 'mu4e-compose) (require 'mu4e-compose)
(require 'mu4e-actions) (require 'mu4e-actions)
(require 'mu4e-message) (require 'mu4e-message)
@ -929,8 +930,6 @@ after the end of the search results."
(define-key map (kbd "<C-kp-add>") 'mu4e-headers-split-view-grow) (define-key map (kbd "<C-kp-add>") 'mu4e-headers-split-view-grow)
(define-key map (kbd "<C-kp-subtract>") 'mu4e-headers-split-view-shrink) (define-key map (kbd "<C-kp-subtract>") 'mu4e-headers-split-view-shrink)
(define-key map ";" 'mu4e-context-switch)
;; switching to view mode (if it's visible) ;; switching to view mode (if it's visible)
(define-key map "y" 'mu4e-select-other-view) (define-key map "y" 'mu4e-select-other-view)
@ -1133,8 +1132,6 @@ no user-interaction ongoing."
(make-local-variable 'mu4e~highlighted-docid) (make-local-variable 'mu4e~highlighted-docid)
(set (make-local-variable 'hl-line-face) 'mu4e-header-highlight-face) (set (make-local-variable 'hl-line-face) 'mu4e-header-highlight-face)
(mu4e-context-in-modeline)
;; maybe update the current headers upon indexing changes ;; maybe update the current headers upon indexing changes
(add-hook 'mu4e-index-updated-hook 'mu4e~headers-maybe-auto-update) (add-hook 'mu4e-index-updated-hook 'mu4e~headers-maybe-auto-update)
(add-hook 'mu4e-index-updated-hook (add-hook 'mu4e-index-updated-hook
@ -1147,6 +1144,7 @@ no user-interaction ongoing."
header-line-format (mu4e~header-line-format)) header-line-format (mu4e~header-line-format))
(mu4e~mark-initialize) ;; initialize the marking subsystem (mu4e~mark-initialize) ;; initialize the marking subsystem
(mu4e-context-minor-mode)
(hl-line-mode 1)) (hl-line-mode 1))
(defun mu4e~headers-index-updated-hook-fn () (defun mu4e~headers-index-updated-hook-fn ()
@ -1266,7 +1264,7 @@ docid is not found."
`(:eval `(:eval
(concat (concat
(propertize (propertize
(mu4e~quote-for-modeline ,mu4e~headers-mode-line-label) (mu4e-quote-for-modeline ,mu4e~headers-mode-line-label)
'face 'mu4e-modeline-face) 'face 'mu4e-modeline-face)
" " " "
(if (and mu4e-display-update-status-in-modeline (if (and mu4e-display-update-status-in-modeline

View File

@ -1,6 +1,6 @@
;;; mu4e-main.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*- ;;; mu4e-main.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*-
;; Copyright (C) 2011-2020 Dirk-Jan C. Binnema ;; Copyright (C) 2011-2021 Dirk-Jan C. Binnema
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
@ -43,8 +43,6 @@
This also hides the warning if your `user-mail-address' is not This also hides the warning if your `user-mail-address' is not
part of the personal addresses.") part of the personal addresses.")
(defvar mu4e-main-hide-fully-read nil (defvar mu4e-main-hide-fully-read nil
"When set to t, do not hide bookmarks or maildirs that have "When set to t, do not hide bookmarks or maildirs that have
no unread messages.") no unread messages.")
@ -87,7 +85,7 @@ no unread messages.")
\\{mu4e-main-mode-map}." \\{mu4e-main-mode-map}."
(setq truncate-lines t (setq truncate-lines t
overwrite-mode 'overwrite-mode-binary) overwrite-mode 'overwrite-mode-binary)
(mu4e-context-in-modeline) (mu4e-context-minor-mode)
(set (make-local-variable 'revert-buffer-function) #'mu4e~main-view-real)) (set (make-local-variable 'revert-buffer-function) #'mu4e~main-view-real))

View File

@ -764,11 +764,6 @@ I.e. a message with the draft flag set."
"Face for a header title in the headers view." "Face for a header title in the headers view."
:group 'mu4e-faces) :group 'mu4e-faces)
(defface mu4e-context-face
'((t :inherit mu4e-title-face :weight bold))
"Face for displaying the context in the modeline."
:group 'mu4e-faces)
(defface mu4e-modeline-face (defface mu4e-modeline-face
'((t :inherit font-lock-string-face :weight bold)) '((t :inherit font-lock-string-face :weight bold))
"Face for the query in the mode-line." "Face for the query in the mode-line."

View File

@ -28,6 +28,7 @@
;;; Code: ;;; Code:
(require 'mu4e-view-common) (require 'mu4e-view-common)
(require 'mu4e-context)
(require 'calendar) (require 'calendar)
(require 'gnus-art) (require 'gnus-art)
@ -266,9 +267,7 @@ This is useful for advising some Gnus-functionality that does not work in mu4e."
(define-key map "A" #'mu4e-view-mime-part-action) (define-key map "A" #'mu4e-view-mime-part-action)
(define-key map "e" #'mu4e-view-save-attachments) (define-key map "e" #'mu4e-view-save-attachments)
(define-key map ";" #'mu4e-context-switch) ;; toggle header settings
;; toggle header settings
(define-key map "O" #'mu4e-headers-change-sorting) (define-key map "O" #'mu4e-headers-change-sorting)
(define-key map "P" #'mu4e-headers-toggle-threading) (define-key map "P" #'mu4e-headers-toggle-threading)
(define-key map "Q" #'mu4e-headers-toggle-full-search) (define-key map "Q" #'mu4e-headers-toggle-full-search)
@ -403,16 +402,6 @@ This is useful for advising some Gnus-functionality that does not work in mu4e."
(defvar mu4e-view-mode-abbrev-table nil) (defvar mu4e-view-mode-abbrev-table nil)
(defun mu4e~view-mode-body ()
"Body of the mode-function."
(use-local-map mu4e-view-mode-map)
(mu4e-context-in-modeline)
(setq buffer-undo-list t);; don't record undo info
;; autopair mode gives error when pressing RET
;; turn it off
(when (boundp 'autopair-dont-activate)
(setq autopair-dont-activate t)))
;; "Define the major-mode for the mu4e-view." ;; "Define the major-mode for the mu4e-view."
(define-derived-mode mu4e-view-mode gnus-article-mode "mu4e:view" (define-derived-mode mu4e-view-mode gnus-article-mode "mu4e:view"
"Major mode for viewing an e-mail message in mu4e. "Major mode for viewing an e-mail message in mu4e.
@ -430,7 +419,13 @@ Based on Gnus' article-mode."
(lambda(func &rest args) (lambda(func &rest args)
(if (mu4e~view-mode-p) (if (mu4e~view-mode-p)
"." (apply func args)))) "." (apply func args))))
(mu4e~view-mode-body)) (use-local-map mu4e-view-mode-map)
(mu4e-context-minor-mode)
(setq buffer-undo-list t);; don't record undo info
;; autopair mode gives error when pressing RET
;; turn it off
(when (boundp 'autopair-dont-activate)
(setq autopair-dont-activate t)))
;;; Massaging the message view ;;; Massaging the message view

View File

@ -1005,7 +1005,6 @@ E edit (only allowed for draft messages)
misc misc
---- ----
; switch context
a execute some custom action on a header a execute some custom action on a header
| pipe message through shell command | pipe message through shell command
C-+,C-- increase / decrease the number of headers shown C-+,C-- increase / decrease the number of headers shown
@ -1014,6 +1013,10 @@ C-S-u update mail & reindex
q leave the headers buffer q leave the headers buffer
@end verbatim @end verbatim
Furthermore, a number of keybindings are available through minor modes:
@itemize
@item Context; see @pxref{Contexts}.
@end itemize
@node HV Marking @node HV Marking
@section Marking @section Marking
@ -1300,7 +1303,6 @@ A execute some custom action on the message's MIME-parts
misc misc
---- ----
; switch context
. show the raw message view. 'q' takes you back. . show the raw message view. 'q' takes you back.
C-+,C-- increase / decrease the number of headers shown C-+,C-- increase / decrease the number of headers shown
H get help H get help
@ -1308,6 +1310,11 @@ C-S-u update mail & reindex
q leave the message view q leave the message view
@end verbatim @end verbatim
Furthermore, a number of keybindings are available through minor modes:
@itemize
@item Context; see @pxref{Contexts}.
@end itemize
For the marking commands, please refer to @ref{Marking messages}. For the marking commands, please refer to @ref{Marking messages}.
@node MSGV Rich-text and images @node MSGV Rich-text and images