From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Visuwesh Newsgroups: gmane.emacs.bugs Subject: bug#75116: [PATCH] Make 'yank-media' autoselect the best media type Date: Thu, 26 Dec 2024 17:57:50 +0530 Message-ID: <87o70yeiih.fsf@gmail.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="3644"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Cc: Ihor Radchenko , pinmacs@cas.cat, rpluim@gmail.com, Eli Zaretskii To: 75116@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Thu Dec 26 13:29:23 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@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 ) id 1tQmzS-0000lc-Hm for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 26 Dec 2024 13:29:22 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tQmzC-000132-2J; Thu, 26 Dec 2024 07:29:06 -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 ) id 1tQmz9-00012o-MK for bug-gnu-emacs@gnu.org; Thu, 26 Dec 2024 07:29:03 -0500 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tQmz9-0006PX-DJ; Thu, 26 Dec 2024 07:29:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=MIME-Version:Date:From:To:Subject; bh=JGaRogkqW8qru0U7Ye+xb6fQP8EYxcvTp6WHzq7Hfvw=; b=S/2xCCOph+5Hi7Ohq766Ulf/pBgptSr3YlyLiLb+7n2hrYW8QXz+4GfGv70/8nFawcqU+OnU78DNA4pJG6iqepR7paz9egPOhAF4s+Rm2h/pdqOus68UMoGYxbThqvAdcivsDFpdtS7ru/RYjq6eNP7DXUqmk4G55O5DMz+jjJMa5UDLBlYfdGnP0jNCRj6kGSoetyDuwrbjJ6fiUGpoZ7fUq7DOnDnYmLdMZopd2TbYVRj9PGbOGvUfaJNFtUua+Ilrshs6VzkTDQFnJ0SFlz+r3IHltq+YcplkZeNbmz4Th5Osc9FKdbzaf5ZewuFtrWfb4QRZCkAdTh5w4xRS5g==; Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1tQmz8-0003Ur-4j; Thu, 26 Dec 2024 07:29:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Visuwesh Original-Sender: "Debbugs-submit" Resent-CC: yantar92@posteo.net, pinmacs@cas.cat, rpluim@gmail.com, eliz@gnu.org, bug-gnu-emacs@gnu.org Resent-Date: Thu, 26 Dec 2024 12:29:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 75116 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch X-Debbugs-Original-To: bug-gnu-emacs@gnu.org X-Debbugs-Original-Xcc: Ihor Radchenko , pinmacs@cas.cat, rpluim@gmail.com, Eli Zaretskii Original-Received: via spool by submit@debbugs.gnu.org id=B.173521608413371 (code B ref -1); Thu, 26 Dec 2024 12:29:01 +0000 Original-Received: (at submit) by debbugs.gnu.org; 26 Dec 2024 12:28:04 +0000 Original-Received: from localhost ([127.0.0.1]:40391 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tQmyB-0003Tb-OF for submit@debbugs.gnu.org; Thu, 26 Dec 2024 07:28:04 -0500 Original-Received: from lists.gnu.org ([209.51.188.17]:37602) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tQmy7-0003T8-Qf for submit@debbugs.gnu.org; Thu, 26 Dec 2024 07:28:02 -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 ) id 1tQmy6-0000xb-Fa for bug-gnu-emacs@gnu.org; Thu, 26 Dec 2024 07:27:58 -0500 Original-Received: from mail-pl1-x644.google.com ([2607:f8b0:4864:20::644]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tQmy3-0006JN-Km for bug-gnu-emacs@gnu.org; Thu, 26 Dec 2024 07:27:58 -0500 Original-Received: by mail-pl1-x644.google.com with SMTP id d9443c01a7336-21636268e43so2386705ad.2 for ; Thu, 26 Dec 2024 04:27:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1735216074; x=1735820874; darn=gnu.org; h=mime-version:user-agent:message-id:date:subject:to:from:from:to:cc :subject:date:message-id:reply-to; bh=JGaRogkqW8qru0U7Ye+xb6fQP8EYxcvTp6WHzq7Hfvw=; b=GT2UUGPI/lT6InCtyYBTNpZ++SxRL6YRG+fIZdugm2/b3GC4dNYzi/KLjz9fPm24fQ oBpRJpKqF/uTatjWSGRcQmgfAscTbd3t/7FD1xpEi24xgUpLyYL/WqL9vW9PFNCPlI3M qTH6ycB3iZg9tuiqMtFZWi3ca1hAyFAyDJGQtsmiNXwBC9ppITaAv+DZGk7vl3payBzF DUwyd11x10RUafjLZJDz3GIpO7oEdCgtRT5G+GtHVQLA4ucjJtqTro647yf9gsxyKDAI /EwXILlIKqpbi1oOsivhex3YR/cLuBiBeIo682v+bvNr9p7mfJDS1JRpbD/f4yNKvYSK 3xFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1735216074; x=1735820874; h=mime-version:user-agent:message-id:date:subject:to:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=JGaRogkqW8qru0U7Ye+xb6fQP8EYxcvTp6WHzq7Hfvw=; b=oWHDUkwf/ez3+KqbFeuKnRf9VwgEnHA0E1TSAjQkAE2bhBzciTlQwNLV90I+vLVk7Z uN0xQBiIAmttOzLfhbnIeQVZYc1RvanrXxzw2cvR5lCmCTdlZdxrzWRnXG9FsZFtP82d scBnT+suYfYxuJr8m3wmBiUI1L9bcsxvo7wXXC8x3HMyupKp6afSn/5hH/tI4QrMhYOO psSocI/kL0gX0uwe8a0SlSo7DJ8SjKSiQTj+EggIuW4iyJ1Q2sihdLJXQsEa4T1Rxf6y KrccEu+EWkx1SuxiS/qB4fJAR2l/SjE6QPBcBit7FUR9A7eAbZF7cz05mEoLbw9cPWa1 v1aw== X-Gm-Message-State: AOJu0Yw78HGr9aVk9jQSmavJUt66NIgUGuLaySzQ6NRhh/AsURYq+Kj5 SaCSF8k6NWK7RXYpxhft+U/5BiNSv12LV8VWLmHUdwYrVWQbZ0Z4DgpXv0C9 X-Gm-Gg: ASbGncuOjC6OsiTT/hggH6QVK8/HyS8wxcARCI6zRU0pVjJiTKYYxkhTf3LyS6EvwAh vrf1IHic9Ohmt0lzrKdIK3RNIy7GhYsFGVNi/b3Z9n50kehBR3D12gkECaEYHYOazp6KRGYlv5q STOWQ6LkwZ9kOj7j96eV5D+RuCDMVgQxk6ITmPfVxhJCn3v00UuE3ddcwWP5BPVgQn2lUWXejLg WTJFONydlxc7XZISQan9m3aermP/j7RKPxLq2/BCm1hKxdAaAo= X-Google-Smtp-Source: AGHT+IFOL7RmEm8HeLN6lhBQWbLVzxOwQJhTJrCpKHwSmSozcN6AkBzFQ0LqvopHWIlslV2uaZXWyw== X-Received: by 2002:a05:6a20:12d2:b0:1e1:3970:d75a with SMTP id adf61e73a8af0-1e5e0458eadmr40019268637.9.1735216073762; Thu, 26 Dec 2024 04:27:53 -0800 (PST) Original-Received: from localhost ([49.205.85.12]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-72aad81575fsm12737330b3a.36.2024.12.26.04.27.52 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Dec 2024 04:27:52 -0800 (PST) Received-SPF: pass client-ip=2607:f8b0:4864:20::644; envelope-from=visuweshm@gmail.com; helo=mail-pl1-x644.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: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:297767 Archived-At: --=-=-= Content-Type: text/plain Tags: patch This is a continuation of the long thread in emacs-devel: https://yhetil.org/emacs-devel/79fc91f3-c2c3-44db-9817-595808917f26@cas.cat/ This message provides a summary: https://yhetil.org/87r06cj2nd.fsf@gmail.com Ihor wrote: > The only comment is that leaving an option to return a list of types > rather than only a single type will make things more flexible. And this is now done in the attached patch. Before I go about writing NEWS and updating the manual, what do you think about the attached instead? I think the variable yank-media-preferred-types gives a more granular control for major-mode authors than (add-function (local 'yank-media-autoselect-function) ...) --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=yank-media-autoselect-other.diff diff --git a/lisp/yank-media.el b/lisp/yank-media.el index 17981c37c0e..010e942680d 100644 --- a/lisp/yank-media.el +++ b/lisp/yank-media.el @@ -29,19 +29,57 @@ (defvar yank-media--registered-handlers nil) +(defvar yank-media-preferred-types + `(;; Check first since LibreOffice also puts a PNG image in the + ;; clipboard when a table cell is copied. + application/x-libreoffice-tsvc + ;; Give PNG more priority. + image/png + image/jpeg + ;; These are files copied/cut to the clipboard from a file manager. + ,(lambda (mimetypes) + (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. + text/html) + "List of mime types in the order of preference. +Each element in the list should be a symbol to choose the mime type +denoted by it, or a function of one argument, the mime types available, +and should return the mime types to use.") + +(defvar yank-media-autoselect-function #'yank-media-autoselect-function + "Function to auto select the best mime types 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 or a list of types to +use, or nil if no preferred type is found.") + +(defun yank-media-autoselect-function (mimetypes) + (catch 'preferred + (dolist (typ yank-media-preferred-types) + (let ((ret (if (functionp typ) + (funcall typ mimetypes) + (and (memq typ mimetypes) typ)))) + (when ret (throw 'preferred typ)))))) + ;;;###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. 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 +87,28 @@ 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= 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 one preferred mime type so use it unconditionally. + ((and pref-type (symbolp pref-type)) + (funcall (cdr (assq pref-type all-types)) pref-type + (yank-media--get-selection pref-type))) + ;; The user chose to not autoselect and there's just a single type, + ;; just call the handler. + ((and (null pref-type) (length= all-types 1)) + (funcall (cdar all-types) (caar all-types) + (yank-media--get-selection (caar all-types)))) + ;; More than one type, ask the user for what type to insert. + (t (let ((type (intern (completing-read "Several types available, choose one: " - (mapcar #'car all-types) nil t)))) + (or pref-type (mapcar #'car all-types)) + nil t)))) (funcall (alist-get type all-types) - type (yank-media--get-selection type)))))) + type (yank-media--get-selection type))))))) (defun yank-media--find-matching-media (handled-type) (seq-filter --=-=-= Content-Type: text/plain I know that I have to update the Info node (info "(elisp) Yanking Media"). Does (info "(emacs) Clipboard") need any update too? In GNU Emacs 31.0.50 (build 27, x86_64-pc-linux-gnu, X toolkit, cairo version 1.18.2, Xaw scroll bars) of 2024-12-07 built on astatine Repository revision: 9ddec89e422d0dd6e9069731b8f2dd2c90aa5607 Repository branch: master Windowing system distributor 'The X.Org Foundation', version 11.0.12101014 System Description: Debian GNU/Linux trixie/sid Configured using: 'configure --with-sound=alsa --with-x-toolkit=lucid --without-xaw3d --without-gconf --without-libsystemd --with-cairo CFLAGS=-g3' --=-=-= Content-Type: text/patch Content-Disposition: attachment; filename=0001-Make-yank-media-autoselect-the-best-media-type.patch >From b12ea40822eb0cacf67de514f273cba6f283e580 Mon Sep 17 00:00:00 2001 From: Visuwesh Date: Thu, 26 Dec 2024 17:50:13 +0530 Subject: [PATCH] Make 'yank-media' autoselect the best media type * lisp/yank-media.el (yank-media-autoselect-function) (yank-media-autoselect-function): Add new variable and function to make 'yank-media' choose the best/preferred media type out of the available ones. (yank-media): Change to account for above. --- lisp/yank-media.el | 62 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/lisp/yank-media.el b/lisp/yank-media.el index 17981c37c0e..86dc05cd4f0 100644 --- a/lisp/yank-media.el +++ b/lisp/yank-media.el @@ -29,19 +29,49 @@ (defvar yank-media--registered-handlers nil) +(defvar yank-media-autoselect-function #'yank-media-autoselect-function + "Function to auto select the best mime types 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 or a list of types 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. 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,28 @@ 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= 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 one preferred mime type so use it unconditionally. + ((and pref-type (symbolp pref-type)) + (funcall (cdr (assq pref-type all-types)) pref-type + (yank-media--get-selection pref-type))) + ;; The user chose to not autoselect and there's just a single type, + ;; just call the handler. + ((and (null pref-type) (length= all-types 1)) + (funcall (cdar all-types) (caar all-types) + (yank-media--get-selection (caar all-types)))) + ;; More than one type, ask the user for what type to insert. + (t (let ((type (intern (completing-read "Several types available, choose one: " - (mapcar #'car all-types) nil t)))) + (or pref-type (mapcar #'car all-types)) + nil t)))) (funcall (alist-get type all-types) - type (yank-media--get-selection type)))))) + type (yank-media--get-selection type))))))) (defun yank-media--find-matching-media (handled-type) (seq-filter -- 2.45.2 --=-=-=--