aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVisuwesh2025-02-13 16:43:06 +0530
committerEli Zaretskii2025-02-22 11:37:23 +0200
commit0ee50a3420fb8df8f3477dac610dcd53c633fff5 (patch)
treef36523c55e1cb7c42022cc39dc88b83a919119dd
parent3e269371507ea4cd7e933e39320d258a3b98de44 (diff)
downloademacs-0ee50a3420fb8df8f3477dac610dcd53c633fff5.tar.gz
emacs-0ee50a3420fb8df8f3477dac610dcd53c633fff5.zip
Make yank-media auto select the best mime type
* lisp/yank-media.el (yank-media-preferred-types): Add new variable that holds the list of mime types in order of their preference. (yank-media-autoselect-function): Add new variable and function to choose the most preferred media type. (yank-media): Make 'yank-media' choose the most preferred mime type by default. * doc/emacs/killing.texi (Clipboard): * doc/lispref/frames.texi (Yanking Media): Document the new behaviour, and the new variables. * etc/NEWS: Announce the change. (Bug#75116)
-rw-r--r--doc/emacs/killing.texi6
-rw-r--r--doc/lispref/frames.texi24
-rw-r--r--etc/NEWS8
-rw-r--r--lisp/yank-media.el85
4 files changed, 111 insertions, 12 deletions
diff --git a/doc/emacs/killing.texi b/doc/emacs/killing.texi
index 070e15dee76..aee68608bbf 100644
--- a/doc/emacs/killing.texi
+++ b/doc/emacs/killing.texi
@@ -587,8 +587,10 @@ change the variable @code{select-enable-clipboard} to @code{nil}.
587instance, a web browser will usually let you choose ``Copy Image'' on 587instance, a web browser will usually let you choose ``Copy Image'' on
588images, and this image will be put on the clipboard. On capable 588images, and this image will be put on the clipboard. On capable
589platforms, Emacs can yank these objects with the @code{yank-media} 589platforms, Emacs can yank these objects with the @code{yank-media}
590command---but only in modes that have support for it (@pxref{Yanking 590command---but only in modes that have support for it. By default, it
591Media,,, elisp, The Emacs Lisp Reference Manual}). 591auto-selects the preferred media type available in the clipboard but
592this can be overriden by giving the prefix argument to the command
593(@pxref{Yanking Media,,, elisp, The Emacs Lisp Reference Manual}).
592 594
593@cindex clipboard manager 595@cindex clipboard manager
594@vindex x-select-enable-clipboard-manager 596@vindex x-select-enable-clipboard-manager
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index bc2d6b07ae8..984f9bb597d 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -4812,6 +4812,30 @@ designating the matching selection data type, and the data returned by
4812@code{gui-get-selection}. 4812@code{gui-get-selection}.
4813@end defun 4813@end defun
4814 4814
4815The @code{yank-media} command auto selects the preferred @sc{mime} type
4816by default. The rules used for the selection can be controlled through
4817the variables @code{yank-media-autoselect-function} and
4818@code{yank-media-preferred-types}.
4819
4820@defvar yank-media-autoselect-function
4821This variable should specify a function that will be called with the
4822list of @sc{mime} types available for the current major mode, and should
4823return a list of preferred @sc{mime} types to use. The first @sc{mime}
4824type in the list will always be used by the @code{yank-media} command
4825when auto selection is requested.
4826@end defvar
4827
4828@defvar yank-media-preferred-types
4829This variable changes the default selection process of
4830@code{yank-media-autoselect-function}. It is a list that should contain
4831the sole @sc{mime} type to choose in the order of their preference. It
4832can also contain a function in which case it is called with the list of
4833available @sc{mime} types and must return a list of preferred @sc{mime}
4834types in order of their preference. This list is passed onto the
4835@code{yank-media} command so the first element of the returned list is
4836chosen when auto selection is requested.
4837@end defvar
4838
4815The @code{yank-media-types} command presents a list of selection data 4839The @code{yank-media-types} command presents a list of selection data
4816types that are currently available, which is useful when implementing 4840types that are currently available, which is useful when implementing
4817yank-media handlers; for programs generally offer an eclectic and 4841yank-media handlers; for programs generally offer an eclectic and
diff --git a/etc/NEWS b/etc/NEWS
index b9b537ab4f5..110e955e82a 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1252,6 +1252,14 @@ connected, to facilitate enabling 'strokes-mode' in sessions where the
1252availability of a mouse device varies during execution (as is frequently 1252availability of a mouse device varies during execution (as is frequently
1253observed on Android). 1253observed on Android).
1254 1254
1255** Yank media
1256
1257+++
1258*** 'yank-media' now auto-selects the most preferred MIME type.
1259Major-mode authors can customise the variables
1260'yank-media-autoselect-function' and/or 'yank-media-preferred-types' to
1261change the selection rules.
1262
1255 1263
1256* New Modes and Packages in Emacs 31.1 1264* New Modes and Packages in Emacs 31.1
1257 1265
diff --git a/lisp/yank-media.el b/lisp/yank-media.el
index bb62ba272d3..31166b8e634 100644
--- a/lisp/yank-media.el
+++ b/lisp/yank-media.el
@@ -29,19 +29,67 @@
29 29
30(defvar yank-media--registered-handlers nil) 30(defvar yank-media--registered-handlers nil)
31 31
32(defvar yank-media-autoselect-function #'yank-media-autoselect-function
33 "Function to auto select the best MIME types when many are available.
34The function is called with a list of MIME types that have handler in
35the current buffer, and should return the list of MIME types to use in
36order of their priority. When `yank-media' auto-selects the MIME type,
37it will always choose the first one of the returned list.
38Major-mode authors can change this variable to influence the selection
39process.")
40
41(defvar yank-media-preferred-types
42 `(;; Check first since LibreOffice also puts a PNG image in the
43 ;; clipboard when a table cell is copied.
44 application/x-libreoffice-tsvc
45 ;; Give PNG more priority.
46 image/png
47 image/jpeg
48 ;; These are files copied/cut to the clipboard from a file manager
49 ;; in a GNU/Linux and/or BSD environment.
50 ,@(when (memq window-system '(x pgtk))
51 (list (lambda (mimetypes)
52 (ensure-list
53 (seq-find (lambda (type)
54 (string-match-p "x-special/\\(gnome\\|KDE\\|mate\\)-copied-files"
55 (symbol-name type)))
56 mimetypes)))))
57 ;; FIXME: We should have a way to handle text/rtf.
58 text/html)
59 "List of MIME types in the order of preference.
60Each element in the list should be a symbol to choose that MIME type
61exclusively, or a function of one argument and should return the list of
62MIME types to use in order of their priority or nil if no preferred type
63is found.
64Major-mode authors can change this variable to influence the selection
65process, or by directly changing the variable
66`yank-media-autoselect-function'.")
67
68(defun yank-media-autoselect-function (mimetypes)
69 (catch 'preferred
70 (dolist (typ yank-media-preferred-types)
71 (let ((ret (if (functionp typ)
72 (funcall typ mimetypes)
73 (and (memq typ mimetypes) (list typ)))))
74 (when ret (throw 'preferred ret))))))
75
32;;;###autoload 76;;;###autoload
33(defun yank-media () 77(defun yank-media (&optional noselect)
34 "Yank media (images, HTML and the like) from the clipboard. 78 "Yank media (images, HTML and the like) from the clipboard.
35This command depends on the current major mode having support for 79This command depends on the current major mode having support for
36accepting the media type. The mode has to register itself using 80accepting the media type. The mode has to register itself using
37the `yank-media-handler' mechanism. 81the `yank-media-handler' mechanism.
82Optional argument NOSELECT non-nil (interactively, with a prefix
83argument) means to skip auto-selecting the best MIME type and ask for
84the MIME type to use.
38 85
39Also see `yank-media-types' for a command that lets you explore 86Also see `yank-media-types' for a command that lets you explore
40all the different selection types." 87all the different selection types."
41 (interactive) 88 (interactive "P")
42 (unless yank-media--registered-handlers 89 (unless yank-media--registered-handlers
43 (user-error "The `%s' mode hasn't registered any handlers" major-mode)) 90 (user-error "The `%s' mode hasn't registered any handlers" major-mode))
44 (let ((all-types nil)) 91 (let ((all-types nil)
92 pref-type)
45 (pcase-dolist (`(,handled-type . ,handler) 93 (pcase-dolist (`(,handled-type . ,handler)
46 yank-media--registered-handlers) 94 yank-media--registered-handlers)
47 (dolist (type (yank-media--find-matching-media handled-type)) 95 (dolist (type (yank-media--find-matching-media handled-type))
@@ -49,18 +97,35 @@ all the different selection types."
49 (unless all-types 97 (unless all-types
50 (user-error 98 (user-error
51 "No handler in the current buffer for anything on the clipboard")) 99 "No handler in the current buffer for anything on the clipboard"))
52 ;; We have a handler in the current buffer; if there's just 100 (setq pref-type (and (null noselect)
53 ;; matching type, just call the handler. 101 (funcall yank-media-autoselect-function
54 (if (length= all-types 1) 102 (mapcar #'car all-types))))
103 (cond
104 ;; We are asked to autoselect and have a preferred MIME type.
105 ((and (null noselect) pref-type)
106 (funcall (cdr (assq (car pref-type) all-types))
107 (car pref-type)
108 (yank-media--get-selection (car pref-type))))
109 ;; We are asked to autoselect and no preferred MIME type.
110 ((and (null noselect) (null pref-type))
111 (message
112 (substitute-command-keys
113 "No preferred MIME type to yank, try \\[universal-argument] \\[yank-media]")))
114 ;; No autoselection and there's only one media type available.
115 ((and noselect (length= all-types 1))
116 (when (y-or-n-p (format "Yank the `%s' clipboard item?"
117 (caar all-types)))
55 (funcall (cdar all-types) (caar all-types) 118 (funcall (cdar all-types) (caar all-types)
56 (yank-media--get-selection (caar all-types))) 119 (yank-media--get-selection (caar all-types)))))
57 ;; More than one type the user for what type to insert. 120 ;; No autoselection and multiple media types available.
121 ((and noselect (length> all-types 1))
58 (let ((type 122 (let ((type
59 (intern 123 (intern
60 (completing-read "Several types available, choose one: " 124 (completing-read "Several types available, choose one: "
61 (mapcar #'car all-types) nil t)))) 125 (or pref-type (mapcar #'car all-types))
126 nil t))))
62 (funcall (alist-get type all-types) 127 (funcall (alist-get type all-types)
63 type (yank-media--get-selection type)))))) 128 type (yank-media--get-selection type)))))))
64 129
65(defun yank-media--find-matching-media (handled-type) 130(defun yank-media--find-matching-media (handled-type)
66 (seq-filter 131 (seq-filter