mu4e-view: whitespace cleanup

This commit is contained in:
Dirk-Jan C. Binnema 2022-12-13 23:49:57 +02:00
parent 98fcf0192c
commit 9ae567f5f5
1 changed files with 348 additions and 348 deletions

View File

@ -60,7 +60,7 @@ Otherwise, don't move to the next message."
(defcustom mu4e-view-fields (defcustom mu4e-view-fields
'(:from :to :cc :subject :flags :date :maildir :mailing-list :tags '(:from :to :cc :subject :flags :date :maildir :mailing-list :tags
:attachments :signature :decryption) :attachments :signature :decryption)
"Header fields to display in the message view buffer. "Header fields to display in the message view buffer.
For the complete list of available headers, see For the complete list of available headers, see
`mu4e-header-info'. `mu4e-header-info'.
@ -75,11 +75,11 @@ details."
(defcustom mu4e-view-actions (defcustom mu4e-view-actions
(seq-filter 'identity (seq-filter 'identity
`( ("capture message" . mu4e-action-capture-message) `( ("capture message" . mu4e-action-capture-message)
("view in browser" . mu4e-action-view-in-browser) ("view in browser" . mu4e-action-view-in-browser)
,(when (fboundp 'xwidget-webkit-browse-url) ,(when (fboundp 'xwidget-webkit-browse-url)
'("xview in xwidget" . mu4e-action-view-in-xwidget)) '("xview in xwidget" . mu4e-action-view-in-xwidget))
("show this thread" . mu4e-action-show-thread))) ("show this thread" . mu4e-action-show-thread)))
"List of actions to perform on messages in view mode. "List of actions to perform on messages in view mode.
The actions are cons-cells of the form: The actions are cons-cells of the form:
(NAME . FUNC) (NAME . FUNC)
@ -136,13 +136,13 @@ other windows."
"Display the raw contents of message at point in a new buffer." "Display the raw contents of message at point in a new buffer."
(interactive) (interactive)
(let ((path (mu4e-message-readable-path)) (let ((path (mu4e-message-readable-path))
(buf (get-buffer-create mu4e~view-raw-buffer-name))) (buf (get-buffer-create mu4e~view-raw-buffer-name)))
(with-current-buffer buf (with-current-buffer buf
(let ((inhibit-read-only t)) (let ((inhibit-read-only t))
(erase-buffer) (erase-buffer)
(mu4e-raw-view-mode) (mu4e-raw-view-mode)
(insert-file-contents path) (insert-file-contents path)
(goto-char (point-min)))) (goto-char (point-min))))
(mu4e-display-buffer buf t))) (mu4e-display-buffer buf t)))
(defun mu4e-view-pipe (cmd) (defun mu4e-view-pipe (cmd)
@ -156,38 +156,38 @@ Then, display the results."
"Evaluate BODY in the context of the headers buffer." "Evaluate BODY in the context of the headers buffer."
`(progn `(progn
(let* ((msg (mu4e-message-at-point)) (let* ((msg (mu4e-message-at-point))
(buffer (cond (buffer (cond
;; are we already inside a headers buffer? ;; are we already inside a headers buffer?
((mu4e-current-buffer-type-p 'headers) (current-buffer)) ((mu4e-current-buffer-type-p 'headers) (current-buffer))
;; if not, are we inside a view buffer, and does ;; if not, are we inside a view buffer, and does
;; it have linked headers buffer? ;; it have linked headers buffer?
((mu4e-current-buffer-type-p 'view) ((mu4e-current-buffer-type-p 'view)
(when (mu4e--view-detached-p (current-buffer)) (when (mu4e--view-detached-p (current-buffer))
(mu4e-error (mu4e-error
"Cannot navigate in a detached view buffer.")) "Cannot navigate in a detached view buffer."))
(mu4e-get-headers-buffer)) (mu4e-get-headers-buffer))
;; fallback; but what would trigger this? ;; fallback; but what would trigger this?
(t (mu4e-get-headers-buffer)))) (t (mu4e-get-headers-buffer))))
(docid (mu4e-message-field msg :docid))) (docid (mu4e-message-field msg :docid)))
(unless docid (unless docid
(mu4e-error "Message without docid: action is not possible")) (mu4e-error "Message without docid: action is not possible"))
(with-current-buffer buffer (with-current-buffer buffer
(mu4e-display-buffer buffer) (mu4e-display-buffer buffer)
(if (or (mu4e~headers-goto-docid docid) (if (or (mu4e~headers-goto-docid docid)
;; TODO: Is this the best way to find another ;; TODO: Is this the best way to find another
;; relevant docid for a view buffer? ;; relevant docid for a view buffer?
;; ;;
;; If you attach a view buffer to another headers ;; If you attach a view buffer to another headers
;; buffer that does not contain the current docid ;; buffer that does not contain the current docid
;; then `mu4e~headers-goto-docid' returns nil and we ;; then `mu4e~headers-goto-docid' returns nil and we
;; get an error. This "hack" instead gets its ;; get an error. This "hack" instead gets its
;; now-changed headers buffer's current message as a ;; now-changed headers buffer's current message as a
;; docid ;; docid
(mu4e~headers-goto-docid (mu4e~headers-goto-docid
(with-current-buffer buffer (with-current-buffer buffer
(mu4e-message-field (mu4e-message-at-point) :docid)))) (mu4e-message-field (mu4e-message-at-point) :docid))))
,@body ,@body
(mu4e-error "Cannot find message in headers buffer")))))) (mu4e-error "Cannot find message in headers buffer"))))))
(defun mu4e-view-headers-next (&optional n) (defun mu4e-view-headers-next (&optional n)
"Move point to the next message header. "Move point to the next message header.
@ -239,7 +239,7 @@ bymessage-at-point. The actions are specified in
`mu4e-view-actions'." `mu4e-view-actions'."
(interactive) (interactive)
(let* ((msg (or msg (mu4e-message-at-point))) (let* ((msg (or msg (mu4e-message-at-point)))
(actionfunc (mu4e-read-option "Action: " mu4e-view-actions))) (actionfunc (mu4e-read-option "Action: " mu4e-view-actions)))
(funcall actionfunc msg))) (funcall actionfunc msg)))
(defun mu4e-view-mark-pattern () (defun mu4e-view-mark-pattern ()
@ -290,25 +290,25 @@ Add this function to `mu4e-view-mode-hook' to enable this feature."
(save-excursion (save-excursion
(goto-char (point-min)) (goto-char (point-min))
(while (re-search-forward (while (re-search-forward
(concat "^" message-mark-insert-begin) nil t) (concat "^" message-mark-insert-begin) nil t)
(setq ov-beg (match-beginning 0) (setq ov-beg (match-beginning 0)
ov-end (match-end 0) ov-end (match-end 0)
ov-inv (make-overlay ov-beg ov-end) ov-inv (make-overlay ov-beg ov-end)
beg ov-end) beg ov-end)
(overlay-put ov-inv 'invisible t) (overlay-put ov-inv 'invisible t)
(overlay-put ov-inv 'mu4e-overlay t) (overlay-put ov-inv 'mu4e-overlay t)
(when (re-search-forward (when (re-search-forward
(concat "^" message-mark-insert-end) nil t) (concat "^" message-mark-insert-end) nil t)
(setq ov-beg (match-beginning 0) (setq ov-beg (match-beginning 0)
ov-end (match-end 0) ov-end (match-end 0)
ov-inv (make-overlay ov-beg ov-end) ov-inv (make-overlay ov-beg ov-end)
end ov-beg) end ov-beg)
(overlay-put ov-inv 'invisible t)) (overlay-put ov-inv 'invisible t))
(when (and beg end) (when (and beg end)
(let ((ov (make-overlay beg end))) (let ((ov (make-overlay beg end)))
(overlay-put ov 'mu4e-overlay t) (overlay-put ov 'mu4e-overlay t)
(overlay-put ov 'face 'mu4e-region-code)) (overlay-put ov 'face 'mu4e-region-code))
(setq beg nil end nil)))))) (setq beg nil end nil))))))
;;; View Utilities ;;; View Utilities
@ -328,19 +328,19 @@ Add this function to `mu4e-view-mode-hook' to enable this feature."
(unless mu4e-linked-headers-buffer (unless mu4e-linked-headers-buffer
(mu4e-error "This view buffer is already detached.")) (mu4e-error "This view buffer is already detached."))
(mu4e-message "Detached view buffer from %s" (mu4e-message "Detached view buffer from %s"
(prog1 mu4e-linked-headers-buffer (prog1 mu4e-linked-headers-buffer
(with-current-buffer mu4e-linked-headers-buffer (with-current-buffer mu4e-linked-headers-buffer
(when (eq (selected-window) mu4e~headers-view-win) (when (eq (selected-window) mu4e~headers-view-win)
(setq mu4e~headers-view-win nil))) (setq mu4e~headers-view-win nil)))
(setq mu4e-linked-headers-buffer nil)))) (setq mu4e-linked-headers-buffer nil))))
(defun mu4e-view-attach (headers-buffer) (defun mu4e-view-attach (headers-buffer)
"Attaches a view buffer to a headers buffer." "Attaches a view buffer to a headers buffer."
(interactive (interactive
(list (get-buffer (read-buffer (list (get-buffer (read-buffer
"Select a headers buffer to attach to: " nil t "Select a headers buffer to attach to: " nil t
(lambda (buf) (with-current-buffer (car buf) (lambda (buf) (with-current-buffer (car buf)
(mu4e-current-buffer-type-p 'headers))))))) (mu4e-current-buffer-type-p 'headers)))))))
(mu4e-message "Attached view buffer to %s" headers-buffer) (mu4e-message "Attached view buffer to %s" headers-buffer)
(setq mu4e-linked-headers-buffer headers-buffer) (setq mu4e-linked-headers-buffer headers-buffer)
(with-current-buffer headers-buffer (with-current-buffer headers-buffer
@ -392,12 +392,12 @@ list."
(defmacro mu4e~view-defun-mark-for (mark) (defmacro mu4e~view-defun-mark-for (mark)
"Define a function mu4e-view-mark-for- MARK." "Define a function mu4e-view-mark-for- MARK."
(let ((funcname (intern (format "mu4e-view-mark-for-%s" mark))) (let ((funcname (intern (format "mu4e-view-mark-for-%s" mark)))
(docstring (format "Mark the current message for %s." mark))) (docstring (format "Mark the current message for %s." mark)))
`(progn `(progn
(defun ,funcname () ,docstring (defun ,funcname () ,docstring
(interactive) (interactive)
(mu4e~view-in-headers-context (mu4e~view-in-headers-context
(mu4e-headers-mark-and-next ',mark))) (mu4e-headers-mark-and-next ',mark)))
(put ',funcname 'definition-name ',mark)))) (put ',funcname 'definition-name ',mark))))
(mu4e~view-defun-mark-for move) (mu4e~view-defun-mark-for move)
@ -447,8 +447,8 @@ If the url is mailto link, start writing an email to that address."
(let* (( url (or url (mu4e~view-get-property-from-event 'mu4e-url)))) (let* (( url (or url (mu4e~view-get-property-from-event 'mu4e-url))))
(when url (when url
(if (string-match-p "^mailto:" url) (if (string-match-p "^mailto:" url)
(browse-url-mail url) (browse-url-mail url)
(browse-url url))))) (browse-url url)))))
(defun mu4e~view-get-property-from-event (prop) (defun mu4e~view-get-property-from-event (prop)
@ -456,13 +456,13 @@ If the url is mailto link, start writing an email to that address."
The action is chosen based on the `last-command-event'. The action is chosen based on the `last-command-event'.
Meant to be evoked from interactive commands." Meant to be evoked from interactive commands."
(if (and (eventp last-command-event) (if (and (eventp last-command-event)
(mouse-event-p last-command-event)) (mouse-event-p last-command-event))
(let ((posn (event-end last-command-event))) (let ((posn (event-end last-command-event)))
(when (numberp (posn-point posn)) (when (numberp (posn-point posn))
(get-text-property (get-text-property
(posn-point posn) (posn-point posn)
prop prop
(window-buffer (posn-window posn))))) (window-buffer (posn-window posn)))))
(get-text-property (point) prop))) (get-text-property (point) prop)))
;; this is fairly simplistic... ;; this is fairly simplistic...
@ -472,27 +472,27 @@ Also number them so they can be opened using `mu4e-view-go-to-url'."
(let ((num 0)) (let ((num 0))
(save-excursion (save-excursion
(setq mu4e~view-link-map ;; buffer local (setq mu4e~view-link-map ;; buffer local
(make-hash-table :size 32 :weakness nil)) (make-hash-table :size 32 :weakness nil))
(goto-char (point-min)) (goto-char (point-min))
(while (re-search-forward mu4e~view-beginning-of-url-regexp nil t) (while (re-search-forward mu4e~view-beginning-of-url-regexp nil t)
(let ((bounds (thing-at-point-bounds-of-url-at-point))) (let ((bounds (thing-at-point-bounds-of-url-at-point)))
(when bounds (when bounds
(let* ((url (thing-at-point-url-at-point)) (let* ((url (thing-at-point-url-at-point))
(ov (make-overlay (car bounds) (cdr bounds)))) (ov (make-overlay (car bounds) (cdr bounds))))
(puthash (cl-incf num) url mu4e~view-link-map) (puthash (cl-incf num) url mu4e~view-link-map)
(add-text-properties (add-text-properties
(car bounds) (car bounds)
(cdr bounds) (cdr bounds)
`(face mu4e-link-face `(face mu4e-link-face
mouse-face highlight mouse-face highlight
mu4e-url ,url mu4e-url ,url
keymap ,mu4e-view-active-urls-keymap keymap ,mu4e-view-active-urls-keymap
help-echo help-echo
"[mouse-1] or [M-RET] to open the link")) "[mouse-1] or [M-RET] to open the link"))
(overlay-put ov 'mu4e-overlay t) (overlay-put ov 'mu4e-overlay t)
(overlay-put ov 'after-string (overlay-put ov 'after-string
(propertize (format "\u200B[%d]" num) (propertize (format "\u200B[%d]" num)
'face 'mu4e-url-number-face))))))))) 'face 'mu4e-url-number-face)))))))))
(defun mu4e~view-get-urls-num (prompt &optional multi) (defun mu4e~view-get-urls-num (prompt &optional multi)
@ -505,21 +505,21 @@ string."
(let* ((count (hash-table-count mu4e~view-link-map)) (def)) (let* ((count (hash-table-count mu4e~view-link-map)) (def))
(when (zerop count) (mu4e-error "No links for this message")) (when (zerop count) (mu4e-error "No links for this message"))
(if (not multi) (if (not multi)
(if (= count 1) (if (= count 1)
(read-number (mu4e-format "%s: " prompt) 1) (read-number (mu4e-format "%s: " prompt) 1)
(read-number (mu4e-format "%s (1-%d): " prompt count))) (read-number (mu4e-format "%s (1-%d): " prompt count)))
(progn (progn
(setq def (if (= count 1) "1" (format "1-%d" count))) (setq def (if (= count 1) "1" (format "1-%d" count)))
(read-string (mu4e-format "%s (default %s): " prompt def) (read-string (mu4e-format "%s (default %s): " prompt def)
nil nil def))))) nil nil def)))))
(defun mu4e-view-go-to-url (&optional multi) (defun mu4e-view-go-to-url (&optional multi)
"Offer to go visit one or more URLs. "Offer to go visit one or more URLs.
If MULTI (prefix-argument) is non-nil, offer to go to a range of URLs." If MULTI (prefix-argument) is non-nil, offer to go to a range of URLs."
(interactive "P") (interactive "P")
(mu4e~view-handle-urls "URL to visit" (mu4e~view-handle-urls "URL to visit"
multi multi
(lambda (url) (mu4e~view-browse-url-from-binding url)))) (lambda (url) (mu4e~view-browse-url-from-binding url))))
(defun mu4e-view-save-url (&optional multi) (defun mu4e-view-save-url (&optional multi)
"Offer to save URLs to the kill ring. "Offer to save URLs to the kill ring.
@ -527,9 +527,9 @@ If MULTI (prefix-argument) is nil, save a single one, otherwise, offer
to save a range of URLs." to save a range of URLs."
(interactive "P") (interactive "P")
(mu4e~view-handle-urls "URL to save" multi (mu4e~view-handle-urls "URL to save" multi
(lambda (url) (lambda (url)
(kill-new url) (kill-new url)
(mu4e-message "Saved %s to the kill-ring" url)))) (mu4e-message "Saved %s to the kill-ring" url))))
(defun mu4e-view-fetch-url (&optional multi) (defun mu4e-view-fetch-url (&optional multi)
"Offer to fetch (download) URLs. "Offer to fetch (download) URLs.
@ -541,7 +541,7 @@ URLs. The urls are fetched to `mu4e-attachment-dir'."
"URL to fetch" multi "URL to fetch" multi
(lambda (url) (lambda (url)
(let ((target (concat (mu4e~get-attachment-dir url) "/" (let ((target (concat (mu4e~get-attachment-dir url) "/"
(file-name-nondirectory url)))) (file-name-nondirectory url))))
(url-copy-file url target) (url-copy-file url target)
(mu4e-message "Fetched %s -> %s" url target))))) (mu4e-message "Fetched %s -> %s" url target)))))
@ -557,7 +557,7 @@ it to a range of uris. PROMPT is the query to present to the user."
"Apply URLFUNC to some URL with NUM in the current message. "Apply URLFUNC to some URL with NUM in the current message.
Prompting the user with PROMPT for the number." Prompting the user with PROMPT for the number."
(let* ((num (or num (mu4e~view-get-urls-num prompt))) (let* ((num (or num (mu4e~view-get-urls-num prompt)))
(url (gethash num mu4e~view-link-map))) (url (gethash num mu4e~view-link-map)))
(unless url (mu4e-warn "Invalid number for URL")) (unless url (mu4e-warn "Invalid number for URL"))
(funcall urlfunc url))) (funcall urlfunc url)))
@ -573,9 +573,9 @@ of urls. You can type multiple values separated by space, e.g. 1
Furthermore, there is a shortcut \"a\" which means all urls, but as Furthermore, there is a shortcut \"a\" which means all urls, but as
this is the default, you may not need it." this is the default, you may not need it."
(let* ((linkstr (mu4e~view-get-urls-num (let* ((linkstr (mu4e~view-get-urls-num
"URL number range (or 'a' for 'all')" t)) "URL number range (or 'a' for 'all')" t))
(count (hash-table-count mu4e~view-link-map)) (count (hash-table-count mu4e~view-link-map))
(linknums (mu4e-split-ranges-to-numbers linkstr count))) (linknums (mu4e-split-ranges-to-numbers linkstr count)))
(dolist (num linknums) (dolist (num linknums)
(mu4e~view-handle-single-url prompt urlfunc num)))) (mu4e~view-handle-single-url prompt urlfunc num))))
@ -629,14 +629,14 @@ As a side-effect, a message that is being viewed loses its
(setq gnus-article-buffer (mu4e-get-view-buffer nil t)) (setq gnus-article-buffer (mu4e-get-view-buffer nil t))
(with-current-buffer gnus-article-buffer (with-current-buffer gnus-article-buffer
(when linked-headers-buffer (when linked-headers-buffer
(setq mu4e-linked-headers-buffer linked-headers-buffer)) (setq mu4e-linked-headers-buffer linked-headers-buffer))
(let ((inhibit-read-only t)) (let ((inhibit-read-only t))
(remove-overlays (point-min)(point-max) 'mu4e-overlay t) (remove-overlays (point-min)(point-max) 'mu4e-overlay t)
(erase-buffer) (erase-buffer)
(insert-file-contents-literally (insert-file-contents-literally
(mu4e-message-readable-path msg) nil nil nil t) (mu4e-message-readable-path msg) nil nil nil t)
(setq-local mu4e~view-message msg) (setq-local mu4e~view-message msg)
(mu4e~view-render-buffer msg)) (mu4e~view-render-buffer msg))
(mu4e-loading-mode 0))) (mu4e-loading-mode 0)))
(unless (mu4e--view-detached-p gnus-article-buffer) (unless (mu4e--view-detached-p gnus-article-buffer)
(with-current-buffer mu4e-linked-headers-buffer (with-current-buffer mu4e-linked-headers-buffer
@ -647,9 +647,9 @@ As a side-effect, a message that is being viewed loses its
;; Otherwise, `mu4e-display-buffer' may adjust the view buffer's ;; Otherwise, `mu4e-display-buffer' may adjust the view buffer's
;; window height based on a buffer that has no text in it yet! ;; window height based on a buffer that has no text in it yet!
(setq-local mu4e~headers-view-win (setq-local mu4e~headers-view-win
(mu4e-display-buffer gnus-article-buffer nil)) (mu4e-display-buffer gnus-article-buffer nil))
(unless (window-live-p mu4e~headers-view-win) (unless (window-live-p mu4e~headers-view-win)
(mu4e-error "Cannot get a message view")) (mu4e-error "Cannot get a message view"))
(select-window mu4e~headers-view-win))) (select-window mu4e~headers-view-win)))
(with-current-buffer gnus-article-buffer (with-current-buffer gnus-article-buffer
(run-hooks 'mu4e-after-view-message-hook))) (run-hooks 'mu4e-after-view-message-hook)))
@ -675,17 +675,17 @@ determine which browser function to use."
(mu4e-message-readable-path msg) nil nil nil t) (mu4e-message-readable-path msg) nil nil nil t)
(run-hooks 'gnus-article-decode-hook) (run-hooks 'gnus-article-decode-hook)
(let ((header (unless skip-headers (let ((header (unless skip-headers
(cl-loop for field in '("from" "to" "cc" "date" "subject") (cl-loop for field in '("from" "to" "cc" "date" "subject")
when (message-fetch-field field) when (message-fetch-field field)
concat (format "%s: %s\n" (capitalize field) it)))) concat (format "%s: %s\n" (capitalize field) it))))
(parts (mm-dissect-buffer t t))) (parts (mm-dissect-buffer t t)))
;; If singlepart, enforce a list. ;; If singlepart, enforce a list.
(when (and (bufferp (car parts)) (when (and (bufferp (car parts))
(stringp (car (mm-handle-type parts)))) (stringp (car (mm-handle-type parts))))
(setq parts (list parts))) (setq parts (list parts)))
;; Process the list ;; Process the list
(unless (gnus-article-browse-html-parts parts header) (unless (gnus-article-browse-html-parts parts header)
(mu4e-warn "Message does not contain a \"text/html\" part")) (mu4e-warn "Message does not contain a \"text/html\" part"))
(mm-destroy-parts parts)))) (mm-destroy-parts parts))))
(defun mu4e-action-view-in-xwidget (msg) (defun mu4e-action-view-in-xwidget (msg)
@ -693,47 +693,47 @@ determine which browser function to use."
(unless (fboundp 'xwidget-webkit-browse-url) (unless (fboundp 'xwidget-webkit-browse-url)
(mu4e-error "No xwidget support available")) (mu4e-error "No xwidget support available"))
(let ((browse-url-handlers nil) (let ((browse-url-handlers nil)
(browse-url-browser-function (browse-url-browser-function
(lambda (url &optional _rest) (lambda (url &optional _rest)
(xwidget-webkit-browse-url url)))) (xwidget-webkit-browse-url url))))
(mu4e-action-view-in-browser msg))) (mu4e-action-view-in-browser msg)))
(defun mu4e~view-render-buffer (msg) (defun mu4e~view-render-buffer (msg)
"Render current buffer with MSG using Gnus' article mode." "Render current buffer with MSG using Gnus' article mode."
(setq gnus-summary-buffer (get-buffer-create " *appease-gnus*")) (setq gnus-summary-buffer (get-buffer-create " *appease-gnus*"))
(let* ((inhibit-read-only t) (let* ((inhibit-read-only t)
(max-specpdl-size mu4e-view-max-specpdl-size) (max-specpdl-size mu4e-view-max-specpdl-size)
(mm-decrypt-option 'known) (mm-decrypt-option 'known)
(ct (mail-fetch-field "Content-Type")) (ct (mail-fetch-field "Content-Type"))
(ct (and ct (mail-header-parse-content-type ct))) (ct (and ct (mail-header-parse-content-type ct)))
(charset (mail-content-type-get ct 'charset)) (charset (mail-content-type-get ct 'charset))
(charset (and charset (intern charset))) (charset (and charset (intern charset)))
(mu4e~view-rendering t); Needed if e.g. an ics file is buttonized (mu4e~view-rendering t); Needed if e.g. an ics file is buttonized
(gnus-article-emulate-mime t) (gnus-article-emulate-mime t)
(gnus-unbuttonized-mime-types '(".*/.*")) (gnus-unbuttonized-mime-types '(".*/.*"))
(gnus-buttonized-mime-types (gnus-buttonized-mime-types
(append (list "multipart/signed" "multipart/encrypted") (append (list "multipart/signed" "multipart/encrypted")
gnus-buttonized-mime-types)) gnus-buttonized-mime-types))
(gnus-newsgroup-charset (gnus-newsgroup-charset
(if (and charset (coding-system-p charset)) charset (if (and charset (coding-system-p charset)) charset
(detect-coding-region (point-min) (point-max) t))) (detect-coding-region (point-min) (point-max) t)))
;; Possibly add headers (before "Attachments") ;; Possibly add headers (before "Attachments")
(gnus-display-mime-function (mu4e~view-gnus-display-mime msg)) (gnus-display-mime-function (mu4e~view-gnus-display-mime msg))
(gnus-icalendar-additional-identities (gnus-icalendar-additional-identities
(mu4e-personal-addresses 'no-regexp))) (mu4e-personal-addresses 'no-regexp)))
(condition-case err (condition-case err
(progn (progn
(mm-enable-multibyte) (mm-enable-multibyte)
(run-hooks 'gnus-article-decode-hook) (run-hooks 'gnus-article-decode-hook)
(gnus-article-prepare-display) (gnus-article-prepare-display)
(mu4e~view-activate-urls) (mu4e~view-activate-urls)
(setq mu4e~gnus-article-mime-handles gnus-article-mime-handles (setq mu4e~gnus-article-mime-handles gnus-article-mime-handles
gnus-article-decoded-p gnus-article-decode-hook) gnus-article-decoded-p gnus-article-decode-hook)
(set-buffer-modified-p nil) (set-buffer-modified-p nil)
(add-hook 'kill-buffer-hook #'mu4e~view-kill-mime-handles)) (add-hook 'kill-buffer-hook #'mu4e~view-kill-mime-handles))
(epg-error (epg-error
(mu4e-warn "EPG error: %s; fall back to raw view" (mu4e-warn "EPG error: %s; fall back to raw view"
(error-message-string err)))))) (error-message-string err))))))
(defun mu4e~view-kill-mime-handles () (defun mu4e~view-kill-mime-handles ()
"Kill cached MIME-handles, if any." "Kill cached MIME-handles, if any."
@ -752,7 +752,7 @@ determine which browser function to use."
"Toggle whether to show all MIME-parts." "Toggle whether to show all MIME-parts."
(interactive) (interactive)
(setq gnus-inhibit-mime-unbuttonizing (setq gnus-inhibit-mime-unbuttonizing
(not gnus-inhibit-mime-unbuttonizing)) (not gnus-inhibit-mime-unbuttonizing))
(mu4e-view-refresh)) (mu4e-view-refresh))
(defun mu4e-view-toggle-fill-flowed() (defun mu4e-view-toggle-fill-flowed()
@ -767,54 +767,54 @@ determine which browser function to use."
(gnus-display-mime ihandles) (gnus-display-mime ihandles)
(unless ihandles (unless ihandles
(save-restriction (save-restriction
(article-goto-body) (article-goto-body)
(forward-line -1) (forward-line -1)
(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)))
(pcase field (pcase field
((or ':path ':maildir :list ':user-agent ':message-id) ((or ':path ':maildir :list ':user-agent ':message-id)
(mu4e~view-gnus-insert-header field fieldval)) (mu4e~view-gnus-insert-header field fieldval))
(':mailing-list (':mailing-list
(let ((list (plist-get msg :list))) (let ((list (plist-get msg :list)))
(if list (mu4e-get-mailing-list-shortname list) ""))) (if list (mu4e-get-mailing-list-shortname list) "")))
((or ':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)))
((or ':subject ':to ':from ':cc ':bcc ':from-or-to ((or ':subject ':to ':from ':cc ':bcc ':from-or-to
':date :attachments ':signature ':date :attachments ':signature
':decryption)) ; handled by Gnus ':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
gnus-article-highlight-headers)))) gnus-article-highlight-headers))))
(gnus-treat-article 'head)))))) (gnus-treat-article 'head))))))
(defun mu4e~view-gnus-insert-header (field val) (defun mu4e~view-gnus-insert-header (field val)
"Insert a header FIELD with value VAL." "Insert a header FIELD with value VAL."
(let* ((info (cdr (assoc field mu4e-header-info))) (let* ((info (cdr (assoc field mu4e-header-info)))
(key (plist-get info :name)) (key (plist-get info :name))
(help (plist-get info :help))) (help (plist-get info :help)))
(if (and val (> (length val) 0)) (if (and val (> (length val) 0))
(insert (propertize (concat key ":") 'help-echo help) (insert (propertize (concat key ":") 'help-echo help)
" " val "\n")))) " " val "\n"))))
(defun mu4e~view-gnus-insert-header-custom (msg field) (defun mu4e~view-gnus-insert-header-custom (msg field)
"Insert MSG's custom FIELD." "Insert MSG's custom FIELD."
(let* ((info (cdr-safe (or (assoc field mu4e-header-info-custom) (let* ((info (cdr-safe (or (assoc field mu4e-header-info-custom)
(mu4e-error "Custom field %S not found" field)))) (mu4e-error "Custom field %S not found" field))))
(key (plist-get info :name)) (key (plist-get info :name))
(func (or (plist-get info :function) (func (or (plist-get info :function)
(mu4e-error "No :function defined for custom field %S %S" (mu4e-error "No :function defined for custom field %S %S"
field info))) field info)))
(val (funcall func msg)) (val (funcall func msg))
(help (plist-get info :help))) (help (plist-get info :help)))
(when (and val (> (length val) 0)) (when (and val (> (length val) 0))
(insert (propertize (concat key ":") 'help-echo help) " " val "\n")))) (insert (propertize (concat key ":") 'help-echo help) " " val "\n"))))
@ -823,14 +823,14 @@ determine which browser function to use."
"Avoid error when displaying an ical attachment without a charset." "Avoid error when displaying an ical attachment without a charset."
(if (and (boundp 'mu4e~view-rendering) mu4e~view-rendering) (if (and (boundp 'mu4e~view-rendering) mu4e~view-rendering)
(let* ((handle (car handle-attendee)) (let* ((handle (car handle-attendee))
(attendee (cadr handle-attendee)) (attendee (cadr handle-attendee))
(buf (mm-handle-buffer handle)) (buf (mm-handle-buffer handle))
(ty (mm-handle-type handle)) (ty (mm-handle-type handle))
(rest (cddr handle))) (rest (cddr handle)))
;; Put the fallback at the end: ;; Put the fallback at the end:
(setq ty (append ty '((charset . "utf-8")))) (setq ty (append ty '((charset . "utf-8"))))
(setq handle (cons buf (cons ty rest))) (setq handle (cons buf (cons ty rest)))
(list handle attendee)) (list handle attendee))
handle-attendee)) handle-attendee))
(defun mu4e~view-mode-p () (defun mu4e~view-mode-p ()
@ -961,26 +961,26 @@ This is useful for advising some Gnus-functionality that does not work in mu4e."
(define-key map [menu-bar headers] (cons "Mu4e" menumap)) (define-key map [menu-bar headers] (cons "Mu4e" menumap))
(define-key menumap [quit-buffer] (define-key menumap [quit-buffer]
'("Quit view" . mu4e~view-quit-buffer)) '("Quit view" . mu4e~view-quit-buffer))
(define-key menumap [display-help] '("Help" . mu4e-display-manual)) (define-key menumap [display-help] '("Help" . kill-buffer-and-window))
(define-key menumap [sepa0] '("--")) (define-key menumap [sepa0] '("--"))
(define-key menumap [wrap-lines] (define-key menumap [wrap-lines]
'("Toggle wrap lines" . visual-line-mode)) '("Toggle wrap lines" . visual-line-mode))
(define-key menumap [raw-view] (define-key menumap [raw-view]
'("View raw message" . mu4e-view-raw-message)) '("View raw message" . mu4e-view-raw-message))
(define-key menumap [pipe] (define-key menumap [pipe]
'("Pipe through shell" . mu4e-view-pipe)) '("Pipe through shell" . mu4e-view-pipe))
(define-key menumap [sepa1] '("--")) (define-key menumap [sepa1] '("--"))
(define-key menumap [mark-delete] (define-key menumap [mark-delete]
'("Mark for deletion" . mu4e-view-mark-for-delete)) '("Mark for deletion" . mu4e-view-mark-for-delete))
(define-key menumap [mark-untrash] (define-key menumap [mark-untrash]
'("Mark for untrash" . mu4e-view-mark-for-untrash)) '("Mark for untrash" . mu4e-view-mark-for-untrash))
(define-key menumap [mark-trash] (define-key menumap [mark-trash]
'("Mark for trash" . mu4e-view-mark-for-trash)) '("Mark for trash" . mu4e-view-mark-for-trash))
(define-key menumap [mark-move] (define-key menumap [mark-move]
'("Mark for move" . mu4e-view-mark-for-move)) '("Mark for move" . mu4e-view-mark-for-move))
(define-key menumap [sepa2] '("--")) (define-key menumap [sepa2] '("--"))
(define-key menumap [resend] '("Resend" . mu4e-compose-resend)) (define-key menumap [resend] '("Resend" . mu4e-compose-resend))
@ -990,17 +990,17 @@ This is useful for advising some Gnus-functionality that does not work in mu4e."
(define-key menumap [sepa3] '("--")) (define-key menumap [sepa3] '("--"))
(define-key menumap [query-next] (define-key menumap [query-next]
'("Next query" . mu4e-headers-query-next)) '("Next query" . mu4e-headers-query-next))
(define-key menumap [query-prev] (define-key menumap [query-prev]
'("Previous query" . mu4e-headers-query-prev)) '("Previous query" . mu4e-headers-query-prev))
(define-key menumap [narrow-search] (define-key menumap [narrow-search]
'("Narrow search" . mu4e-headers-search-narrow)) '("Narrow search" . mu4e-headers-search-narrow))
(define-key menumap [bookmark] (define-key menumap [bookmark]
'("Search bookmark" . mu4e-headers-search-bookmark)) '("Search bookmark" . mu4e-headers-search-bookmark))
(define-key menumap [jump] (define-key menumap [jump]
'("Jump to maildir" . mu4e~headers-jump-to-maildir)) '("Jump to maildir" . mu4e~headers-jump-to-maildir))
(define-key menumap [search] (define-key menumap [search]
'("Search" . mu4e-headers-search)) '("Search" . mu4e-headers-search))
(define-key menumap [sepa4] '("--")) (define-key menumap [sepa4] '("--"))
(define-key menumap [next] '("Next" . mu4e-view-headers-next)) (define-key menumap [next] '("Next" . mu4e-view-headers-next))
@ -1048,9 +1048,9 @@ Based on Gnus' article-mode."
;; advice gnus-block-private-groups to always return "." ;; advice gnus-block-private-groups to always return "."
;; so that by default we block images. ;; so that by default we block images.
(advice-add 'gnus-block-private-groups :around (advice-add 'gnus-block-private-groups :around
(lambda(func &rest args) (lambda(func &rest args)
(if (mu4e~view-mode-p) (if (mu4e~view-mode-p)
"." (apply func args)))) "." (apply func args))))
(use-local-map mu4e-view-mode-map) (use-local-map mu4e-view-mode-map)
(mu4e-context-minor-mode) (mu4e-context-minor-mode)
(mu4e-search-minor-mode) (mu4e-search-minor-mode)
@ -1094,12 +1094,12 @@ The alist uniquely maps the number to the gnus-part."
(save-excursion (save-excursion
(goto-char (point-min)) (goto-char (point-min))
(while (not (eobp)) (while (not (eobp))
(let ((part (get-text-property (point) 'gnus-data)) (let ((part (get-text-property (point) 'gnus-data))
(index (get-text-property (point) 'gnus-part))) (index (get-text-property (point) 'gnus-part)))
(when (and part (numberp index) (not (assoc index parts)) (when (and part (numberp index) (not (assoc index parts))
(push `(,index . ,part) parts))) (push `(,index . ,part) parts)))
(goto-char (or (next-single-property-change (point) 'gnus-part) (goto-char (or (next-single-property-change (point) 'gnus-part)
(point-max)))))) (point-max))))))
parts)) parts))
@ -1118,47 +1118,47 @@ Note, currently this does not work well with file names
containing commas." containing commas."
(interactive "P") (interactive "P")
(cl-assert (and (eq major-mode 'mu4e-view-mode) (cl-assert (and (eq major-mode 'mu4e-view-mode)
(derived-mode-p 'gnus-article-mode))) (derived-mode-p 'gnus-article-mode)))
(let* ((parts (mu4e~view-gather-mime-parts)) (let* ((parts (mu4e~view-gather-mime-parts))
(handles '()) (handles '())
(files '()) (files '())
(compfn (if (and (boundp 'helm-mode) helm-mode) (compfn (if (and (boundp 'helm-mode) helm-mode)
#'completing-read #'completing-read
;; Fallback to `completing-read-multiple' with poor ;; Fallback to `completing-read-multiple' with poor
;; completion ;; completion
#'completing-read-multiple)) #'completing-read-multiple))
dir) dir)
(dolist (part parts) (dolist (part parts)
(let ((fname (or (cdr (assoc 'filename (assoc "attachment" (cdr part)))) (let ((fname (or (cdr (assoc 'filename (assoc "attachment" (cdr part))))
(cl-loop for item in part (cl-loop for item in part
for name = (and (listp item) for name = (and (listp item)
(assoc-default 'name item)) (assoc-default 'name item))
thereis (and (stringp name) name))))) thereis (and (stringp name) name)))))
(when fname (when fname
(push `(,fname . ,(cdr part)) handles) (push `(,fname . ,(cdr part)) handles)
(push fname files)))) (push fname files))))
(if files (if files
(progn (progn
(setq files (let ((helm-comp-read-use-marked t)) (setq files (let ((helm-comp-read-use-marked t))
(funcall compfn "Save part(s): " files)) (funcall compfn "Save part(s): " files))
dir (if arg (read-directory-name "Save to directory: ") dir (if arg (read-directory-name "Save to directory: ")
mu4e-attachment-dir)) mu4e-attachment-dir))
(cl-loop for (f . h) in handles (cl-loop for (f . h) in handles
when (member f files) when (member f files)
do (mm-save-part-to-file do (mm-save-part-to-file
h (let ((file (expand-file-name f dir))) h (let ((file (expand-file-name f dir)))
(if (file-exists-p file) (if (file-exists-p file)
(let (newname (count 1)) (let (newname (count 1))
(while (and (while (and
(setq newname (setq newname
(concat (concat
(file-name-sans-extension file) (file-name-sans-extension file)
(format "(%s)" count) (format "(%s)" count)
(file-name-extension file t))) (file-name-extension file t)))
(file-exists-p newname)) (file-exists-p newname))
(cl-incf count)) (cl-incf count))
newname) newname)
file))))) file)))))
(mu4e-message "No attached files found")))) (mu4e-message "No attached files found"))))
@ -1176,7 +1176,7 @@ containing commas."
(:name "open" :handler mu4e~view-open-file :receives temp) (:name "open" :handler mu4e~view-open-file :receives temp)
;; open with some custom file. ;; open with some custom file.
(:name "wopen-with" :handler (lambda (file)(mu4e~view-open-file file t)) (:name "wopen-with" :handler (lambda (file)(mu4e~view-open-file file t))
:receives temp) :receives temp)
;; ;;
;; some more examples ;; some more examples
@ -1191,13 +1191,13 @@ containing commas."
(:name "emacs" :handler find-file-read-only :receives temp) (:name "emacs" :handler find-file-read-only :receives temp)
;; open in this emacs instance, "raw" ;; open in this emacs instance, "raw"
(:name "raw" :handler (lambda (str) (:name "raw" :handler (lambda (str)
(let ((tmpbuf (let ((tmpbuf
(get-buffer-create " *mu4e-raw-mime*"))) (get-buffer-create " *mu4e-raw-mime*")))
(with-current-buffer tmpbuf (with-current-buffer tmpbuf
(insert str) (insert str)
(view-mode) (view-mode)
(goto-char (point-min))) (goto-char (point-min)))
(display-buffer tmpbuf))) :receives pipe)) (display-buffer tmpbuf))) :receives pipe))
"Specifies actions for MIME-parts. "Specifies actions for MIME-parts.
@ -1205,16 +1205,16 @@ Each of the actions is a plist with keys
`(:name <name> ;; name of the action; shortcut is first letter of name `(:name <name> ;; name of the action; shortcut is first letter of name
:handler ;; one of: :handler ;; one of:
;; - a function receiving the index/temp/pipe ;; - a function receiving the index/temp/pipe
;; - a string, which is taken as a shell command ;; - a string, which is taken as a shell command
:receives ;; a symbol specifying what the handler receives :receives ;; a symbol specifying what the handler receives
;; - index: the index number of the mime part (default) ;; - index: the index number of the mime part (default)
;; - temp: the full path to the mime part in a ;; - temp: the full path to the mime part in a
;; temporary file, which is deleted immediately ;; temporary file, which is deleted immediately
;; after invoking handler ;; after invoking handler
;; - pipe: the attachment is piped to some shell command ;; - pipe: the attachment is piped to some shell command
;; or as a string parameter to a function ;; or as a string parameter to a function
).") ).")
@ -1225,17 +1225,17 @@ otherwise random; the result is placed in a temporary directory
with a unique name. Returns the full path for the file created. with a unique name. Returns the full path for the file created.
The directory and file are self-destructed." The directory and file are self-destructed."
(let* ((tmpdir (make-temp-file "mu4e-temp-" t)) (let* ((tmpdir (make-temp-file "mu4e-temp-" t))
(fname (mm-handle-filename handle)) (fname (mm-handle-filename handle))
(fname (and fname (fname (and fname
(gnus-map-function mm-file-name-rewrite-functions (gnus-map-function mm-file-name-rewrite-functions
(file-name-nondirectory fname)))) (file-name-nondirectory fname))))
(fname (if fname (fname (if fname
(concat tmpdir "/" (replace-regexp-in-string "/" "-" fname)) (concat tmpdir "/" (replace-regexp-in-string "/" "-" fname))
(let ((temporary-file-directory tmpdir)) (let ((temporary-file-directory tmpdir))
(make-temp-file "mimepart"))))) (make-temp-file "mimepart")))))
(mm-save-part-to-file handle fname) (mm-save-part-to-file handle fname)
(run-at-time "30 sec" nil (run-at-time "30 sec" nil
(lambda () (ignore-errors (delete-directory tmpdir t)))) (lambda () (ignore-errors (delete-directory tmpdir t))))
fname)) fname))
@ -1244,12 +1244,12 @@ The directory and file are self-destructed."
Otherwise, or if FORCE-ASK is set, ask user for the program to Otherwise, or if FORCE-ASK is set, ask user for the program to
open with." open with."
(if (and (not force-ask) (if (and (not force-ask)
(functionp mu4e-view-open-program)) (functionp mu4e-view-open-program))
(funcall mu4e-view-open-program file) (funcall mu4e-view-open-program file)
(let ((opener (let ((opener
(or (and (not force-ask) mu4e-view-open-program (or (and (not force-ask) mu4e-view-open-program
(executable-find mu4e-view-open-program)) (executable-find mu4e-view-open-program))
(read-shell-command "Open MIME-part with: ")))) (read-shell-command "Open MIME-part with: "))))
(call-process opener nil 0 nil file)))) (call-process opener nil 0 nil file))))
(defun mu4e-view-mime-part-action (&optional n) (defun mu4e-view-mime-part-action (&optional n)
@ -1258,43 +1258,43 @@ If N is not specified, ask for it. For instance, '3 A o' opens
the third MIME-part." the third MIME-part."
(interactive "NNumber of MIME-part: ") (interactive "NNumber of MIME-part: ")
(let* ((parts (mu4e~view-gather-mime-parts)) (let* ((parts (mu4e~view-gather-mime-parts))
(options (options
(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 (seq-find (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))
(mu4e-error "No such action"))) (mu4e-error "No such action")))
(handler (handler
(or (plist-get action :handler) (or (plist-get action :handler)
(mu4e-error "No :handler item found for action %S" action))) (mu4e-error "No :handler item found for action %S" action)))
(receives (receives
(or (plist-get action :receives) (or (plist-get action :receives)
(mu4e-error "No :receives item found for action %S" action)))) (mu4e-error "No :receives item found for action %S" action))))
(save-excursion (save-excursion
(cond (cond
((functionp handler) ((functionp handler)
(cond (cond
((eq receives 'index) (funcall handler n)) ((eq receives 'index) (funcall handler n))
((eq receives 'pipe) (funcall handler (mm-with-unibyte-buffer ((eq receives 'pipe) (funcall handler (mm-with-unibyte-buffer
(mm-insert-part handle) (mm-insert-part handle)
(buffer-string)))) (buffer-string))))
((eq receives 'temp) ((eq receives 'temp)
(funcall handler (mu4e~view-mime-part-to-temp-file handle))) (funcall handler (mu4e~view-mime-part-to-temp-file handle)))
(t (mu4e-error "Invalid :receive for %S" action)))) (t (mu4e-error "Invalid :receive for %S" action))))
((stringp handler) ((stringp handler)
(cond (cond
((eq receives 'index) ((eq receives 'index)
(shell-command (concat handler " " (shell-quote-argument n)))) (shell-command (concat handler " " (shell-quote-argument n))))
((eq receives 'pipe) (mm-pipe-part handle handler)) ((eq receives 'pipe) (mm-pipe-part handle handler))
((eq receives 'temp) ((eq receives 'temp)
(shell-command (shell-command
(shell-command (concat handler " " (shell-command (concat handler " "
(shell-quote-argument (shell-quote-argument
(mu4e~view-mime-part-to-temp-file handle)))))) (mu4e~view-mime-part-to-temp-file handle))))))
(t (mu4e-error "Invalid action %S" action)))))))) (t (mu4e-error "Invalid action %S" action))))))))
(defun mu4e-view-toggle-html () (defun mu4e-view-toggle-html ()
"Toggle html-display of the first html-part found." "Toggle html-display of the first html-part found."
@ -1303,10 +1303,10 @@ the third MIME-part."
;; pertinence, i.e. the first HTML part found in it is the most important one. ;; pertinence, i.e. the first HTML part found in it is the most important one.
(save-excursion (save-excursion
(if-let ((html-part (if-let ((html-part
(seq-find (lambda (handle) (seq-find (lambda (handle)
(equal (mm-handle-media-type (cdr handle)) "text/html")) (equal (mm-handle-media-type (cdr handle)) "text/html"))
gnus-article-mime-handle-alist))) gnus-article-mime-handle-alist)))
(gnus-article-inline-part (car html-part)) (gnus-article-inline-part (car html-part))
(mu4e-warn "No html part in this message")))) (mu4e-warn "No html part in this message"))))
(defun mu4e-process-file-through-pipe (path pipecmd) (defun mu4e-process-file-through-pipe (path pipecmd)
@ -1314,9 +1314,9 @@ the third MIME-part."
(let ((buf (get-buffer-create "*mu4e-output"))) (let ((buf (get-buffer-create "*mu4e-output")))
(with-current-buffer buf (with-current-buffer buf
(let ((inhibit-read-only t)) (let ((inhibit-read-only t))
(erase-buffer) (erase-buffer)
(call-process-shell-command pipecmd path t t) (call-process-shell-command pipecmd path t t)
(view-mode))) (view-mode)))
(display-buffer buf))) (display-buffer buf)))
;;; Bug Reference mode support ;;; Bug Reference mode support
@ -1337,17 +1337,17 @@ value against HEADER-REGEXP in
(when (derived-mode-p 'mu4e-view-mode) (when (derived-mode-p 'mu4e-view-mode)
(let (header-values) (let (header-values)
(save-excursion (save-excursion
(goto-char (point-min)) (goto-char (point-min))
(dolist (field '("list" "list-id" "to" "from" "cc" "subject")) (dolist (field '("list" "list-id" "to" "from" "cc" "subject"))
(let ((val (mail-fetch-field field))) (let ((val (mail-fetch-field field)))
(when val (when val
(push val header-values))))) (push val header-values)))))
(bug-reference-maybe-setup-from-mail (bug-reference-maybe-setup-from-mail
(mail-fetch-field "maildir") (mail-fetch-field "maildir")
header-values)))) header-values))))
(add-hook 'bug-reference-auto-setup-functions (add-hook 'bug-reference-auto-setup-functions
#'mu4e--view-try-setup-bug-reference-mode) #'mu4e--view-try-setup-bug-reference-mode)
(provide 'mu4e-view) (provide 'mu4e-view)