equalsraf / neovim-qt

Neovim client library and GUI, in Qt5.
https://github.com/equalsraf/neovim-qt/wiki
ISC License
1.85k stars 171 forks source link

Integrate the clipboard provider into Neovim-Qt #298

Open xelra opened 7 years ago

xelra commented 7 years ago

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 commented 7 years ago

Waiting on https://github.com/neovim/neovim/pull/6030 https://github.com/neovim/neovim/issues/6029.

If possible implement the provider in the shim.

Shougo commented 7 years ago

Implemented the feature in neovim!

skt041959 commented 6 years ago

Hi @equalsraf

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

equalsraf commented 6 years ago

@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 commented 5 years ago

Moving on this after pushing some bits upstream - now in https://github.com/equalsraf/neovim-qt/pull/479

equalsraf commented 5 years ago

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 commented 5 years ago

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

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; :man_facepalming:

svermeulen commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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

equalsraf commented 5 years ago

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 commented 5 years ago

https://gist.github.com/equalsraf/e8e50a9d503322b7cf52c43c7685e401

krishnakumarg1984 commented 5 years ago

Can we enable this by default?

equalsraf commented 5 years ago

Can we enable this by default?

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

krishnakumarg1984 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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?

Kraust commented 5 years ago

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 commented 5 years ago

Yeah that is consistent with what we are seeing here

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.

Kraust commented 5 years ago

👍 That was what I was missing, I wasn't calling reloadprovider directly. With that step added I have full control over my clipboard now.

dakom commented 5 years ago

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

equalsraf commented 5 years ago

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

dakom commented 5 years ago

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 commented 5 years ago

@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 commented 5 years ago

ugh was a silly mistake on my part ;) nm

equalsraf commented 5 years ago

ugh was a silly mistake on my part ;) nm

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

ezh commented 5 years ago

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 commented 5 years ago
 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 commented 5 years ago

@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 commented 5 years ago

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

equalsraf commented 5 years ago

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 commented 5 years ago

https://github.com/neovim/neovim/pull/10161 was merged, can this issue be closed now? Or what's remaining?

equalsraf commented 5 years ago

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 commented 5 years ago

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

adrubesh commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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

xakep71k commented 3 years ago

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

hinell commented 1 year ago

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