embark icon indicating copy to clipboard operation
embark copied to clipboard

Is it possible to use embark to view an attachment externally in gnus?

Open jave opened this issue 6 months ago • 6 comments

Is it possible to use embark to view an attachment externally in gnus?

At the moment I save the attachment to a file using gnus, then navigate to the file using dired, then I open it externaly using & in dired, invoking for instance evince for a pdf.

I tried invoking embark on an attachment in gnus, but wasn't able to find a suitable method.

jave avatar May 19 '25 15:05 jave

Good question! This sounds like something I might also want to do. Embark currently doesn't have anything for this. I think it would be easy to add a target finder that acts on the underlying file of the attachment (downloading it first, if necessary).

oantolin avatar May 21 '25 16:05 oantolin

Oh, I would also like to have this too. Often I accidentally hit embark-act on a Gnus attachment, and then I realize that I have to save the file first.

minad avatar May 24 '25 11:05 minad

A simple prototype:

(defun embark-target-gnus-attachment ()
  (declare-function mm-handle-filename "mm-decode")
  (declare-function mm-save-part-to-file "mm-decode")
  (defvar gnus-article-current)
  (when-let ((handle (get-text-property (point) 'gnus-data))
             (file (mm-handle-filename handle))
             (beg (previous-single-property-change (point) 'gnus-data nil (pos-bol)))
             (end (next-single-property-change beg 'gnus-data nil (pos-eol))))
    (let* ((inhibit-message t)
           (tmp (file-name-concat
                 temporary-file-directory
                 (concat "embark-gnus-attachment-"
                         (sha1 (format "%s%s%S"
                                       user-login-name gnus-article-current file)))))
           (file (file-name-concat tmp (string-replace "/" "-" file))))
      (unless (file-exists-p file)
        (with-file-modes #o700 (make-directory tmp t))
        (mm-save-part-to-file handle file))
      `(file ,file ,beg . ,end))))

(add-hook 'embark-target-finders #'embark-target-gnus-attachment)

I'd love to see something like this in Embark, but I think it needs to be a little more robust for that. In particular, writing the file in the finder seems a bit dangerous.

EDIT: After having played with it for a while, I think it is robust enough. I make sure that the attachment is written only once to a protected and stable temporary directory.

minad avatar May 25 '25 20:05 minad

GNUS has it's own suite of commands to act on attachments: the gnus-mime-* commands. You can open an attachment in a buffer, save it to a file, pipe it through a process, print it, choose a viewer to open it with, etc., or show a menu of these actions. A bunch of them are bound into a keymap at point while point is on an attachment button. I didn't know about all these commands and I wonder if a file target finder is really needed given them.

oantolin avatar May 26 '25 04:05 oantolin

Well, you are right. I am inclined to close #756.

But then I just tried gnus-mime-view-part-internally, gnus-mime-view-part-externally and gnus-mime-view-part. These commands just don't work as nicely. For example gnus-mime-view-part-externally on a PDF attachment asks me for a mime type (why?!) and then still opens the file in pdf-view-mode. gnus-mime-view-part-internally just doesn't do anything (that's odd given that RET works and displays the part after confirmation). gnus-mime-view-part gives me a list of commands to open the PDF, but it seems to rely on some ancient mailcap list, instead of using the "modern" XDG machinery and the standard assigned applications. This means the PDF viewer which I use by default is not even offered.

Maybe the gnus-mime-* commands should just be modernized upstream, replacing mailcap with XDG or offering it as an alternative. I am not sure about Gnus - it seems to lie dormant in some maintenance mode since 10 years or more. It still works very well, maybe except for some of these more recent integrations or its synchronous nature.

minad avatar May 26 '25 04:05 minad

Maybe it is just a matter of configuring mailcap properly, such that it behaves more in line with the rest (I will experiment). I think treating attachements like files in Embark is kind of neat, but otoh the target finder is quite heavy since it saves the file immediately. It could maybe do that instead just before running the action, then it would feel a little more "embarky". This might be possible via some Embark action hooks, but would bring some complexity as well.

EDIT: The mailcap fix is quite easy. With this there is indeed not really a point of adding an Embark target. The key "o" can be used to save, "e" to open externally and "RET" to open internally.

(setq mailcap-user-mime-data '(((viewer . "xdg-open %s") (type . ".*")))))

minad avatar May 26 '25 04:05 minad