Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate the clipboard provider into Neovim-Qt #298

Open
xelra opened this issue Jun 22, 2017 · 41 comments
Open

Integrate the clipboard provider into Neovim-Qt #298

xelra opened this issue Jun 22, 2017 · 41 comments

Comments

@xelra
Copy link

xelra commented Jun 22, 2017

We talked about this some time ago on IRC, but I felt that it might be best to put the feature request down here.

I'm using Neovim-Qt mostly to connect to remote Neovim sessions over SSH. One of my initial motivations to do so was because I thought that would solve the clipboard problem. Unfortunately the clipboard is still handled by the remote Neovim session.

It would be great if the + and * registers would point to the local system clipboard, the one running Neovim-Qt.

Thank you very much for considering.

@equalsraf
Copy link
Owner

Waiting on neovim/neovim#6030 neovim/neovim#6029.

If possible implement the provider in the shim.

@Shougo
Copy link

Shougo commented Jun 28, 2017

Implemented the feature in neovim!

@equalsraf equalsraf removed the waiting label Jul 26, 2018
equalsraf pushed a commit that referenced this issue Jul 26, 2018
Implement a clipboard provider in the GUI shim. Calls to the provider
are handled by the GUI that provides access to its clipboard.

Vim (and Neovim) stores the selection type along with data in the
clipboard. To achieve this the selection type (a string) is stored in
the clipboard with the mimetype application/x-nvim-selection-type.

Fixes #298.
equalsraf pushed a commit that referenced this issue Aug 1, 2018
Implement a clipboard provider in the GUI shim. Calls to the provider
are handled by the GUI that provides access to its clipboard.

Vim (and Neovim) stores the selection type along with data in the
clipboard. To achieve this the selection type (a string) is stored in
the clipboard with the mimetype application/x-nvim-selection-type.

Fixes #298.
@skt041959
Copy link

Hi @equalsraf

When will the tb-clipboard branch merge into master branch?

@equalsraf
Copy link
Owner

@skt041959 as it is it wont be merged. Ideally some kind soul (or me if time allows it) would add support upstream to override the clipboard provider using a function instead of using a custom executable.

@equalsraf
Copy link
Owner

Moving on this after pushing some bits upstream - now in #479

@equalsraf
Copy link
Owner

FYI #479 has been merged.It is NOT enabled by default. You need to call GuiClipboard to enable it

call GuiClipboard()

This essentially sets g:clipboard.

I plan to tag a new release with this so everyone can test it. Keep in mind this requires the master branch from nvim (0.3.2)

@equalsraf
Copy link
Owner

Dont know if anyone has been using or following this. So here is a quick update has a note for me to follow later on.

There are a couple of problems with this right now

  • neovim caches provider availability (search for CHECK_PROVIDER in eval.c) which means that if GuiClipboard() is called too late (TM) then attempting to access the clipboard always with an error about no clipboard being available, even if checkHealth says otherwise.
  • neovim-qt sets the channel information about the clipboard too late, meaning that calling GuiClipboard in ginit.vim ALWAYS fails to setup the clipboard

The second part is already in #498. It is still unclear to me if the first part can or should be addressed in the shim.

TLDR; 🤦‍♂️

@svermeulen
Copy link

I use this and it works great except that every once in awhile it doesn't initialize properly and I have to restart neovim until it does, I'm assuming for the reasons you mention

@kwon-young
Copy link

kwon-young commented Jan 30, 2019

I've also been trying to use this but I can't seem to make it work when connecting to a remote neovim using nvim-qt --server.
Here the series I command run:

# on server foo
ky@foo $ nvim --listen foo:7777 --headless
# on local machine bar
ky@bar $ nvim-qt --server foo:7777
# in nvim-qt
: call GuiClipboard()

When running :checkhealth after calling GuiClipboard, neovim report that it found a custom clipboard provider.
I can use the + and * register but unfortunately, they don't affect my clipboard on my local machine.
Did I miss something?
@svermeulen did you manage to make it work using a remote neovim?

Finally, when nvim-qt spawns its own neovim on my local machine, calling GuiClipboard works as expected.

Using neovim 3.4 and latest neovim-qt from master branch.

@equalsraf
Copy link
Owner

I use this and it works great except that every once in awhile it doesn't initialize properly and I have to restart neovim until it does, I'm assuming for the reasons you mention

Precisely. Neovim caches the clipboard setup, so if you come in too late it does not work. This happens almost every time with remote instances (to my great frustration since i work mostly with a remote instance).

@kwon-young you can try to work around it by moving the shim plugin loading to be as early as possible and immediately call GuiClipboard().

@justinmk
Copy link
Contributor

justinmk commented Jan 31, 2019

@equalsraf would it help if Nvim set up a dictwatcheradd() watcher on g:clipboard, so that let g:clipboard = ... reloads the clipboard provider?

@equalsraf
Copy link
Owner

Nope. I think the real issue is that has_clipboard gets cached in eval.c.

checkhealth actually reports ok for the provider, but any call to grab data from it via getreg prints No provider: Try checkhealth... despite g:clipboard being set.

Calling the provider manually via g:clipboard['paste']['*']() actually works.

I need to sit down for a couple of days to try and figure a way to fix that without breaking other stuff.

@equalsraf
Copy link
Owner

@krishnakumarg1984
Copy link

Can we enable this by default?

@equalsraf
Copy link
Owner

Can we enable this by default?

hi @krishnakumarg1984, good question, how is this feature working for you so far?

@krishnakumarg1984
Copy link

I didn't face any reliability issues when copying from remote servers and seems stable enough for me. Is there some automated testing possible to thoroughly test this feature before deciding to enable by default?

@equalsraf
Copy link
Owner

I didn't face any reliability issues when copying from remote servers

Strange, remote servers are precisely the case we are still struggling with. I usually dont get a working clipboard.

.> Is there some automated testing possible to thoroughly test this feature

The only test at the moment is this but it does not test for remote instances.

@Kraust
Copy link

Kraust commented Feb 12, 2019

I have tried to get GuiClipboard working with a windows instance of neovim-qt and a linux instance of neovim without any success. I am using both the latest rev of neovim-qt, the shim plugin and neovim (I have tried both with and without the patch in your gist). I have tried calling GuiClippboard() both in gInit and after I had attached to my session.
No error messages are displayed in any case.
Would like further input on the matter, I could be missing something here.

@equalsraf
Copy link
Owner

hi @Kraust

It is very strange that you see no errors. It seems more likely that the gui clipboard is not being activated. Can you quickly check a couple of things?

  • does :checkhealth complain about your clipboard
  • echo &clipboard i.e. is your clipboard set to unammed or unnamedplust? This needs to be set to work with regular yank/paste.
  • if you copy something into the clipboard and them call :echo getreg('+') do you get its contents
  • what about :echo g:clipboard['paste']['+']() (GuiClipboard must be called before this)

@Kraust
Copy link

Kraust commented Feb 12, 2019

First time, with call GuiClipboard() in my ginit.vim:

:checkhealth

health#provider#check
========================================================================
## Clipboard (optional)
  - OK: Clipboard tool found: custom

:echo &clipboard

unnamedplus

(I have set clipboard+=unnamedplus in my vimrc)

:echo getreg('+')

clipboard: No provider. Try ":checkhealth" or "h clipboard"
<and the contents of what I yanked previously>

Note: I re-ran :checkhealth here and still got the same as above.

(I did a call GuiClipboard() here as well)

:echo g:clipboard['paste']['+']()

I get the contents of my Windows clipboard and not the contents of my Linux one.

Note, to further add, if I am running an xserver on windows (e.g. Xming) I can get my clipboard via x11 forwarding only if I have a terminal session up (which is what you'd expect). I am not doing that in my above testing.


Second time without call GuiClipboard() in my ginit.vim

health#provider#check
========================================================================
## Clipboard (optional)
  - WARNING: No clipboard tool found. Clipboard registers (`"+` and `"*`) will not work.
    - ADVICE:
      - :help |clipboard|

:echo &clipboard
unnamedplus
 :echo getreg('+')
clipboard: No provider. Try ":checkhealth" or "h clipboard"
<and the contents of what I yanked previously>
call GuiClipboard()
health#provider#check
========================================================================
## Clipboard (optional)
  - OK: Clipboard tool found: custom
:echo g:clipboard['paste']['+']()
<the contents of what I currently have in my windows clipboard>

Here if I yank something again, I still get the same error in :echo getreg('+') and it does not get sent to my windows clipboard.

@equalsraf
Copy link
Owner

Yeah that is consistent with what we are seeing here

  • the internals are actually working, that is why g:clipboard['paste']['+']() returns the correct clipboard contents
  • checkhealth checks directly with g:clipboard so it states that everything is ok (as long as GuilClipboard was called)
  • getreg is the authoritative source and that always fails, which is our issue. It is strange that you dont get an error when pasting though

You said you were trying using the patch from the gist. How are you using it? You should follow a call to GuiClipboard() with call reloadprovider('clipboard') which should return true.

@dakom
Copy link

dakom commented Feb 13, 2019

So... just to understand, "+y and "+p don't work?

@equalsraf
Copy link
Owner

@dakom both the plus and star register will not work if GuilClipboard was called.

@dakom
Copy link

dakom commented Feb 13, 2019

I'm not familiar with that function... I see it mentioned above, but is there a way to get yank/paste to work with the clipboard in windows?

@equalsraf
Copy link
Owner

@dakom the clipboard should already work in windows. This issue is about the case when using the local clipboard with a remote instance of neovim - which users enable using that function.

If you are having issues in general with the clipboard you can open another issue. But if it is not working it is likely some issue with neovim, since it should be working out of the box.

@dakom
Copy link

dakom commented Feb 14, 2019

ugh was a silly mistake on my part ;) nm

@equalsraf
Copy link
Owner

ugh was a silly mistake on my part ;) nm

No worries I'd rather have a silly problem than a hard bug.

@ezh
Copy link

ezh commented Feb 17, 2019

Very simple workaround.
I'm using remote nvim.

copy /usr/share/nvim/runtime/autoload/provider/clipboard.vim
to ~/.your-custom-runtime/nvim/autoload/provider/clipboard.vim

and modify function! s:clipboard.get(reg) abort

function! s:clipboard.get(reg) abort
  if type(s:paste[a:reg]) == v:t_func
    return s:paste[a:reg]()
  elseif s:selections[a:reg].owner > 0
    return s:selections[a:reg].data
  end
  if g:clipboard['name'] == 'custom'
    return g:clipboard['paste']['+']()
  end
  return s:try_cmd(s:paste[a:reg])
endfunction

so I just added

  if g:clipboard['name'] == 'custom'
    return g:clipboard['paste']['+']()
  end

@equalsraf Thank you for Neovim-Qt

@ezh
Copy link

ezh commented Feb 17, 2019

 diff -Naur clipboard.vim.orig clipboard.vim
--- clipboard.vim.orig  2019-01-04 22:05:23.000000000 +0300
+++ clipboard.vim       2019-02-18 01:01:21.892554959 +0300
@@ -133,6 +133,9 @@
   elseif s:selections[a:reg].owner > 0
     return s:selections[a:reg].data
   end
+  if g:clipboard['name'] == 'custom'
+    return g:clipboard['paste'][a:reg]()
+  end
   return s:try_cmd(s:paste[a:reg])
 endfunction

@@ -151,6 +154,9 @@
   end

   if s:cache_enabled == 0
+    if g:clipboard['name'] == 'custom'
+      return g:clipboard['copy'][a:reg](a:lines)
+    end
     call s:try_cmd(s:copy[a:reg], a:lines)
     return 0
   end

@svermeulen
Copy link

svermeulen commented Feb 18, 2019

@dakom the clipboard should already work in windows. This issue is about the case when using the local clipboard with a remote instance of neovim - which users enable using that function.

@equalsraf Just want to mention that I'm on windows and I suffer from what I assume is this issue a lot. Often, after nvim-qt starts up, the + register will not work as expected. Copying from outside nvim-qt and the attempting to paste inside nvim-qt does not use the copied value.

When this issue occurs, the + register actually doesn't even get displayed when running :reg. So what I have been doing is, every time I start nvim-qt, I run :reg and if I don't see the + register I keep restarting nvim-qt until it displays there (and can sometimes take as many as 4 attempts for it to work)

I can reproduce this with gvimrc.vim:

call GuiClipboard()

And init.vim:

set clipboard+=unnamedplus

With just these settings, I can start nvim-qt and randomly find that the + register is not displayed in :reg.

Edit: I should also mention that I want to use this feature because the default (win32yank) is very flaky and causes other (worse) issues for me

Edit2: Noticed a couple other things when this issue occurs. If I execute echo getreg('+') it prints clipboard: no provider. Try ":checkhealth" or ":h clipboard".. Running :checkhealth reports no errors and says OK: clipboard tool found: custom

@svermeulen
Copy link

svermeulen commented Feb 21, 2019

Just want to mention that I was able to resolve this for myself by doing the following:

  • Building neovim (master) manually and including @equalsraf's patch to add the reloadprovider method
  • Downloading the most recent build of nvim-qt from appveyor and pasting it over top of my custom neovim build
  • Including call reloadprovider('clipboard') after call GuiClipboard() in my gvimrc.vim

@equalsraf
Copy link
Owner

Thanks @svermeulen. The question now is how to merge this upstream in a way that does not break other stuff - as it is that reloadprovider thing is not very safe.

@justinmk
Copy link
Contributor

neovim/neovim#10161 was merged, can this issue be closed now? Or what's remaining?

@equalsraf
Copy link
Owner

I've been using this for a few weeks now. Works fine, just missing some niceties in the shim plugin.

To enable

:call GuiClipboard()

If you are reconnecting the UI you need to call it again.

Since the UI autocommands were also merged, it is simply a matter of calling GuiClipboard() from the autocommand (assuming neovim supports it). Otherwise placing a call in ginit.vim is also an option.

Just a quick reminder that you need o install the gui shim on the neovim host side.

@justinmk
Copy link
Contributor

@equalsraf are you planning to enable guiclipboard by default eventually?

equalsraf pushed a commit that referenced this issue Jul 2, 2020
After successfuly loading the shim call GuiClipboard to enable the
native GUI clipboard.

ref #298
equalsraf pushed a commit that referenced this issue Sep 11, 2020
After successfuly loading the shim call GuiClipboard to enable the
native GUI clipboard.

ref #298
@adrubesh
Copy link

adrubesh commented Mar 21, 2021

On a recent install of neovim-qt, it seems that 'GuiClipboard' doesn't exist? Or is my install broken? This is on Win10

image

@equalsraf
Copy link
Owner

It should still be there. Are other gui functions or commands available?

When in doubt you can check :scriptnames (the path to nvim_gui_shim.vim should be there). If it is missing it was not loaded.
Check the value in &rtp to see what path is in there to load the shim.

@adrubesh
Copy link

@equalsraf Ah, thanks, I'm using nvim --server to connect to a remote nvim and forgot the shim on the server side :)

@xakep71k
Copy link

use ssh with -Y key to make clipboard work without GuiClibboard() call

equalsraf pushed a commit that referenced this issue Feb 2, 2022
After successfuly loading the shim call GuiClipboard to enable the
native GUI clipboard.

ref #298
equalsraf pushed a commit that referenced this issue Feb 2, 2022
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
equalsraf pushed a commit that referenced this issue Feb 3, 2022
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
@hinell
Copy link

hinell commented Nov 19, 2022

Having issues with the latest build on a local machine (not a remote one). We need to implement native support for this asap. Switched back to xclip.

[K]Ubuntu 22.04.1 LTS (Jammy Jellyfish)
NVIM-QT v0.2.18.9999

NVIM v0.8.0-v0.8.0
NVIM v0.9.0-dev-6e8ed5a

equalsraf pushed a commit that referenced this issue Apr 2, 2023
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests