patch 9.1.1857: Missing clipboard provider support

Problem:  Missing clipboard provider support
          (lilydjwg)
Solution: Add clipboard provider feature
          (Foxe Chen)

fixes: #12419
closes: #17998

Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Foxe Chen
2025-10-14 19:35:17 +00:00
committed by Christian Brabandt
parent 1a09f11f5d
commit 67860efe5b
21 changed files with 851 additions and 22 deletions

View File

@ -1,4 +1,4 @@
*builtin.txt* For Vim version 9.1. Last change: 2025 Oct 13
*builtin.txt* For Vim version 9.1. Last change: 2025 Oct 14
VIM REFERENCE MANUAL by Bram Moolenaar
@ -13061,6 +13061,7 @@ channel Compiled with support for |channel| and |job|
cindent Compiled with 'cindent' support. (always true)
clientserver Compiled with remote invocation support |clientserver|.
clipboard Compiled with 'clipboard' support.
clipboard_provider Compiled with |clipboard-providers| support
clipboard_working Compiled with 'clipboard' support and it can be used.
cmdline_compl Compiled with |cmdline-completion| support.
cmdline_hist Compiled with |cmdline-history| support.

View File

@ -1,4 +1,4 @@
*eval.txt* For Vim version 9.1. Last change: 2025 Oct 12
*eval.txt* For Vim version 9.1. Last change: 2025 Oct 14
VIM REFERENCE MANUAL by Bram Moolenaar
@ -38,6 +38,7 @@ a remark is given.
12. The sandbox |eval-sandbox|
13. Textlock |textlock|
14. Vim script library |vim-script-library|
15. Clipboard providers |clipboard-providers|
Testing support is documented in |testing.txt|.
Profiling is documented at |profiling|.
@ -2251,6 +2252,11 @@ v:clipmethod The current method of accessing the clipboard that is being
unavailable.
See 'clipmethod' for more details.
*v:clipproviders*
v:clipproviders
A dictionary containing clipboard providers, see
|clipboard-providers| for more information.
*v:cmdarg* *cmdarg-variable*
v:cmdarg This variable is used for two purposes:
1. The extra arguments given to a file read/write command.
@ -5263,5 +5269,133 @@ Usage: >vim
:call dist#vim9#Launch(<args>)
:Launch <app> <args>.
<
==============================================================================
15. Clipboard providers *clipboard-providers*
When Vim is compiled with the |+clipboard_provider| feature, which requires
the |+eval| feature, creating custom clipboards is possible. These providers
handle the "+" and "*" registers. Note that on non-Unix or non-VMS systems,
only the "*" register will be available for use.
To add a provider, add a new entry to the |v:clipproviders| dictionary, in the
format of: >
let v:clipproviders["name"] = {
\ "available": function("Available"),
\ "paste": {
\ '+': function("Paste"), " For the + register
\ '*': function("Paste"), " For the * register
\ },
\ "copy": {
\ '+': function("Copy"), " Same thing as above
\ '*': function("Copy"),
\ },
\ }
The key is the provider name, which should be used in 'clipmethod', for
example in the following example, you would add "name" to 'clipmethod' in
order to use it. >
set clipmethod=name,wayland,x11,gui
Each callback can either be a name of a function in a string, a |Funcref|, or
a |lambda| expression.
Note that these dictionary entries are optional, for example, if you don't
care about the "copy" functions, then you can simply exclude them. When Vim
yanks/copies something, then simply nothing will be done.
*clipboard-provider-available*
The "available" callback should return a string, which should contain which
clipboard registers are available. For example, if the "+" register is only
available, then the function would return "+", or if both "+" and "*" are
available, then return "+*".
*clipboard-provider-paste*
The "paste" callback takes a first argument which is the register being put
(string), and a second argument which is the type of access (string). It
should return either a tuple/list or string. If a tuple/list is returned, it
should have two elements:
- The register type conforming to |setreg()|.
- A list of strings
If the register type is an empty string, then the type is automatically
chosen, see |setreg()|. If a string is returned, then it can either be "clear"
or "previous". "clear" makes Vim clear the register, and "previous" makes Vim
use the previous register contents (or current depending on how you view it).
The second argument, the access type, can either be "explicit" or "implicit".
"explicit" means that the user is directly accessing the clipboard, such as
putting text, or calling |getreg()|; "implicit" means that the clipboard is
being accessed indirectly, such when |:registers| is called, or when an
unrelated operation causes Vim to access the clipboard.
This is useful since some operations in Vim implicity access the clipboard
indirectly. For example, if when you want to create a provider for the OSC52
command (accessing the clipboard via an escape code). Many terminals show a
confirmation if you want Vim to access the clipboard. This can be very
annoying with the terminal asking for permission everytime you do something
that accesses the clipboard behind the scenes. A good way to handle implicit
access is to return "previous", which leaves the register contents unchanged.
*clipboard-provider-copy*
The "copy" callback returns nothing, and takes the given arguments in order:
- The register being operated on
- The register type, conforming to |getregtype()|
- A list of strings to copy
The provider can do whatever it wants with the given information. This
function is called on every request to change the clipboard register(s).
*clipboard-provider-textlock*
In both the "paste" and "copy" callbacks, it is not allowed to change the
buffer text, see |textlock|.
*clipboard-provider-example*
Here is an example script that uses the clipboard provider feature through the
OSC52 command: >vim
func Available()
return "+"
endfunc
func Paste(reg, type)
" If implicit access, don't do anything
if a:type == "implicit"
return "previous"
endif
augroup OSC
autocmd!
autocmd TermResponseAll osc ++once call feedkeys("\<F30>", '!')
augroup END
" Send command
call echoraw("\<Esc>]52;c;?\<Esc>\\")
" Wait until autocmd is triggered
while getchar(-1) != "\<F30>"
endwhile
autocmd! OSC
" Extract the base64 stuff
let l:stuff = matchstr(v:termosc, '52;c;\zs[A-Za-z0-9+/=]\+')
return ("", blob2str(base64_decode(l:stuff)))
endfunc
func Copy(reg, type, lines)
call echoraw("\<Esc>]52;c;" ..
\ base64_encode(str2blob(a:lines)) .. "\<Esc>\\")
endfunc
let v:clipproviders["myosc"] = {
\ "available": function("Available"),
\ "paste": {
\ '+': function("Paste"),
\ },
\ "copy": {
\ '+': function("Copy"),
\ },
\ }
set clipmethod=myosc
<
vim:tw=78:ts=8:noet:ft=help:norl:

View File

@ -1919,10 +1919,15 @@ A jump table for the options with a short description can be found at |Q_op|.
x11 X11 selections
gui GUI specific method
other Some other method
* Clipboard provider method
Note: "other" is used on systems without X11/Wayland, such as
MS-Windows or MacOS, when running Vim without the GUI.
Note that the name of the clipboard provider should be used when you
want to use a clipboard provider. See |clipboard-providers| for more
information.
The option value is a list of comma separated items. The list is
parsed left to right in order, and the first method that Vim
determines is available or is working is used as the actual method for

View File

@ -1411,6 +1411,7 @@ $quote eval.txt /*$quote*
+cindent various.txt /*+cindent*
+clientserver various.txt /*+clientserver*
+clipboard various.txt /*+clipboard*
+clipboard_provider various.txt /*+clipboard_provider*
+clipboard_working various.txt /*+clipboard_working*
+cmd editing.txt /*+cmd*
+cmdline_compl various.txt /*+cmdline_compl*
@ -6691,6 +6692,12 @@ clipboard-autoselectml options.txt /*clipboard-autoselectml*
clipboard-autoselectplus options.txt /*clipboard-autoselectplus*
clipboard-exclude options.txt /*clipboard-exclude*
clipboard-html options.txt /*clipboard-html*
clipboard-provider-available eval.txt /*clipboard-provider-available*
clipboard-provider-copy eval.txt /*clipboard-provider-copy*
clipboard-provider-example eval.txt /*clipboard-provider-example*
clipboard-provider-paste eval.txt /*clipboard-provider-paste*
clipboard-provider-textlock eval.txt /*clipboard-provider-textlock*
clipboard-providers eval.txt /*clipboard-providers*
clipboard-unnamed options.txt /*clipboard-unnamed*
clipboard-unnamedplus options.txt /*clipboard-unnamedplus*
clojure-indent indent.txt /*clojure-indent*
@ -11254,6 +11261,7 @@ v:char eval.txt /*v:char*
v:charconvert_from eval.txt /*v:charconvert_from*
v:charconvert_to eval.txt /*v:charconvert_to*
v:clipmethod eval.txt /*v:clipmethod*
v:clipproviders eval.txt /*v:clipproviders*
v:cmdarg eval.txt /*v:cmdarg*
v:cmdbang eval.txt /*v:cmdbang*
v:collate eval.txt /*v:collate*

View File

@ -1,4 +1,4 @@
*various.txt* For Vim version 9.1. Last change: 2025 Oct 12
*various.txt* For Vim version 9.1. Last change: 2025 Oct 14
VIM REFERENCE MANUAL by Bram Moolenaar
@ -378,6 +378,7 @@ m *+channel* inter process communication |channel|
T *+cindent* 'cindent', C indenting; Always enabled
N *+clientserver* Unix and Win32: Remote invocation |clientserver|
*+clipboard* |clipboard| support compiled-in
N *+clipboard_provider* |clipboard-providers| support compiled-in
*+clipboard_working* |clipboard| support compiled-in and working
T *+cmdline_compl* command line completion |cmdline-completion|
T *+cmdline_hist* command line history |cmdline-history|
@ -807,7 +808,10 @@ K Run a program to lookup the keyword under the
:clip[reset] Attempts to choose a new method for accessing the
clipboard, using the 'clipmethod' option. This is
useful when the current method has become unavailable,
and you want to try using another method.
and you want to try using another method. If the
|+clipboard_provider| feature is being used, this
command should be called after the availability of one
of the clipboard registers changes.
{only available when compiled with the |+clipboard|
feature}

View File

@ -1,4 +1,4 @@
*version9.txt* For Vim version 9.1. Last change: 2025 Oct 12
*version9.txt* For Vim version 9.1. Last change: 2025 Oct 14
VIM REFERENCE MANUAL by Bram Moolenaar
@ -41653,6 +41653,8 @@ Other new features ~
- |items()| function now supports Blob.
- |clipboard-providers| support.
*changed-9.2*
Changed~
-------
@ -41900,13 +41902,29 @@ Options: ~
compositor
Vim Variables: ~
|v:clipmethod| The current 'clipmethod'.
|v:clipproviders| A dictionary containing clipboard providers
information.
|v:stacktrace| The most recent caught exception.
|v:t_enumvalue| Value of |enumvalue|.
|v:t_enum| Value of |enum| type.
|v:t_tuple| Value of |Tuple| type.
|v:termda1| The escape sequence returned for the primary device
attribute query (DA1).
|v:termosc| The most recent received OSC response.
|v:wayland_display| The name of the Wayland display Vim is connected to.
Vim Arguments: ~
|-Y| Do not connect to the |wayland| compositor.
|--clientserver| Specify backend for clientserver functionality.
Configure Switches: ~
--with-wayland Enable the |wayland| feature.
--enable-wayland-focus-steal Enable the |wayland-focus-steal| feature.
--enable-socketserver Enable the |socketserver-clientserver|
feature.
--enable-clipboard-provider Enable the |clipboard-providers| feature.
==============================================================================
INCOMPATIBLE CHANGES *incompatible-9.2*