Subject: bug#77731: [PATCH] Add yank-media-handler for copied files from file manager

From: Visuwesh <[email-masked]>
Date: Fri, 11 Apr 2025 14:58:32 +0530

[ This has been sitting in my drafts folder for many months now.  ]

Attached patch adds a yank-media-handler to message-mode to attach files
copied/cut from a file manager.  I tested this patch using pcmanfm and
xfe.  The regexp for the media-type was chosen after the blogpost [1],
pcmanfm in particular sets the media-type to
x-special/gnome-copied-files.

I strip the null byte in the split-string call in the handler because
pcmanfm adds a null byte at the end of clipboard selection.  I don't
know if this is the case with other file managers.

I also cannot find the spec of this clipboard type but [2] and pcmanfm
suggests that the selection is

    OPERATION
    file://FILE1
    file://FILE2...

where OPERATION is either cut or copy, and the rest of the lines are
links to the files.  I do the same as what Org does to parse the above.

1. https://larsee.com/blog/2019/05/clipboard-files/
2. https://indigo.re/posts/2021-12-21-clipboard-data.html

In GNU Emacs 30.0.50 (build 7, x86_64-pc-linux-gnu, X toolkit, Xaw
 scroll bars) of 2023-09-10 built on astatine
Repository revision: af1e860570191014d94484d6944348b1766ba59f
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12101008
System Description: Debian GNU/Linux trixie/sid

Configured using:
 'configure --with-sound=alsa --with-x-toolkit=lucid --with-json
 --without-xaw3d --without-gconf --without-libsystemd --without-cairo'

>From 09d24c4f5aca0c618a23e680b4a0cb77ad690236 Mon Sep 17 00:00:00 2001
From: Visuwesh <[email-masked]>
Date: Fri, 11 Apr 2025 14:55:29 +0530
Subject: [PATCH] Add yank-media-handler for copied files from file manager

* lisp/gnus/message.el (message--yank-media-copied-files-handler): Add
yank-media handler to attach files copied/cut files from file manager.
(message-mode): Register the handler.
* etc/NEWS: Announce the change.
---
 etc/NEWS             |  4 ++++
 lisp/gnus/message.el | 11 +++++++++++
 2 files changed, 15 insertions(+)

diff --git a/etc/NEWS b/etc/NEWS
index 0ff3e8184ee..db5c20589bf 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -776,6 +776,10 @@ default, can be set to a non-nil value to restore the previous behavior.
 It is believed to no longer be useful as a method to fight spam.  The
 'message-generate-hashcash' option is now obsolete and has no effect.
 
+*** Files copied from file managers can be attached using 'yank-media'.
+Pasting files copied from file managers using the 'yank-media' now
+attaches those files.
+
 ** Gnus
 
 ---
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el
index a7f27fe1021..d000fcbe720 100644
--- a/lisp/gnus/message.el
+++ b/lisp/gnus/message.el
@@ -3201,6 +3201,8 @@ message-mode
   (setq-local message-mime-part 0)
   (message-setup-fill-variables)
   (yank-media-handler "image/.*" #'message--yank-media-image-handler)
+  (yank-media-handler "x-special/\\(KDE\|gnome\|mate\\)-copied-files"
+                      #'message--yank-media-copied-files-handler)
   (when message-fill-column
     (setq fill-column message-fill-column)
     (turn-on-auto-fill))
@@ -8944,6 +8946,15 @@ message--yank-media-image-handler
    nil nil t)
   (insert "\n\n"))
 
+(defun message--yank-media-copied-files-handler (_ data)
+  "Attach files copied/cut from the file manager.
+DATA is a string where the first line is the operation to
+perform: copy or cut.  Rest are file: links.  The operation is
+always ignored, and the files are only attached."
+  (let* ((files (cdr (split-string data "[\0\n\r]" t "^file://"))))
+    (dolist (f files)
+      (mml-attach-file f (or (mm-default-file-type f) "application/octet-stream")))))
+
 (defun message--image-part-string (type image)
   (format "<#part type=\"%s\" disposition=inline data-encoding=base64 raw=t>\n%s\n<#/part>"
           type
-- 
2.47.2