Skip to content

Commit e14d05e

Browse files
equalsrafequalsraf
equalsraf
authored and
equalsraf
committed
Enable native clipboard provider by default
After successfuly loading the shim call GuiClipboard to enable the native GUI clipboard. - A new command GuiClipboard enables/disables the clipboard. - Internally the Shim keeps the state of the setting and sets autocommands to reconfigure the clipboard on UI attachment. The old function GuiClipboard is kept for compatibility. ref #298
1 parent 12f3f79 commit e14d05e

File tree

4 files changed

+112
-25
lines changed

4 files changed

+112
-25
lines changed

src/gui/runtime/doc/nvim_gui_shim.txt

+17
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,22 @@ GuiWindowOpacity Set window opacity. Takes a single argument,
8686
a double in the range 0.0 to 1.0 (fully opaque).
8787
This capability might not be supported in some platforms.
8888

89+
*GuiClipboard*
90+
GuiClipboard Enable or disable the native GUI clipboard.
91+
When enabled, neovim will use the GUI as its clipboard
92+
provider.
93+
94+
To enable,
95+
>
96+
GuiClipboard 1
97+
<
98+
to disable pass 0 to the command
99+
>
100+
GuiClipboard 0
101+
<
102+
After disabling the GUI clipboard, neovim will select
103+
a clipboard provider from the available options.
104+
89105
==============================================================================
90106
2. GUI variables
91107

@@ -208,6 +224,7 @@ menu can be mapped to right click events in ginit.vim, e.g.
208224
nnoremap <silent><RightMouse> :call GuiShowContextMenu()<CR>
209225
inoremap <silent><RightMouse> <Esc>:call GuiShowContextMenu()<CR>
210226
vnoremap <silent><RightMouse> :call GuiShowContextMenu()<CR>gv
227+
<
211228

212229
==============================================================================
213230
4. Internals

src/gui/runtime/plugin/nvim_gui_shim.vim

+81-25
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ function GuiName()
142142
return get(info.client, 'name', '')
143143
endfunction
144144

145+
let s:ui_clipboard_enabled = 0
146+
145147
function s:ui_has_clipboard(idx, ui_info)
146148
if has_key(a:ui_info, 'chan') == 0
147149
return 0
@@ -158,45 +160,99 @@ function s:ui_has_clipboard(idx, ui_info)
158160
endif
159161
endfunction
160162

161-
"Enable a GUI provided clipboard
162-
function GuiClipboard()
163+
function s:reload_clipboard_provider()
164+
" We need to reload the neovim clipboard provider here so it picks up on
165+
" g:clipboard. In older versions of neovim (<=0.3.8) the provider would
166+
" short circuit if a working clipboard was not available. After 0.3.8
167+
" the provider should not short circuit, and unsetting
168+
" g:loaded_clipboard_provider will enable a full reload of the provider.
169+
"
170+
" TLDR; source this to reinitialize the clipboard provider, this may not
171+
" work
172+
unlet! g:loaded_clipboard_provider
173+
runtime autoload/provider/clipboard.vim
174+
endfunction
175+
176+
function s:disable_custom_clipboard()
177+
if exists("g:clipboard")
178+
unlet g:clipboard
179+
endif
180+
call s:reload_clipboard_provider()
181+
endfunction
182+
183+
"Enable a GUI clipboard
184+
function s:SetupGuiClipboard(silent)
163185
if !has("nvim-0.3.2")
164-
echoerr "UI clipboard requires nvim >=0.3.2"
186+
if a:silent == 0
187+
echoerr "UI clipboard requires nvim >=0.3.2"
188+
endif
165189
return
166190
endif
167191

168192
let uis = nvim_list_uis()
169193
call filter(uis, funcref('s:ui_has_clipboard'))
170194
if len(uis) == 0
171-
echoerr "No UIs with clipboard support are attached"
195+
if a:silent == 0
196+
echoerr "No UIs with clipboard support are attached"
197+
end
198+
call s:disable_custom_clipboard()
172199
return
173200
endif
174201
let ui_chan = uis[-1].chan
175202

176-
let g:clipboard = {
177-
\ 'name': 'custom',
178-
\ 'copy': {
179-
\ '+': {lines, regtype -> rpcnotify(ui_chan, 'Gui', 'SetClipboard', lines, regtype, '+')},
180-
\ '*': {lines, regtype -> rpcnotify(ui_chan, 'Gui', 'SetClipboard', lines, regtype, '*')},
181-
\ },
182-
\ 'paste': {
183-
\ '+': {-> rpcrequest(ui_chan, 'Gui', 'GetClipboard', '+')},
184-
\ '*': {-> rpcrequest(ui_chan, 'Gui', 'GetClipboard', '*')},
185-
\ },
186-
\ }
203+
let g:clipboard = {
204+
\ 'name': 'custom',
205+
\ 'copy': {
206+
\ '+': {lines, regtype -> rpcnotify(ui_chan, 'Gui', 'SetClipboard', lines, regtype, '+')},
207+
\ '*': {lines, regtype -> rpcnotify(ui_chan, 'Gui', 'SetClipboard', lines, regtype, '*')},
208+
\ },
209+
\ 'paste': {
210+
\ '+': {-> rpcrequest(ui_chan, 'Gui', 'GetClipboard', '+')},
211+
\ '*': {-> rpcrequest(ui_chan, 'Gui', 'GetClipboard', '*')},
212+
\ },
213+
\ }
214+
215+
call s:reload_clipboard_provider()
216+
endfunction
187217

188-
" We need to reload the neovim clipboard provider here so it picks up on
189-
" g:clipboard. In older versions of neovim (<=0.3.8) the provider would
190-
" short circuit if a working clipboard was not available. After 0.3.8
191-
" the provider should not short circuit, andunsetting
192-
" g:loaded_clipboard_provider will enable a full reload of the provider.
193-
"
194-
" TLDR; source this to reinitialize the clipboard provider, this may not
195-
" work
196-
unlet! g:loaded_clipboard_provider
197-
runtime autoload/provider/clipboard.vim
218+
" For compatibility with an earlier version
219+
function GuiClipboard()
220+
call s:SetupGuiClipboard(0)
221+
endfunction
222+
223+
" Enable/Disable the GUI clipboard
224+
function s:GuiClipboardSet(enable)
225+
if a:enable == 0
226+
let s:ui_clipboard_enabled = 0
227+
call s:disable_custom_clipboard()
228+
elseif s:ui_clipboard_enabled == 1
229+
" clipboard already enabled
230+
else
231+
if exists("g:clipboard")
232+
echoerr "A custom g:clipboard is already configured"
233+
endif
234+
235+
call s:SetupGuiClipboard(0)
236+
let s:ui_clipboard_enabled = 1
237+
endif
238+
endfunction
239+
command! -nargs=1 GuiClipboard call s:GuiClipboardSet(<args>)
240+
241+
" If enabled reconfigure the GUI clipboard
242+
function s:UpdateGuiClipboard()
243+
if s:ui_clipboard_enabled == 1
244+
call s:SetupGuiClipboard(1)
245+
endif
198246
endfunction
199247

248+
" When a UI attaches/detaches try to reconfigure the GUI
249+
" clipboard
250+
augroup GuiClipboard
251+
autocmd!
252+
autocmd UIEnter * :call s:UpdateGuiClipboard()
253+
autocmd UILeave * :call s:UpdateGuiClipboard()
254+
augroup END
255+
200256
" Directory autocommands for Treeview
201257
augroup guiDirEvents
202258
autocmd!

src/gui/shell.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ void Shell::setAttached(bool attached)
279279

280280
MsgpackRequest* req_shim{ m_nvim->api0()->vim_command("runtime plugin/nvim_gui_shim.vim") };
281281
connect(req_shim, &MsgpackRequest::error, this, &Shell::handleShimError);
282+
connect(req_shim, &MsgpackRequest::finished, this, &Shell::handleShimLoad);
282283

283284
MsgpackRequest* req_ginit{ m_nvim->api0()->vim_command(GetGVimInitCommand()) };
284285
connect(req_ginit, &MsgpackRequest::error, this, &Shell::handleGinitError);
@@ -1882,6 +1883,18 @@ void Shell::handleShimError(quint32 msgid, quint64 fun, const QVariant& err)
18821883
qDebug() << "GUI shim error " << err;
18831884
}
18841885

1886+
void Shell::handleShimLoad(quint32 msgid, quint64 fun, const QVariant& resp)
1887+
{
1888+
// Enable native clipboard, if api version 6 is available
1889+
auto api6 = m_nvim->api6();
1890+
if (api6) {
1891+
qDebug() << "Enabling native clipboard";
1892+
QVariantList args;
1893+
auto req = api6->nvim_command("GuiClipboard 1");
1894+
connect(req, &MsgpackRequest::error, this, &Shell::handleShimError);
1895+
}
1896+
}
1897+
18851898
void Shell::handleGetBackgroundOption(quint32 msgid, quint64 fun, const QVariant& val)
18861899
{
18871900
const QString mode{ val.toString() };

src/gui/shell.h

+1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ protected slots:
114114
void updateClientInfo();
115115
void handleGinitError(quint32 msgid, quint64 fun, const QVariant& err);
116116
void handleShimError(quint32 msgid, quint64 fun, const QVariant& err);
117+
void handleShimLoad(quint32 msgid, quint64 fun, const QVariant& resp);
117118
void handleGetBackgroundOption(quint32 msgid, quint64 fun, const QVariant& val);
118119

119120
protected:

0 commit comments

Comments
 (0)