bug#65872: [PATCH] Fix interactive display of MIME parts

Davide Masserut via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <[email protected]> Fri, 31 Jul 2026 18:14:36 +0200
Newsgroups gmane.emacs.bugs
Message-ID <[email protected]>
Hi Sean,

Thanks for taking a look.

Symbols are already a support representation for mailcap viewers. 
The docstrings of `mailcap-mime-data' and `mailcap-user-mime-data' 
say the viewer can be either a shell-command or a symbol naming a 
zero-argument function. For example, the PDF viewers list include 
the symbol `doc-view-mode` alongside external command strings such 
as "gv -safer %s".

`mm-display-external' already handles both representations. Thus, 
this is not intended to introduce a new kind of viewer.

The problem is confined to the interactive selection: 
`completing-read' accepts the mixed collection but returns the 
candidate as a string.

I revised the patch to find the selected symbol in original 
collection. The "%s" handling is then applied only if the 
recovered method is actually a string.

Thanks,
Davide
0001-Preserve-Lisp-viewers-selected-interactively.patch (text/x-patch, 1.8 KB)
From 54b322dbdd538e721120ce1e632b500842a306f7 Mon Sep 17 00:00:00 2001
From: Davide Masserut <[email protected]>
Date: Mon, 11 Sep 2023 16:49:21 +0200
Subject: [PATCH] Preserve Lisp viewers selected interactively

`mailcap-mime-info' may return viewer functions as symbols as well as
external commands as strings.  However, `completing-read' returns both
as strings, causing `mm-display-external' to treat a selected Lisp
viewer as a shell command.

* lisp/gnus/mm-decode.el (mm-interactively-view-part): Recover the
selected method from the original collection and add the filename
placeholder only to string methods.
---
 lisp/gnus/mm-decode.el | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/lisp/gnus/mm-decode.el b/lisp/gnus/mm-decode.el
index 717c8a022ef..910246f46de 100644
--- a/lisp/gnus/mm-decode.el
+++ b/lisp/gnus/mm-decode.el
@@ -1503,13 +1503,19 @@ mm-interactively-view-part
 	 (methods
 	  (mapcar (lambda (i) (cdr (assoc 'viewer i)))
 		  (mailcap-mime-info type 'all)))
-	 (method (let ((minibuffer-local-completion-map
-			mm-viewer-completion-map))
-		   (completing-read "Viewer: " methods))))
+	 (method-name
+	  (let ((minibuffer-local-completion-map
+		 mm-viewer-completion-map))
+	    (completing-read "Viewer: " methods)))
+	 ;; `completing-read' converts symbols to strings.  Recover the
+	 ;; corresponding object from the original collection.
+	 (method (or (cl-find method-name methods :test #'string=)
+		     method-name)))
     (when (string= method "")
       (error "No method given"))
-    (if (string-match "^[^% \t]+$" method)
-	(setq method (concat method " %s")))
+    (when (and (stringp method)
+	       (string-match-p "^[^% \t]+$" method))
+      (setq method (concat method " %s")))
     (mm-display-external handle method)))
 
 (defun mm-preferred-alternative (handles &optional preferred)
-- 
2.55.0