diff options
| author | Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> | 2026-03-14 21:38:32 +0200 |
|---|---|---|
| committer | Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> | 2026-03-14 22:20:13 +0200 |
| commit | 9b40d7d3f8825e90234f3a07fd6888e4a1f672f3 (patch) | |
| tree | c2620b97b682702db2dac5174b1a80c1854382c6 /mu4e | |
| parent | 90c47ddcaa7d41087b64a9549d457a572dcaa6bb (diff) | |
mu4e-view/mime: clean up message rendering
Make the message-rendering slightly less messy
Of course, It still is a bit messy, partly because e're bending over
gnu's message rendering backwards.
But it removes the MIME-buttons. If you want them back, use "M b".
Update the mime-handling so we can still get things even with the
MIME-buttons disabled.
Diffstat (limited to 'mu4e')
| -rw-r--r-- | mu4e/mu4e-mime-parts.el | 74 | ||||
| -rw-r--r-- | mu4e/mu4e-view.el | 73 |
2 files changed, 74 insertions, 73 deletions
diff --git a/mu4e/mu4e-mime-parts.el b/mu4e/mu4e-mime-parts.el index fa97dad..507e35d 100644 --- a/mu4e/mu4e-mime-parts.el +++ b/mu4e/mu4e-mime-parts.el @@ -93,50 +93,42 @@ There are some internal fields as well, e.g. ; subject to change: :target-dir : Target directory for saving :attachment-like : When it has a filename, we can save it - :handle : Gnus handle." + :handle : Gnus handle. + +This uses `gnus-article-mime-handle-alist'." (or mu4e--view-mime-parts (setq mu4e--view-mime-parts - (let ((parts) (indices)) - (save-excursion - (goto-char (point-min)) - (while (not (eobp)) - (when-let* ((part (get-text-property (point) 'gnus-data)) - (index (get-text-property (point) 'gnus-part))) - (when (and part (numberp index) (not (member index indices))) - (let* ((disp (mm-handle-disposition part)) - (fname (mm-handle-filename part)) - (fname (and fname ;; massage - (gnus-map-function mm-file-name-rewrite-functions - (file-name-nondirectory fname)))) - (mime-type (mm-handle-media-type part)) - (info - `(:part-index ,index - :mime-type ,mime-type - :encoding ,(mm-handle-encoding part) - :disposition ,(car-safe disp) - - ;; if there's no file-name, invent one - ;; XXX perhaps guess extension based on mime-type - :filename ,(or fname - (format "mime-part-%02d" index)) - - ;; below are internal - - :target-dir ,(mu4e-determine-attachment-dir - fname mime-type) - ;; 'attachment-like' just means it has its own - ;; filename an we thus we can save it through - ;; `mu4e-view-save-attachments', even if it has an - ;; 'inline' disposition. - :attachment-like ,(if fname t nil) - :handle ,part))) - (push index indices) - (push info parts)))) - (goto-char (or (next-single-property-change (point) 'gnus-part) - (point-max))))) - ;; sort by the GNU's part-index, so the order is the same as - ;; in the message on screen + (let ((parts)) + (dolist (entry gnus-article-mime-handle-alist) + (let* ((index (car entry)) + (handle (cdr entry))) + (when (and (numberp index) (listp handle) + (bufferp (car-safe handle))) + (let* ((disp (mm-handle-disposition handle)) + (fname (mm-handle-filename handle)) + (fname (and fname + (gnus-map-function + mm-file-name-rewrite-functions + (file-name-nondirectory fname)))) + (mime-type (mm-handle-media-type handle))) + (push `(:part-index ,index + :mime-type ,mime-type + :encoding ,(mm-handle-encoding handle) + :disposition ,(car-safe disp) + ;; if there's no file-name, invent one + ;; XXX perhaps guess extension based on mime-type + :filename ,(or fname + (format "mime-part-%02d" index)) + :target-dir ,(mu4e-determine-attachment-dir + fname mime-type) + ;; 'attachment-like' just means it has its own + ;; filename an we thus we can save it through + ;; `mu4e-view-save-attachments', even if it has an + ;; 'inline' disposition. + :attachment-like ,(if fname t nil) + :handle ,handle) + parts))))) (seq-sort (lambda (p1 p2) (< (plist-get p1 :part-index) (plist-get p2 :part-index))) parts))))) diff --git a/mu4e/mu4e-view.el b/mu4e/mu4e-view.el index d243fdb..f42c3ae 100644 --- a/mu4e/mu4e-view.el +++ b/mu4e/mu4e-view.el @@ -601,23 +601,9 @@ message." (defvar gnus-icalendar-additional-identities) (defvar-local mu4e--view-rendering nil) -(defun mu4e--fake-original-article-buffer () - "Create a fake original gnus article buffer. - -With this, some Gnus commands that require an original message -buffer can work, e.g. for dealing with mailing-lists. We only -store the headers, not the body, to save some memory, as we don't -need the body. - -This must be called while in the raw message buffer." - (message-narrow-to-headers-or-head) - (let ((headers (buffer-string))) - (widen) - (with-current-buffer - (get-buffer-create gnus-original-article-buffer 'no-hooks) - (erase-buffer) - (insert headers) - (current-buffer)))) +(defvar mu4e--view-show-mime-buttons nil + "Whether to show MIME part buttons (e.g. \"[1. text/html]\"). +Toggle with `mu4e-view-toggle-mime-buttons'.") (defun mu4e--original-article-field (field) "Get FIELD from the original article." @@ -642,7 +628,7 @@ As a side-effect, a message that is being viewed loses its ;; Unfortunately that does create its own issues: namely ensuring ;; buffer-local state that *must* survive is correctly copied ;; across. - (let ((linked-headers-buffer) (orig-art-buf)) + (let ((linked-headers-buffer)) (when-let* ((existing-buffer (mu4e-get-view-buffer nil nil))) ;; required; this state must carry over from the killed buffer ;; to the new one. @@ -659,16 +645,10 @@ As a side-effect, a message that is being viewed loses its (gnus-buttonized-mime-types (append (list "multipart/signed" "multipart/encrypted") gnus-buttonized-mime-types)) - (gnus-inhibit-mime-unbuttonizing t)) - (remove-overlays (point-min)(point-max) 'mu4e-overlay t) + (gnus-inhibit-mime-unbuttonizing mu4e--view-show-mime-buttons)) (erase-buffer) (insert-file-contents-literally (mu4e-message-readable-path msg) nil nil nil t) - ;; set up an original-article-buffer, gnus wants it. - (setq orig-art-buf (mu4e--fake-original-article-buffer)) - ;; some messages have ^M which causes various rendering - ;; problems later (#2260, #2508), so let's remove those - (article-remove-cr) (setq-local mu4e--view-message msg) (ignore-errors (mu4e--view-render-buffer msg))) @@ -692,7 +672,8 @@ As a side-effect, a message that is being viewed loses its ;; support bookmarks. (setq-local bookmark-make-record-function #'mu4e--make-bookmark-record - gnus-original-article orig-art-buf) + gnus-original-article + (get-buffer gnus-original-article-buffer)) ;; only needed on some setups; #2683 (goto-char (point-min))))) @@ -743,22 +724,41 @@ determine which browser function to use." (mu4e-action-view-in-browser msg))) (defun mu4e--view-render-buffer (msg) - "Render current buffer with MSG using Gnus' article mode." - (setq-local gnus-summary-buffer (get-buffer-create " *appease-gnus*")) + "Render current buffer with MSG using Gnus' article mode. +The buffer must already contain the raw message. This function +decodes and displays it, sets up the original-article-buffer, and +activates URLs." (let* ((inhibit-read-only t) + ;; Let gnus-summary-buffer be nil; all gnus-art.el code + ;; guards its usage with `gnus-buffer-live-p' or + ;; `condition-case', so nil is safe and avoids the need + ;; for a fake summary buffer. + (gnus-summary-buffer nil) + (gnus-article-buffer (current-buffer)) (max-specpdl-size mu4e-view-max-specpdl-size) (mm-decrypt-option 'known) (ct (mail-fetch-field "Content-Type")) (ct (and ct (mail-header-parse-content-type ct))) (charset (mail-content-type-get ct '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 nil) ;; avoid perf problems (gnus-newsgroup-charset (if (and charset (coding-system-p charset)) charset (detect-coding-region (point-min) (point-max) t))) ;; Possibly add headers (before "Attachments") (gnus-display-mime-function (mu4e--view-gnus-display-mime msg))) + ;; Populate gnus-original-article-buffer with the headers so + ;; Gnus helpers (e.g. mailing-list detection) can find them. + (message-narrow-to-headers-or-head) + (let ((headers (buffer-string))) + (widen) + (with-current-buffer + (get-buffer-create gnus-original-article-buffer 'no-hooks) + (erase-buffer) + (insert headers))) + ;; Strip ^M that can cause rendering problems (#2260, #2508). + (article-remove-cr) (condition-case err (progn (mm-enable-multibyte) @@ -766,7 +766,6 @@ determine which browser function to use." (ignore-errors (run-hooks 'gnus-article-decode-hook)) (gnus-article-prepare-display) (mu4e--view-activate-urls) - ;; `gnus-summary-bookmark-make-record' does not work properly when "appeased." (kill-local-variable 'bookmark-make-record-function) (setq mu4e~gnus-article-mime-handles gnus-article-mime-handles gnus-article-decoded-p gnus-article-decode-hook) @@ -799,6 +798,15 @@ To go back to normal display, quit the message and re-open." (gnus-mime-display-multipart-as-mixed toggle)) (mu4e-view-refresh))) +(defun mu4e-view-toggle-mime-buttons () + "Toggle display of MIME part buttons and re-render." + (interactive) + (setq mu4e--view-show-mime-buttons + (not mu4e--view-show-mime-buttons)) + (mu4e-view-refresh) + (mu4e-message "MIME part buttons %s" + (if mu4e--view-show-mime-buttons "shown" "hidden"))) + (defun mu4e-view-toggle-fill-flowed() "Toggle flowed-message text filling." (interactive) @@ -1137,8 +1145,9 @@ Based on Gnus' article-mode." ("htoggle headers" . gnus-article-hide-headers) ("ytoggle crypto" . gnus-article-hide-pem) ("ftoggle fill-flowed" . mu4e-view-toggle-fill-flowed) - ("mtoggle show all MIME parts" . mu4e-view-toggle-show-mime-parts) - ("Mtoggle show emulate MIME" . mu4e-view-toggle-emulate-mime)) + ("btoggle MIME buttons" . mu4e-view-toggle-mime-buttons) + ("mtoggle show all MIME parts" . mu4e-view-show-mime-parts) + ("Mtoggle emulate MIME" . mu4e-view-toggle-emulate-mime)) "Various options for \"massaging\" the message view. See `(gnus) Article Treatment' for more options." :group 'mu4e-view |
