0
0
mirror of https://github.com/vim/vim.git synced 2025-10-18 07:54:29 -04:00

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 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) cindent Compiled with 'cindent' support. (always true)
clientserver Compiled with remote invocation support |clientserver|. clientserver Compiled with remote invocation support |clientserver|.
clipboard Compiled with 'clipboard' support. clipboard Compiled with 'clipboard' support.
clipboard_provider Compiled with |clipboard-providers| support
clipboard_working Compiled with 'clipboard' support and it can be used. clipboard_working Compiled with 'clipboard' support and it can be used.
cmdline_compl Compiled with |cmdline-completion| support. cmdline_compl Compiled with |cmdline-completion| support.
cmdline_hist Compiled with |cmdline-history| 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 VIM REFERENCE MANUAL by Bram Moolenaar
@@ -38,6 +38,7 @@ a remark is given.
12. The sandbox |eval-sandbox| 12. The sandbox |eval-sandbox|
13. Textlock |textlock| 13. Textlock |textlock|
14. Vim script library |vim-script-library| 14. Vim script library |vim-script-library|
15. Clipboard providers |clipboard-providers|
Testing support is documented in |testing.txt|. Testing support is documented in |testing.txt|.
Profiling is documented at |profiling|. Profiling is documented at |profiling|.
@@ -2251,6 +2252,11 @@ v:clipmethod The current method of accessing the clipboard that is being
unavailable. unavailable.
See 'clipmethod' for more details. 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* *cmdarg-variable*
v:cmdarg This variable is used for two purposes: v:cmdarg This variable is used for two purposes:
1. The extra arguments given to a file read/write command. 1. The extra arguments given to a file read/write command.
@@ -5263,5 +5269,133 @@ Usage: >vim
:call dist#vim9#Launch(<args>) :call dist#vim9#Launch(<args>)
:Launch <app> <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: 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 x11 X11 selections
gui GUI specific method gui GUI specific method
other Some other method other Some other method
* Clipboard provider method
Note: "other" is used on systems without X11/Wayland, such as Note: "other" is used on systems without X11/Wayland, such as
MS-Windows or MacOS, when running Vim without the GUI. 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 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 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 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* +cindent various.txt /*+cindent*
+clientserver various.txt /*+clientserver* +clientserver various.txt /*+clientserver*
+clipboard various.txt /*+clipboard* +clipboard various.txt /*+clipboard*
+clipboard_provider various.txt /*+clipboard_provider*
+clipboard_working various.txt /*+clipboard_working* +clipboard_working various.txt /*+clipboard_working*
+cmd editing.txt /*+cmd* +cmd editing.txt /*+cmd*
+cmdline_compl various.txt /*+cmdline_compl* +cmdline_compl various.txt /*+cmdline_compl*
@@ -6691,6 +6692,12 @@ clipboard-autoselectml options.txt /*clipboard-autoselectml*
clipboard-autoselectplus options.txt /*clipboard-autoselectplus* clipboard-autoselectplus options.txt /*clipboard-autoselectplus*
clipboard-exclude options.txt /*clipboard-exclude* clipboard-exclude options.txt /*clipboard-exclude*
clipboard-html options.txt /*clipboard-html* 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-unnamed options.txt /*clipboard-unnamed*
clipboard-unnamedplus options.txt /*clipboard-unnamedplus* clipboard-unnamedplus options.txt /*clipboard-unnamedplus*
clojure-indent indent.txt /*clojure-indent* 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_from eval.txt /*v:charconvert_from*
v:charconvert_to eval.txt /*v:charconvert_to* v:charconvert_to eval.txt /*v:charconvert_to*
v:clipmethod eval.txt /*v:clipmethod* v:clipmethod eval.txt /*v:clipmethod*
v:clipproviders eval.txt /*v:clipproviders*
v:cmdarg eval.txt /*v:cmdarg* v:cmdarg eval.txt /*v:cmdarg*
v:cmdbang eval.txt /*v:cmdbang* v:cmdbang eval.txt /*v:cmdbang*
v:collate eval.txt /*v:collate* 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 VIM REFERENCE MANUAL by Bram Moolenaar
@@ -378,6 +378,7 @@ m *+channel* inter process communication |channel|
T *+cindent* 'cindent', C indenting; Always enabled T *+cindent* 'cindent', C indenting; Always enabled
N *+clientserver* Unix and Win32: Remote invocation |clientserver| N *+clientserver* Unix and Win32: Remote invocation |clientserver|
*+clipboard* |clipboard| support compiled-in *+clipboard* |clipboard| support compiled-in
N *+clipboard_provider* |clipboard-providers| support compiled-in
*+clipboard_working* |clipboard| support compiled-in and working *+clipboard_working* |clipboard| support compiled-in and working
T *+cmdline_compl* command line completion |cmdline-completion| T *+cmdline_compl* command line completion |cmdline-completion|
T *+cmdline_hist* command line history |cmdline-history| 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 :clip[reset] Attempts to choose a new method for accessing the
clipboard, using the 'clipmethod' option. This is clipboard, using the 'clipmethod' option. This is
useful when the current method has become unavailable, 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| {only available when compiled with the |+clipboard|
feature} 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 VIM REFERENCE MANUAL by Bram Moolenaar
@@ -41653,6 +41653,8 @@ Other new features ~
- |items()| function now supports Blob. - |items()| function now supports Blob.
- |clipboard-providers| support.
*changed-9.2* *changed-9.2*
Changed~ Changed~
------- -------
@@ -41900,13 +41902,29 @@ Options: ~
compositor compositor
Vim Variables: ~ 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 |v:termda1| The escape sequence returned for the primary device
attribute query (DA1). 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: ~ Vim Arguments: ~
|-Y| Do not connect to the |wayland| compositor. |-Y| Do not connect to the |wayland| compositor.
|--clientserver| Specify backend for clientserver functionality. |--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* INCOMPATIBLE CHANGES *incompatible-9.2*

View File

@@ -2,7 +2,7 @@
" Language: Vim script " Language: Vim script
" Maintainer: Hirohito Higashi <h.east.727 ATMARK gmail.com> " Maintainer: Hirohito Higashi <h.east.727 ATMARK gmail.com>
" Doug Kearns <dougkearns@gmail.com> " Doug Kearns <dougkearns@gmail.com>
" Last Change: 2025 Oct 11 " Last Change: 2025 Oct 14
" Former Maintainer: Charles E. Campbell " Former Maintainer: Charles E. Campbell
" DO NOT CHANGE DIRECTLY. " DO NOT CHANGE DIRECTLY.
@@ -166,7 +166,7 @@ syn keyword vimFuncName contained win_execute win_findbuf win_getid win_gettype
" Predefined variable names {{{2 " Predefined variable names {{{2
" GEN_SYN_VIM: vimVarName, START_STR='syn keyword vimVimVarName contained', END_STR='' " 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 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 --- "--- syntax here and above generated by runtime/syntax/generator/gen_syntax_vim.vim ---

31
src/auto/configure vendored
View File

@@ -857,6 +857,7 @@ enable_arabic
enable_farsi enable_farsi
enable_xim enable_xim
enable_fontset enable_fontset
enable_clipboard_provider
with_wayland with_wayland
enable_wayland_focus_steal enable_wayland_focus_steal
with_x with_x
@@ -1539,6 +1540,7 @@ Optional Features:
--disable-farsi Deprecated. --disable-farsi Deprecated.
--enable-xim Include XIM input support. --enable-xim Include XIM input support.
--enable-fontset Include X fontset output support. --enable-fontset Include X fontset output support.
--enable-clipboard-provider Include clipboard provider support.
--enable-wayland-focus-steal --enable-wayland-focus-steal
Include focus stealing support for Wayland Include focus stealing support for Wayland
clipboard. clipboard.
@@ -9208,6 +9210,35 @@ fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_fontset" >&5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_fontset" >&5
printf "%s\n" "$enable_fontset" >&6; } printf "%s\n" "$enable_fontset" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking --enable-clipboard-provider" >&5
printf %s "checking --enable-clipboard-provider... " >&6; }
# Check whether --enable-clipboard-provider was given.
if test ${enable_clipboard_provider+y}
then :
enableval=$enable_clipboard_provider; enable_clipboard_provider=$enableval
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5
printf "%s\n" "$enableval" >&6; }
else case e in #(
e) if test "x$features" = xtiny
then :
enable_clipboard_provider="no"
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cannot use clipboard provider with tiny features" >&5
printf "%s\n" "cannot use clipboard provider with tiny features" >&6; }
else case e in #(
e) enable_clipboard_provider="yes"
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; } ;;
esac
fi ;;
esac
fi
if test "$enable_clipboard_provider" = "yes"; then
printf "%s\n" "#define FEAT_CLIPBOARD_PROVIDER 1" >>confdefs.h
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if shm_open is available" >&5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if shm_open is available" >&5
printf %s "checking if shm_open is available... " >&6; } printf %s "checking if shm_open is available... " >&6; }
cppflags_save=$CPPFLAGS cppflags_save=$CPPFLAGS

View File

@@ -134,6 +134,12 @@ static bool clip_wl_owner_exists(Clipboard_T *cbd);
#endif // FEAT_WAYLAND_CLIPBOARD #endif // FEAT_WAYLAND_CLIPBOARD
#ifdef FEAT_CLIPBOARD_PROVIDER
static int clip_provider_is_available(Clipboard_T *cbd, char_u *provider);
static void clip_provider_set_selection(Clipboard_T *cbd, char_u *provider);
static void clip_provider_request_selection(Clipboard_T *cbd, char_u *provider);
#endif
/* /*
* Selection stuff using Visual mode, for cutting and pasting text to other * Selection stuff using Visual mode, for cutting and pasting text to other
* windows. * windows.
@@ -254,7 +260,7 @@ clip_gen_own_selection(Clipboard_T *cbd UNUSED)
} }
else if (clipmethod == CLIPMETHOD_OTHER) else if (clipmethod == CLIPMETHOD_OTHER)
{ {
#if !defined(FEAT_XCLIPBOARD) && !defined(FEAT_WAYLAND_CLIPBOARD) #ifndef UNIX
return clip_mch_own_selection(cbd); return clip_mch_own_selection(cbd);
#endif #endif
} }
@@ -321,7 +327,7 @@ clip_gen_lose_selection(Clipboard_T *cbd UNUSED)
} }
else if (clipmethod == CLIPMETHOD_OTHER) else if (clipmethod == CLIPMETHOD_OTHER)
{ {
#if !defined(FEAT_XCLIPBOARD) && !defined(FEAT_WAYLAND_CLIPBOARD) #ifndef UNIX
clip_mch_lose_selection(cbd); clip_mch_lose_selection(cbd);
#endif #endif
} }
@@ -1354,7 +1360,7 @@ clip_gen_set_selection(Clipboard_T *cbd)
{ {
#ifdef FEAT_GUI #ifdef FEAT_GUI
if (gui.in_use) if (gui.in_use)
clip_mch_set_selection(cbd); clip_mch_set_selection(cbd);
#endif #endif
} }
else if (clipmethod == CLIPMETHOD_WAYLAND) else if (clipmethod == CLIPMETHOD_WAYLAND)
@@ -1371,8 +1377,14 @@ clip_gen_set_selection(Clipboard_T *cbd)
} }
else if (clipmethod == CLIPMETHOD_OTHER) else if (clipmethod == CLIPMETHOD_OTHER)
{ {
#if !defined(FEAT_XCLIPBOARD) && !defined(FEAT_WAYLAND_CLIPBOARD) #ifndef UNIX
clip_mch_set_selection(cbd); clip_mch_set_selection(cbd);
#endif
}
else if (clipmethod == CLIPMETHOD_PROVIDER)
{
#ifdef FEAT_CLIPBOARD_PROVIDER
clip_provider_set_selection(cbd, clipprovider_name);
#endif #endif
} }
} }
@@ -1401,8 +1413,14 @@ clip_gen_request_selection(Clipboard_T *cbd UNUSED)
} }
else if (clipmethod == CLIPMETHOD_OTHER) else if (clipmethod == CLIPMETHOD_OTHER)
{ {
#if !defined(FEAT_XCLIPBOARD) && !defined(FEAT_WAYLAND_CLIPBOARD) #ifndef UNIX
clip_mch_request_selection(cbd); clip_mch_request_selection(cbd);
#endif
}
else if (clipmethod == CLIPMETHOD_PROVIDER)
{
#ifdef FEAT_CLIPBOARD_PROVIDER
clip_provider_request_selection(cbd, clipprovider_name);
#endif #endif
} }
} }
@@ -2266,10 +2284,18 @@ clip_get_selection(Clipboard_T *cbd)
} }
else if (!is_clipboard_needs_update()) else if (!is_clipboard_needs_update())
{ {
clip_free_selection(cbd); #ifdef FEAT_CLIPBOARD_PROVIDER
// We will choose if we want to the free the selection if using provider
if (clipmethod != CLIPMETHOD_PROVIDER)
clip_free_selection(cbd);
#endif
// Try to get selected text from another window // Try to get selected text from another window
clip_gen_request_selection(cbd); clip_gen_request_selection(cbd);
#ifdef FEAT_CLIPBOARD_PROVIDER
if (clipmethod == CLIPMETHOD_PROVIDER)
clip_access_type = CLIP_ACCESS_IMPLICIT;
#endif
} }
} }
@@ -3507,15 +3533,34 @@ get_clipmethod(char_u *str, bool *regular, bool *primary)
} }
else if (STRCMP(buf, "other") == 0) else if (STRCMP(buf, "other") == 0)
{ {
#if !defined(FEAT_XCLIPBOARD) && !defined(FEAT_WAYLAND_CLIPBOARD) #ifndef UNIX
method = CLIPMETHOD_OTHER; method = CLIPMETHOD_OTHER;
*regular = *primary = true; *regular = *primary = true;
#endif #endif
} }
else else
{ {
ret = CLIPMETHOD_FAIL; #ifdef FEAT_CLIPBOARD_PROVIDER
goto exit; // Check if it is the name of a provider
int reg = clip_provider_is_available(&clip_plus, buf);
int pri = clip_provider_is_available(&clip_star, buf);
if (reg == 1 || pri == 1)
{
method = CLIPMETHOD_PROVIDER;
vim_free(clipprovider_name);
clipprovider_name = vim_strsave(buf);
*regular = reg == 1;
*primary = pri == 1;
}
else if (reg == -1)
#endif
{
ret = CLIPMETHOD_FAIL;
goto exit;
}
} }
// Keep on going in order to catch errors // Keep on going in order to catch errors
@@ -3548,6 +3593,15 @@ clipmethod_to_str(clipmethod_T method)
return (char_u *)"gui"; return (char_u *)"gui";
case CLIPMETHOD_OTHER: case CLIPMETHOD_OTHER:
return (char_u *)"other"; return (char_u *)"other";
case CLIPMETHOD_PROVIDER:
#ifdef FEAT_CLIPBOARD_PROVIDER
if (clipprovider_name == NULL)
return (char_u *)"none";
else
return clipprovider_name;
#else
return (char_u *)"none";
#endif
default: default:
return (char_u *)"none"; return (char_u *)"none";
} }
@@ -3584,16 +3638,26 @@ choose_clipmethod(void)
clip_plus.did_warn = false; clip_plus.did_warn = false;
clip_star.did_warn = false; clip_star.did_warn = false;
} }
// Disown clipboard if we are switching to a new method else if ((clipmethod != CLIPMETHOD_NONE && method != clipmethod))
else if (clipmethod != CLIPMETHOD_NONE && method != clipmethod)
{ {
// Disown clipboard if we are switching to a new method
if (clip_star.owned) if (clip_star.owned)
clip_lose_selection(&clip_star); clip_lose_selection(&clip_star);
if (clip_plus.owned) if (clip_plus.owned)
clip_lose_selection(&clip_plus); clip_lose_selection(&clip_plus);
clip_init_single(&clip_plus, regular); clip_init_single(&clip_plus, regular);
clip_init_single(&clip_star, primary); clip_init_single(&clip_star, primary);
} }
else
{
// If availability of a clipboard changed, then update the clipboard
// structure.
if (regular != clip_plus.available)
clip_init_single(&clip_plus, regular);
if (primary != clip_star.available)
clip_init_single(&clip_star, primary);
}
clipmethod = method; clipmethod = method;
@@ -3621,4 +3685,321 @@ ex_clipreset(exarg_T *eap UNUSED)
clipmethod_to_str(clipmethod)); clipmethod_to_str(clipmethod));
} }
#ifdef FEAT_CLIPBOARD_PROVIDER
/*
* Check if a clipboard provider with given name exists and is available for the
* given clipboard. Returns 1 if the provider exists and the 'available'
* function returned true, 0 if the provider exists but the function returned
* false, and -1 on error.
*/
static int
clip_provider_is_available(Clipboard_T *cbd, char_u *provider)
{
dict_T *providers = get_vim_var_dict(VV_CLIPPROVIDERS);
typval_T provider_tv = {0};
callback_T callback = {0};
typval_T rettv = {0};
typval_T func_tv = {0};
char_u *avail;
int res = 0;
if (dict_get_tv(providers, (char *)provider, &provider_tv) == FAIL
|| provider_tv.v_type != VAR_DICT)
return -1;
if (dict_get_tv(provider_tv.vval.v_dict, "available", &func_tv) == FAIL)
{
clear_tv(&provider_tv);
// If "available" functon not specified assume always TRUE
return 1;
}
if ((callback = get_callback(&func_tv)).cb_name == NULL)
goto fail;
if (call_callback(&callback, -1, &rettv, 0, NULL) == FAIL ||
rettv.v_type != VAR_STRING)
goto fail;
avail = rettv.vval.v_string;
if ((vim_strchr(avail, '+') != NULL && cbd == &clip_plus)
|| (vim_strchr(avail, '*') != NULL && cbd == &clip_star))
res = 1;
if (FALSE)
fail:
res = -1;
free_callback(&callback);
clear_tv(&func_tv);
clear_tv(&rettv);
clear_tv(&provider_tv);
return res;
}
/*
* Get the specified callback "function" from the provider dictionary of for
* register "reg".
*/
static int
clip_provider_get_callback(
char_u *reg,
char_u *provider,
char_u *function,
callback_T *callback)
{
dict_T *providers = get_vim_var_dict(VV_CLIPPROVIDERS);
typval_T provider_tv;
typval_T action_tv;
typval_T func_tv;
callback_T cb;
if (dict_get_tv(providers, (char *)provider, &provider_tv) == FAIL)
return FAIL;
else if (provider_tv.v_type != VAR_DICT)
{
clear_tv(&provider_tv);
return FAIL;
}
else if (dict_get_tv(
provider_tv.vval.v_dict,
(char *)function,
&action_tv) == FAIL)
{
clear_tv(&provider_tv);
return FAIL;
}
else if (action_tv.v_type != VAR_DICT)
{
clear_tv(&provider_tv);
clear_tv(&action_tv);
return FAIL;
}
else if (dict_get_tv(action_tv.vval.v_dict, (char *)reg, &func_tv) == FAIL)
{
clear_tv(&provider_tv);
clear_tv(&action_tv);
return FAIL;
}
else if ((cb = get_callback(&func_tv)).cb_name == NULL)
{
clear_tv(&provider_tv);
clear_tv(&action_tv);
clear_tv(&func_tv);
return FAIL;
}
clear_tv(&provider_tv);
clear_tv(&action_tv);
// func_tv owns the function name, so we must make a copy for the callback
set_callback(callback, &cb);
free_callback(&cb);
clear_tv(&func_tv);
return OK;
}
static void
clip_provider_set_selection(Clipboard_T *cbd, char_u *provider)
{
char_u *reg = (char_u *)(cbd == &clip_star ? "*" : "+");
callback_T callback;
typval_T rettv;
typval_T argvars[4];
yankreg_T *y_ptr;
char_u type[2 + NUMBUFLEN] = {0};
list_T *list = NULL;
if (clip_provider_get_callback(
reg,
provider,
(char_u *)"copy",
&callback) == FAIL)
return;
// Possibly get selected text, if using autoselect for 'clipboard'
cbd->owned = TRUE;
clip_get_selection(cbd);
cbd->owned = FALSE;
// Convert register type into a string
if (cbd == &clip_plus)
y_ptr = get_y_register(PLUS_REGISTER);
else
y_ptr = get_y_register(STAR_REGISTER);
switch (y_ptr->y_type)
{
case MCHAR:
type[0] = 'v';
break;
case MLINE:
type[0] = 'V';
break;
case MBLOCK:
sprintf((char *)type, "%c%d", Ctrl_V, y_ptr->y_width + 1);
break;
default:
type[0] = 0;
break;
}
argvars[0].v_type = VAR_STRING;
argvars[0].vval.v_string = reg;
argvars[1].v_type = VAR_STRING;
argvars[1].vval.v_string = type;
// Get register contents by creating a list of lines
list = list_alloc();
if (list == NULL)
{
free_callback(&callback);
return;
}
for (int i = 0; i < y_ptr->y_size; i++)
if (list_append_string(list, y_ptr->y_array[i].string, -1) == FAIL)
{
free_callback(&callback);
list_unref(list);
return;
}
list->lv_refcount++;
argvars[2].v_type = VAR_LIST;
argvars[2].v_lock = VAR_FIXED;
argvars[2].vval.v_list = list;
argvars[3].v_type = VAR_UNKNOWN;
textlock++;
call_callback(&callback, -1, &rettv, 3, argvars);
clear_tv(&rettv);
textlock--;
free_callback(&callback);
list_unref(list);
}
static void
clip_provider_request_selection(Clipboard_T *cbd, char_u *provider)
{
char_u *reg = (char_u *)(cbd == &clip_star ? "*" : "+");
callback_T callback;
typval_T argvars[3];
typval_T rettv;
int ret;
char_u *reg_type;
list_T *lines;
if (clip_provider_get_callback(
reg,
provider,
(char_u *)"paste",
&callback) == FAIL)
return;
argvars[0].v_type = VAR_STRING;
argvars[0].vval.v_string = reg;
argvars[1].v_type = VAR_STRING;
argvars[1].vval.v_string = (char_u *)
(clip_access_type == CLIP_ACCESS_EXPLICIT ? "explicit" : "implicit");
argvars[2].v_type = VAR_UNKNOWN;
textlock++;
ret = call_callback(&callback, -1, &rettv, 2, argvars);
textlock--;
if (ret == FAIL)
goto exit;
else if (rettv.v_type == VAR_STRING
&& STRCMP(rettv.vval.v_string, "clear") == 0)
{
clip_free_selection(cbd);
goto exit;
}
else if (rettv.v_type == VAR_STRING
&& STRCMP(rettv.vval.v_string, "previous") == 0)
goto exit;
else if (rettv.v_type == VAR_TUPLE
&& TUPLE_LEN(rettv.vval.v_tuple) == 2
&& TUPLE_ITEM(rettv.vval.v_tuple, 0)->v_type == VAR_STRING
&& TUPLE_ITEM(rettv.vval.v_tuple, 1)->v_type == VAR_LIST)
{
reg_type = TUPLE_ITEM(rettv.vval.v_tuple, 0)->vval.v_string;
lines = TUPLE_ITEM(rettv.vval.v_tuple, 1)->vval.v_list;
}
else if (rettv.v_type == VAR_LIST
&& rettv.vval.v_list->lv_len == 2
&& rettv.vval.v_list->lv_first->li_tv.v_type == VAR_STRING
&& rettv.vval.v_list->lv_first->li_next->li_tv.v_type == VAR_LIST)
{
reg_type = rettv.vval.v_list->lv_first->li_tv.vval.v_string;
lines = rettv.vval.v_list->lv_first->li_next->li_tv.vval.v_list;
}
else
goto exit;
{
char_u yank_type = MAUTO;
long block_len = -1;
yankreg_T *y_ptr;
char_u **contents;
listitem_T *li;
int i = 0;
contents = ALLOC_MULT(char_u *, lines->lv_len + 1); // Ends with a NULL
if (contents == NULL)
goto exit;
// Convert strings in list to type char_u **
FOR_ALL_LIST_ITEMS(lines, li)
{
char_u *str = tv_get_string_chk(&li->li_tv);
if (str == NULL)
goto exit;
contents[i++] = vim_strsave(str);
}
contents[i] = NULL;
if (STRLEN(reg_type) > 0
&& get_yank_type(&reg_type, &yank_type, &block_len) == FAIL)
goto exit;
if (cbd == &clip_plus)
y_ptr = get_y_register(PLUS_REGISTER);
else
y_ptr = get_y_register(STAR_REGISTER);
clip_free_selection(cbd);
str_to_reg(y_ptr,
yank_type,
(char_u *)contents,
STRLEN(contents),
block_len,
TRUE);
for (int k = 0; k < i; k++)
vim_free(contents[k]);
vim_free(contents);
}
exit:
free_callback(&callback);
clear_tv(&rettv);
}
#endif // FEAT_CLIPBOARD_PROVIDER
#endif // FEAT_CLIPBOARD #endif // FEAT_CLIPBOARD

View File

@@ -528,3 +528,6 @@
/* Define if you want to load libgpm dynamically */ /* Define if you want to load libgpm dynamically */
#undef DYNAMIC_GPM #undef DYNAMIC_GPM
/* Define if you want to have clipboard provider functionality*/
#undef FEAT_CLIPBOARD_PROVIDER

View File

@@ -2434,6 +2434,21 @@ AC_ARG_ENABLE(fontset,
AC_MSG_RESULT($enable_fontset) AC_MSG_RESULT($enable_fontset)
dnl defining FEAT_XFONTSET is delayed, so that it can be disabled for no GUI dnl defining FEAT_XFONTSET is delayed, so that it can be disabled for no GUI
AC_MSG_CHECKING(--enable-clipboard-provider)
AC_ARG_ENABLE(clipboard-provider,
[ --enable-clipboard-provider Include clipboard provider support.],
[enable_clipboard_provider=$enableval
AC_MSG_RESULT($enableval)],
AS_IF([test "x$features" = xtiny],
[enable_clipboard_provider="no"
AC_MSG_RESULT([cannot use clipboard provider with tiny features])],
[enable_clipboard_provider="yes"
AC_MSG_RESULT([yes])]))
if test "$enable_clipboard_provider" = "yes"; then
AC_DEFINE(FEAT_CLIPBOARD_PROVIDER)
fi
AC_MSG_CHECKING(if shm_open is available) AC_MSG_CHECKING(if shm_open is available)
cppflags_save=$CPPFLAGS cppflags_save=$CPPFLAGS
CPPFLAGS="$CPPFLAGS $X_CFLAGS" CPPFLAGS="$CPPFLAGS $X_CFLAGS"

View File

@@ -6500,6 +6500,11 @@ f_getreg(typval_T *argvars, typval_T *rettv)
return; return;
} }
#ifdef FEAT_CLIPBOARD_PROVIDER
if (clipmethod == CLIPMETHOD_PROVIDER)
clip_access_type = CLIP_ACCESS_EXPLICIT;
#endif
if (return_list) if (return_list)
{ {
rettv->v_type = VAR_LIST; rettv->v_type = VAR_LIST;
@@ -6866,6 +6871,13 @@ f_has(typval_T *argvars, typval_T *rettv)
1 1
#else #else
0 0
#endif
},
{"clipboard_provider",
#ifdef FEAT_CLIPBOARD_PROVIDER
1
#else
0
#endif #endif
}, },
{"cmdline_compl", 1}, {"cmdline_compl", 1},
@@ -11493,7 +11505,7 @@ f_setpos(typval_T *argvars, typval_T *rettv)
/* /*
* Translate a register type string to the yank type and block length * Translate a register type string to the yank type and block length
*/ */
static int int
get_yank_type(char_u **pp, char_u *yank_type, long *block_len) get_yank_type(char_u **pp, char_u *yank_type, long *block_len)
{ {
char_u *stropt = *pp; char_u *stropt = *pp;

View File

@@ -166,7 +166,8 @@ static struct vimvar
{VV_NAME("wayland_display", VAR_STRING), NULL, VV_RO}, {VV_NAME("wayland_display", VAR_STRING), NULL, VV_RO},
{VV_NAME("clipmethod", VAR_STRING), NULL, VV_RO}, {VV_NAME("clipmethod", VAR_STRING), NULL, VV_RO},
{VV_NAME("termda1", VAR_STRING), NULL, VV_RO}, {VV_NAME("termda1", VAR_STRING), NULL, VV_RO},
{VV_NAME("termosc", VAR_STRING), NULL, VV_RO}, {VV_NAME("termosc", VAR_STRING), NULL, VV_RO},
{VV_NAME("clipproviders", VAR_DICT), &t_dict_string, VV_RO}
}; };
// shorthand // shorthand

View File

@@ -905,6 +905,19 @@
# define FEAT_CLIPBOARD # define FEAT_CLIPBOARD
#endif #endif
/*
* +clipboard_provider Allow Vim to use clipboard providers
*/
#if defined(FEAT_CLIPBOARD_PROVIDER)
# ifndef FEAT_EVAL
# undef FEAT_CLIPBOARD_PROVIDER
# else
# ifndef FEAT_CLIPBOARD
# define FEAT_CLIPBOARD
# endif
# endif
#endif
#ifdef FEAT_GUI #ifdef FEAT_GUI
# ifndef FEAT_CLIPBOARD # ifndef FEAT_CLIPBOARD
# define FEAT_CLIPBOARD # define FEAT_CLIPBOARD

View File

@@ -972,7 +972,8 @@ EXTERN int gui_win_y INIT(= -1);
#ifdef FEAT_CLIPBOARD #ifdef FEAT_CLIPBOARD
EXTERN Clipboard_T clip_star; // PRIMARY selection in X11/Wayland EXTERN Clipboard_T clip_star; // PRIMARY selection in X11/Wayland
# if defined(FEAT_X11) || defined(FEAT_WAYLAND_CLIPBOARD) # if defined(FEAT_X11) || defined(FEAT_WAYLAND_CLIPBOARD) \
|| ((defined(UNIX) || defined(VMS)) && defined(FEAT_CLIPBOARD_PROVIDER))
EXTERN Clipboard_T clip_plus; // CLIPBOARD selection in X11/Wayland EXTERN Clipboard_T clip_plus; // CLIPBOARD selection in X11/Wayland
# else # else
# define clip_plus clip_star // there is only one clipboard # define clip_plus clip_star // there is only one clipboard
@@ -2067,6 +2068,9 @@ EXTERN int p_tgc_set INIT(= FALSE);
#ifdef FEAT_CLIPBOARD #ifdef FEAT_CLIPBOARD
EXTERN clipmethod_T clipmethod INIT(= CLIPMETHOD_NONE); EXTERN clipmethod_T clipmethod INIT(= CLIPMETHOD_NONE);
# ifdef FEAT_CLIPBOARD_PROVIDER
EXTERN char_u *clipprovider_name INIT(= NULL);
# endif
#endif #endif
#ifdef FEAT_WAYLAND #ifdef FEAT_WAYLAND
@@ -2116,3 +2120,16 @@ INIT(= CLIENTSERVER_METHOD_NONE);
// Path to socket of last client that communicated with us // Path to socket of last client that communicated with us
EXTERN char_u *client_socket INIT(= NULL); EXTERN char_u *client_socket INIT(= NULL);
#endif #endif
#ifdef FEAT_CLIPBOARD_PROVIDER
typedef enum
{
CLIP_ACCESS_IMPLICIT,
CLIP_ACCESS_EXPLICIT,
} clip_access_T;
// Only relevant for the clipboard provider feature. This indicates if the
// clipboard request is implicit (ex. access when doing :registers),
// explicit (ex. typing "+p). Always defaults to implicit.
EXTERN clip_access_T clip_access_type INIT(= CLIP_ACCESS_IMPLICIT);
#endif

View File

@@ -28,4 +28,5 @@ void f_len(typval_T *argvars, typval_T *rettv);
void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv); void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv);
void range_list_materialize(list_T *list); void range_list_materialize(list_T *list);
long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit); long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit);
int get_yank_type(char_u **pp, char_u *yank_type, long *block_len);
/* vim: set ft=c : */ /* vim: set ft=c : */

View File

@@ -1559,6 +1559,10 @@ do_put(
#ifdef FEAT_CLIPBOARD #ifdef FEAT_CLIPBOARD
// Adjust register name for "unnamed" in 'clipboard'. // Adjust register name for "unnamed" in 'clipboard'.
adjust_clip_reg(&regname); adjust_clip_reg(&regname);
# ifdef FEAT_CLIPBOARD_PROVIDER
if (clipmethod == CLIPMETHOD_PROVIDER)
clip_access_type = CLIP_ACCESS_EXPLICIT;
# endif
(void)may_get_selection(regname); (void)may_get_selection(regname);
#endif #endif

View File

@@ -105,6 +105,7 @@ NEW_TESTS = \
test_cjk_linebreak \ test_cjk_linebreak \
test_clientserver \ test_clientserver \
test_clipmethod \ test_clipmethod \
test_clipboard_provider \
test_close_count \ test_close_count \
test_cmd_lists \ test_cmd_lists \
test_cmdline \ test_cmdline \
@@ -395,6 +396,7 @@ NEW_TESTS_RES = \
test_cjk_linebreak.res \ test_cjk_linebreak.res \
test_clientserver.res \ test_clientserver.res \
test_clipmethod.res \ test_clipmethod.res \
test_clipboard_provider.res \
test_close_count.res \ test_close_count.res \
test_cmd_lists.res \ test_cmd_lists.res \
test_cmdline.res \ test_cmdline.res \

View File

@@ -0,0 +1,170 @@
" Test for clipboard provider feature
CheckFeature clipboard_provider
func! AvailableBoth()
return "+*"
endfunc
func! AvailablePlus()
return "+"
endfunc
func! PasteList(reg, type)
return ["c", ["list"]]
endfunc
func! PasteTuple(reg, type)
return ("", ["tuple", "of", "strings"])
endfunc
func! PasteType(reg, type)
let g:vim_test_type = a:type
return ("c", [a:type])
endfunc
func! PasteRegType(reg, type)
return (g:vim_test_reg_type, ["7 chars"])
endfunc
func! Copy(reg, type, lines)
let g:vim_test_stuff = {
\ "type": a:type,
\ "lines": a:lines
\ }
endfunc
" Test if "available" function works properly for provider
func Test_clipboard_provider_available()
CheckUnix
let v:clipproviders["test"] = {
\ "available": function("AvailablePlus"),
\ "paste": {
\ '+': function("PasteList"),
\ '*': function("PasteList")
\ }
\ }
set clipmethod=test
call assert_equal("test", v:clipmethod)
call assert_equal("list", getreg("+"))
" Test if star register is unavailable
call assert_equal("", getreg("*"))
let v:clipproviders["test"] = {
\ "available": function("AvailableBoth"),
\ "paste": {
\ '+': function("PasteList"),
\ '*': function("PasteList")
\ }
\ }
clipreset
call assert_equal("list", getreg("+"))
call assert_equal("list", getreg("*"))
let v:clipproviders["test"] = {
\ "paste": {
\ '+': function("PasteList"),
\ '*': function("PasteList")
\ }
\ }
" Should default to TRUE
call assert_equal("list", getreg("+"))
call assert_equal("list", getreg("*"))
set clipmethod&
endfunc
" Test if "paste" functions work properly for provider
func Test_clipboard_provider_paste()
" Test if tuples and lists work the same
let v:clipproviders["test"] = {
\ "paste": {
\ '*': function("PasteList")
\ }
\ }
set clipmethod=test
call assert_equal("test", v:clipmethod)
call assert_equal("list", getreg("*"))
let v:clipproviders["test"] = {
\ "paste": {
\ '*': function("PasteTuple")
\ }
\ }
call assert_equal("tuple\nof\nstrings\n", getreg("*"))
" Test if "implicit" and "explicit" arguments are correctly used
let v:clipproviders["test"] = {
\ "paste": {
\ '*': function("PasteType")
\ }
\ }
call assert_equal("explicit", getreg("*"))
:registers
call assert_equal("implicit", g:vim_test_type)
unlet g:vim_test_type
" Test if correct register type is used
let v:clipproviders["test"] = {
\ "paste": {
\ '*': function("PasteRegType")
\ }
\ }
let g:vim_test_reg_type = "v"
call assert_equal("v", getregtype("*"))
let g:vim_test_reg_type = "c"
call assert_equal("v", getregtype("*"))
let g:vim_test_reg_type = "l"
call assert_equal("V", getregtype("*"))
let g:vim_test_reg_type = "l"
call assert_equal("V", getregtype("*"))
let g:vim_test_reg_type = "b"
call assert_equal("7", getregtype("*"))
let g:vim_test_reg_type = ""
call assert_equal("7", getregtype("*"))
let g:vim_test_reg_type = "b40"
call assert_equal("40", getregtype("*"))
set clipmethod&
endfunc
" Test if "copy" functions work properly for provider
func Test_clipboard_provider_copy()
let v:clipproviders["test"] = {
\ "copy": {
\ '*': function("Copy")
\ }
\ }
set clipmethod=test
call assert_equal("test", v:clipmethod)
call setreg("*", ["hello", "world", "!"], "c")
call assert_equal(["hello", "world", "!"], g:vim_test_stuff.lines)
call assert_equal("v", g:vim_test_stuff.type)
call setreg("*", ["hello", "world", "!"], "l")
call assert_equal(["hello", "world", "!"], g:vim_test_stuff.lines)
call assert_equal("V", g:vim_test_stuff.type)
call setreg("*", ["hello", "world", "!"], "b40")
call assert_equal(["hello", "world", "!"], g:vim_test_stuff.lines)
call assert_equal("40", g:vim_test_stuff.type)
set clipmethod&
endfunc

View File

@@ -155,6 +155,11 @@ static char *(features[]) =
"+clipboard", "+clipboard",
#else #else
"-clipboard", "-clipboard",
#endif
#ifdef FEAT_CLIPBOARD_PROVIDER
"+clipboard_provider",
#else
"-clipboard_provider",
#endif #endif
"+cmdline_compl", "+cmdline_compl",
"+cmdline_hist", "+cmdline_hist",
@@ -729,6 +734,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1857,
/**/ /**/
1856, 1856,
/**/ /**/

View File

@@ -2256,7 +2256,8 @@ typedef int sock_T;
#define VV_CLIPMETHOD 113 #define VV_CLIPMETHOD 113
#define VV_TERMDA1 114 #define VV_TERMDA1 114
#define VV_TERMOSC 115 #define VV_TERMOSC 115
#define VV_LEN 116 // number of v: vars #define VV_CLIPPROVIDERS 116
#define VV_LEN 117 // number of v: vars
// used for v_number in VAR_BOOL and VAR_SPECIAL // used for v_number in VAR_BOOL and VAR_SPECIAL
#define VVAL_FALSE 0L // VAR_BOOL #define VVAL_FALSE 0L // VAR_BOOL
@@ -2318,6 +2319,7 @@ typedef enum {
CLIPMETHOD_X11, CLIPMETHOD_X11,
CLIPMETHOD_GUI, CLIPMETHOD_GUI,
CLIPMETHOD_OTHER, CLIPMETHOD_OTHER,
CLIPMETHOD_PROVIDER
} clipmethod_T; } clipmethod_T;
// Info about selected text // Info about selected text