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*

View File

@ -2,7 +2,7 @@
" Language: Vim script
" Maintainer: Hirohito Higashi <h.east.727 ATMARK gmail.com>
" Doug Kearns <dougkearns@gmail.com>
" Last Change: 2025 Oct 11
" Last Change: 2025 Oct 14
" Former Maintainer: Charles E. Campbell
" DO NOT CHANGE DIRECTLY.
@ -166,7 +166,7 @@ syn keyword vimFuncName contained win_execute win_findbuf win_getid win_gettype
" Predefined variable names {{{2
" GEN_SYN_VIM: vimVarName, START_STR='syn keyword vimVimVarName contained', END_STR=''
syn keyword vimVimVarName contained count count1 prevcount errmsg warningmsg statusmsg shell_error this_session version lnum termresponse fname lang lc_time ctype charconvert_from charconvert_to fname_in fname_out fname_new fname_diff cmdarg foldstart foldend folddashes foldlevel progname servername dying exception throwpoint register cmdbang insertmode val key profiling fcs_reason fcs_choice beval_bufnr beval_winnr beval_winid beval_lnum beval_col beval_text scrollstart swapname swapchoice swapcommand char mouse_win mouse_winid mouse_lnum mouse_col operator searchforward hlsearch oldfiles windowid progpath completed_item option_new option_old option_oldlocal option_oldglobal option_command option_type errors false true none null numbermax numbermin numbersize
syn keyword vimVimVarName contained vim_did_enter testing t_number t_string t_func t_list t_dict t_float t_bool t_none t_job t_channel t_blob t_class t_object termrfgresp termrbgresp termu7resp termstyleresp termblinkresp event versionlong echospace argv collate exiting colornames sizeofint sizeoflong sizeofpointer maxcol python3_version t_typealias t_enum t_enumvalue stacktrace t_tuple wayland_display clipmethod termda1 termosc
syn keyword vimVimVarName contained vim_did_enter testing t_number t_string t_func t_list t_dict t_float t_bool t_none t_job t_channel t_blob t_class t_object termrfgresp termrbgresp termu7resp termstyleresp termblinkresp event versionlong echospace argv collate exiting colornames sizeofint sizeoflong sizeofpointer maxcol python3_version t_typealias t_enum t_enumvalue stacktrace t_tuple wayland_display clipmethod termda1 termosc clipproviders
"--- syntax here and above generated by runtime/syntax/generator/gen_syntax_vim.vim ---