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 -*-
;; Copyright (C) 2011-2021 Dirk-Jan C. Binnema
;; Copyright (C) 2011-2022 Dirk-Jan C. Binnema
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
@ -27,7 +27,6 @@
;;; Code:
(require 'cl-lib)
(require 'ido)
(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>
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
@ -23,7 +23,6 @@
;;; Commentary:
;;; Code:
(require 'cl-lib)
(require 'mu4e-helpers)
@ -33,18 +32,6 @@
"Settings for bookmarks."
: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
'(( :name "Unread messages"
: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.
Optionally, you can add the following:
`:hide' - if t, the bookmark is hidden from the main-view and
speedbar.
`:hide-unread' - do not show the counts of unread/total number
of matches for the query in the main-view. This can be useful
if a bookmark uses a very slow query. :hide-unread
is implied from :hide. Furthermore, it is implied if
`:query' is a function.
Optionally, you can add the following: `:hide' - if t, the
bookmark is hidden from the main-view and speedbar.
`:hide-unread' - do not show the counts of unread/total number of
matches for the query in the main-view. This can be useful if a
bookmark uses a very slow query.
Queries used to determine the unread/all counts do _not_ apply
`mu4e-query-rewrite-function'; nor do they discard duplicate or
unreadable messages (for efficiency). Thus, the numbers shown may
differ from the number you get from a 'real' query."
`:hide-unread' is implied from `:hide'. Furthermore, it is
implied when `:query' is a function.
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))
:version "1.3.9"
: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.
Raise an error if none is found."
(let* ((chosen-bm
(or (cl-find-if
(or (seq-find
(lambda (bm)
(= kar (plist-get bm :key)))
(mu4e-bookmarks))
@ -125,7 +111,7 @@ Raise an error if none is found."
Append it to `mu4e-bookmarks'. Replaces any existing bookmark
with KEY."
(setq mu4e-bookmarks
(cl-remove-if
(seq-remove
(lambda (bm)
(= (plist-get bm :key) key))
(mu4e-bookmarks)))
@ -137,14 +123,11 @@ with KEY."
(defun mu4e-bookmarks ()
"Get `mu4e-bookmarks' in the (new) format.
Convert from the old format if needed."
(cl-map 'list
(lambda (item)
(if (and (listp item) (= (length item) 3))
`(:name ,(nth 1 item)
:query ,(nth 0 item)
:key ,(nth 2 item))
item))
mu4e-bookmarks))
(seq-map (lambda (item)
(if (and (listp item) (= (length item) 3))
`(:name ,(nth 1 item) :query ,(nth 0 item)
:key ,(nth 2 item))
item)) mu4e-bookmarks))
(provide 'mu4e-bookmarks)
;;; mu4e-bookmarks.el ends here

View File

@ -1,6 +1,6 @@
;;; 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>
;; 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)
mu4e-sent-messages-behavior)))
(mdir
(cl-case sent-behavior
(delete nil)
(trash (mu4e-get-trash-folder mu4e-compose-parent-message))
(sent (mu4e-get-sent-folder mu4e-compose-parent-message))
(otherwise
(mu4e-error "Unsupported value '%S'
`mu4e-sent-messages-behavior'"
mu4e-sent-messages-behavior))))
(pcase sent-behavior
('delete nil)
('trash (mu4e-get-trash-folder mu4e-compose-parent-message))
('sent (mu4e-get-sent-folder mu4e-compose-parent-message))
(_ (mu4e-error
"Unsupported value %S for `mu4e-sent-messages-behavior'"
mu4e-sent-messages-behavior))))
(fccfile (and mdir
(concat (mu4e-root-maildir) mdir "/cur/"
(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"))
(subj (unless (and subj (string-match "^[:blank:]*$" subj)) subj))
(str (or subj
(cl-case compose-type
(reply "*reply*")
(forward "*forward*")
(otherwise "*draft*")))))
(pcase compose-type
('reply "*reply*")
('forward "*forward*")
(_ "*draft*")))))
(rename-buffer (generate-new-buffer-name
(truncate-string-to-width
str mu4e~compose-buffer-max-name-length)
@ -586,12 +585,9 @@ are optional."
(if (member compose-type '(new forward))
(message-goto-to)
;; otherwise, it depends...
(cl-case message-cite-reply-position
((above traditional)
(message-goto-body))
(t
(when (message-goto-signature)
(forward-line -2)))))
(pcase message-cite-reply-position
((or 'above 'traditional) (message-goto-body))
(_ (when (message-goto-signature) (forward-line -2)))))
;; bind to `mu4e-compose-parent-message' of compose buffer
(set (make-local-variable 'mu4e-compose-parent-message) original-msg)
@ -729,7 +725,7 @@ buffer."
(while (re-search-forward "<[^ <]+@[^ <]+>" nil t)
(push (match-string 0) refs))
;; the last will be the first
(setq forwarded-from (cl-first refs))))))
(setq forwarded-from (car refs))))))
;; remove the <>
(when (and in-reply-to (string-match "<\\(.*\\)>" in-reply-to))
(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 -*-
;; Copyright (C) 2015-2021 Dirk-Jan C. Binnema
;; Copyright (C) 2015-2022 Dirk-Jan C. Binnema
;; Author: 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)
"Let user choose some context based on its name with PROMPT."
(when mu4e-contexts
(let* ((names (cl-map 'list (lambda (context)
(cons (mu4e-context-name context) context))
(let* ((names (seq-map (lambda (context)
(cons (mu4e-context-name context) context))
mu4e-contexts))
(context (mu4e-read-option prompt names)))
(or context (mu4e-error "No such context")))))
@ -130,8 +130,8 @@ non-nil."
(interactive "P")
(unless mu4e-contexts
(mu4e-error "No contexts defined"))
(let* ((names (cl-map 'list (lambda (context)
(cons (mu4e-context-name context) context))
(let* ((names (seq-map (lambda (context)
(cons (mu4e-context-name context) context))
mu4e-contexts))
(context
(if name
@ -191,17 +191,17 @@ match, POLICY determines what to do:
(if (eq policy 'always-ask)
(mu4e--context-ask-user "Select context: ")
(or ;; is there a matching one?
(cl-find-if (lambda (context)
(when (mu4e-context-match-func context)
(funcall (mu4e-context-match-func context) msg)))
mu4e-contexts)
(seq-find (lambda (context)
(when (mu4e-context-match-func context)
(funcall (mu4e-context-match-func context) msg)))
mu4e-contexts)
;; no context found yet; consult policy
(cl-case policy
(pick-first (car mu4e-contexts))
(ask (mu4e--context-ask-user "Select context: "))
(ask-if-none (or (mu4e-context-current)
(pcase policy
('pick-first (car mu4e-contexts))
('ask (mu4e--context-ask-user "Select context: "))
('ask-if-none (or (mu4e-context-current)
(mu4e--context-ask-user "Select context: ")))
(otherwise nil))))))
(_ nil))))))
(defun mu4e-context-in-modeline ()
"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 -*-
;; Copyright (C) 2021 Dirk-Jan C. Binnema
;; Copyright (C) 2021-2022 Dirk-Jan C. Binnema
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
@ -25,7 +25,6 @@
;; Dealing with maildirs & folders
;;; Code:
(require 'cl-lib)
(require 'mu4e-helpers)
(require 'mu4e-context)
(require 'mu4e-server)
@ -148,32 +147,23 @@ mime-type are nill."
(defun mu4e-maildir-shortcuts ()
"Get `mu4e-maildir-shortcuts' in the (new) format.
Converts from the old format if needed."
(cl-map 'list
(lambda (item) ;; convert from old format?
(if (and (consp item) (not (consp (cdr item))))
`(:maildir ,(car item) :key ,(cdr item))
item))
mu4e-maildir-shortcuts))
(seq-map (lambda (item) ;; convert from old format?
(if (and (consp item) (not (consp (cdr item))))
`(:maildir ,(car item) :key ,(cdr item))
item))
mu4e-maildir-shortcuts))
(defun mu4e--maildirs-with-query ()
"Llike `mu4e-maildir-shortcuts', but with :query populated.
This is meant to be the exact same data structure as
`mu4e-bookmarks'."
(cl-mapcar
(lambda (m)
(append
;; we want to change the :maildir key to :name, and add a :query key
(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))))
"Like `mu4e-maildir-shortcuts', but with :query populated.
This is compatibile with `mu4e-bookmarks'."
(seq-map
(lambda (item)
(let* ((maildir (plist-get item :maildir))
(item (plist-put item :name maildir))
(item (plist-put item :query (format "maildir:\"%s\"" maildir))))
item)) ;; we don't need ":maildir", but it's harmless.
(mu4e-maildir-shortcuts)))
;; the standard folders can be functions too
(defun mu4e--get-folder (foldervar msg)
"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
(mu4e-get-maildirs) nil nil "/"))
(or (plist-get
(cl-find-if (lambda (item) (= kar (plist-get item :key)))
(mu4e-maildir-shortcuts)) :maildir)
(seq-find (lambda (item) (= kar (plist-get item :key)))
(mu4e-maildir-shortcuts)) :maildir)
(mu4e-warn "Unknown shortcut '%c'" kar)))))))
(defun mu4e-ask-maildir-check-exists (prompt)
@ -333,21 +323,19 @@ Offer to create it if it does not exist yet."
;; be nil
(defun mu4e~get-attachment-dir (&optional fname mimetype)
"Get the directory for saving attachments from
`mu4e-attachment-dir' (which can be either a string or a function,
see its docstring)."
(let
((dir
(cond
((stringp mu4e-attachment-dir)
mu4e-attachment-dir)
((functionp mu4e-attachment-dir)
(funcall mu4e-attachment-dir fname mimetype))
(t
(mu4e-error "unsupported type for mu4e-attachment-dir" )))))
"Get the directory for saving attachments from `mu4e-attachment-dir'.
This is optionally based on the file-name FNAME and its MIMETYPE."
(let ((dir
(cond
((stringp mu4e-attachment-dir)
mu4e-attachment-dir)
((functionp mu4e-attachment-dir)
(funcall mu4e-attachment-dir fname mimetype))
(t
(mu4e-error "Unsupported type for mu4e-attachment-dir" )))))
(if dir
(expand-file-name dir)
(mu4e-error "mu4e-attachment-dir evaluates to nil"))))
(mu4e-error "Mu4e-attachment-dir evaluates to nil"))))
(provide 'mu4e-folders)
;;; mu4e-folders.el ends here

View File

@ -50,7 +50,7 @@
(require 'mu4e-folders)
(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))
(let ((inhibit-read-only t))
(with-current-buffer (mu4e-get-headers-buffer)
(mu4e~mark-clear)
(mu4e--mark-clear)
(erase-buffer)
(when msg
(goto-char (point-min))
@ -667,7 +667,7 @@ displaying in the header view."
(propertize
(concat
(mu4e~headers-docid-cookie docid)
mu4e~mark-fringe line "\n")
mu4e--mark-fringe line "\n")
'docid docid 'msg msg))))
(defun mu4e~headers-remove-header (docid &optional ignore-missing)
@ -722,7 +722,7 @@ headers."
(initial-column (current-column))
(inhibit-read-only t)
(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?
;; 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")))
(cons
(make-string
(+ mu4e~mark-fringe-len (floor (fringe-columns 'left t))) ?\s)
(+ mu4e--mark-fringe-len (floor (fringe-columns 'left t))) ?\s)
(mapcar
(lambda (item)
(let* ( ;; with threading enabled, we're necessarily sorting by date.
@ -1179,7 +1179,7 @@ The following specs are supported:
overwrite-mode nil
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-update-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.
(let ((msg (get-text-property (point) 'msg)))
(delete-char mu4e~mark-fringe-len)
(delete-char mu4e--mark-fringe-len)
(insert (propertize
(format mu4e~mark-fringe-format mark)
(format mu4e--mark-fringe-format mark)
'face 'mu4e-header-marks-face
'docid docid
'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
matching messages with that mark."
(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: "
'( ("subject" . :subject)
("from" . :from)
@ -1404,7 +1404,7 @@ matching messages with that mark."
(let* ((pred (mu4e-read-option "Match function: "
mu4e-headers-custom-markers))
(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)))
(defun mu4e~headers-get-thread-info (msg what)
@ -1464,7 +1464,7 @@ descendants."
(list current-prefix-arg
;; FIXME: e.g., for refiling we should evaluate this
;; for each line separately
(mu4e~mark-get-markpair
(mu4e--mark-get-markpair
(if subthread "Mark subthread with: " "Mark whole thread with: ")
t))))
(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
;; to the main view
(kill-buffer)
(mu4e~main-view 'refresh))))
(mu4e--main-view 'refresh))))
;;; Loading messages

View File

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

View File

@ -26,8 +26,6 @@
;; The shortname (friendly) should a at most 8 characters, camel-case
;;; Code:
(require 'cl-lib)
;;; Configuration
(defvar mu4e-mailing-lists
@ -118,9 +116,9 @@ Based on `mu4e-mailing-lists', `mu4e-user-mailing-lists', and
(or
(gethash list-id mu4e--lists-hash)
(and (boundp 'mu4e-mailing-list-patterns)
(cl-member-if
(seq-drop-while
(lambda (pattern)
(string-match pattern list-id))
(not (string-match pattern list-id)))
mu4e-mailing-list-patterns)
(match-string 1 list-id))
;; 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 -*-
;; Copyright (C) 2011-2021 Dirk-Jan C. Binnema
;; Copyright (C) 2011-2022 Dirk-Jan C. Binnema
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
@ -36,7 +36,6 @@
(require 'cl-lib)
;; Configuration
@ -45,21 +44,19 @@
'mu4e-main-hide-personal-addresses "1.5.7")
(defvar mu4e-main-hide-personal-addresses nil
"Whether to hide the personal address in the main view. This
can be useful to avoid the noise when there are many.
"Whether to hide the personal address in the main view.
This also hides the warning if your `user-mail-address' is not
part of the personal addresses.")
This can be useful to avoid the noise when there are many, and
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.")
"Whether to hide bookmarks or maildirs without unread messages.")
;;; Mode
(define-derived-mode mu4e-org-mode org-mode "mu4e:org"
"Major mode for mu4e documents, derived from
`org-mode'.")
"Major mode for mu4e documents.")
(defun mu4e-info (path)
"Show a buffer with the information (an org-file) at PATH."
@ -90,10 +87,10 @@ no unread messages.")
(let ((map (make-sparse-keymap)))
(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 "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 "U" 'mu4e-update-mail-and-index)
@ -121,10 +118,10 @@ no unread messages.")
(mu4e-context-minor-mode)
(mu4e-search-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.
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
@ -165,7 +162,8 @@ clicked."
(mu4e--maildirs-with-query))
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...
(cl-loop with bmks = (mu4e-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)))
concat (concat
;; menu entry
(mu4e~main-action-str
(mu4e--main-action-str
(concat "\t* [b" key "] " name)
(concat "b" key))
;; append all/unread numbers, if available.
@ -204,7 +202,7 @@ clicked."
"\n")))
(defun mu4e~main-maildirs ()
(defun mu4e--main-maildirs ()
"Return a string of maildirs with their counts."
(cl-loop with mds = (mu4e--maildirs-with-query)
with longest = (mu4e--longest-of-maildirs-and-bookmarks)
@ -226,7 +224,7 @@ clicked."
when (not (and mu4e-main-hide-fully-read (eq unread 0)))
concat (concat
;; menu entry
(mu4e~main-action-str
(mu4e--main-action-str
(concat "\t* [j" key "] " name)
(concat "j" key))
;; append all/unread numbers, if available.
@ -243,8 +241,8 @@ clicked."
"\n")))
(defun mu4e~key-val (key val &optional unit)
"Return a key / value pair."
(defun mu4e--key-val (key val &optional unit)
"Show a KEY / VAL pair, with optional UNIT."
(concat
"\t* "
(propertize (format "%-20s" key) 'face 'mu4e-header-title-face)
@ -255,24 +253,24 @@ clicked."
"")
"\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.
(defun mu4e~main-view-real (_ignore-auto _noconfirm)
(defun mu4e--main-view-real (_ignore-auto _noconfirm)
"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")
(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.
When REFRESH is non nil refresh infos from server."
(let ((inhibit-read-only t))
;; Maybe refresh infos from server.
(if refresh
(mu4e--start 'mu4e~main-redraw-buffer)
(mu4e~main-redraw-buffer))))
(mu4e--start '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
(let ((inhibit-read-only t)
(pos (point))
@ -285,45 +283,48 @@ When REFRESH is non nil refresh infos from server."
(propertize mu4e-mu-version 'face 'mu4e-header-key-face)
"\n\n"
(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)
(mu4e~main-action-str
(mu4e--main-action-str
"\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)
"\n"
(propertize " Bookmarks\n\n" 'face 'mu4e-title-face)
(mu4e~main-bookmarks)
(mu4e--main-bookmarks)
"\n"
(propertize " Maildirs\n\n" 'face 'mu4e-title-face)
(mu4e~main-maildirs)
(mu4e--main-maildirs)
"\n"
(propertize " Misc\n\n" 'face 'mu4e-title-face)
(mu4e~main-action-str "\t* [;]Switch context\n"
(lambda()(interactive)(mu4e-context-switch)(revert-buffer)))
(mu4e--main-action-str "\t* [;]Switch context\n"
(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)
;; show the queue functions if `smtpmail-queue-dir' is defined
(if (file-directory-p smtpmail-queue-dir)
(mu4e~main-view-queue)
(mu4e--main-view-queue)
"")
"\n"
(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* [H]elp\n" 'mu4e-display-manual)
(mu4e~main-action-str "\t* [q]uit\n" 'mu4e-quit)
(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* [H]elp\n" 'mu4e-display-manual)
(mu4e--main-action-str "\t* [q]uit\n" 'mu4e-quit)
"\n"
(propertize " Info\n\n" 'face 'mu4e-title-face)
(mu4e~key-val "database-path" (mu4e-database-path))
(mu4e~key-val "maildir" (mu4e-root-maildir))
(mu4e~key-val "in store"
(format "%d" (plist-get mu4e--server-props :doccount)) "messages")
(mu4e--key-val "database-path" (mu4e-database-path))
(mu4e--key-val "maildir" (mu4e-root-maildir))
(mu4e--key-val "in store"
(format "%d" (plist-get mu4e--server-props :doccount))
"messages")
(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 ""
(unless (mu4e-personal-address-p user-mail-address)
@ -334,26 +335,26 @@ When REFRESH is non nil refresh infos from server."
(mu4e-main-mode)
(goto-char pos))))
(defun mu4e~main-view-queue ()
(defun mu4e--main-view-queue ()
"Display queue-related actions in the main view."
(concat
(mu4e~main-action-str "\t* toggle [m]ail sending mode "
'mu4e~main-toggle-mail-sending-mode)
(mu4e--main-action-str "\t* toggle [m]ail sending mode "
'mu4e--main-toggle-mail-sending-mode)
"(currently "
(propertize (if smtpmail-queue-mail "queued" "direct")
'face 'mu4e-header-key-face)
")\n"
(let ((queue-size (mu4e~main-queue-size)))
(let ((queue-size (mu4e--main-queue-size)))
(if (zerop queue-size)
""
(mu4e~main-action-str
(mu4e--main-action-str
(format "\t* [f]lush %s queued %s\n"
(propertize (int-to-string queue-size)
'face 'mu4e-header-key-face)
(if (> queue-size 1) "mails" "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."
(condition-case nil
(with-temp-buffer
@ -362,7 +363,7 @@ When REFRESH is non nil refresh infos from server."
(count-lines (point-min) (point-max)))
(error 0)))
(defun mu4e~main-view (&optional refresh)
(defun mu4e--main-view (&optional refresh)
"Create the mu4e main-view, and switch to it.
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 (buffer-live-p (mu4e-get-headers-buffer))
(switch-to-buffer (mu4e-get-headers-buffer))
(mu4e~main-menu))
;; `mu4e~main-view' is called from `mu4e~start', so don't call it
(mu4e--main-menu))
;; `mu4e--main-view' is called from `mu4e--start', so don't call it
;; a second time here i.e. do not refresh unless specified
;; explicitly with REFRESH arg.
(switch-to-buffer buf)
(with-current-buffer buf
(mu4e~main-view-real-1 refresh))
(mu4e--main-view-real-1 refresh))
(goto-char (point-min)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Interactive functions
;; NEW
;; 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."
(interactive)
(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
(revert-buffer))))
(defun mu4e~main-menu ()
"mu4e main view in the minibuffer."
(defun mu4e--main-menu ()
"The mu4e main menu."
(interactive)
(let ((key
(read-key
(mu4e-format
"%s"
(concat
(mu4e~main-action-str "[j]ump " 'mu4e-jump-to-maildir)
(mu4e~main-action-str "[s]earch " 'mu4e-search)
(mu4e~main-action-str "[C]ompose " 'mu4e-compose-new)
(mu4e~main-action-str "[b]ookmarks " 'mu4e-headers-search-bookmark)
(mu4e~main-action-str "[;]Switch context " 'mu4e-context-switch)
(mu4e~main-action-str "[U]pdate " 'mu4e-update-mail-and-index)
(mu4e~main-action-str "[N]ews " 'mu4e-news)
(mu4e~main-action-str "[A]bout " 'mu4e-about)
(mu4e~main-action-str "[H]elp " 'mu4e-display-manual))))))
(mu4e--main-action-str "[j]ump " 'mu4e-jump-to-maildir)
(mu4e--main-action-str "[s]earch " 'mu4e-search)
(mu4e--main-action-str "[C]ompose " 'mu4e-compose-new)
(mu4e--main-action-str "[b]ookmarks " 'mu4e-headers-search-bookmark)
(mu4e--main-action-str "[;]Switch context " 'mu4e-context-switch)
(mu4e--main-action-str "[U]pdate " 'mu4e-update-mail-and-index)
(mu4e--main-action-str "[N]ews " 'mu4e-news)
(mu4e--main-action-str "[A]bout " 'mu4e-about)
(mu4e--main-action-str "[H]elp " 'mu4e-display-manual))))))
(unless (member key '(?\C-g ?\C-\[))
(let ((mu4e-command (lookup-key mu4e-main-mode-map (string key) t)))
(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))))
(when (or (not mu4e-command) (eq mu4e-command 'mu4e-context-switch))
(sit-for 1)
(mu4e~main-menu))))))
(mu4e--main-menu))))))
;;; _
(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>
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
@ -27,9 +27,7 @@
;;; Code:
(require 'cl-lib)
(require 'mu4e-server)
(require 'mu4e-message)
(require 'mu4e-folders)
@ -69,7 +67,7 @@ particularly fast).")
;;; Insert stuff
(defvar mu4e~mark-map nil
(defvar mu4e--mark-map nil
"Contains a mapping of docid->markinfo.
When a message is marked, the information is added here. markinfo
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
;; handy definitions; only `mu4e-mark-fringe-len' should be change (if ever),
;; 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.")
(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.")
(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.")
(defun mu4e~mark-initialize ()
(defun mu4e--mark-initialize ()
"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."
(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."
(cl-find-if
(lambda (b)
(with-current-buffer b
(eq major-mode 'mu4e-headers-mode)))
(buffer-list)))
(seq-find (lambda (b)
(with-current-buffer b
(eq major-mode 'mu4e-headers-mode)))
(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.
The current buffer must be either a headers or view buffer."
`(cond
@ -122,7 +119,7 @@ The current buffer must be either a headers or view buffer."
(t
;; even in other modes (e.g. mu4e-main-mode we try to find
;; the headers buffer
(let ((hbuf (mu4e~mark-find-headers-buffer)))
(let ((hbuf (mu4e--mark-find-headers-buffer)))
(if (buffer-live-p hbuf)
(with-current-buffer hbuf ,@body)
,@body)))))
@ -133,7 +130,7 @@ The current buffer must be either a headers or view buffer."
:prompt "refile"
:dyn-target (lambda (target msg) (mu4e-get-refile-folder msg))
: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
:char ("D" . "x")
:prompt "Delete"
@ -148,9 +145,9 @@ The current buffer must be either a headers or view buffer."
(move
:char ("m" . "")
:prompt "move"
:ask-target mu4e~mark-get-move-target
:ask-target mu4e--mark-get-move-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
:char ("!" . "")
:prompt "!read"
@ -160,8 +157,9 @@ The current buffer must be either a headers or view buffer."
:char ("d" . "")
:prompt "dtrash"
:dyn-target (lambda (target msg) (mu4e-get-trash-folder msg))
:action (lambda (docid msg target) (mu4e--server-move docid
(mu4e~mark-check-target target) "+T-N")))
:action (lambda (docid msg target)
(mu4e--server-move docid
(mu4e--mark-check-target target) "+T-N")))
(unflag
:char ("-" . "")
:prompt "-unflag"
@ -254,7 +252,7 @@ The following marks are available, and the corresponding props:
(if mu4e-use-fancy-chars (cdr char) (car char))
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))
(shown-target (if show-fct
(funcall show-fct target)
@ -266,20 +264,21 @@ The following marks are available, and the corresponding props:
(when (mu4e~headers-mark docid markkar)
;; update the hash -- remove everything current, and if add the new
;; stuff, unless we're unmarking
(remhash docid mu4e~mark-map)
(remhash docid mu4e--mark-map)
;; 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)
(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
;; an overlay
(when (and shown-target mu4e-headers-show-target)
(let* ((targetstr (propertize (concat "-> " shown-target " ")
'face 'mu4e-system-face))
;; mu4e~headers-goto-docid docid t \will take us just after
;; the docid cookie and then we skip the mu4e~mark-fringe
(start (+ (length mu4e~mark-fringe)
;; the docid cookie and then we skip the mu4e--mark-fringe
(start (+ (length mu4e--mark-fringe)
(mu4e~headers-goto-docid docid t)))
(overlay (make-overlay start (+ start (length targetstr)))))
(overlay-put overlay 'display targetstr)
@ -287,7 +286,7 @@ The following marks are available, and the corresponding props:
(overlay-put overlay 'evaporate t)
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."
(interactive)
;; (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)))
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."
(let ((getter (plist-get (cdr (assq mark mu4e-marks)) :ask-target)))
(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.
The result may depend on the message at point."
(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.
Optionally, provide TARGET (for moves)."
(unless target
(setq target (mu4e~mark-ask-target mark)))
(setq target (mu4e--mark-ask-target mark)))
(if (not (use-region-p))
;; single message
(mu4e-mark-at-point mark target)
@ -333,13 +332,13 @@ Optionally, provide TARGET (for moves)."
(defun mu4e-mark-restore (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
(save-excursion
(when (mu4e~headers-goto-docid docid)
(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).
If ALLOW-SOMETHING is non-nil, allow the 'something' pseudo mark
as well."
@ -349,9 +348,9 @@ as well."
mu4e-marks))
(marks
(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))
(target (mu4e~mark-ask-target mark)))
(target (mu4e--mark-ask-target mark)))
(cons mark target)))
(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
user which one)."
(interactive)
(mu4e~mark-in-context
(mu4e--mark-in-context
(let ((markpair))
(maphash
(lambda (docid val)
@ -367,13 +366,13 @@ user which one)."
(when (eql mark 'something)
(unless 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
(when (mu4e~headers-goto-docid docid)
(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."
(let ((fulltarget (concat (mu4e-root-maildir) target)))
(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."
(interactive "P")
(mu4e~mark-in-context
(let* ((marknum (hash-table-count mu4e~mark-map))
(mu4e--mark-in-context
(let* ((marknum (hash-table-count mu4e--mark-map))
(prompt (format "Are you sure you want to execute %d mark%s?"
marknum (if (> marknum 1) "s" ""))))
(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)
docid msg target))
(mu4e-error "Unrecognized mark %S" mark))))
mu4e~mark-map))
mu4e--mark-map))
(mu4e-mark-unmark-all)
(message nil)))))
(defun mu4e-mark-unmark-all ()
"Unmark all marked messages."
(interactive)
(mu4e~mark-in-context
(when (or (null mu4e~mark-map) (zerop (hash-table-count mu4e~mark-map)))
(mu4e--mark-in-context
(when (or (null mu4e--mark-map) (zerop (hash-table-count mu4e--mark-map)))
(mu4e-warn "Nothing is marked"))
(maphash
(lambda (docid _val)
(save-excursion
(when (mu4e~headers-goto-docid docid)
(mu4e-mark-set 'unmark))))
mu4e~mark-map)
mu4e--mark-map)
;; in any case, clear the marks map
(mu4e~mark-clear)))
(mu4e--mark-clear)))
(defun mu4e-mark-docid-marked-p (docid)
"Is the given DOCID marked?"
(when (gethash docid mu4e~mark-map) t))
(when (gethash docid mu4e--mark-map) t))
(defun mu4e-mark-marks-num ()
"Return the number of mark-instances in the current buffer."
(mu4e~mark-in-context
(if mu4e~mark-map (hash-table-count mu4e~mark-map) 0)))
(mu4e--mark-in-context
(if mu4e--mark-map (hash-table-count mu4e--mark-map) 0)))
(defun mu4e-mark-handle-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,
quitting the buffer) is taken; returning t means 'take the following
action', return nil means 'don't do anything'."
(mu4e~mark-in-context
(mu4e--mark-in-context
(let ((marknum (mu4e-mark-marks-num))
(what mu4e-headers-leave-behavior))
(unless (zerop marknum) ;; nothing to do?

View File

@ -1,6 +1,6 @@
;;; 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>
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
@ -26,7 +26,6 @@
;;; Code:
(require 'cl-lib)
(require 'mu4e-vars)
(require 'flow-fill)
(require 'shr)
@ -36,9 +35,6 @@
(declare-function mu4e-personal-address-p "mu4e-contacts")
(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-view-prefer-html "No longer in use" "1.7.0")
(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
(if (listp rx)
;; 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))
rx)
;; not a list, check the rx
(cl-find-if
(seq-find
(lambda (ct)
(let ((name (car ct)) (email (cdr ct))
;; 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
which `mu4e-personal-address-p' return t. Returns the contact
cell that matched, or nil."
(cl-find-if (lambda (cell) (mu4e-personal-address-p (cdr cell)))
(mu4e-message-field msg cfield)))
(seq-find (lambda (cell) (mu4e-personal-address-p (cdr cell)))
(mu4e-message-field msg cfield)))
(defun mu4e-message-sent-by-me (msg)
"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?
In any of the contact
fields?"
(cl-some
(seq-some
(lambda (field)
(mu4e-message-contact-field-matches-me msg field))
'(:from :to :cc :bcc)))
@ -212,8 +208,7 @@ symbol, see `mu4e-header-info'."
(defun mu4e-message-readable-path (&optional msg)
"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)))
(unless (file-readable-p 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)
(mu4e-message "Saved '%s' to kill-ring" path)))
;;; _
;;;
(provide 'mu4e-message)
;;; mu4e-message.el ends here

View File

@ -27,7 +27,6 @@
;;; Code:
(require 'seq)
(require 'cl-lib)
(require 'mu4e-helpers)
(require 'mu4e-message)
(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
stack size."
(let ((stack
(cl-case where
(past mu4e--search-query-past)
(future mu4e--search-query-future))))
(pcase where
('past mu4e--search-query-past)
('future mu4e--search-query-future))))
;; only add if not the same item
(unless (and stack (string= (car stack) query))
(push query stack)
@ -305,22 +304,22 @@ stack size."
(when (> (length stack) mu4e--search-query-stack-size)
(setq stack (cl-subseq stack 0 mu4e--search-query-stack-size)))
;; 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
(cl-case where
(past (setq mu4e--search-query-past stack))
(future (setq mu4e--search-query-future stack))))))
(pcase where
('past (setq mu4e--search-query-past stack))
('future (setq mu4e--search-query-future stack))))))
(defun mu4e--search-pop-query (whence)
"Pop a query from the stack.
WHENCE is a symbol telling us where to get it from, either `future'
or `past'."
(cl-case whence
(past
(pcase whence
('past
(unless mu4e--search-query-past
(mu4e-warn "No more previous queries"))
(pop mu4e--search-query-past))
(future
('future
(unless mu4e--search-query-future
(mu4e-warn "No more next queries"))
(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 -*-
;; Copyright (C) 2011-2021 Dirk-Jan C. Binnema
;; Copyright (C) 2011-2022 Dirk-Jan C. Binnema
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
@ -34,7 +34,8 @@
:group 'mail)
(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
references) to these messages. This can be useful e.g. to include
sent messages into message threads."
@ -42,7 +43,8 @@ sent messages into message threads."
:group 'mu4e-headers)
(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
message, which is a common occurrence for example when using Gmail
and offlineimap."
@ -75,7 +77,7 @@ Follows the format of `format-time-string'."
(defface mu4e-draft-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."
:group 'mu4e-faces)
@ -155,11 +157,6 @@ I.e. a message with the draft flag set."
"Face for the query in the mode-line."
: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
'((t :inherit font-lock-comment-face))
"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."
: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
'((t :inherit font-lock-comment-face :slant italic))
"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
'((t :inherit message-separator :slant italic))
"Face for the separator between headers / message in
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."
"Face for the headers/message separator in mu4e-compose-mode."
:group 'mu4e-faces)
(defface mu4e-region-code
@ -380,31 +329,34 @@ Note, `:sortable' is not supported for custom header fields.")
'(
;; some examples & debug helpers.
(:thread-path . ;; Shows the internal thread-path
( :name "Thread-path"
:shortname "Thp"
:help "The thread-path"
:function (lambda (msg)
(let ((thread (mu4e-message-field msg :thread)))
(or (and thread (plist-get thread :path)) "")))))
(:thread-path
. ;; Shows the internal thread-path
( :name "Thread-path"
:shortname "Thp"
:help "The thread-path"
:function (lambda (msg)
(let ((thread (mu4e-message-field msg :thread)))
(or (and thread (plist-get thread :path)) "")))))
(:thread-date . ;; Shows the internal thread-date
( :name "Thread-date"
:shortname "Thd"
:help "The thread-date"
:function (lambda (msg)
(let* ((thread (mu4e-message-field msg :thread))
(tdate (and thread (plist-get thread :date-tstamp))))
(format-time-string "%F %T " (or tdate 0))))))
(:recipnum .
( :name "Number of recipients"
:shortname "Recip#"
:help "Number of recipients for this message"
:function
(lambda (msg)
(format "%d"
(+ (length (mu4e-message-field msg :to))
(length (mu4e-message-field msg :cc))))))))
(:thread-date
. ;; Shows the internal thread-date
( :name "Thread-date"
:shortname "Thd"
:help "The thread-date"
:function (lambda (msg)
(let* ((thread (mu4e-message-field msg :thread))
(tdate (and thread (plist-get thread :date-tstamp))))
(format-time-string "%F %T " (or tdate 0))))))
(:recipnum
.
( :name "Number of recipients"
:shortname "Recip#"
:help "Number of recipients for this message"
:function
(lambda (msg)
(format "%d"
(+ (length (mu4e-message-field msg :to))
(length (mu4e-message-field msg :cc))))))))
"A list of custom (user-defined) headers.
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))
(dolist (field mu4e-view-fields)
(let ((fieldval (mu4e-message-field msg field)))
(cl-case field
((:path :maildir :user-agent :mailing-list :message-id)
(pcase field
((or ':path ':maildir ':user-agent ':mailing-list ':message-id)
(mu4e~view-gnus-insert-header field fieldval))
((:flags :tags)
((or ':flags ':tags)
(let ((flags (mapconcat (lambda (flag)
(if (symbolp flag)
(symbol-name flag)
flag)) fieldval ", ")))
(mu4e~view-gnus-insert-header field flags)))
(:size (mu4e~view-gnus-insert-header
(':size (mu4e~view-gnus-insert-header
field (mu4e-display-size fieldval)))
((:subject :to :from :cc :bcc :from-or-to :date :attachments
:signature :decryption)) ; handled by Gnus
(t
((or ':subject ':to ':from ':cc ':bcc ':from-or-to
':date :attachments ':signature
':decryption)) ; handled by Gnus
(_
(mu4e~view-gnus-insert-header-custom msg field)))))
(let ((gnus-treatment-function-alist
'((gnus-treat-highlight-headers
@ -1231,7 +1232,7 @@ the third MIME-part."
(mapcar (lambda (action) `(,(plist-get action :name) . ,action))
mu4e-view-mime-part-actions))
(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)))
(action
(or (and options (mu4e-read-option "Action on MIME-part: " options))

View File

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