mu4e: cleanups and flycheck fixes

- Remove some unused faces
- Fix some flycheck warnings
- Replace some `cl-` functions with `pcase` and `seq`
This commit is contained in:
Dirk-Jan C. Binnema 2022-01-23 10:29:45 +02:00
parent 3e3d26be8f
commit a4707afe12
15 changed files with 296 additions and 385 deletions

View File

@ -1,6 +1,6 @@
;;; mu4e-actions.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*- ;;; mu4e-actions.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*-
;; Copyright (C) 2011-2021 Dirk-Jan C. Binnema ;; Copyright (C) 2011-2022 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>
@ -27,7 +27,6 @@
;;; Code: ;;; Code:
(require 'cl-lib)
(require 'ido) (require 'ido)
(require 'mu4e-helpers) (require 'mu4e-helpers)

View File

@ -1,6 +1,6 @@
;;; mu4e-bookmarks.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*- ;;; mu4e-bookmarks.el -- part of mu4e -*- lexical-binding: t -*-
;; Copyright (C) 2011-2021 Dirk-Jan C. Binnema ;; Copyright (C) 2011-2022 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>
@ -23,7 +23,6 @@
;;; Commentary: ;;; Commentary:
;;; Code: ;;; Code:
(require 'cl-lib)
(require 'mu4e-helpers) (require 'mu4e-helpers)
@ -33,18 +32,6 @@
"Settings for bookmarks." "Settings for bookmarks."
:group 'mu4e) :group 'mu4e)
;; for backward compatibility, when a bookmark was defined with defstruct.
(cl-defun make-mu4e-bookmark (&key name query key)
"Create a mu4e plist.
It has has with the following elements:
- NAME: the user-visible name of the bookmark
- KEY: a single key to search for this bookmark
- QUERY: the query for this bookmark. Either a literal string or a function
that evaluates to a string."
`(:name ,name :query ,query :key ,key))
(make-obsolete 'make-mu4e-bookmark "`unneeded; `mu4e-bookmarks'
are plists" "1.3.7")
(defcustom mu4e-bookmarks (defcustom mu4e-bookmarks
'(( :name "Unread messages" '(( :name "Unread messages"
:query "flag:unread AND NOT flag:trashed" :query "flag:unread AND NOT flag:trashed"
@ -68,21 +55,20 @@ Each of the list elements is a plist with at least:
Note that the :query parameter can be a function/lambda. Note that the :query parameter can be a function/lambda.
Optionally, you can add the following: Optionally, you can add the following: `:hide' - if t, the
`:hide' - if t, the bookmark is hidden from the main-view and bookmark is hidden from the main-view and speedbar.
speedbar. `:hide-unread' - do not show the counts of unread/total number of
`:hide-unread' - do not show the counts of unread/total number matches for the query in the main-view. This can be useful if a
of matches for the query in the main-view. This can be useful bookmark uses a very slow query.
if a bookmark uses a very slow query. :hide-unread
is implied from :hide. Furthermore, it is implied if
`:query' is a function.
Queries used to determine the unread/all counts do _not_ apply `:hide-unread' is implied from `:hide'. Furthermore, it is
`mu4e-query-rewrite-function'; nor do they discard duplicate or implied when `:query' is a function.
unreadable messages (for efficiency). Thus, the numbers shown may
differ from the number you get from a 'real' query." Note: for efficiency, queries used to determine the unread/all
counts do not apply `mu4e-query-rewrite-function', nor do they
discard duplicate or unreadable messages. Thus, the numbers shown
may differ from the number you get from a 'real' query."
:type '(repeat (plist)) :type '(repeat (plist))
:version "1.3.9"
:group 'mu4e-bookmarks) :group 'mu4e-bookmarks)
@ -106,7 +92,7 @@ differ from the number you get from a 'real' query."
"Get the corresponding bookmarked query for shortcut KAR. "Get the corresponding bookmarked query for shortcut KAR.
Raise an error if none is found." Raise an error if none is found."
(let* ((chosen-bm (let* ((chosen-bm
(or (cl-find-if (or (seq-find
(lambda (bm) (lambda (bm)
(= kar (plist-get bm :key))) (= kar (plist-get bm :key)))
(mu4e-bookmarks)) (mu4e-bookmarks))
@ -125,7 +111,7 @@ Raise an error if none is found."
Append it to `mu4e-bookmarks'. Replaces any existing bookmark Append it to `mu4e-bookmarks'. Replaces any existing bookmark
with KEY." with KEY."
(setq mu4e-bookmarks (setq mu4e-bookmarks
(cl-remove-if (seq-remove
(lambda (bm) (lambda (bm)
(= (plist-get bm :key) key)) (= (plist-get bm :key) key))
(mu4e-bookmarks))) (mu4e-bookmarks)))
@ -137,14 +123,11 @@ with KEY."
(defun mu4e-bookmarks () (defun mu4e-bookmarks ()
"Get `mu4e-bookmarks' in the (new) format. "Get `mu4e-bookmarks' in the (new) format.
Convert from the old format if needed." Convert from the old format if needed."
(cl-map 'list (seq-map (lambda (item)
(lambda (item) (if (and (listp item) (= (length item) 3))
(if (and (listp item) (= (length item) 3)) `(:name ,(nth 1 item) :query ,(nth 0 item)
`(:name ,(nth 1 item) :key ,(nth 2 item))
:query ,(nth 0 item) item)) mu4e-bookmarks))
:key ,(nth 2 item))
item))
mu4e-bookmarks))
(provide 'mu4e-bookmarks) (provide 'mu4e-bookmarks)
;;; mu4e-bookmarks.el ends here ;;; mu4e-bookmarks.el ends here

View File

@ -1,6 +1,6 @@
;;; mu4e-compose.el -- part of mu4e -*- lexical-binding: t -*- ;;; mu4e-compose.el -- part of mu4e -*- lexical-binding: t -*-
;; Copyright (C) 2011-2021 Dirk-Jan C. Binnema ;; Copyright (C) 2011-2022 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>
@ -129,14 +129,13 @@ If needed, set the Fcc header, and register the handler function."
(funcall mu4e-sent-messages-behavior) (funcall mu4e-sent-messages-behavior)
mu4e-sent-messages-behavior))) mu4e-sent-messages-behavior)))
(mdir (mdir
(cl-case sent-behavior (pcase sent-behavior
(delete nil) ('delete nil)
(trash (mu4e-get-trash-folder mu4e-compose-parent-message)) ('trash (mu4e-get-trash-folder mu4e-compose-parent-message))
(sent (mu4e-get-sent-folder mu4e-compose-parent-message)) ('sent (mu4e-get-sent-folder mu4e-compose-parent-message))
(otherwise (_ (mu4e-error
(mu4e-error "Unsupported value '%S' "Unsupported value %S for `mu4e-sent-messages-behavior'"
`mu4e-sent-messages-behavior'" mu4e-sent-messages-behavior))))
mu4e-sent-messages-behavior))))
(fccfile (and mdir (fccfile (and mdir
(concat (mu4e-root-maildir) mdir "/cur/" (concat (mu4e-root-maildir) mdir "/cur/"
(mu4e~draft-message-filename-construct "S"))))) (mu4e~draft-message-filename-construct "S")))))
@ -453,10 +452,10 @@ buffers; lets remap its faces so it uses the ones for mu4e."
(let* ((subj (message-field-value "subject")) (let* ((subj (message-field-value "subject"))
(subj (unless (and subj (string-match "^[:blank:]*$" subj)) subj)) (subj (unless (and subj (string-match "^[:blank:]*$" subj)) subj))
(str (or subj (str (or subj
(cl-case compose-type (pcase compose-type
(reply "*reply*") ('reply "*reply*")
(forward "*forward*") ('forward "*forward*")
(otherwise "*draft*"))))) (_ "*draft*")))))
(rename-buffer (generate-new-buffer-name (rename-buffer (generate-new-buffer-name
(truncate-string-to-width (truncate-string-to-width
str mu4e~compose-buffer-max-name-length) str mu4e~compose-buffer-max-name-length)
@ -586,12 +585,9 @@ are optional."
(if (member compose-type '(new forward)) (if (member compose-type '(new forward))
(message-goto-to) (message-goto-to)
;; otherwise, it depends... ;; otherwise, it depends...
(cl-case message-cite-reply-position (pcase message-cite-reply-position
((above traditional) ((or 'above 'traditional) (message-goto-body))
(message-goto-body)) (_ (when (message-goto-signature) (forward-line -2)))))
(t
(when (message-goto-signature)
(forward-line -2)))))
;; bind to `mu4e-compose-parent-message' of compose buffer ;; bind to `mu4e-compose-parent-message' of compose buffer
(set (make-local-variable 'mu4e-compose-parent-message) original-msg) (set (make-local-variable 'mu4e-compose-parent-message) original-msg)
@ -729,7 +725,7 @@ buffer."
(while (re-search-forward "<[^ <]+@[^ <]+>" nil t) (while (re-search-forward "<[^ <]+@[^ <]+>" nil t)
(push (match-string 0) refs)) (push (match-string 0) refs))
;; the last will be the first ;; the last will be the first
(setq forwarded-from (cl-first refs)))))) (setq forwarded-from (car refs))))))
;; remove the <> ;; remove the <>
(when (and in-reply-to (string-match "<\\(.*\\)>" in-reply-to)) (when (and in-reply-to (string-match "<\\(.*\\)>" in-reply-to))
(mu4e--server-move (match-string 1 in-reply-to) nil "+R-N")) (mu4e--server-move (match-string 1 in-reply-to) nil "+R-N"))

View File

@ -1,6 +1,6 @@
;;; mu4e-context.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*- ;;; mu4e-context.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*-
;; Copyright (C) 2015-2021 Dirk-Jan C. Binnema ;; Copyright (C) 2015-2022 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>
@ -114,8 +114,8 @@ An empty string \"\" if there is none."
(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 (seq-map (lambda (context)
(cons (mu4e-context-name context) context)) (cons (mu4e-context-name context) context))
mu4e-contexts)) mu4e-contexts))
(context (mu4e-read-option prompt names))) (context (mu4e-read-option prompt names)))
(or context (mu4e-error "No such context"))))) (or context (mu4e-error "No such context")))))
@ -130,8 +130,8 @@ non-nil."
(interactive "P") (interactive "P")
(unless mu4e-contexts (unless mu4e-contexts
(mu4e-error "No contexts defined")) (mu4e-error "No contexts defined"))
(let* ((names (cl-map 'list (lambda (context) (let* ((names (seq-map (lambda (context)
(cons (mu4e-context-name context) context)) (cons (mu4e-context-name context) context))
mu4e-contexts)) mu4e-contexts))
(context (context
(if name (if name
@ -191,17 +191,17 @@ match, POLICY determines what to do:
(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) (seq-find (lambda (context)
(when (mu4e-context-match-func context) (when (mu4e-context-match-func context)
(funcall (mu4e-context-match-func context) msg))) (funcall (mu4e-context-match-func context) msg)))
mu4e-contexts) mu4e-contexts)
;; no context found yet; consult policy ;; no context found yet; consult policy
(cl-case policy (pcase 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)))))) (_ nil))))))
(defun mu4e-context-in-modeline () (defun mu4e-context-in-modeline ()
"Display the mu4e-context (if any) in a (buffer-specific) "Display the mu4e-context (if any) in a (buffer-specific)

View File

@ -1,6 +1,6 @@
;;; mu4e-folders.el -- part of mu4e -*- lexical-binding: t -*- ;;; mu4e-folders.el -- part of mu4e -*- lexical-binding: t -*-
;; Copyright (C) 2021 Dirk-Jan C. Binnema ;; Copyright (C) 2021-2022 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>
@ -25,7 +25,6 @@
;; Dealing with maildirs & folders ;; Dealing with maildirs & folders
;;; Code: ;;; Code:
(require 'cl-lib)
(require 'mu4e-helpers) (require 'mu4e-helpers)
(require 'mu4e-context) (require 'mu4e-context)
(require 'mu4e-server) (require 'mu4e-server)
@ -148,32 +147,23 @@ mime-type are nill."
(defun mu4e-maildir-shortcuts () (defun mu4e-maildir-shortcuts ()
"Get `mu4e-maildir-shortcuts' in the (new) format. "Get `mu4e-maildir-shortcuts' in the (new) format.
Converts from the old format if needed." Converts from the old format if needed."
(cl-map 'list (seq-map (lambda (item) ;; convert from old format?
(lambda (item) ;; convert from old format? (if (and (consp item) (not (consp (cdr item))))
(if (and (consp item) (not (consp (cdr item)))) `(:maildir ,(car item) :key ,(cdr item))
`(:maildir ,(car item) :key ,(cdr item)) item))
item)) mu4e-maildir-shortcuts))
mu4e-maildir-shortcuts))
(defun mu4e--maildirs-with-query () (defun mu4e--maildirs-with-query ()
"Llike `mu4e-maildir-shortcuts', but with :query populated. "Like `mu4e-maildir-shortcuts', but with :query populated.
This is compatibile with `mu4e-bookmarks'."
This is meant to be the exact same data structure as (seq-map
`mu4e-bookmarks'." (lambda (item)
(cl-mapcar (let* ((maildir (plist-get item :maildir))
(lambda (m) (item (plist-put item :name maildir))
(append (item (plist-put item :query (format "maildir:\"%s\"" maildir))))
;; we want to change the :maildir key to :name, and add a :query key item)) ;; we don't need ":maildir", but it's harmless.
(list :name (plist-get m :maildir)
:query (format "maildir:\"%s\"" (plist-get m :maildir)))
;; next we want to append any other keys to our previous list (e.g. :hide,
;; :key, etc) but skipping :maildir (since it's renamed to :name)
(cl-loop for (key value) on m by 'cddr
when (not (equal key :maildir))
append (list key value))))
(mu4e-maildir-shortcuts))) (mu4e-maildir-shortcuts)))
;; the standard folders can be functions too ;; the standard folders can be functions too
(defun mu4e--get-folder (foldervar msg) (defun mu4e--get-folder (foldervar msg)
"Within the mu-context of MSG, get message folder FOLDERVAR. "Within the mu-context of MSG, get message folder FOLDERVAR.
@ -313,8 +303,8 @@ all maildirs under `mu4e-maildir'."
(funcall mu4e-completing-read-function prompt (funcall mu4e-completing-read-function prompt
(mu4e-get-maildirs) nil nil "/")) (mu4e-get-maildirs) nil nil "/"))
(or (plist-get (or (plist-get
(cl-find-if (lambda (item) (= kar (plist-get item :key))) (seq-find (lambda (item) (= kar (plist-get item :key)))
(mu4e-maildir-shortcuts)) :maildir) (mu4e-maildir-shortcuts)) :maildir)
(mu4e-warn "Unknown shortcut '%c'" kar))))))) (mu4e-warn "Unknown shortcut '%c'" kar)))))))
(defun mu4e-ask-maildir-check-exists (prompt) (defun mu4e-ask-maildir-check-exists (prompt)
@ -333,21 +323,19 @@ Offer to create it if it does not exist yet."
;; be nil ;; be nil
(defun mu4e~get-attachment-dir (&optional fname mimetype) (defun mu4e~get-attachment-dir (&optional fname mimetype)
"Get the directory for saving attachments from "Get the directory for saving attachments from `mu4e-attachment-dir'.
`mu4e-attachment-dir' (which can be either a string or a function, This is optionally based on the file-name FNAME and its MIMETYPE."
see its docstring)." (let ((dir
(let (cond
((dir ((stringp mu4e-attachment-dir)
(cond mu4e-attachment-dir)
((stringp mu4e-attachment-dir) ((functionp mu4e-attachment-dir)
mu4e-attachment-dir) (funcall mu4e-attachment-dir fname mimetype))
((functionp mu4e-attachment-dir) (t
(funcall mu4e-attachment-dir fname mimetype)) (mu4e-error "Unsupported type for mu4e-attachment-dir" )))))
(t
(mu4e-error "unsupported type for mu4e-attachment-dir" )))))
(if dir (if dir
(expand-file-name dir) (expand-file-name dir)
(mu4e-error "mu4e-attachment-dir evaluates to nil")))) (mu4e-error "Mu4e-attachment-dir evaluates to nil"))))
(provide 'mu4e-folders) (provide 'mu4e-folders)
;;; mu4e-folders.el ends here ;;; mu4e-folders.el ends here

View File

@ -50,7 +50,7 @@
(require 'mu4e-folders) (require 'mu4e-folders)
(declare-function mu4e-view "mu4e-view") (declare-function mu4e-view "mu4e-view")
(declare-function mu4e~main-view "mu4e-main") (declare-function mu4e--main-view "mu4e-main")
@ -312,7 +312,7 @@ This is mostly useful for profiling.")
(setq mu4e~headers-render-start (float-time)) (setq mu4e~headers-render-start (float-time))
(let ((inhibit-read-only t)) (let ((inhibit-read-only t))
(with-current-buffer (mu4e-get-headers-buffer) (with-current-buffer (mu4e-get-headers-buffer)
(mu4e~mark-clear) (mu4e--mark-clear)
(erase-buffer) (erase-buffer)
(when msg (when msg
(goto-char (point-min)) (goto-char (point-min))
@ -667,7 +667,7 @@ displaying in the header view."
(propertize (propertize
(concat (concat
(mu4e~headers-docid-cookie docid) (mu4e~headers-docid-cookie docid)
mu4e~mark-fringe line "\n") mu4e--mark-fringe line "\n")
'docid docid 'msg msg)))) 'docid docid 'msg msg))))
(defun mu4e~headers-remove-header (docid &optional ignore-missing) (defun mu4e~headers-remove-header (docid &optional ignore-missing)
@ -722,7 +722,7 @@ headers."
(initial-column (current-column)) (initial-column (current-column))
(inhibit-read-only t) (inhibit-read-only t)
(point (mu4e~headers-docid-pos docid)) (point (mu4e~headers-docid-pos docid))
(markinfo (gethash docid mu4e~mark-map))) (markinfo (gethash docid mu4e--mark-map)))
(when point ;; is the message present in this list? (when point ;; is the message present in this list?
;; if it's marked, unmark it now ;; if it's marked, unmark it now
@ -1061,7 +1061,7 @@ after the end of the search results."
(downarrow (if mu4e-use-fancy-chars "" " V"))) (downarrow (if mu4e-use-fancy-chars "" " V")))
(cons (cons
(make-string (make-string
(+ mu4e~mark-fringe-len (floor (fringe-columns 'left t))) ?\s) (+ mu4e--mark-fringe-len (floor (fringe-columns 'left t))) ?\s)
(mapcar (mapcar
(lambda (item) (lambda (item)
(let* ( ;; with threading enabled, we're necessarily sorting by date. (let* ( ;; with threading enabled, we're necessarily sorting by date.
@ -1179,7 +1179,7 @@ The following specs are supported:
overwrite-mode nil overwrite-mode nil
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) (mu4e-context-minor-mode)
(mu4e-update-minor-mode) (mu4e-update-minor-mode)
(mu4e-search-minor-mode) (mu4e-search-minor-mode)
@ -1238,9 +1238,9 @@ message plist, or nil if not found."
;; clear old marks, and add the new ones. ;; clear old marks, and add the new ones.
(let ((msg (get-text-property (point) 'msg))) (let ((msg (get-text-property (point) 'msg)))
(delete-char mu4e~mark-fringe-len) (delete-char mu4e--mark-fringe-len)
(insert (propertize (insert (propertize
(format mu4e~mark-fringe-format mark) (format mu4e--mark-fringe-format mark)
'face 'mu4e-header-marks-face 'face 'mu4e-header-marks-face
'docid docid 'docid docid
'msg msg))) 'msg msg)))
@ -1376,7 +1376,7 @@ parameter). MARKPAIR is a cell (MARK . TARGET); see
match and a regular expression to match with. Then, mark all match and a regular expression to match with. Then, mark all
matching messages with that mark." matching messages with that mark."
(interactive) (interactive)
(let ((markpair (mu4e~mark-get-markpair "Mark matched messages with: " t)) (let ((markpair (mu4e--mark-get-markpair "Mark matched messages with: " t))
(field (mu4e-read-option "Field to match: " (field (mu4e-read-option "Field to match: "
'( ("subject" . :subject) '( ("subject" . :subject)
("from" . :from) ("from" . :from)
@ -1404,7 +1404,7 @@ matching messages with that mark."
(let* ((pred (mu4e-read-option "Match function: " (let* ((pred (mu4e-read-option "Match function: "
mu4e-headers-custom-markers)) mu4e-headers-custom-markers))
(param (when (cdr pred) (eval (cdr pred)))) (param (when (cdr pred) (eval (cdr pred))))
(markpair (mu4e~mark-get-markpair "Mark matched messages with: " t))) (markpair (mu4e--mark-get-markpair "Mark matched messages with: " t)))
(mu4e-headers-mark-for-each-if markpair (car pred) param))) (mu4e-headers-mark-for-each-if markpair (car pred) param)))
(defun mu4e~headers-get-thread-info (msg what) (defun mu4e~headers-get-thread-info (msg what)
@ -1464,7 +1464,7 @@ descendants."
(list current-prefix-arg (list current-prefix-arg
;; FIXME: e.g., for refiling we should evaluate this ;; FIXME: e.g., for refiling we should evaluate this
;; for each line separately ;; for each line separately
(mu4e~mark-get-markpair (mu4e--mark-get-markpair
(if subthread "Mark subthread with: " "Mark whole thread with: ") (if subthread "Mark subthread with: " "Mark whole thread with: ")
t)))) t))))
(mu4e-headers-mark-thread-using-markpair markpair subthread)) (mu4e-headers-mark-thread-using-markpair markpair subthread))
@ -1766,7 +1766,7 @@ other windows."
;; now, all *other* windows should be gone. kill ourselves, and return ;; now, all *other* windows should be gone. kill ourselves, and return
;; to the main view ;; to the main view
(kill-buffer) (kill-buffer)
(mu4e~main-view 'refresh)))) (mu4e--main-view 'refresh))))
;;; Loading messages ;;; Loading messages

View File

@ -354,21 +354,21 @@ function is meant for debugging."
(current-time)) (current-time))
'face 'font-lock-string-face)) 'face 'font-lock-string-face))
(msg-face (msg-face
(cl-case type (pcase type
(from-server 'font-lock-type-face) ('from-server 'font-lock-type-face)
(to-server 'font-lock-function-name-face) ('to-server 'font-lock-function-name-face)
(misc 'font-lock-variable-name-face) ('misc 'font-lock-variable-name-face)
(error 'font-lock-warning-face) ('error 'font-lock-warning-face)
(otherwise (mu4e-error "Unsupported log type")))) (_ (mu4e-error "Unsupported log type"))))
(msg (propertize (apply 'format frm args) 'face msg-face))) (msg (propertize (apply 'format frm args) 'face msg-face)))
(save-excursion (save-excursion
(goto-char (point-max)) (goto-char (point-max))
(insert tstamp (insert tstamp
(cl-case type (pcase type
(from-server " <- ") ('from-server " <- ")
(to-server " -> ") ('to-server " -> ")
(error " !! ") ('error " !! ")
(otherwise " ")) (_ " "))
msg "\n") msg "\n")
;; if `mu4e-log-max-lines is specified and exceeded, clearest the ;; if `mu4e-log-max-lines is specified and exceeded, clearest the
;; oldest lines ;; oldest lines
@ -508,11 +508,11 @@ in an external program."
"Display the mu4e manual page for the current mode. "Display the mu4e manual page for the current mode.
Or go to the top level if there is none." Or go to the top level if there is none."
(interactive) (interactive)
(info (cl-case major-mode (info (pcase major-mode
('mu4e-main-mode "(mu4e)Main view") ('mu4e-main-mode "(mu4e)Main view")
('mu4e-headers-mode "(mu4e)Headers view") ('mu4e-headers-mode "(mu4e)Headers view")
('mu4e-view-mode "(mu4e)Message view") ('mu4e-view-mode "(mu4e)Message view")
(t "mu4e")))) (_ "mu4e"))))
;;; Macros ;;; Macros

View File

@ -26,8 +26,6 @@
;; The shortname (friendly) should a at most 8 characters, camel-case ;; The shortname (friendly) should a at most 8 characters, camel-case
;;; Code: ;;; Code:
(require 'cl-lib)
;;; Configuration ;;; Configuration
(defvar mu4e-mailing-lists (defvar mu4e-mailing-lists
@ -118,9 +116,9 @@ Based on `mu4e-mailing-lists', `mu4e-user-mailing-lists', and
(or (or
(gethash list-id mu4e--lists-hash) (gethash list-id mu4e--lists-hash)
(and (boundp 'mu4e-mailing-list-patterns) (and (boundp 'mu4e-mailing-list-patterns)
(cl-member-if (seq-drop-while
(lambda (pattern) (lambda (pattern)
(string-match pattern list-id)) (not (string-match pattern list-id)))
mu4e-mailing-list-patterns) mu4e-mailing-list-patterns)
(match-string 1 list-id)) (match-string 1 list-id))
;; if it's not in the db, take the part until the first dot if there is one; ;; if it's not in the db, take the part until the first dot if there is one;

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-2021 Dirk-Jan C. Binnema ;; Copyright (C) 2011-2022 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>
@ -36,7 +36,6 @@
(require 'cl-lib) (require 'cl-lib)
;; Configuration ;; Configuration
@ -45,21 +44,19 @@
'mu4e-main-hide-personal-addresses "1.5.7") 'mu4e-main-hide-personal-addresses "1.5.7")
(defvar mu4e-main-hide-personal-addresses nil (defvar mu4e-main-hide-personal-addresses nil
"Whether to hide the personal address in the main view. This "Whether to hide the personal address in the main view.
can be useful to avoid the noise when there are many.
This also hides the warning if your `user-mail-address' is not This can be useful to avoid the noise when there are many, and
part of the personal addresses.") also hides the warning if your `user-mail-address' is not 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 "Whether to hide bookmarks or maildirs without unread messages.")
no unread messages.")
;;; Mode ;;; Mode
(define-derived-mode mu4e-org-mode org-mode "mu4e:org" (define-derived-mode mu4e-org-mode org-mode "mu4e:org"
"Major mode for mu4e documents, derived from "Major mode for mu4e documents.")
`org-mode'.")
(defun mu4e-info (path) (defun mu4e-info (path)
"Show a buffer with the information (an org-file) at PATH." "Show a buffer with the information (an org-file) at PATH."
@ -90,10 +87,10 @@ no unread messages.")
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))
(define-key map "q" 'mu4e-quit) (define-key map "q" 'mu4e-quit)
(define-key map "j" 'mu4e~headers-jump-to-maildir) (define-key map "j" 'mu4e--headers-jump-to-maildir)
(define-key map "C" 'mu4e-compose-new) (define-key map "C" 'mu4e-compose-new)
(define-key map "m" 'mu4e~main-toggle-mail-sending-mode) (define-key map "m" 'mu4e--main-toggle-mail-sending-mode)
(define-key map "f" 'smtpmail-send-queued-mail) (define-key map "f" 'smtpmail-send-queued-mail)
;; ;;
(define-key map "U" 'mu4e-update-mail-and-index) (define-key map "U" 'mu4e-update-mail-and-index)
@ -121,10 +118,10 @@ no unread messages.")
(mu4e-context-minor-mode) (mu4e-context-minor-mode)
(mu4e-search-minor-mode) (mu4e-search-minor-mode)
(mu4e-update-minor-mode) (mu4e-update-minor-mode)
(set (make-local-variable 'revert-buffer-function) #'mu4e~main-view-real)) (set (make-local-variable 'revert-buffer-function) #'mu4e--main-view-real))
(defun mu4e~main-action-str (str &optional func-or-shortcut) (defun mu4e--main-action-str (str &optional func-or-shortcut)
"Highlight the first occurrence of [.] in STR. "Highlight the first occurrence of [.] in STR.
If FUNC-OR-SHORTCUT is non-nil and if it is a function, call it If FUNC-OR-SHORTCUT is non-nil and if it is a function, call it
when STR is clicked (using RET or mouse-2); if FUNC-OR-SHORTCUT is when STR is clicked (using RET or mouse-2); if FUNC-OR-SHORTCUT is
@ -165,7 +162,8 @@ clicked."
(mu4e--maildirs-with-query)) (mu4e--maildirs-with-query))
maximize (string-width (plist-get b :name)))) maximize (string-width (plist-get b :name))))
(defun mu4e~main-bookmarks () (defun mu4e--main-bookmarks ()
"Return the entries for the bookmarks menu."
;; TODO: it's a bit uncool to hard-code the "b" shortcut... ;; TODO: it's a bit uncool to hard-code the "b" shortcut...
(cl-loop with bmks = (mu4e-bookmarks) (cl-loop with bmks = (mu4e-bookmarks)
with longest = (mu4e--longest-of-maildirs-and-bookmarks) with longest = (mu4e--longest-of-maildirs-and-bookmarks)
@ -187,7 +185,7 @@ clicked."
when (not (and mu4e-main-hide-fully-read (eq unread 0))) when (not (and mu4e-main-hide-fully-read (eq unread 0)))
concat (concat concat (concat
;; menu entry ;; menu entry
(mu4e~main-action-str (mu4e--main-action-str
(concat "\t* [b" key "] " name) (concat "\t* [b" key "] " name)
(concat "b" key)) (concat "b" key))
;; append all/unread numbers, if available. ;; append all/unread numbers, if available.
@ -204,7 +202,7 @@ clicked."
"\n"))) "\n")))
(defun mu4e~main-maildirs () (defun mu4e--main-maildirs ()
"Return a string of maildirs with their counts." "Return a string of maildirs with their counts."
(cl-loop with mds = (mu4e--maildirs-with-query) (cl-loop with mds = (mu4e--maildirs-with-query)
with longest = (mu4e--longest-of-maildirs-and-bookmarks) with longest = (mu4e--longest-of-maildirs-and-bookmarks)
@ -226,7 +224,7 @@ clicked."
when (not (and mu4e-main-hide-fully-read (eq unread 0))) when (not (and mu4e-main-hide-fully-read (eq unread 0)))
concat (concat concat (concat
;; menu entry ;; menu entry
(mu4e~main-action-str (mu4e--main-action-str
(concat "\t* [j" key "] " name) (concat "\t* [j" key "] " name)
(concat "j" key)) (concat "j" key))
;; append all/unread numbers, if available. ;; append all/unread numbers, if available.
@ -243,8 +241,8 @@ clicked."
"\n"))) "\n")))
(defun mu4e~key-val (key val &optional unit) (defun mu4e--key-val (key val &optional unit)
"Return a key / value pair." "Show a KEY / VAL pair, with optional UNIT."
(concat (concat
"\t* " "\t* "
(propertize (format "%-20s" key) 'face 'mu4e-header-title-face) (propertize (format "%-20s" key) 'face 'mu4e-header-title-face)
@ -255,24 +253,24 @@ clicked."
"") "")
"\n")) "\n"))
;; NEW This is the old `mu4e~main-view' function but without ;; NEW This is the old `mu4e--main-view' function but without
;; buffer switching at the end. ;; buffer switching at the end.
(defun mu4e~main-view-real (_ignore-auto _noconfirm) (defun mu4e--main-view-real (_ignore-auto _noconfirm)
"The revert buffer function for `mu4e-main-mode'." "The revert buffer function for `mu4e-main-mode'."
(mu4e~main-view-real-1 'refresh)) (mu4e--main-view-real-1 'refresh))
(declare-function mu4e--start "mu4e") (declare-function mu4e--start "mu4e")
(defun mu4e~main-view-real-1 (&optional refresh) (defun mu4e--main-view-real-1 (&optional refresh)
"Create `mu4e-main-buffer-name' and set it up. "Create `mu4e-main-buffer-name' and set it up.
When REFRESH is non nil refresh infos from server." When REFRESH is non nil refresh infos from server."
(let ((inhibit-read-only t)) (let ((inhibit-read-only t))
;; Maybe refresh infos from server. ;; Maybe refresh infos from server.
(if refresh (if refresh
(mu4e--start 'mu4e~main-redraw-buffer) (mu4e--start 'mu4e--main-redraw-buffer)
(mu4e~main-redraw-buffer)))) (mu4e--main-redraw-buffer))))
(defun mu4e~main-redraw-buffer () (defun mu4e--main-redraw-buffer ()
(with-current-buffer mu4e-main-buffer-name (with-current-buffer mu4e-main-buffer-name
(let ((inhibit-read-only t) (let ((inhibit-read-only t)
(pos (point)) (pos (point))
@ -285,45 +283,48 @@ When REFRESH is non nil refresh infos from server."
(propertize mu4e-mu-version 'face 'mu4e-header-key-face) (propertize mu4e-mu-version 'face 'mu4e-header-key-face)
"\n\n" "\n\n"
(propertize " Basics\n\n" 'face 'mu4e-title-face) (propertize " Basics\n\n" 'face 'mu4e-title-face)
(mu4e~main-action-str (mu4e--main-action-str
"\t* [j]ump to some maildir\n" 'mu4e-jump-to-maildir) "\t* [j]ump to some maildir\n" 'mu4e-jump-to-maildir)
(mu4e~main-action-str (mu4e--main-action-str
"\t* enter a [s]earch query\n" 'mu4e-search) "\t* enter a [s]earch query\n" 'mu4e-search)
(mu4e~main-action-str (mu4e--main-action-str
"\t* [C]ompose a new message\n" 'mu4e-compose-new) "\t* [C]ompose a new message\n" 'mu4e-compose-new)
"\n" "\n"
(propertize " Bookmarks\n\n" 'face 'mu4e-title-face) (propertize " Bookmarks\n\n" 'face 'mu4e-title-face)
(mu4e~main-bookmarks) (mu4e--main-bookmarks)
"\n" "\n"
(propertize " Maildirs\n\n" 'face 'mu4e-title-face) (propertize " Maildirs\n\n" 'face 'mu4e-title-face)
(mu4e~main-maildirs) (mu4e--main-maildirs)
"\n" "\n"
(propertize " Misc\n\n" 'face 'mu4e-title-face) (propertize " Misc\n\n" 'face 'mu4e-title-face)
(mu4e~main-action-str "\t* [;]Switch context\n" (mu4e--main-action-str "\t* [;]Switch context\n"
(lambda()(interactive)(mu4e-context-switch)(revert-buffer))) (lambda()(interactive)
(mu4e-context-switch)(revert-buffer)))
(mu4e~main-action-str "\t* [U]pdate email & database\n" (mu4e--main-action-str "\t* [U]pdate email & database\n"
'mu4e-update-mail-and-index) 'mu4e-update-mail-and-index)
;; show the queue functions if `smtpmail-queue-dir' is defined ;; show the queue functions if `smtpmail-queue-dir' is defined
(if (file-directory-p smtpmail-queue-dir) (if (file-directory-p smtpmail-queue-dir)
(mu4e~main-view-queue) (mu4e--main-view-queue)
"") "")
"\n" "\n"
(mu4e~main-action-str "\t* [N]ews\n" 'mu4e-news) (mu4e--main-action-str "\t* [N]ews\n" 'mu4e-news)
(mu4e~main-action-str "\t* [A]bout mu4e\n" 'mu4e-about) (mu4e--main-action-str "\t* [A]bout mu4e\n" 'mu4e-about)
(mu4e~main-action-str "\t* [H]elp\n" 'mu4e-display-manual) (mu4e--main-action-str "\t* [H]elp\n" 'mu4e-display-manual)
(mu4e~main-action-str "\t* [q]uit\n" 'mu4e-quit) (mu4e--main-action-str "\t* [q]uit\n" 'mu4e-quit)
"\n" "\n"
(propertize " Info\n\n" 'face 'mu4e-title-face) (propertize " Info\n\n" 'face 'mu4e-title-face)
(mu4e~key-val "database-path" (mu4e-database-path)) (mu4e--key-val "database-path" (mu4e-database-path))
(mu4e~key-val "maildir" (mu4e-root-maildir)) (mu4e--key-val "maildir" (mu4e-root-maildir))
(mu4e~key-val "in store" (mu4e--key-val "in store"
(format "%d" (plist-get mu4e--server-props :doccount)) "messages") (format "%d" (plist-get mu4e--server-props :doccount))
"messages")
(if mu4e-main-hide-personal-addresses "" (if mu4e-main-hide-personal-addresses ""
(mu4e~key-val "personal addresses" (if addrs (mapconcat #'identity addrs ", " ) "none")))) (mu4e--key-val "personal addresses"
(if addrs (mapconcat #'identity addrs ", " ) "none"))))
(if mu4e-main-hide-personal-addresses "" (if mu4e-main-hide-personal-addresses ""
(unless (mu4e-personal-address-p user-mail-address) (unless (mu4e-personal-address-p user-mail-address)
@ -334,26 +335,26 @@ When REFRESH is non nil refresh infos from server."
(mu4e-main-mode) (mu4e-main-mode)
(goto-char pos)))) (goto-char pos))))
(defun mu4e~main-view-queue () (defun mu4e--main-view-queue ()
"Display queue-related actions in the main view." "Display queue-related actions in the main view."
(concat (concat
(mu4e~main-action-str "\t* toggle [m]ail sending mode " (mu4e--main-action-str "\t* toggle [m]ail sending mode "
'mu4e~main-toggle-mail-sending-mode) 'mu4e--main-toggle-mail-sending-mode)
"(currently " "(currently "
(propertize (if smtpmail-queue-mail "queued" "direct") (propertize (if smtpmail-queue-mail "queued" "direct")
'face 'mu4e-header-key-face) 'face 'mu4e-header-key-face)
")\n" ")\n"
(let ((queue-size (mu4e~main-queue-size))) (let ((queue-size (mu4e--main-queue-size)))
(if (zerop queue-size) (if (zerop queue-size)
"" ""
(mu4e~main-action-str (mu4e--main-action-str
(format "\t* [f]lush %s queued %s\n" (format "\t* [f]lush %s queued %s\n"
(propertize (int-to-string queue-size) (propertize (int-to-string queue-size)
'face 'mu4e-header-key-face) 'face 'mu4e-header-key-face)
(if (> queue-size 1) "mails" "mail")) (if (> queue-size 1) "mails" "mail"))
'smtpmail-send-queued-mail))))) 'smtpmail-send-queued-mail)))))
(defun mu4e~main-queue-size () (defun mu4e--main-queue-size ()
"Return, as an int, the number of emails in the queue." "Return, as an int, the number of emails in the queue."
(condition-case nil (condition-case nil
(with-temp-buffer (with-temp-buffer
@ -362,7 +363,7 @@ When REFRESH is non nil refresh infos from server."
(count-lines (point-min) (point-max))) (count-lines (point-min) (point-max)))
(error 0))) (error 0)))
(defun mu4e~main-view (&optional refresh) (defun mu4e--main-view (&optional refresh)
"Create the mu4e main-view, and switch to it. "Create the mu4e main-view, and switch to it.
When REFRESH is non nil refresh infos from server." When REFRESH is non nil refresh infos from server."
@ -370,20 +371,20 @@ When REFRESH is non nil refresh infos from server."
(if (eq mu4e-split-view 'single-window) (if (eq mu4e-split-view 'single-window)
(if (buffer-live-p (mu4e-get-headers-buffer)) (if (buffer-live-p (mu4e-get-headers-buffer))
(switch-to-buffer (mu4e-get-headers-buffer)) (switch-to-buffer (mu4e-get-headers-buffer))
(mu4e~main-menu)) (mu4e--main-menu))
;; `mu4e~main-view' is called from `mu4e~start', so don't call it ;; `mu4e--main-view' is called from `mu4e--start', so don't call it
;; a second time here i.e. do not refresh unless specified ;; a second time here i.e. do not refresh unless specified
;; explicitly with REFRESH arg. ;; explicitly with REFRESH arg.
(switch-to-buffer buf) (switch-to-buffer buf)
(with-current-buffer buf (with-current-buffer buf
(mu4e~main-view-real-1 refresh)) (mu4e--main-view-real-1 refresh))
(goto-char (point-min))))) (goto-char (point-min)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Interactive functions ;; Interactive functions
;; NEW ;; NEW
;; Toggle mail sending mode without switching ;; Toggle mail sending mode without switching
(defun mu4e~main-toggle-mail-sending-mode () (defun mu4e--main-toggle-mail-sending-mode ()
"Toggle sending mail mode, either queued or direct." "Toggle sending mail mode, either queued or direct."
(interactive) (interactive)
(unless (file-directory-p smtpmail-queue-dir) (unless (file-directory-p smtpmail-queue-dir)
@ -396,23 +397,23 @@ When REFRESH is non nil refresh infos from server."
(with-current-buffer mu4e-main-buffer-name (with-current-buffer mu4e-main-buffer-name
(revert-buffer)))) (revert-buffer))))
(defun mu4e~main-menu () (defun mu4e--main-menu ()
"mu4e main view in the minibuffer." "The mu4e main menu."
(interactive) (interactive)
(let ((key (let ((key
(read-key (read-key
(mu4e-format (mu4e-format
"%s" "%s"
(concat (concat
(mu4e~main-action-str "[j]ump " 'mu4e-jump-to-maildir) (mu4e--main-action-str "[j]ump " 'mu4e-jump-to-maildir)
(mu4e~main-action-str "[s]earch " 'mu4e-search) (mu4e--main-action-str "[s]earch " 'mu4e-search)
(mu4e~main-action-str "[C]ompose " 'mu4e-compose-new) (mu4e--main-action-str "[C]ompose " 'mu4e-compose-new)
(mu4e~main-action-str "[b]ookmarks " 'mu4e-headers-search-bookmark) (mu4e--main-action-str "[b]ookmarks " 'mu4e-headers-search-bookmark)
(mu4e~main-action-str "[;]Switch context " 'mu4e-context-switch) (mu4e--main-action-str "[;]Switch context " 'mu4e-context-switch)
(mu4e~main-action-str "[U]pdate " 'mu4e-update-mail-and-index) (mu4e--main-action-str "[U]pdate " 'mu4e-update-mail-and-index)
(mu4e~main-action-str "[N]ews " 'mu4e-news) (mu4e--main-action-str "[N]ews " 'mu4e-news)
(mu4e~main-action-str "[A]bout " 'mu4e-about) (mu4e--main-action-str "[A]bout " 'mu4e-about)
(mu4e~main-action-str "[H]elp " 'mu4e-display-manual)))))) (mu4e--main-action-str "[H]elp " 'mu4e-display-manual))))))
(unless (member key '(?\C-g ?\C-\[)) (unless (member key '(?\C-g ?\C-\[))
(let ((mu4e-command (lookup-key mu4e-main-mode-map (string key) t))) (let ((mu4e-command (lookup-key mu4e-main-mode-map (string key) t)))
(if mu4e-command (if mu4e-command
@ -423,7 +424,7 @@ When REFRESH is non nil refresh infos from server."
(message (mu4e-format "key %s not bound to a command" (string key)))) (message (mu4e-format "key %s not bound to a command" (string key))))
(when (or (not mu4e-command) (eq mu4e-command 'mu4e-context-switch)) (when (or (not mu4e-command) (eq mu4e-command 'mu4e-context-switch))
(sit-for 1) (sit-for 1)
(mu4e~main-menu)))))) (mu4e--main-menu))))))
;;; _ ;;; _
(provide 'mu4e-main) (provide 'mu4e-main)

View File

@ -1,6 +1,6 @@
;;; mu4e-mark.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*- ;;; mu4e-mark.el -- part of mu4e -*- lexical-binding: t -*-
;; Copyright (C) 2011-2020 Dirk-Jan C. Binnema ;; Copyright (C) 2011-2022 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>
@ -27,9 +27,7 @@
;;; Code: ;;; Code:
(require 'cl-lib)
(require 'mu4e-server) (require 'mu4e-server)
(require 'mu4e-message) (require 'mu4e-message)
(require 'mu4e-folders) (require 'mu4e-folders)
@ -69,7 +67,7 @@ particularly fast).")
;;; Insert stuff ;;; Insert stuff
(defvar mu4e~mark-map nil (defvar mu4e--mark-map nil
"Contains a mapping of docid->markinfo. "Contains a mapping of docid->markinfo.
When a message is marked, the information is added here. markinfo When a message is marked, the information is added here. markinfo
is a cons cell consisting of the following: \(mark . target) is a cons cell consisting of the following: \(mark . target)
@ -83,30 +81,29 @@ TARGET (optional) is the target directory (for 'move')")
;; the fringe is the space on the left of headers, where we put marks below some ;; the fringe is the space on the left of headers, where we put marks below some
;; handy definitions; only `mu4e-mark-fringe-len' should be change (if ever), ;; handy definitions; only `mu4e-mark-fringe-len' should be change (if ever),
;; the others follow from that. ;; the others follow from that.
(defconst mu4e~mark-fringe-len 2 (defconst mu4e--mark-fringe-len 2
"Width of the fringe for marks on the left.") "Width of the fringe for marks on the left.")
(defconst mu4e~mark-fringe (make-string mu4e~mark-fringe-len ?\s) (defconst mu4e--mark-fringe (make-string mu4e--mark-fringe-len ?\s)
"The space on the left of message headers to put marks.") "The space on the left of message headers to put marks.")
(defconst mu4e~mark-fringe-format (format "%%-%ds" mu4e~mark-fringe-len) (defconst mu4e--mark-fringe-format (format "%%-%ds" mu4e--mark-fringe-len)
"Format string to set a mark and leave remaining space.") "Format string to set a mark and leave remaining space.")
(defun mu4e~mark-initialize () (defun mu4e--mark-initialize ()
"Initialize the marks-subsystem." "Initialize the marks-subsystem."
(set (make-local-variable 'mu4e~mark-map) (make-hash-table))) (set (make-local-variable 'mu4e--mark-map) (make-hash-table)))
(defun mu4e~mark-clear () (defun mu4e--mark-clear ()
"Clear the marks-subsystem." "Clear the marks-subsystem."
(clrhash mu4e~mark-map)) (clrhash mu4e--mark-map))
(defun mu4e~mark-find-headers-buffer () (defun mu4e--mark-find-headers-buffer ()
"Find the headers buffer, if any." "Find the headers buffer, if any."
(cl-find-if (seq-find (lambda (b)
(lambda (b) (with-current-buffer b
(with-current-buffer b (eq major-mode 'mu4e-headers-mode)))
(eq major-mode 'mu4e-headers-mode))) (buffer-list)))
(buffer-list)))
(defmacro mu4e~mark-in-context (&rest body) (defmacro mu4e--mark-in-context (&rest body)
"Evaluate BODY in the context of the headers buffer. "Evaluate BODY in the context of the headers buffer.
The current buffer must be either a headers or view buffer." The current buffer must be either a headers or view buffer."
`(cond `(cond
@ -122,7 +119,7 @@ The current buffer must be either a headers or view buffer."
(t (t
;; even in other modes (e.g. mu4e-main-mode we try to find ;; even in other modes (e.g. mu4e-main-mode we try to find
;; the headers buffer ;; the headers buffer
(let ((hbuf (mu4e~mark-find-headers-buffer))) (let ((hbuf (mu4e--mark-find-headers-buffer)))
(if (buffer-live-p hbuf) (if (buffer-live-p hbuf)
(with-current-buffer hbuf ,@body) (with-current-buffer hbuf ,@body)
,@body))))) ,@body)))))
@ -133,7 +130,7 @@ The current buffer must be either a headers or view buffer."
:prompt "refile" :prompt "refile"
:dyn-target (lambda (target msg) (mu4e-get-refile-folder msg)) :dyn-target (lambda (target msg) (mu4e-get-refile-folder msg))
:action (lambda (docid msg target) :action (lambda (docid msg target)
(mu4e--server-move docid (mu4e~mark-check-target target) "-N"))) (mu4e--server-move docid (mu4e--mark-check-target target) "-N")))
(delete (delete
:char ("D" . "x") :char ("D" . "x")
:prompt "Delete" :prompt "Delete"
@ -148,9 +145,9 @@ The current buffer must be either a headers or view buffer."
(move (move
:char ("m" . "") :char ("m" . "")
:prompt "move" :prompt "move"
:ask-target mu4e~mark-get-move-target :ask-target mu4e--mark-get-move-target
:action (lambda (docid msg target) :action (lambda (docid msg target)
(mu4e--server-move docid (mu4e~mark-check-target target) "-N"))) (mu4e--server-move docid (mu4e--mark-check-target target) "-N")))
(read (read
:char ("!" . "") :char ("!" . "")
:prompt "!read" :prompt "!read"
@ -160,8 +157,9 @@ The current buffer must be either a headers or view buffer."
:char ("d" . "") :char ("d" . "")
:prompt "dtrash" :prompt "dtrash"
:dyn-target (lambda (target msg) (mu4e-get-trash-folder msg)) :dyn-target (lambda (target msg) (mu4e-get-trash-folder msg))
:action (lambda (docid msg target) (mu4e--server-move docid :action (lambda (docid msg target)
(mu4e~mark-check-target target) "+T-N"))) (mu4e--server-move docid
(mu4e--mark-check-target target) "+T-N")))
(unflag (unflag
:char ("-" . "") :char ("-" . "")
:prompt "-unflag" :prompt "-unflag"
@ -254,7 +252,7 @@ The following marks are available, and the corresponding props:
(if mu4e-use-fancy-chars (cdr char) (car char)) (if mu4e-use-fancy-chars (cdr char) (car char))
char))) char)))
(markkar (funcall get-markkar (plist-get markdesc :char))) (markkar (funcall get-markkar (plist-get markdesc :char)))
(target (mu4e~mark-get-dyn-target mark target)) (target (mu4e--mark-get-dyn-target mark target))
(show-fct (plist-get markdesc :show-target)) (show-fct (plist-get markdesc :show-target))
(shown-target (if show-fct (shown-target (if show-fct
(funcall show-fct target) (funcall show-fct target)
@ -266,20 +264,21 @@ The following marks are available, and the corresponding props:
(when (mu4e~headers-mark docid markkar) (when (mu4e~headers-mark docid markkar)
;; update the hash -- remove everything current, and if add the new ;; update the hash -- remove everything current, and if add the new
;; stuff, unless we're unmarking ;; stuff, unless we're unmarking
(remhash docid mu4e~mark-map) (remhash docid mu4e--mark-map)
;; remove possible mark overlays ;; remove possible mark overlays
(remove-overlays (line-beginning-position) (line-end-position) 'mu4e-mark t) (remove-overlays (line-beginning-position) (line-end-position)
'mu4e-mark t)
;; now, let's set a mark (unless we were unmarking) ;; now, let's set a mark (unless we were unmarking)
(unless (eql mark 'unmark) (unless (eql mark 'unmark)
(puthash docid (cons mark target) mu4e~mark-map) (puthash docid (cons mark target) mu4e--mark-map)
;; when we have a target (ie., when moving), show the target folder in ;; when we have a target (ie., when moving), show the target folder in
;; an overlay ;; an overlay
(when (and shown-target mu4e-headers-show-target) (when (and shown-target mu4e-headers-show-target)
(let* ((targetstr (propertize (concat "-> " shown-target " ") (let* ((targetstr (propertize (concat "-> " shown-target " ")
'face 'mu4e-system-face)) 'face 'mu4e-system-face))
;; mu4e~headers-goto-docid docid t \will take us just after ;; mu4e~headers-goto-docid docid t \will take us just after
;; the docid cookie and then we skip the mu4e~mark-fringe ;; the docid cookie and then we skip the mu4e--mark-fringe
(start (+ (length mu4e~mark-fringe) (start (+ (length mu4e--mark-fringe)
(mu4e~headers-goto-docid docid t))) (mu4e~headers-goto-docid docid t)))
(overlay (make-overlay start (+ start (length targetstr))))) (overlay (make-overlay start (+ start (length targetstr)))))
(overlay-put overlay 'display targetstr) (overlay-put overlay 'display targetstr)
@ -287,7 +286,7 @@ The following marks are available, and the corresponding props:
(overlay-put overlay 'evaporate t) (overlay-put overlay 'evaporate t)
docid))))))) docid)))))))
(defun mu4e~mark-get-move-target () (defun mu4e--mark-get-move-target ()
"Ask for a move target, and propose to create it if it does not exist." "Ask for a move target, and propose to create it if it does not exist."
(interactive) (interactive)
;; (mu4e-message-at-point) ;; raises error if there is none ;; (mu4e-message-at-point) ;; raises error if there is none
@ -302,12 +301,12 @@ The following marks are available, and the corresponding props:
(mu4e--server-mkdir fulltarget))) (mu4e--server-mkdir fulltarget)))
target))) target)))
(defun mu4e~mark-ask-target (mark) (defun mu4e--mark-ask-target (mark)
"Ask the target for MARK, if the user should be asked the target." "Ask the target for MARK, if the user should be asked the target."
(let ((getter (plist-get (cdr (assq mark mu4e-marks)) :ask-target))) (let ((getter (plist-get (cdr (assq mark mu4e-marks)) :ask-target)))
(and getter (funcall getter)))) (and getter (funcall getter))))
(defun mu4e~mark-get-dyn-target (mark target) (defun mu4e--mark-get-dyn-target (mark target)
"Get the dynamic TARGET for MARK. "Get the dynamic TARGET for MARK.
The result may depend on the message at point." The result may depend on the message at point."
(let ((getter (plist-get (cdr (assq mark mu4e-marks)) :dyn-target))) (let ((getter (plist-get (cdr (assq mark mu4e-marks)) :dyn-target)))
@ -319,7 +318,7 @@ The result may depend on the message at point."
"Mark the header at point with MARK or all in the region. "Mark the header at point with MARK or all in the region.
Optionally, provide TARGET (for moves)." Optionally, provide TARGET (for moves)."
(unless target (unless target
(setq target (mu4e~mark-ask-target mark))) (setq target (mu4e--mark-ask-target mark)))
(if (not (use-region-p)) (if (not (use-region-p))
;; single message ;; single message
(mu4e-mark-at-point mark target) (mu4e-mark-at-point mark target)
@ -333,13 +332,13 @@ Optionally, provide TARGET (for moves)."
(defun mu4e-mark-restore (docid) (defun mu4e-mark-restore (docid)
"Restore the visual mark for the message with DOCID." "Restore the visual mark for the message with DOCID."
(let ((markcell (gethash docid mu4e~mark-map))) (let ((markcell (gethash docid mu4e--mark-map)))
(when markcell (when markcell
(save-excursion (save-excursion
(when (mu4e~headers-goto-docid docid) (when (mu4e~headers-goto-docid docid)
(mu4e-mark-at-point (car markcell) (cdr markcell))))))) (mu4e-mark-at-point (car markcell) (cdr markcell)))))))
(defun mu4e~mark-get-markpair (prompt &optional allow-something) (defun mu4e--mark-get-markpair (prompt &optional allow-something)
"Ask user with PROMPT for a mark and return (MARK . TARGET). "Ask user with PROMPT for a mark and return (MARK . TARGET).
If ALLOW-SOMETHING is non-nil, allow the 'something' pseudo mark If ALLOW-SOMETHING is non-nil, allow the 'something' pseudo mark
as well." as well."
@ -349,9 +348,9 @@ as well."
mu4e-marks)) mu4e-marks))
(marks (marks
(if allow-something (if allow-something
marks (cl-remove-if (lambda (m) (eq 'something (cdr m))) marks))) marks (seq-remove (lambda (m) (eq 'something (cdr m))) marks)))
(mark (mu4e-read-option prompt marks)) (mark (mu4e-read-option prompt marks))
(target (mu4e~mark-ask-target mark))) (target (mu4e--mark-ask-target mark)))
(cons mark target))) (cons mark target)))
(defun mu4e-mark-resolve-deferred-marks () (defun mu4e-mark-resolve-deferred-marks ()
@ -359,7 +358,7 @@ as well."
If there are such marks, replace them with a _real_ mark (ask the If there are such marks, replace them with a _real_ mark (ask the
user which one)." user which one)."
(interactive) (interactive)
(mu4e~mark-in-context (mu4e--mark-in-context
(let ((markpair)) (let ((markpair))
(maphash (maphash
(lambda (docid val) (lambda (docid val)
@ -367,13 +366,13 @@ user which one)."
(when (eql mark 'something) (when (eql mark 'something)
(unless markpair (unless markpair
(setq markpair (setq markpair
(mu4e~mark-get-markpair "Set deferred mark(s) to: " nil))) (mu4e--mark-get-markpair "Set deferred mark(s) to: " nil)))
(save-excursion (save-excursion
(when (mu4e~headers-goto-docid docid) (when (mu4e~headers-goto-docid docid)
(mu4e-mark-set (car markpair) (cdr markpair))))))) (mu4e-mark-set (car markpair) (cdr markpair)))))))
mu4e~mark-map)))) mu4e--mark-map))))
(defun mu4e~mark-check-target (target) (defun mu4e--mark-check-target (target)
"Check if TARGET exists; if not, offer to create it." "Check if TARGET exists; if not, offer to create it."
(let ((fulltarget (concat (mu4e-root-maildir) target))) (let ((fulltarget (concat (mu4e-root-maildir) target)))
(if (not (mu4e-create-maildir-maybe fulltarget)) (if (not (mu4e-create-maildir-maybe fulltarget))
@ -393,8 +392,8 @@ work well.
If NO-CONFIRMATION is non-nil, don't ask user for confirmation." If NO-CONFIRMATION is non-nil, don't ask user for confirmation."
(interactive "P") (interactive "P")
(mu4e~mark-in-context (mu4e--mark-in-context
(let* ((marknum (hash-table-count mu4e~mark-map)) (let* ((marknum (hash-table-count mu4e--mark-map))
(prompt (format "Are you sure you want to execute %d mark%s?" (prompt (format "Are you sure you want to execute %d mark%s?"
marknum (if (> marknum 1) "s" "")))) marknum (if (> marknum 1) "s" ""))))
(if (zerop marknum) (if (zerop marknum)
@ -417,34 +416,34 @@ If NO-CONFIRMATION is non-nil, don't ask user for confirmation."
(funcall (plist-get (cdr markdescr) :action) (funcall (plist-get (cdr markdescr) :action)
docid msg target)) docid msg target))
(mu4e-error "Unrecognized mark %S" mark)))) (mu4e-error "Unrecognized mark %S" mark))))
mu4e~mark-map)) mu4e--mark-map))
(mu4e-mark-unmark-all) (mu4e-mark-unmark-all)
(message nil))))) (message nil)))))
(defun mu4e-mark-unmark-all () (defun mu4e-mark-unmark-all ()
"Unmark all marked messages." "Unmark all marked messages."
(interactive) (interactive)
(mu4e~mark-in-context (mu4e--mark-in-context
(when (or (null mu4e~mark-map) (zerop (hash-table-count mu4e~mark-map))) (when (or (null mu4e--mark-map) (zerop (hash-table-count mu4e--mark-map)))
(mu4e-warn "Nothing is marked")) (mu4e-warn "Nothing is marked"))
(maphash (maphash
(lambda (docid _val) (lambda (docid _val)
(save-excursion (save-excursion
(when (mu4e~headers-goto-docid docid) (when (mu4e~headers-goto-docid docid)
(mu4e-mark-set 'unmark)))) (mu4e-mark-set 'unmark))))
mu4e~mark-map) mu4e--mark-map)
;; in any case, clear the marks map ;; in any case, clear the marks map
(mu4e~mark-clear))) (mu4e--mark-clear)))
(defun mu4e-mark-docid-marked-p (docid) (defun mu4e-mark-docid-marked-p (docid)
"Is the given DOCID marked?" "Is the given DOCID marked?"
(when (gethash docid mu4e~mark-map) t)) (when (gethash docid mu4e--mark-map) t))
(defun mu4e-mark-marks-num () (defun mu4e-mark-marks-num ()
"Return the number of mark-instances in the current buffer." "Return the number of mark-instances in the current buffer."
(mu4e~mark-in-context (mu4e--mark-in-context
(if mu4e~mark-map (hash-table-count mu4e~mark-map) 0))) (if mu4e--mark-map (hash-table-count mu4e--mark-map) 0)))
(defun mu4e-mark-handle-when-leaving () (defun mu4e-mark-handle-when-leaving ()
"Handle any mark-instances in the current buffer when leaving. "Handle any mark-instances in the current buffer when leaving.
@ -452,7 +451,7 @@ This is done according to the value of `mu4e-headers-leave-behavior'. This
function is to be called before any further action (like searching, function is to be called before any further action (like searching,
quitting the buffer) is taken; returning t means 'take the following quitting the buffer) is taken; returning t means 'take the following
action', return nil means 'don't do anything'." action', return nil means 'don't do anything'."
(mu4e~mark-in-context (mu4e--mark-in-context
(let ((marknum (mu4e-mark-marks-num)) (let ((marknum (mu4e-mark-marks-num))
(what mu4e-headers-leave-behavior)) (what mu4e-headers-leave-behavior))
(unless (zerop marknum) ;; nothing to do? (unless (zerop marknum) ;; nothing to do?

View File

@ -1,6 +1,6 @@
;;; mu4e-message.el -- part of mu4e -*- lexical-binding: t -*- ;;; mu4e-message.el -- part of mu4e -*- lexical-binding: t -*-
;; Copyright (C) 2012-2020 Dirk-Jan C. Binnema ;; Copyright (C) 2012-2022 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>
@ -26,7 +26,6 @@
;;; Code: ;;; Code:
(require 'cl-lib)
(require 'mu4e-vars) (require 'mu4e-vars)
(require 'flow-fill) (require 'flow-fill)
(require 'shr) (require 'shr)
@ -36,9 +35,6 @@
(declare-function mu4e-personal-address-p "mu4e-contacts") (declare-function mu4e-personal-address-p "mu4e-contacts")
(declare-function mu4e-make-temp-file "mu4e-helpers") (declare-function mu4e-make-temp-file "mu4e-helpers")
(defvar mu4e~view-message)
(defvar shr-inhibit-images)
(make-obsolete-variable 'mu4e-html2text-command "No longer in use" "1.7.0") (make-obsolete-variable 'mu4e-html2text-command "No longer in use" "1.7.0")
(make-obsolete-variable 'mu4e-view-prefer-html "No longer in use" "1.7.0") (make-obsolete-variable 'mu4e-view-prefer-html "No longer in use" "1.7.0")
(make-obsolete-variable 'mu4e-view-html-plaintext-ratio-heuristic (make-obsolete-variable 'mu4e-view-html-plaintext-ratio-heuristic
@ -151,11 +147,11 @@ expressions, in which case any of those are tried for a match."
(when cfield (when cfield
(if (listp rx) (if (listp rx)
;; if rx is a list, try each one of them for a match ;; if rx is a list, try each one of them for a match
(cl-find-if (seq-find
(lambda (a-rx) (mu4e-message-contact-field-matches msg cfield a-rx)) (lambda (a-rx) (mu4e-message-contact-field-matches msg cfield a-rx))
rx) rx)
;; not a list, check the rx ;; not a list, check the rx
(cl-find-if (seq-find
(lambda (ct) (lambda (ct)
(let ((name (car ct)) (email (cdr ct)) (let ((name (car ct)) (email (cdr ct))
;; the 'rx' may be some `/rx/` from mu4e-personal-addresses; ;; the 'rx' may be some `/rx/` from mu4e-personal-addresses;
@ -174,8 +170,8 @@ of the of the contacts in field CFIELD (either :to, :from, :cc or
:bcc) of msg MSG matches *me*, that is, any of the addresses for :bcc) of msg MSG matches *me*, that is, any of the addresses for
which `mu4e-personal-address-p' return t. Returns the contact which `mu4e-personal-address-p' return t. Returns the contact
cell that matched, or nil." cell that matched, or nil."
(cl-find-if (lambda (cell) (mu4e-personal-address-p (cdr cell))) (seq-find (lambda (cell) (mu4e-personal-address-p (cdr cell)))
(mu4e-message-field msg cfield))) (mu4e-message-field msg cfield)))
(defun mu4e-message-sent-by-me (msg) (defun mu4e-message-sent-by-me (msg)
"Is this MSG (to be) sent by me? "Is this MSG (to be) sent by me?
@ -186,7 +182,7 @@ Checks if the from field matches user's personal addresses."
"Does MSG have user's personal address? "Does MSG have user's personal address?
In any of the contact In any of the contact
fields?" fields?"
(cl-some (seq-some
(lambda (field) (lambda (field)
(mu4e-message-contact-field-matches-me msg field)) (mu4e-message-contact-field-matches-me msg field))
'(:from :to :cc :bcc))) '(:from :to :cc :bcc)))
@ -212,8 +208,7 @@ symbol, see `mu4e-header-info'."
(defun mu4e-message-readable-path (&optional msg) (defun mu4e-message-readable-path (&optional msg)
"Get a readable path to MSG or raise an error. "Get a readable path to MSG or raise an error.
If MSG is nil, use mu4e-message-at-point. If MSG is nil, use `mu4e-message-at-point'."
"
(let ((path (plist-get (or msg (mu4e-message-at-point)) :path))) (let ((path (plist-get (or msg (mu4e-message-at-point)) :path)))
(unless (file-readable-p path) (unless (file-readable-p path)
(mu4e-error "No readable message at %s; database outdated?" path)) (mu4e-error "No readable message at %s; database outdated?" path))
@ -226,6 +221,6 @@ If MSG is nil, use mu4e-message-at-point.
(kill-new path) (kill-new path)
(mu4e-message "Saved '%s' to kill-ring" path))) (mu4e-message "Saved '%s' to kill-ring" path)))
;;; _ ;;;
(provide 'mu4e-message) (provide 'mu4e-message)
;;; mu4e-message.el ends here ;;; mu4e-message.el ends here

View File

@ -27,7 +27,6 @@
;;; Code: ;;; Code:
(require 'seq) (require 'seq)
(require 'cl-lib)
(require 'mu4e-helpers) (require 'mu4e-helpers)
(require 'mu4e-message) (require 'mu4e-message)
(require 'mu4e-bookmarks) (require 'mu4e-bookmarks)
@ -295,9 +294,9 @@ WHERE is a symbol telling us where to push; it's a symbol, either
'future or 'past. Functional also removes duplicates, limits the 'future or 'past. Functional also removes duplicates, limits the
stack size." stack size."
(let ((stack (let ((stack
(cl-case where (pcase where
(past mu4e--search-query-past) ('past mu4e--search-query-past)
(future mu4e--search-query-future)))) ('future mu4e--search-query-future))))
;; only add if not the same item ;; only add if not the same item
(unless (and stack (string= (car stack) query)) (unless (and stack (string= (car stack) query))
(push query stack) (push query stack)
@ -305,22 +304,22 @@ stack size."
(when (> (length stack) mu4e--search-query-stack-size) (when (> (length stack) mu4e--search-query-stack-size)
(setq stack (cl-subseq stack 0 mu4e--search-query-stack-size))) (setq stack (cl-subseq stack 0 mu4e--search-query-stack-size)))
;; remove all duplicates of the new element ;; remove all duplicates of the new element
(cl-remove-if (lambda (elm) (string= elm (car stack))) (cdr stack)) (seq-remove (lambda (elm) (string= elm (car stack))) (cdr stack))
;; update the stacks ;; update the stacks
(cl-case where (pcase where
(past (setq mu4e--search-query-past stack)) ('past (setq mu4e--search-query-past stack))
(future (setq mu4e--search-query-future stack)))))) ('future (setq mu4e--search-query-future stack))))))
(defun mu4e--search-pop-query (whence) (defun mu4e--search-pop-query (whence)
"Pop a query from the stack. "Pop a query from the stack.
WHENCE is a symbol telling us where to get it from, either `future' WHENCE is a symbol telling us where to get it from, either `future'
or `past'." or `past'."
(cl-case whence (pcase whence
(past ('past
(unless mu4e--search-query-past (unless mu4e--search-query-past
(mu4e-warn "No more previous queries")) (mu4e-warn "No more previous queries"))
(pop mu4e--search-query-past)) (pop mu4e--search-query-past))
(future ('future
(unless mu4e--search-query-future (unless mu4e--search-query-future
(mu4e-warn "No more next queries")) (mu4e-warn "No more next queries"))
(pop mu4e--search-query-future)))) (pop mu4e--search-query-future))))

View File

@ -1,6 +1,6 @@
;;; mu4e-vars.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*- ;;; mu4e-vars.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*-
;; Copyright (C) 2011-2021 Dirk-Jan C. Binnema ;; Copyright (C) 2011-2022 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>
@ -34,7 +34,8 @@
:group 'mail) :group 'mail)
(defcustom mu4e-headers-include-related t (defcustom mu4e-headers-include-related t
"With this option set to non-nil, not just return the matches for "Wether to include 'related' messages in queries.
With this option set to non-nil, not just return the matches for
a searches, but also messages that are related (through their a searches, but also messages that are related (through their
references) to these messages. This can be useful e.g. to include references) to these messages. This can be useful e.g. to include
sent messages into message threads." sent messages into message threads."
@ -42,7 +43,8 @@ sent messages into message threads."
:group 'mu4e-headers) :group 'mu4e-headers)
(defcustom mu4e-headers-skip-duplicates t (defcustom mu4e-headers-skip-duplicates t
"With this option set to non-nil, show only one of duplicate "Whether to skip duplicate messages.
With this option set to non-nil, show only one of duplicate
messages. This is useful when you have multiple copies of the same messages. This is useful when you have multiple copies of the same
message, which is a common occurrence for example when using Gmail message, which is a common occurrence for example when using Gmail
and offlineimap." and offlineimap."
@ -75,7 +77,7 @@ Follows the format of `format-time-string'."
(defface mu4e-draft-face (defface mu4e-draft-face
'((t :inherit font-lock-string-face)) '((t :inherit font-lock-string-face))
"Face for a draft message header "Face for a draft message header.
I.e. a message with the draft flag set." I.e. a message with the draft flag set."
:group 'mu4e-faces) :group 'mu4e-faces)
@ -155,11 +157,6 @@ I.e. a message with the draft flag set."
"Face for the query in the mode-line." "Face for the query in the mode-line."
:group 'mu4e-faces) :group 'mu4e-faces)
(defface mu4e-view-body-face
'((t :inherit default))
"Face for the body in the message-view."
:group 'mu4e-faces)
(defface mu4e-footer-face (defface mu4e-footer-face
'((t :inherit font-lock-comment-face)) '((t :inherit font-lock-comment-face))
"Face for message footers (signatures)." "Face for message footers (signatures)."
@ -170,47 +167,6 @@ I.e. a message with the draft flag set."
"Face for the number tags for URLs." "Face for the number tags for URLs."
:group 'mu4e-faces) :group 'mu4e-faces)
(defface mu4e-attach-number-face
'((t :inherit font-lock-variable-name-face :weight bold))
"Face for the number tags for attachments."
:group 'mu4e-faces)
(defface mu4e-cited-1-face
'((t :inherit font-lock-builtin-face :weight normal :slant italic))
"Face for cited message parts (level 1)."
:group 'mu4e-faces)
(defface mu4e-cited-2-face
'((t :inherit font-lock-preprocessor-face :weight normal :slant italic))
"Face for cited message parts (level 2)."
:group 'mu4e-faces)
(defface mu4e-cited-3-face
'((t :inherit font-lock-variable-name-face :weight normal :slant italic))
"Face for cited message parts (level 3)."
:group 'mu4e-faces)
(defface mu4e-cited-4-face
'((t :inherit font-lock-keyword-face :weight normal :slant italic))
"Face for cited message parts (level 4)."
:group 'mu4e-faces)
(defface mu4e-cited-5-face
'((t :inherit font-lock-comment-face :weight normal :slant italic))
"Face for cited message parts (level 5)."
:group 'mu4e-faces)
(defface mu4e-cited-6-face
'((t :inherit font-lock-comment-delimiter-face :weight normal :slant italic))
"Face for cited message parts (level 6)."
:group 'mu4e-faces)
(defface mu4e-cited-7-face
'((t :inherit font-lock-type-face :weight normal :slant italic
))
"Face for cited message parts (level 7)."
:group 'mu4e-faces)
(defface mu4e-system-face (defface mu4e-system-face
'((t :inherit font-lock-comment-face :slant italic)) '((t :inherit font-lock-comment-face :slant italic))
"Face for system message (such as the footers for message headers)." "Face for system message (such as the footers for message headers)."
@ -228,14 +184,7 @@ I.e. a message with the draft flag set."
(defface mu4e-compose-separator-face (defface mu4e-compose-separator-face
'((t :inherit message-separator :slant italic)) '((t :inherit message-separator :slant italic))
"Face for the separator between headers / message in "Face for the headers/message separator in mu4e-compose-mode."
mu4e-compose-mode."
:group 'mu4e-faces)
(defface mu4e-compose-header-face
'((t :inherit message-separator :slant italic))
"Face for the separator between headers / message in
mu4e-compose-mode."
:group 'mu4e-faces) :group 'mu4e-faces)
(defface mu4e-region-code (defface mu4e-region-code
@ -380,31 +329,34 @@ Note, `:sortable' is not supported for custom header fields.")
'( '(
;; some examples & debug helpers. ;; some examples & debug helpers.
(:thread-path . ;; Shows the internal thread-path (:thread-path
( :name "Thread-path" . ;; Shows the internal thread-path
:shortname "Thp" ( :name "Thread-path"
:help "The thread-path" :shortname "Thp"
:function (lambda (msg) :help "The thread-path"
(let ((thread (mu4e-message-field msg :thread))) :function (lambda (msg)
(or (and thread (plist-get thread :path)) ""))))) (let ((thread (mu4e-message-field msg :thread)))
(or (and thread (plist-get thread :path)) "")))))
(:thread-date . ;; Shows the internal thread-date (:thread-date
( :name "Thread-date" . ;; Shows the internal thread-date
:shortname "Thd" ( :name "Thread-date"
:help "The thread-date" :shortname "Thd"
:function (lambda (msg) :help "The thread-date"
(let* ((thread (mu4e-message-field msg :thread)) :function (lambda (msg)
(tdate (and thread (plist-get thread :date-tstamp)))) (let* ((thread (mu4e-message-field msg :thread))
(format-time-string "%F %T " (or tdate 0)))))) (tdate (and thread (plist-get thread :date-tstamp))))
(:recipnum . (format-time-string "%F %T " (or tdate 0))))))
( :name "Number of recipients" (:recipnum
:shortname "Recip#" .
:help "Number of recipients for this message" ( :name "Number of recipients"
:function :shortname "Recip#"
(lambda (msg) :help "Number of recipients for this message"
(format "%d" :function
(+ (length (mu4e-message-field msg :to)) (lambda (msg)
(length (mu4e-message-field msg :cc)))))))) (format "%d"
(+ (length (mu4e-message-field msg :to))
(length (mu4e-message-field msg :cc))))))))
"A list of custom (user-defined) headers. "A list of custom (user-defined) headers.
The format is similar to `mu4e-header-info', but adds a :function The format is similar to `mu4e-header-info', but adds a :function

View File

@ -770,20 +770,21 @@ determine which browser function to use."
(narrow-to-region (point) (point)) (narrow-to-region (point) (point))
(dolist (field mu4e-view-fields) (dolist (field mu4e-view-fields)
(let ((fieldval (mu4e-message-field msg field))) (let ((fieldval (mu4e-message-field msg field)))
(cl-case field (pcase field
((:path :maildir :user-agent :mailing-list :message-id) ((or ':path ':maildir ':user-agent ':mailing-list ':message-id)
(mu4e~view-gnus-insert-header field fieldval)) (mu4e~view-gnus-insert-header field fieldval))
((:flags :tags) ((or ':flags ':tags)
(let ((flags (mapconcat (lambda (flag) (let ((flags (mapconcat (lambda (flag)
(if (symbolp flag) (if (symbolp flag)
(symbol-name flag) (symbol-name flag)
flag)) fieldval ", "))) flag)) fieldval ", ")))
(mu4e~view-gnus-insert-header field flags))) (mu4e~view-gnus-insert-header field flags)))
(:size (mu4e~view-gnus-insert-header (':size (mu4e~view-gnus-insert-header
field (mu4e-display-size fieldval))) field (mu4e-display-size fieldval)))
((:subject :to :from :cc :bcc :from-or-to :date :attachments ((or ':subject ':to ':from ':cc ':bcc ':from-or-to
:signature :decryption)) ; handled by Gnus ':date :attachments ':signature
(t ':decryption)) ; handled by Gnus
(_
(mu4e~view-gnus-insert-header-custom msg field))))) (mu4e~view-gnus-insert-header-custom msg field)))))
(let ((gnus-treatment-function-alist (let ((gnus-treatment-function-alist
'((gnus-treat-highlight-headers '((gnus-treat-highlight-headers
@ -1231,7 +1232,7 @@ the third MIME-part."
(mapcar (lambda (action) `(,(plist-get action :name) . ,action)) (mapcar (lambda (action) `(,(plist-get action :name) . ,action))
mu4e-view-mime-part-actions)) mu4e-view-mime-part-actions))
(handle (handle
(or (cdr-safe (cl-find-if (lambda (part) (eq (car part) n)) parts)) (or (cdr-safe (seq-find (lambda (part) (eq (car part) n)) parts))
(mu4e-error "MIME-part %s not found" n))) (mu4e-error "MIME-part %s not found" n)))
(action (action
(or (and options (mu4e-read-option "Action on MIME-part: " options)) (or (and options (mu4e-read-option "Action on MIME-part: " options))

View File

@ -73,7 +73,7 @@ is non-nil."
(interactive "P") (interactive "P")
;; start mu4e, then show the main view ;; start mu4e, then show the main view
(mu4e--init-handlers) (mu4e--init-handlers)
(mu4e--start (unless background 'mu4e~main-view))) (mu4e--start (unless background 'mu4e--main-view)))
(defun mu4e-quit() (defun mu4e-quit()
"Quit the mu4e session." "Quit the mu4e session."
@ -183,13 +183,13 @@ invoke
(defun mu4e--error-handler (errcode errmsg) (defun mu4e--error-handler (errcode errmsg)
"Handler function for showing an error with ERRCODE and ERRMSG." "Handler function for showing an error with ERRCODE and ERRMSG."
;; don't use mu4e-error here; it's running in the process filter context ;; don't use mu4e-error here; it's running in the process filter context
(cl-case errcode (pcase errcode
(4 (mu4e-warn "No matches for this search query.")) ('4 (mu4e-warn "No matches for this search query."))
(110 (display-warning 'mu4e errmsg :error)) ;; schema version. ('110 (display-warning 'mu4e errmsg :error)) ;; schema version.
(t (mu4e-error "Error %d: %s" errcode errmsg)))) (_ (mu4e-error "Error %d: %s" errcode errmsg))))
(defun mu4e--update-status (info) (defun mu4e--update-status (info)
"Update the status message." "Update the status message with INFO."
(setq mu4e-index-update-status (setq mu4e-index-update-status
`(:tstamp ,(current-time) `(:tstamp ,(current-time)
:checked ,(plist-get info :checked) :checked ,(plist-get info :checked)
@ -225,7 +225,7 @@ invoke
(when (and (buffer-live-p mainbuf) (get-buffer-window mainbuf)) (when (and (buffer-live-p mainbuf) (get-buffer-window mainbuf))
(save-window-excursion (save-window-excursion
(select-window (get-buffer-window mainbuf)) (select-window (get-buffer-window mainbuf))
(mu4e~main-view 'refresh)))))) (mu4e--main-view 'refresh))))))
((plist-get info :message) ((plist-get info :message)
(mu4e-index-message "%s" (plist-get info :message)))))) (mu4e-index-message "%s" (plist-get info :message))))))