diff --git a/mu4e/meson.build b/mu4e/meson.build index c8e69273..cb52c7b6 100644 --- a/mu4e/meson.build +++ b/mu4e/meson.build @@ -45,6 +45,7 @@ mu4e_srcs=[ 'mu4e-main.el', 'mu4e-mark.el', 'mu4e-message.el', + 'mu4e-modeline.el', 'mu4e-obsolete.el', 'mu4e-org.el', 'mu4e-search.el', diff --git a/mu4e/mu4e-context.el b/mu4e/mu4e-context.el index fe661ecf..0858db8e 100644 --- a/mu4e/mu4e-context.el +++ b/mu4e/mu4e-context.el @@ -1,6 +1,6 @@ ;;; mu4e-context.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*- -;; Copyright (C) 2015-2022 Dirk-Jan C. Binnema +;; Copyright (C) 2015-2023 Dirk-Jan C. Binnema ;; Author: Dirk-Jan C. Binnema ;; Maintainer: Dirk-Jan C. Binnema @@ -28,6 +28,7 @@ ;;; Code: (require 'mu4e-helpers) +(require 'mu4e-modeline) ;;; Configuration @@ -82,14 +83,6 @@ none." (if ctx (mu4e-context-name ctx) ""))) ctx)) -(defun mu4e-context-label () - "Propertized string with the current context name. -An empty string \"\" if there is none." - (if (mu4e-context-current) - (concat "[" (propertize (mu4e-quote-for-modeline - (mu4e-context-name (mu4e-context-current))) - 'face 'mu4e-context-face) "]") "")) - (cl-defstruct mu4e-context "A mu4e context object with the following members: - `name': the name of the context, eg. \"Work\" or \"Private\". @@ -154,7 +147,7 @@ non-nil." (run-hooks 'mu4e-context-changed-hook) (mu4e-message "Switched context to %s" (mu4e-context-name context)) - (force-mode-line-update)) + (mu4e--modeline-update)) context)) (defun mu4e--context-autoswitch (&optional msg policy) @@ -204,13 +197,6 @@ as it is." (mu4e--context-ask-user "Select context: "))) (_ nil)))))) -(defun mu4e-context-in-modeline () - "Display the mu4e-context (if any) in a (buffer-specific) -global-mode-line." - (add-to-list - (make-local-variable 'global-mode-string) - '(:eval (mu4e-context-label)))) - (defmacro with-mu4e-context-vars (context &rest body) "Evaluate BODY, with variables let-bound for CONTEXT (if any). `funcall'." @@ -221,6 +207,14 @@ global-mode-line." (mapcar (lambda(cell) (cdr cell)) vars) (eval ,@body)))) +(defun mu4e--context-modeline-item () + "Propertized string with the current context name. +An empty string \"\" if there is none." + (if (mu4e-context-current) + (concat "[" (propertize (mu4e-quote-for-modeline + (mu4e-context-name (mu4e-context-current))) + 'face 'mu4e-context-face) "] " ) "")) + (define-minor-mode mu4e-context-minor-mode "Mode for switching the mu4e context." :global nil @@ -231,7 +225,8 @@ global-mode-line." (define-key map (kbd ";") #'mu4e-context-switch) map) :lighter "" - (mu4e-context-in-modeline)) + (mu4e--modeline-register #'mu4e--context-modeline-item) + (mu4e--modeline-update)) ;;; (provide 'mu4e-context) diff --git a/mu4e/mu4e-headers.el b/mu4e/mu4e-headers.el index ec9765a4..9fe37682 100644 --- a/mu4e/mu4e-headers.el +++ b/mu4e/mu4e-headers.el @@ -1,6 +1,6 @@ ;;; mu4e-headers.el -- part of mu4e -*- lexical-binding: t; coding:utf-8 -*- -;; Copyright (C) 2011-2022 Dirk-Jan C. Binnema +;; Copyright (C) 2011-2023 Dirk-Jan C. Binnema ;; Author: Dirk-Jan C. Binnema ;; Maintainer: Dirk-Jan C. Binnema @@ -812,7 +812,7 @@ true, do *not* update the query history stack." (mu4e--search-push-query mu4e--search-last-query 'past))) (setq mu4e--search-last-query rewritten-expr) (setq list-buffers-directory rewritten-expr) - (mu4e~headers-update-mode-line)) + (mu4e--modeline-update)) ;; when the buffer is already visible, select it; otherwise, ;; switch to it. @@ -1178,7 +1178,10 @@ The following specs are supported: (mu4e-context-minor-mode) (mu4e-update-minor-mode) (mu4e-search-minor-mode) - (hl-line-mode 1)) + (hl-line-mode 1) + + (mu4e--modeline-register #'mu4e~headers-modeline-item) + (mu4e--modeline-update)) ;;; Highlighting @@ -1244,7 +1247,7 @@ message plist, or nil if not found." ;;; Queries & searching (defvar mu4e~headers-mode-line-label "") -(defun mu4e~headers-update-mode-line () +(defun mu4e~headers-modeline-item () "Update mode-line settings." (let* ((flagstr (mapconcat @@ -1258,30 +1261,8 @@ message plist, or nil if not found." (,mu4e-search-skip-duplicates . ,mu4e-headers-skip-duplicates-label) (,mu4e-search-hide-enabled . ,mu4e-headers-hide-label)) - "")) - (name "mu4e-headers")) - - (setq mode-name name) - (setq mu4e~headers-mode-line-label - (concat flagstr " " mu4e--search-last-query)) - - (make-local-variable 'global-mode-string) - - (add-to-list 'global-mode-string - `(:eval - (concat - (propertize - (mu4e-quote-for-modeline ,mu4e~headers-mode-line-label) - 'face 'mu4e-modeline-face) - " " - (if (and mu4e-display-update-status-in-modeline - (buffer-live-p mu4e--update-buffer) - (process-live-p (get-buffer-process - mu4e--update-buffer))) - (propertize " (updating)" 'face 'mu4e-modeline-face) - "")))))) - - + ""))) + (concat flagstr " " mu4e--search-last-query))) ;;; Search-based marking diff --git a/mu4e/mu4e-modeline.el b/mu4e/mu4e-modeline.el new file mode 100644 index 00000000..51d966b3 --- /dev/null +++ b/mu4e/mu4e-modeline.el @@ -0,0 +1,79 @@ +;;; mu4e-modeline.el -- part of mu4e -*- lexical-binding: t -*- + +;; Copyright (C) 2023 Dirk-Jan C. Binnema + +;; Author: Dirk-Jan C. Binnema +;; Maintainer: Dirk-Jan C. Binnema + +;; This file is not part of GNU Emacs. + +;; mu4e is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; mu4e is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with mu4e. If not, see . + +;;; Commentary: + +;; This file contains functionality for putting mu4e-related information +;; in the emacs modeline, both buffer-specific and globally. + +;;; Code: + +(require 'cl-lib) + +(defvar-local mu4e--modeline-buffer-items nil + "List of buffer-local items for the mu4e modeline. +Each element is function that evaluates to a string.") + +(defvar mu4e--modeline-global-items nil + "List of items for the global modeline. +Each element is function that evaluates to a string.") + +(defun mu4e--modeline-register (func &optional global) + "Register a function for calculating some mu4e modeline part. +If GLOBAL is non-nil, add to the global-modeline; otherwise use +the buffer-local one." + (add-to-list + (if global 'mu4e--modeline-global-items 'mu4e--modeline-buffer-items) + func)) + +(defvar mu4e--modeline-item nil + "Mu4e item for the global-mode-line.") + +(defun mu4e--modeline-string () + "Calculate the current mu4e modeline string." + (mapconcat + (lambda (item) + (if (functionp item) + (or (funcall item) "") + "")) + (append mu4e--modeline-buffer-items mu4e--modeline-global-items) " ")) + +(define-minor-mode mu4e-modeline-mode + "Minor mode for showing mu4e information on the modeline." + ;; This is a bit special 'global' mode, since it consists of both + ;; buffer-specific parts (mu4e--modeline-buffer-items) and global items + ;; (mu4e--modeline-global-items). + :global t + :group 'mu4e + :lighter nil + (if mu4e-modeline-mode + (progn + (setq mu4e--modeline-item '(:eval (mu4e--modeline-string))) + (add-to-list 'global-mode-string mu4e--modeline-item)) + (progn + (setq global-mode-string + (seq-remove (lambda (item) (equal item mu4e--modeline-item)) + global-mode-string)))) + (force-mode-line-update)) + +(provide 'mu4e-modeline) +;; mu4e-modeline.el ends here diff --git a/mu4e/mu4e.el b/mu4e/mu4e.el index cce457c2..dfc88fa4 100644 --- a/mu4e/mu4e.el +++ b/mu4e/mu4e.el @@ -1,6 +1,6 @@ ;;; mu4e.el --- part of mu4e, the mu mail user agent -*- lexical-binding: t -*- -;; Copyright (C) 2011-2022 Dirk-Jan C. Binnema +;; Copyright (C) 2011-2023 Dirk-Jan C. Binnema ;; Author: Dirk-Jan C. Binnema ;; Maintainer: Dirk-Jan C. Binnema @@ -48,6 +48,11 @@ :type 'boolean :group 'mu4e) +(defcustom mu4e-modeline-support t + "Support for shoiwing information in the modeline." + :type 'boolean + :group 'mu4e) + (defcustom mu4e-org-support t "Support Org-mode links." :type 'boolean