From mboxrd@z Thu Jan  1 00:00:00 1970
Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail
From: Visuwesh <visuweshm@gmail.com>
Newsgroups: gmane.emacs.devel
Subject: Re: yank-media: allow users to limit image types that can be inserted
Date: Thu, 12 Dec 2024 21:48:30 +0530
Message-ID: <87r06cj2nd.fsf@gmail.com>
References: <79fc91f3-c2c3-44db-9817-595808917f26@cas.cat>
 <86cykufhw7.fsf@gnu.org> <3a015d0f-549a-401f-be1c-651c9dbd5d9a@cas.cat>
 <8634lqfcaf.fsf@gnu.org> <87ikulwsd6.fsf@gmail.com>
 <86o74ddzxp.fsf@gnu.org> <87msiqvkph.fsf@localhost>
 <86ed42bs03.fsf@gnu.org> <874j4yot7x.fsf@localhost>
 <861q01c3h9.fsf@gnu.org> <87wmht3n17.fsf@gmail.com>
 <86v7xdamck.fsf@gnu.org> <87sesh37ya.fsf@gmail.com>
 <86iktd8o9h.fsf@gnu.org> <87iktb171d.fsf@gmail.com>
 <861pzw4r3j.fsf@gnu.org> <87v7x8y81c.fsf@gmail.com>
 <86ttcs38a8.fsf@gnu.org> <87jzdny1g4.fsf@gmail.com>
 <87plncgrq9.fsf@localhost> <87cyjbwsoh.fsf@gmail.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214";
	logging-data="2848"; mail-complaints-to="usenet@ciao.gmane.io"
User-Agent: Gnus/5.13 (Gnus v5.13)
Cc: Eli Zaretskii <eliz@gnu.org>,  pinmacs@cas.cat,  rpluim@gmail.com,
 emacs-devel@gnu.org
To: Ihor Radchenko <yantar92@posteo.net>
Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Thu Dec 12 17:19:27 2024
Return-path: <emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org>
Envelope-to: ged-emacs-devel@m.gmane-mx.org
Original-Received: from lists.gnu.org ([209.51.188.17])
	by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
	(Exim 4.92)
	(envelope-from <emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org>)
	id 1tLluQ-0000Xt-5k
	for ged-emacs-devel@m.gmane-mx.org; Thu, 12 Dec 2024 17:19:26 +0100
Original-Received: from localhost ([::1] helo=lists1p.gnu.org)
	by lists.gnu.org with esmtp (Exim 4.90_1)
	(envelope-from <emacs-devel-bounces@gnu.org>)
	id 1tLltg-0006ko-64; Thu, 12 Dec 2024 11:18:40 -0500
Original-Received: from eggs.gnu.org ([2001:470:142:3::10])
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <visuweshm@gmail.com>)
 id 1tLlte-0006kR-Mv
 for emacs-devel@gnu.org; Thu, 12 Dec 2024 11:18:38 -0500
Original-Received: from mail-pl1-x641.google.com ([2607:f8b0:4864:20::641])
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.90_1) (envelope-from <visuweshm@gmail.com>)
 id 1tLltc-0006gu-DM; Thu, 12 Dec 2024 11:18:38 -0500
Original-Received: by mail-pl1-x641.google.com with SMTP id
 d9443c01a7336-21628b3fe7dso7192665ad.3; 
 Thu, 12 Dec 2024 08:18:35 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1734020314; x=1734625114; darn=gnu.org;
 h=content-transfer-encoding:mime-version:message-id:date:user-agent
 :references:in-reply-to:subject:cc:to:from:from:to:cc:subject:date
 :message-id:reply-to;
 bh=WQdORharJF0t/nj97ypwASRG7VmJfPaD8aWnrQ6bIuA=;
 b=Glha9G2CZVSzJYUN3VZfAYphlEWAAMj6erYJyxTXG8yNDklnwpZ2f57NYLb4yIcH+g
 FIpVT945dgpjTkdZfwjB6aUy3Gyaw6zrJ89OGhdyGUex9vuPfxj1dMiXfZ20R0K6zSCq
 Omiie+NgtX7RemI/2g5iY9306Jd3ja6Qk/GO7XMb0r7+y00nABf+zsfn+q41V9Id7t6z
 yR3yFHTlkjEidBmvAwFpWwfwzrj6LMr5iCks5sAJBYJJ0WRf+vShhaWa+0CfQqo5obb5
 KwXqPD8UDbhtk2ILYLiog04bNv3cbltXjq7LP2LAoJzLOAQze+6qKPz0FchZg7xIOfmh
 ONSA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1734020314; x=1734625114;
 h=content-transfer-encoding:mime-version:message-id:date:user-agent
 :references:in-reply-to:subject:cc:to:from:x-gm-message-state:from
 :to:cc:subject:date:message-id:reply-to;
 bh=WQdORharJF0t/nj97ypwASRG7VmJfPaD8aWnrQ6bIuA=;
 b=WZACZRnj3ylpaAAzK8N/4Sl+5JL51Bcq2M0CpPrAs6YMzOEVd8GC5jPeJjGOyq4BFp
 ePOhvqpRWL4zcwI/usUFjlnGbu480+DFfJayB5JgKh8WlRa1VKhDdOpI8O0QIe8OiMyi
 VTxSQQ5Iiro103GNts1gP5paCzf88e4+G91V8+Y3GjDoeiobmJpMCPHE11VwqUooiGQh
 B2UdJSqBGbJS1hrfg8uAyu4XRpVygd+YQ1MlYrJIHHL5xbTUYJBVaMf5tde/Paul23SN
 EtzXEELzggvP1u/AHi1BHf4o0bdv4B3n2QldtdT7jg90xn9vv8VXktQQv86qHUXDa1Rm
 aeDA==
X-Forwarded-Encrypted: i=1;
 AJvYcCVV1yJmwQIJu1MdYtNR265b1IU/2MY8ubqDA0zvdag/KrAMSyuq+bkmi7OaI6AGXgpVsBS3RsJO/8D0nQ==@gnu.org
X-Gm-Message-State: AOJu0Yx26dgIRHkATDMbpO9bTAnnsZH/DOnRqTtbv8Lp2VD1pSA//maz
 3lQXTuW/mr7awPBJnRcGvmnG581DE6Kz9UIV8QcyGhdFVyfaT/KC
X-Gm-Gg: ASbGncvB8HzBIT1krqM2CJlEAE84kmBlBq3S1pf4ClJ3cEryPzqvMS1CKb74rOIqjBo
 pWbMlCSmSLxX04HIjWF/3O7gzacyC5mTc9vSmpuWX8GyPRf4Fiyef+OOZ6uQb15fb0TdyyLJGlW
 pPAdpECFhIqyDeFK6DdAuX48jptV2ow/1A7v5rrfqrHSsBEVoM913j5fN/wBS84L3fqd4omkn7Q
 dIAPPcWUQv6V9zlYGDgXMUHGC2mAMwpRNHZzsNRvUpXBOPnHPV9AYp+Vg==
X-Google-Smtp-Source: AGHT+IFOyygc2uWFxalcjiTRL87Cgky7zaFg5fyXgO8Utv9wuWjyyRNqX7WJFa7+zKx0BTwJA/HJdQ==
X-Received: by 2002:a17:902:ea05:b0:216:2a36:5b2a with SMTP id
 d9443c01a7336-2178af005femr67278305ad.47.1734020314379; 
 Thu, 12 Dec 2024 08:18:34 -0800 (PST)
Original-Received: from localhost ([1.7.159.70]) by smtp.gmail.com with ESMTPSA id
 41be03b00d2f7-7fd438e4bf1sm6920780a12.25.2024.12.12.08.18.33
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Thu, 12 Dec 2024 08:18:33 -0800 (PST)
In-Reply-To: <87cyjbwsoh.fsf@gmail.com> (Visuwesh's message of "Mon, 04 Nov
 2024 09:34:30 +0530")
Received-SPF: pass client-ip=2607:f8b0:4864:20::641;
 envelope-from=visuweshm@gmail.com; helo=mail-pl1-x641.google.com
X-Spam_score_int: -20
X-Spam_score: -2.1
X-Spam_bar: --
X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,
 DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001,
 RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,
 SPF_PASS=-0.001 autolearn=ham autolearn_force=no
X-Spam_action: no action
X-BeenThere: emacs-devel@gnu.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: "Emacs development discussions." <emacs-devel.gnu.org>
List-Unsubscribe: <https://lists.gnu.org/mailman/options/emacs-devel>,
 <mailto:emacs-devel-request@gnu.org?subject=unsubscribe>
List-Archive: <https://lists.gnu.org/archive/html/emacs-devel>
List-Post: <mailto:emacs-devel@gnu.org>
List-Help: <mailto:emacs-devel-request@gnu.org?subject=help>
List-Subscribe: <https://lists.gnu.org/mailman/listinfo/emacs-devel>,
 <mailto:emacs-devel-request@gnu.org?subject=subscribe>
Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org
Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org
Xref: news.gmane.io gmane.emacs.devel:326431
Archived-At: <http://permalink.gmane.org/gmane.emacs.devel/326431>

[=E0=AE=A4=E0=AE=BF=E0=AE=99=E0=AF=8D=E0=AE=95=E0=AE=B3=E0=AF=8D =E0=AE=A8=
=E0=AE=B5=E0=AE=AE=E0=AF=8D=E0=AE=AA=E0=AE=B0=E0=AF=8D 04, 2024] Visuwesh w=
rote:

To recap,

The OP asked for a way to choose a specific image type out of the
multiple types available in their clipboard.  We decided that Emacs
should auto-select the best type itself and have a way for major-modes
to customise this selection process.  Auto-selection should also be
skipped with a prefix arg.

> [=E0=AE=9E=E0=AE=BE=E0=AE=AF=E0=AE=BF=E0=AE=B1=E0=AF=81 =E0=AE=A8=E0=AE=
=B5=E0=AE=AE=E0=AF=8D=E0=AE=AA=E0=AE=B0=E0=AF=8D 03, 2024] Ihor Radchenko w=
rote:
>
>> Visuwesh <visuweshm@gmail.com> writes:
>>
>>>> And I'm saying that I don't understand why users would need such
>>>> control, in addition to being able to select a format in each case.
>>>
>>> OK, I think I finally understand your stance: we let yank-media pick the
>>> best format out of all in the clipboard based on rules that a major-mode
>>> can tweak.  Apart from this, we also have C-u or somesuch that asks the
>>> user to select the data type instead of auto-selecting it.  Since the
>>> C-u is good enough to override a case-by-case basis, you do not see
>>> value in having a defcustom to let the user customise the selection
>>> rules for the best data type, correct?
>>
>> So, what will be the plan here? A patch?
>
> I just want to inform that I probably won't be able to get to writing a
> patch until mid December since I hardly have time with my semester end
> nearing.

Here's the promised patch (I can create a bug report if that is
preferred):

diff --git a/lisp/yank-media.el b/lisp/yank-media.el
index 17981c37c0e..a5ad913c24a 100644
--- a/lisp/yank-media.el
+++ b/lisp/yank-media.el
@@ -29,19 +29,49 @@
=20
 (defvar yank-media--registered-handlers nil)
=20
+(defvar yank-media-autoselect-function #'yank-media-autoselect-function
+  "Function to auto select the best mime type when many are available.
+The function is called with a list of mime types that have handler in
+the current buffer, and should return the type to use or nil if no
+preferred type is found.")
+
+(defun yank-media-autoselect-function (mimetypes)
+  (cond
+   ;; Check first since LibreOffice also puts a PNG image in the
+   ;; clipboard when a table cell is copied.
+   ((memq 'application/x-libreoffice-tsvc mimetypes)
+    'application/x-libreoffice-tsvc)
+   ;; Give PNG more priority.
+   ((memq 'image/png mimetypes)
+    'image/png)
+   ((memq 'image/jpeg mimetypes)
+    'image/jpeg)
+   ;; These are files copied/cut to the clipboard from a file manager.
+   ((seq-find (lambda (type)
+                (string-match-p "x-special/\\(gnome\|KDE\|mate\)-files"
+                                (symbol-name type)))
+              mimetypes))
+   ;; FIXME: We should have a way to handle text/rtf.
+   ((memq 'text/html mimetypes)
+    'text/html)))
+
 ;;;###autoload
-(defun yank-media ()
+(defun yank-media (&optional noselect)
   "Yank media (images, HTML and the like) from the clipboard.
 This command depends on the current major mode having support for
 accepting the media type.  The mode has to register itself using
 the `yank-media-handler' mechanism.
+Optional argument NOSELECT non-nil (interactively, with a prefix
+argument) means to skip auto-selecting the best mimetype and ask
+for the media type to use when multiple are available.
=20
 Also see `yank-media-types' for a command that lets you explore
 all the different selection types."
-  (interactive)
+  (interactive "P")
   (unless yank-media--registered-handlers
     (user-error "The `%s' mode hasn't registered any handlers" major-mode))
-  (let ((all-types nil))
+  (let ((all-types nil)
+        pref-type)
     (pcase-dolist (`(,handled-type . ,handler)
                    yank-media--registered-handlers)
       (dolist (type (yank-media--find-matching-media handled-type))
@@ -49,18 +79,27 @@ yank-media
     (unless all-types
       (user-error
        "No handler in the current buffer for anything on the clipboard"))
-    ;; We have a handler in the current buffer; if there's just
-    ;; matching type, just call the handler.
-    (if (length=3D all-types 1)
-        (funcall (cdar all-types) (caar all-types)
-                 (yank-media--get-selection (caar all-types)))
-      ;; More than one type the user for what type to insert.
+    (setq pref-type (and (null noselect)
+                         (funcall yank-media-autoselect-function
+                                  (mapcar #'car all-types))))
+    (cond
+     ;; We have a preferred mime type so use it unconditionally.
+     ((and (null noselect) pref-type)
+      (funcall (cdr (assq pref-type all-types)) pref-type
+               (yank-media--get-selection pref-type)))
+     ;; The user chose to not autoselet and there's just a single type,
+     ;; just call the handler.
+     ((length=3D all-types 1)
+      (funcall (cdar all-types) (caar all-types)
+               (yank-media--get-selection (caar all-types))))
+     ;; More than one type the user for what type to insert.
+     (t
       (let ((type
              (intern
               (completing-read "Several types available, choose one: "
                                (mapcar #'car all-types) nil t))))
         (funcall (alist-get type all-types)
-                 type (yank-media--get-selection type))))))
+                 type (yank-media--get-selection type)))))))
=20
 (defun yank-media--find-matching-media (handled-type)
   (seq-filter

As planned, yank-media auto-selects the best media type out of the
available types by default.  This auto-selection can be skipped by
giving a prefix arg.  Some details about the selection process itself:

  1. The autoselect function can return only one preferred type.
  2. There is no user option to control this selection process.  I
     cannot envision such an option myself.  Major mode authors can
     control the selection rules by using add-function (like they
     already do with e.g., filter-buffer-substring-function):

        (add-function :before/:after/:around/...
                      (local 'yank-media-autoselect-function)
                      #'major-mode-ymaf)

     An informed user could do the same if she desires.
  3. The autoselect function _can_ return nil.  If it does, then we
     proceed as if the prefix arg was given.  This makes sense to me
     since we cannot hope to be exhaustive since the mime type can be
     _anything_.  For e.g., Avogadro puts chemical/x-mdl-molfile when
     you select and copy atoms but I doubt many Emacs user would ever
     come across such a type in their clipboard.  So it is best we fall
     over to the NOSELECT=3Dt when the autoselect function returns nil
     instead of signalling an error.
  4. We select application/x-libreoffice-tsvc first since LibreOffice
     also puts image/png when you copy table cell(s).
  5. We prefer PNG images over other types.
  6. We prefer text/html but I believe the plan is to eventually prefer
     text/rtf?

Now some questions:

  1. Should we allow the autoselect function to return _multiple_
     preferred types?
  2. Should we prefer image/svg over image/png and image/jpeg?  Should
     we prefer it over image/jpeg at least?  Or do we leave it to the
     major-mode to take care of this (e.g., as in Robert's example)?
  3. We prefer images over files cut/copied to the clipboard.  I don't
     know if any software puts both image/png and
     x-special/gnome-copied-files to the clipboard.  If it does, which
     do we prefer?  The list of file:// links or raw image/png data?
  4. The mimetype used for cut/copied files only works in Linux
     environments.  If other platforms can present such file:// links in
     the clipboard and Emacs supports it, we would need to add it to the
     list too.