From 035977a89ae04d99892b3382582ec5b0b8b6a140 Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Sat, 28 Aug 2021 14:56:31 +0300 Subject: [PATCH] mu4e-context: make it a minor-mode Add mu4e-context-minor-mode, for re-use in other parts of mu4e. Update those parts + documentation. --- mu4e/mu4e-compose.el | 12 ++++++--- mu4e/mu4e-context.el | 56 ++++++++++++++++++++++++++++-------------- mu4e/mu4e-headers.el | 8 +++--- mu4e/mu4e-main.el | 6 ++--- mu4e/mu4e-vars.el | 5 ---- mu4e/mu4e-view-gnus.el | 23 +++++++---------- mu4e/mu4e.texi | 11 +++++++-- 7 files changed, 68 insertions(+), 53 deletions(-) diff --git a/mu4e/mu4e-compose.el b/mu4e/mu4e-compose.el index d7b1478e..26f367a7 100644 --- a/mu4e/mu4e-compose.el +++ b/mu4e/mu4e-compose.el @@ -447,7 +447,6 @@ removing the In-Reply-To header." (setq mu4e-compose-mode-map (let ((map (make-sparse-keymap))) (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-k") 'mu4e-message-kill-buffer) (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}." (progn (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 this to allow mu4e to work when gnus-agent is unplugged in gnus (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) (put 'mu4e-compose-type 'permanent-local t) ;; maybe switch the context - (mu4e~context-autoswitch mu4e-compose-parent-message - mu4e-compose-context-policy) + (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. diff --git a/mu4e/mu4e-context.el b/mu4e/mu4e-context.el index 4282834f..300c53eb 100644 --- a/mu4e/mu4e-context.el +++ b/mu4e/mu4e-context.el @@ -27,11 +27,10 @@ ;;; Code: -(require 'cl-lib) -(require 'mu4e-utils) +(require 'mu4e-helpers) -(defvar smtpmail-smtp-user) -(defvar mu4e-view-date-format) + +;;; Configuration (defvar mu4e-contexts nil "The list of `mu4e-context' objects describing mu4e's contexts.") @@ -39,16 +38,23 @@ (defvar mu4e-context-changed-hook nil "Hook run just *after* the context changed.") -(defvar mu4e~context-current nil - "The current context; for internal use. -Use `mu4e-context-switch' to change it.") +(defface mu4e-context-face + '((t :inherit mu4e-title-face :weight bold)) + "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) "Get the currently active context, or nil if there is none. When OUTPUT is non-nil, echo the name of the current context or none." (interactive "p") - (let ((ctx mu4e~context-current)) + (let ((ctx mu4e--context-current)) (when output (mu4e-message "Current context: %s" (if ctx (mu4e-context-name ctx) ""))) @@ -58,7 +64,7 @@ none." "Propertized string with the current context name. An empty string \"\" if there is none." (if (mu4e-context-current) - (concat "[" (propertize (mu4e~quote-for-modeline + (concat "[" (propertize (mu4e-quote-for-modeline (mu4e-context-name (mu4e-context-current))) 'face 'mu4e-context-face) "]") "")) @@ -83,7 +89,7 @@ An empty string \"\" if there is none." 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." (when mu4e-contexts (let* ((names (cl-map 'list (lambda (context) @@ -108,13 +114,13 @@ non-nil." (context (if name (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")) ;; if new context is same as old one one switch with FORCE is set. (when (or force (not (eq context (mu4e-context-current)))) (when (and (mu4e-context-current) - (mu4e-context-leave-func mu4e~context-current)) - (funcall (mu4e-context-leave-func mu4e~context-current))) + (mu4e-context-leave-func mu4e--context-current)) + (funcall (mu4e-context-leave-func mu4e--context-current))) ;; enter the new context (when (mu4e-context-enter-func context) (funcall (mu4e-context-enter-func context))) @@ -122,14 +128,14 @@ non-nil." (mapc (lambda (cell) (set (car cell) (cdr cell))) (mu4e-context-vars context))) - (setq mu4e~context-current context) + (setq mu4e--context-current context) (run-hooks 'mu4e-context-changed-hook) (mu4e-message "Switched context to %s" (mu4e-context-name context)) (force-mode-line-update)) context)) -(defun mu4e~context-autoswitch (&optional msg policy) +(defun mu4e--context-autoswitch (&optional msg policy) "Automatically switch to some context. 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." (when mu4e-contexts (if (eq policy 'always-ask) - (mu4e~context-ask-user "Select context: ") + (mu4e--context-ask-user "Select context: ") (or ;; is there a matching one? (cl-find-if (lambda (context) (when (mu4e-context-match-func context) @@ -170,9 +176,9 @@ match, POLICY determines what to do: ;; no context found yet; consult policy (cl-case policy (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) - (mu4e~context-ask-user "Select context: "))) + (mu4e--context-ask-user "Select context: "))) (otherwise nil)))))) (defun mu4e-context-in-modeline () @@ -182,6 +188,18 @@ global-mode-line." (make-local-variable 'global-mode-string) '(: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) ;;; mu4e-context.el ends here diff --git a/mu4e/mu4e-headers.el b/mu4e/mu4e-headers.el index 203de0c0..fb5930d0 100644 --- a/mu4e/mu4e-headers.el +++ b/mu4e/mu4e-headers.el @@ -38,6 +38,7 @@ (require 'mu4e-proc) (require 'mu4e-vars) (require 'mu4e-mark) +(require 'mu4e-context) (require 'mu4e-compose) (require 'mu4e-actions) (require 'mu4e-message) @@ -929,8 +930,6 @@ after the end of the search results." (define-key map (kbd "") 'mu4e-headers-split-view-grow) (define-key map (kbd "") 'mu4e-headers-split-view-shrink) - (define-key map ";" 'mu4e-context-switch) - ;; switching to view mode (if it's visible) (define-key map "y" 'mu4e-select-other-view) @@ -1133,8 +1132,6 @@ no user-interaction ongoing." (make-local-variable 'mu4e~highlighted-docid) (set (make-local-variable 'hl-line-face) 'mu4e-header-highlight-face) - (mu4e-context-in-modeline) - ;; 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 @@ -1147,6 +1144,7 @@ no user-interaction ongoing." header-line-format (mu4e~header-line-format)) (mu4e~mark-initialize) ;; initialize the marking subsystem + (mu4e-context-minor-mode) (hl-line-mode 1)) (defun mu4e~headers-index-updated-hook-fn () @@ -1266,7 +1264,7 @@ docid is not found." `(:eval (concat (propertize - (mu4e~quote-for-modeline ,mu4e~headers-mode-line-label) + (mu4e-quote-for-modeline ,mu4e~headers-mode-line-label) 'face 'mu4e-modeline-face) " " (if (and mu4e-display-update-status-in-modeline diff --git a/mu4e/mu4e-main.el b/mu4e/mu4e-main.el index 839ccf6b..6e01ceb8 100644 --- a/mu4e/mu4e-main.el +++ b/mu4e/mu4e-main.el @@ -1,6 +1,6 @@ ;;; 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 ;; Maintainer: Dirk-Jan C. Binnema @@ -43,8 +43,6 @@ This also hides the warning if your `user-mail-address' is not part of the personal addresses.") - - (defvar mu4e-main-hide-fully-read nil "When set to t, do not hide bookmarks or maildirs that have no unread messages.") @@ -87,7 +85,7 @@ no unread messages.") \\{mu4e-main-mode-map}." (setq truncate-lines t overwrite-mode 'overwrite-mode-binary) - (mu4e-context-in-modeline) + (mu4e-context-minor-mode) (set (make-local-variable 'revert-buffer-function) #'mu4e~main-view-real)) diff --git a/mu4e/mu4e-vars.el b/mu4e/mu4e-vars.el index 251c1c9f..3d903ea8 100644 --- a/mu4e/mu4e-vars.el +++ b/mu4e/mu4e-vars.el @@ -764,11 +764,6 @@ I.e. a message with the draft flag set." "Face for a header title in the headers view." :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 '((t :inherit font-lock-string-face :weight bold)) "Face for the query in the mode-line." diff --git a/mu4e/mu4e-view-gnus.el b/mu4e/mu4e-view-gnus.el index f4350e2e..2b73f649 100644 --- a/mu4e/mu4e-view-gnus.el +++ b/mu4e/mu4e-view-gnus.el @@ -28,6 +28,7 @@ ;;; Code: (require 'mu4e-view-common) +(require 'mu4e-context) (require 'calendar) (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 "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 "P" #'mu4e-headers-toggle-threading) (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) -(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-derived-mode mu4e-view-mode gnus-article-mode "mu4e:view" "Major mode for viewing an e-mail message in mu4e. @@ -430,7 +419,13 @@ Based on Gnus' article-mode." (lambda(func &rest args) (if (mu4e~view-mode-p) "." (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 diff --git a/mu4e/mu4e.texi b/mu4e/mu4e.texi index ec2f8544..43ccce2a 100644 --- a/mu4e/mu4e.texi +++ b/mu4e/mu4e.texi @@ -1005,7 +1005,6 @@ E edit (only allowed for draft messages) misc ---- -; switch context a execute some custom action on a header | pipe message through shell command C-+,C-- increase / decrease the number of headers shown @@ -1014,6 +1013,10 @@ C-S-u update mail & reindex q leave the headers buffer @end verbatim +Furthermore, a number of keybindings are available through minor modes: +@itemize +@item Context; see @pxref{Contexts}. +@end itemize @node HV Marking @section Marking @@ -1300,7 +1303,6 @@ A execute some custom action on the message's MIME-parts misc ---- -; switch context . show the raw message view. 'q' takes you back. C-+,C-- increase / decrease the number of headers shown H get help @@ -1308,6 +1310,11 @@ C-S-u update mail & reindex q leave the message view @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}. @node MSGV Rich-text and images