diff options
| author | Visuwesh | 2025-02-13 16:43:06 +0530 |
|---|---|---|
| committer | Eli Zaretskii | 2025-02-22 11:37:23 +0200 |
| commit | 0ee50a3420fb8df8f3477dac610dcd53c633fff5 (patch) | |
| tree | f36523c55e1cb7c42022cc39dc88b83a919119dd | |
| parent | 3e269371507ea4cd7e933e39320d258a3b98de44 (diff) | |
| download | emacs-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.texi | 6 | ||||
| -rw-r--r-- | doc/lispref/frames.texi | 24 | ||||
| -rw-r--r-- | etc/NEWS | 8 | ||||
| -rw-r--r-- | lisp/yank-media.el | 85 |
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}. | |||
| 587 | instance, a web browser will usually let you choose ``Copy Image'' on | 587 | instance, a web browser will usually let you choose ``Copy Image'' on |
| 588 | images, and this image will be put on the clipboard. On capable | 588 | images, and this image will be put on the clipboard. On capable |
| 589 | platforms, Emacs can yank these objects with the @code{yank-media} | 589 | platforms, Emacs can yank these objects with the @code{yank-media} |
| 590 | command---but only in modes that have support for it (@pxref{Yanking | 590 | command---but only in modes that have support for it. By default, it |
| 591 | Media,,, elisp, The Emacs Lisp Reference Manual}). | 591 | auto-selects the preferred media type available in the clipboard but |
| 592 | this 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 | ||
| 4815 | The @code{yank-media} command auto selects the preferred @sc{mime} type | ||
| 4816 | by default. The rules used for the selection can be controlled through | ||
| 4817 | the variables @code{yank-media-autoselect-function} and | ||
| 4818 | @code{yank-media-preferred-types}. | ||
| 4819 | |||
| 4820 | @defvar yank-media-autoselect-function | ||
| 4821 | This variable should specify a function that will be called with the | ||
| 4822 | list of @sc{mime} types available for the current major mode, and should | ||
| 4823 | return a list of preferred @sc{mime} types to use. The first @sc{mime} | ||
| 4824 | type in the list will always be used by the @code{yank-media} command | ||
| 4825 | when auto selection is requested. | ||
| 4826 | @end defvar | ||
| 4827 | |||
| 4828 | @defvar yank-media-preferred-types | ||
| 4829 | This variable changes the default selection process of | ||
| 4830 | @code{yank-media-autoselect-function}. It is a list that should contain | ||
| 4831 | the sole @sc{mime} type to choose in the order of their preference. It | ||
| 4832 | can also contain a function in which case it is called with the list of | ||
| 4833 | available @sc{mime} types and must return a list of preferred @sc{mime} | ||
| 4834 | types 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 | ||
| 4836 | chosen when auto selection is requested. | ||
| 4837 | @end defvar | ||
| 4838 | |||
| 4815 | The @code{yank-media-types} command presents a list of selection data | 4839 | The @code{yank-media-types} command presents a list of selection data |
| 4816 | types that are currently available, which is useful when implementing | 4840 | types that are currently available, which is useful when implementing |
| 4817 | yank-media handlers; for programs generally offer an eclectic and | 4841 | yank-media handlers; for programs generally offer an eclectic and |
| @@ -1252,6 +1252,14 @@ connected, to facilitate enabling 'strokes-mode' in sessions where the | |||
| 1252 | availability of a mouse device varies during execution (as is frequently | 1252 | availability of a mouse device varies during execution (as is frequently |
| 1253 | observed on Android). | 1253 | observed on Android). |
| 1254 | 1254 | ||
| 1255 | ** Yank media | ||
| 1256 | |||
| 1257 | +++ | ||
| 1258 | *** 'yank-media' now auto-selects the most preferred MIME type. | ||
| 1259 | Major-mode authors can customise the variables | ||
| 1260 | 'yank-media-autoselect-function' and/or 'yank-media-preferred-types' to | ||
| 1261 | change 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. | ||
| 34 | The function is called with a list of MIME types that have handler in | ||
| 35 | the current buffer, and should return the list of MIME types to use in | ||
| 36 | order of their priority. When `yank-media' auto-selects the MIME type, | ||
| 37 | it will always choose the first one of the returned list. | ||
| 38 | Major-mode authors can change this variable to influence the selection | ||
| 39 | process.") | ||
| 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. | ||
| 60 | Each element in the list should be a symbol to choose that MIME type | ||
| 61 | exclusively, or a function of one argument and should return the list of | ||
| 62 | MIME types to use in order of their priority or nil if no preferred type | ||
| 63 | is found. | ||
| 64 | Major-mode authors can change this variable to influence the selection | ||
| 65 | process, 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. |
| 35 | This command depends on the current major mode having support for | 79 | This command depends on the current major mode having support for |
| 36 | accepting the media type. The mode has to register itself using | 80 | accepting the media type. The mode has to register itself using |
| 37 | the `yank-media-handler' mechanism. | 81 | the `yank-media-handler' mechanism. |
| 82 | Optional argument NOSELECT non-nil (interactively, with a prefix | ||
| 83 | argument) means to skip auto-selecting the best MIME type and ask for | ||
| 84 | the MIME type to use. | ||
| 38 | 85 | ||
| 39 | Also see `yank-media-types' for a command that lets you explore | 86 | Also see `yank-media-types' for a command that lets you explore |
| 40 | all the different selection types." | 87 | all 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 |