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

clipboard=unnamed: block copy/paste #1822

Open
pignatenko opened this Issue Jan 16, 2015 · 46 comments

Comments

Projects
None yet
@pignatenko

pignatenko commented Jan 16, 2015

I recently recompiled from source and block based editing and pasting is entirely screwy.

For example with set ve=block and in ^V mode

This  []
Is    [] 
A     []
Column[]

Puting your cursor in that column then hitting I then adding a comma inserts the comma only on the first line. However doing an append adds commas to every line.

Pasting is also screwed up, when selecting a block and pasting it in another space neovim adds new lines instead of pasting blockwise. So if we selected the first column in the above text and tried to paste it as second column we get this.

This    This
Is
A
Column
Is
A
Column

Instead of

This   This
Is     Is
A       A
ColumnColumn

Prepaste in block mode reformats the block into something entirely grotesque by adding spaces like so

This 



Is
A
Column

And doesn't even paste the buffer contents.

@pignatenko pignatenko changed the title from Block editing and pasting is broken as of 01/14/2015 to Block editing and pasting is broken and not vim compatible as of 01/14/2015 Jan 16, 2015

@pignatenko

This comment has been minimized.

Show comment
Hide comment
@pignatenko

pignatenko Jan 16, 2015

This only happens when you have :set clipboard+=unnamed.

pignatenko commented Jan 16, 2015

This only happens when you have :set clipboard+=unnamed.

@pignatenko pignatenko changed the title from Block editing and pasting is broken and not vim compatible as of 01/14/2015 to Block editing and pasting is broken with unnamed clip and not vim compatible as of 01/14/2015 Jan 16, 2015

@fmoralesc

This comment has been minimized.

Show comment
Hide comment
@fmoralesc

fmoralesc Jan 16, 2015

Contributor

I can confirm.

This is becaue the current method for handling the clipboard is naive, and it uses the default text clipboard target, instead of what vanilla vim does, which is to encode into the "_VIM_TEXT" and "_VIMENC_TEXT" targets what sort of selection was passed, either block or normal. In my tests, in _VIMENC_TEXT a selection made in block mode is appended with \x02utf-8\x00, while a normal visual selection is appended with \x00utf-8\x00. Neither xclip nor xsel support special targets (and I doubt pbcopy does), so the long term solution would be to implement more featureful platform-specific clipboard handlers, and give nvim a way to handle this extended clipboard data format.

To play with this:

from gi.repository import Gtk, Gdk

c = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
d = [c.wait_for_contents(Gdk.Atom.intern(target), False) \
                                     for target in ["_VIM_TEXT", "_VIMENC_TEXT"]]
print(d)
Contributor

fmoralesc commented Jan 16, 2015

I can confirm.

This is becaue the current method for handling the clipboard is naive, and it uses the default text clipboard target, instead of what vanilla vim does, which is to encode into the "_VIM_TEXT" and "_VIMENC_TEXT" targets what sort of selection was passed, either block or normal. In my tests, in _VIMENC_TEXT a selection made in block mode is appended with \x02utf-8\x00, while a normal visual selection is appended with \x00utf-8\x00. Neither xclip nor xsel support special targets (and I doubt pbcopy does), so the long term solution would be to implement more featureful platform-specific clipboard handlers, and give nvim a way to handle this extended clipboard data format.

To play with this:

from gi.repository import Gtk, Gdk

c = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
d = [c.wait_for_contents(Gdk.Atom.intern(target), False) \
                                     for target in ["_VIM_TEXT", "_VIMENC_TEXT"]]
print(d)
@justinmk

This comment has been minimized.

Show comment
Hide comment
@justinmk

justinmk Jan 16, 2015

Member

Nice investigating @fmoralesc.

In my tests, in _VIMENC_TEXT a selection made in block mode is appended with \x02utf-8\x00, while a normal visual selection is appended with \x00utf-8\x00. Neither xclip nor xsel support special targets

I remember seeing this in the source, and was worried about it. To make sure I understand, the "non special" clipboard text that is shared with other processes, is not appended with the special marker, correct? (Otherwise it would corrupt the text for non-Vim processes.)

We could store an internal flag that remembers the selection type, so that at least the most annoying and visible case would be fixed (yanking and pasting using the same nvim process). We could even get fancy and broadcast that information to other nvim processes (#1302). That wouldn't fix the problem if all nvim processes are shutdown, nor for non-local processes. But it would be a fairly low-cost band-aid.

Member

justinmk commented Jan 16, 2015

Nice investigating @fmoralesc.

In my tests, in _VIMENC_TEXT a selection made in block mode is appended with \x02utf-8\x00, while a normal visual selection is appended with \x00utf-8\x00. Neither xclip nor xsel support special targets

I remember seeing this in the source, and was worried about it. To make sure I understand, the "non special" clipboard text that is shared with other processes, is not appended with the special marker, correct? (Otherwise it would corrupt the text for non-Vim processes.)

We could store an internal flag that remembers the selection type, so that at least the most annoying and visible case would be fixed (yanking and pasting using the same nvim process). We could even get fancy and broadcast that information to other nvim processes (#1302). That wouldn't fix the problem if all nvim processes are shutdown, nor for non-local processes. But it would be a fairly low-cost band-aid.

@fmoralesc

This comment has been minimized.

Show comment
Hide comment
@fmoralesc

fmoralesc Jan 16, 2015

Contributor

@justinmk I wrote a clipboard manager once, I know my clipboards ;)

To make sure I understand, the "non special" clipboard text that is shared with other processes, is not appended with the special marker, correct?

Yes. The X clipboard contents are actually a list of "targets", which contain the real data (this is actually requested from the sources if possible, or if the sources haven't actually requested to store it in the server, which is why in ancient times clipboard contents were lost once applications stopped). Most programs provide at least a plain text target (which is what xclip and xsel use), but it is the clients responsibility to process it (the data can be arbitrary). So, even if vim uses a custom target, it the client doesn't process it, it doesn't matter. Some applications use conventional methods to extend the clipboard functionality; for example, when copying files, GNOME actually sets a target with a list of URIs. I created a patch to KeepasX to set a flag that indicated that some text in the clipboard was a password, so the clipboard manager could delete it after some time.

I think we already use an internal flag for when the unnamed register is not used, we should look into that.

Perhaps building our own clipboard setter and getter with support for vim's _VIMENC_TEXT convention wouldn't be a bad idea; that would provide us with clipboard-compatibility (ja!) with vanilla vim.

(I didn't know about #1302, that might be helpful for rewriting macros/editexisting.vim, which I use all the time in gvim).

Contributor

fmoralesc commented Jan 16, 2015

@justinmk I wrote a clipboard manager once, I know my clipboards ;)

To make sure I understand, the "non special" clipboard text that is shared with other processes, is not appended with the special marker, correct?

Yes. The X clipboard contents are actually a list of "targets", which contain the real data (this is actually requested from the sources if possible, or if the sources haven't actually requested to store it in the server, which is why in ancient times clipboard contents were lost once applications stopped). Most programs provide at least a plain text target (which is what xclip and xsel use), but it is the clients responsibility to process it (the data can be arbitrary). So, even if vim uses a custom target, it the client doesn't process it, it doesn't matter. Some applications use conventional methods to extend the clipboard functionality; for example, when copying files, GNOME actually sets a target with a list of URIs. I created a patch to KeepasX to set a flag that indicated that some text in the clipboard was a password, so the clipboard manager could delete it after some time.

I think we already use an internal flag for when the unnamed register is not used, we should look into that.

Perhaps building our own clipboard setter and getter with support for vim's _VIMENC_TEXT convention wouldn't be a bad idea; that would provide us with clipboard-compatibility (ja!) with vanilla vim.

(I didn't know about #1302, that might be helpful for rewriting macros/editexisting.vim, which I use all the time in gvim).

@bfredl

This comment has been minimized.

Show comment
Hide comment
@bfredl

bfredl Jan 16, 2015

Member

Perhaps building our own clipboard setter and getter with support for vim's _VIMENC_TEXT convention wouldn't be a bad idea; that would provide us with clipboard-compatibility (ja!) with vanilla vim.

That would probably be the best 👍 In the meanwhile, we could run xsel (not sure of pbcopy) in nofork mode as a job and be able to detect when pasting, if this instance still "owns" the clipboard (and then use an internal representation with correct regtype), so block yank/paste at least work locally.

Member

bfredl commented Jan 16, 2015

Perhaps building our own clipboard setter and getter with support for vim's _VIMENC_TEXT convention wouldn't be a bad idea; that would provide us with clipboard-compatibility (ja!) with vanilla vim.

That would probably be the best 👍 In the meanwhile, we could run xsel (not sure of pbcopy) in nofork mode as a job and be able to detect when pasting, if this instance still "owns" the clipboard (and then use an internal representation with correct regtype), so block yank/paste at least work locally.

@fmoralesc

This comment has been minimized.

Show comment
Hide comment
@fmoralesc

fmoralesc Jan 16, 2015

Contributor

I wrote a prototype.

It uses both gtk2 and gtk3, because for some reason the gtk3 bindings don't have the ability to set arbitrary contents in the clipboard (at least, I couldn't make it work). Anyways, I couldn't make it copy text :/ (it does copy, but then it doesn't store the data); the copy operation should probably be embedded in a Gtk main loop.

Contributor

fmoralesc commented Jan 16, 2015

I wrote a prototype.

It uses both gtk2 and gtk3, because for some reason the gtk3 bindings don't have the ability to set arbitrary contents in the clipboard (at least, I couldn't make it work). Anyways, I couldn't make it copy text :/ (it does copy, but then it doesn't store the data); the copy operation should probably be embedded in a Gtk main loop.

@fmoralesc

This comment has been minimized.

Show comment
Hide comment
@fmoralesc

fmoralesc Jan 16, 2015

Contributor

Update: I managed to make it copy and save text to the clipboard, but I still can't make it set the _VIMENC_TEXT target. As-is, this would be feature complete replacement for xsel, so perhaps I (or someone else) should just take the plunge and port it to C. The Gtk clipboard implementation is good to have, because it should already support the wayland clipboard. I'm not sure other toolkits do this yet (probably yes).

Contributor

fmoralesc commented Jan 16, 2015

Update: I managed to make it copy and save text to the clipboard, but I still can't make it set the _VIMENC_TEXT target. As-is, this would be feature complete replacement for xsel, so perhaps I (or someone else) should just take the plunge and port it to C. The Gtk clipboard implementation is good to have, because it should already support the wayland clipboard. I'm not sure other toolkits do this yet (probably yes).

@fmoralesc

This comment has been minimized.

Show comment
Hide comment
@fmoralesc

fmoralesc Jan 16, 2015

Contributor

I tried to write the thing using PySide, and setting the _VIMENC_TEXT target works... but then it won't store the clipboard.

#!/usr/bin/env python3

import sys
import PySide.QtCore
import PySide.QtGui

def set(data):
    a = PySide.QtGui.QApplication(sys.argv)
    c = a.clipboard()
    mimedata = PySide.QtCore.QMimeData()
    mimedata.setText(data)
    mimedata.setData("_VIMENC_TEXT", data)
    c.setMimeData(mimedata, mode=c.Clipboard)
    timer = PySide.QtCore.QTimer()
    timer.start(500)
    timer.timeout.connect(lambda: a.exit())
    a.exec_()

if not sys.stdin.isatty():
    data = sys.stdin.read()
    if data not in ("", None):
        set(data)
Contributor

fmoralesc commented Jan 16, 2015

I tried to write the thing using PySide, and setting the _VIMENC_TEXT target works... but then it won't store the clipboard.

#!/usr/bin/env python3

import sys
import PySide.QtCore
import PySide.QtGui

def set(data):
    a = PySide.QtGui.QApplication(sys.argv)
    c = a.clipboard()
    mimedata = PySide.QtCore.QMimeData()
    mimedata.setText(data)
    mimedata.setData("_VIMENC_TEXT", data)
    c.setMimeData(mimedata, mode=c.Clipboard)
    timer = PySide.QtCore.QTimer()
    timer.start(500)
    timer.timeout.connect(lambda: a.exit())
    a.exec_()

if not sys.stdin.isatty():
    data = sys.stdin.read()
    if data not in ("", None):
        set(data)
@fmoralesc

This comment has been minimized.

Show comment
Hide comment
@fmoralesc

fmoralesc Jan 17, 2015

Contributor

The latest iteration of the clipboard handler is at https://gist.github.com/771eefee45eefd3d1a2b. It is now written in vala (because I didn't want to try with C). I still don't manage to make it store the clipboard, but everything else is OK. It would be great if someone else could take a look at this, I'm working on other stuff this weekend.

EDIT: it also needs a method to encode the string in _VIMENC_TEXT's format.

Contributor

fmoralesc commented Jan 17, 2015

The latest iteration of the clipboard handler is at https://gist.github.com/771eefee45eefd3d1a2b. It is now written in vala (because I didn't want to try with C). I still don't manage to make it store the clipboard, but everything else is OK. It would be great if someone else could take a look at this, I'm working on other stuff this weekend.

EDIT: it also needs a method to encode the string in _VIMENC_TEXT's format.

@bfredl

This comment has been minimized.

Show comment
Hide comment
@bfredl

bfredl Jan 17, 2015

Member

I had problems with store before when I tried to write a pygtk3 provider for an earlier iteration of the provider infrastructure. Something to try instead could be to fork to the background (or run it as a nvim job) and run the gtk eventloop (until an owner-changed event when someone else takes over the clipboard)

I also tried running xcopy/xsel in nofork mode as a job earlier today (to be able to know that this instance still owns the clipboard) but it seems I can't send the neccessary EOF to the stdin of a job (needed for xcopy to start accepting readers)

Member

bfredl commented Jan 17, 2015

I had problems with store before when I tried to write a pygtk3 provider for an earlier iteration of the provider infrastructure. Something to try instead could be to fork to the background (or run it as a nvim job) and run the gtk eventloop (until an owner-changed event when someone else takes over the clipboard)

I also tried running xcopy/xsel in nofork mode as a job earlier today (to be able to know that this instance still owns the clipboard) but it seems I can't send the neccessary EOF to the stdin of a job (needed for xcopy to start accepting readers)

@fmoralesc

This comment has been minimized.

Show comment
Hide comment
@fmoralesc

fmoralesc Jan 17, 2015

Contributor

Yes, probably a demon would work fine. Still, xsel manages to set the clipboard, I think it would be good to take a look at what it does.

Contributor

fmoralesc commented Jan 17, 2015

Yes, probably a demon would work fine. Still, xsel manages to set the clipboard, I think it would be good to take a look at what it does.

@justinmk

This comment has been minimized.

Show comment
Hide comment
@justinmk

justinmk Jan 17, 2015

Member

Dependency on python or gtk, or linking to xorg, is really something we should avoid. A gtk or python tool is good to have as an option, which is why it is a goal to make it easy for users (or plugins) to swap in alternative providers. But we we still need to provide an out-of-the-box half-solution for users who don't have gtk or python.

We can fix the most salient problem (for the current nvim process) by tracking the clipboard type internally.

An almost-complete solution could be to have a global user data key-value store: #1180. Then, the only remaining problem AFAICT is pasting from clipboard into a remote (ssh) nvim.

Member

justinmk commented Jan 17, 2015

Dependency on python or gtk, or linking to xorg, is really something we should avoid. A gtk or python tool is good to have as an option, which is why it is a goal to make it easy for users (or plugins) to swap in alternative providers. But we we still need to provide an out-of-the-box half-solution for users who don't have gtk or python.

We can fix the most salient problem (for the current nvim process) by tracking the clipboard type internally.

An almost-complete solution could be to have a global user data key-value store: #1180. Then, the only remaining problem AFAICT is pasting from clipboard into a remote (ssh) nvim.

@justinmk

This comment has been minimized.

Show comment
Hide comment
@justinmk

justinmk Jan 17, 2015

Member

We could ship the gtk tool with neovim, and have the provider select that if gtk is available.

Member

justinmk commented Jan 17, 2015

We could ship the gtk tool with neovim, and have the provider select that if gtk is available.

@fmoralesc

This comment has been minimized.

Show comment
Hide comment
@fmoralesc

fmoralesc Jan 17, 2015

Contributor

We could ship the gtk tool with neovim, and have the provider select that if gtk is available.

@justinmk That's what I was thinking of. I made the tool take very similar commandline arguments to what xsel and xclip have for that purpose. It's also the reason why I ported the utility to vala, which allows native compilation. The current binary is pretty small on x68_64 at 21k (smaller than xsel, actually).

Contributor

fmoralesc commented Jan 17, 2015

We could ship the gtk tool with neovim, and have the provider select that if gtk is available.

@justinmk That's what I was thinking of. I made the tool take very similar commandline arguments to what xsel and xclip have for that purpose. It's also the reason why I ported the utility to vala, which allows native compilation. The current binary is pretty small on x68_64 at 21k (smaller than xsel, actually).

@fmoralesc

This comment has been minimized.

Show comment
Hide comment
@fmoralesc

fmoralesc Jan 17, 2015

Contributor

If we port this utility to xcb, the tool itself would only have X as a runtime dependency. But first, we have to build something that works :p

Contributor

fmoralesc commented Jan 17, 2015

If we port this utility to xcb, the tool itself would only have X as a runtime dependency. But first, we have to build something that works :p

@fmoralesc

This comment has been minimized.

Show comment
Hide comment
@fmoralesc

fmoralesc Jan 17, 2015

Contributor

Also, neovim needs a way to detect the _VIMENC_TEXT target, because currently it treats all clipboards the same (just tried pasting a text block from gvim into nvim).

Contributor

fmoralesc commented Jan 17, 2015

Also, neovim needs a way to detect the _VIMENC_TEXT target, because currently it treats all clipboards the same (just tried pasting a text block from gvim into nvim).

@fmoralesc

This comment has been minimized.

Show comment
Hide comment
@fmoralesc

fmoralesc Jan 17, 2015

Contributor

Disregard the last comment; this is responsibility of the clipboard provider. How can it implement block paste, though? Should it recompose the lines to be affected?

Contributor

fmoralesc commented Jan 17, 2015

Disregard the last comment; this is responsibility of the clipboard provider. How can it implement block paste, though? Should it recompose the lines to be affected?

@justinmk

This comment has been minimized.

Show comment
Hide comment
@justinmk

justinmk Jan 17, 2015

Member

How can it implement block paste, though? Should it recompose the lines to be affected?

s:try_cmd() in the provider should return the type (c, l, or b, per :help setreg()). Also I just noticed that s:clipboard.set() accepts a regtype parameter, but not using it yet.

For handling the regtype, we should be able to re-use the existing logic for other non-clipboard registers to "recompose" the text. We also need to make sure that setreg() and getreg() are handling the regtype correctly for clipboard (I believe they are, @bfredl wrote tests for this).

Member

justinmk commented Jan 17, 2015

How can it implement block paste, though? Should it recompose the lines to be affected?

s:try_cmd() in the provider should return the type (c, l, or b, per :help setreg()). Also I just noticed that s:clipboard.set() accepts a regtype parameter, but not using it yet.

For handling the regtype, we should be able to re-use the existing logic for other non-clipboard registers to "recompose" the text. We also need to make sure that setreg() and getreg() are handling the regtype correctly for clipboard (I believe they are, @bfredl wrote tests for this).

@fmoralesc

This comment has been minimized.

Show comment
Hide comment
@fmoralesc

fmoralesc Jan 17, 2015

Contributor

I just wrote a function that pastes the + register in a blockwise manner, feel free to improve it:

function! BlockPaste()
    let c = split(getreg('+'), '\n', 1)
    let lenght =  len(c)
    let start = line('.')
    let end = start + lenght -1
    let col = col('.')
    let op_lines = range(start, end)
    let idx = 0
    for line in op_lines
        let line_orig = getline(line)
        let head = line_orig[:col-1]
        exe "let tail = line_orig[".col.":]"
        if len(head) < col
            let spaces = col - len(head)
            let head = head.repeat(' ', spaces)
        endif
        let new_line = head . c[idx] . tail
        call setline(line, new_line)
        let idx += 1
    endfor
endfunction

I imagine we could add a check on s:clipboard.get to call something like this in the case a flag has been set to indicate the register is in block mode.

Contributor

fmoralesc commented Jan 17, 2015

I just wrote a function that pastes the + register in a blockwise manner, feel free to improve it:

function! BlockPaste()
    let c = split(getreg('+'), '\n', 1)
    let lenght =  len(c)
    let start = line('.')
    let end = start + lenght -1
    let col = col('.')
    let op_lines = range(start, end)
    let idx = 0
    for line in op_lines
        let line_orig = getline(line)
        let head = line_orig[:col-1]
        exe "let tail = line_orig[".col.":]"
        if len(head) < col
            let spaces = col - len(head)
            let head = head.repeat(' ', spaces)
        endif
        let new_line = head . c[idx] . tail
        call setline(line, new_line)
        let idx += 1
    endfor
endfunction

I imagine we could add a check on s:clipboard.get to call something like this in the case a flag has been set to indicate the register is in block mode.

@bfredl

This comment has been minimized.

Show comment
Hide comment
@bfredl

bfredl Jan 17, 2015

Member

the clipboard provider can return [ [ lines ], 'b'] (or any regtype) to indicate a blockwise paste. Not sure what you mean with "recomposing" ?

Member

bfredl commented Jan 17, 2015

the clipboard provider can return [ [ lines ], 'b'] (or any regtype) to indicate a blockwise paste. Not sure what you mean with "recomposing" ?

@fmoralesc

This comment has been minimized.

Show comment
Hide comment
@fmoralesc

fmoralesc Jan 17, 2015

Contributor

I meant, to actually apply the blockwise paste (like my BlockPaste function does). But I didn't see this was already handled elsewhere.

Contributor

fmoralesc commented Jan 17, 2015

I meant, to actually apply the blockwise paste (like my BlockPaste function does). But I didn't see this was already handled elsewhere.

@bfredl

This comment has been minimized.

Show comment
Hide comment
@bfredl

bfredl Jan 17, 2015

Member

Right now, It is almost the case that clipboard.get should return [lines, regtype] where these two are the arguments to clipboard.set, for a "picture perfect" copy/paste. The provider infrastructure will add an extra newline for a linewise set that won't get removed if get actively specifies the regtype to l. But if we both support the "text" and "vim" clipboard format, it is perhaps clearer if all this logic is handled in the vimscript provider (so that "almost" is removed)

Member

bfredl commented Jan 17, 2015

Right now, It is almost the case that clipboard.get should return [lines, regtype] where these two are the arguments to clipboard.set, for a "picture perfect" copy/paste. The provider infrastructure will add an extra newline for a linewise set that won't get removed if get actively specifies the regtype to l. But if we both support the "text" and "vim" clipboard format, it is perhaps clearer if all this logic is handled in the vimscript provider (so that "almost" is removed)

@justinmk

This comment has been minimized.

Show comment
Hide comment
@justinmk

justinmk Jan 17, 2015

Member

There should be logic in the C source to do that (str_to_reg ?). But all the provider needs to do is return the type from s:clipboard.get() and let the nvim core paste it appropriately, like any other register. s:clipboard.set() just needs to store the regtype in a script-local s:regtype variable, in case it is not using a target-capable clip tool.

Member

justinmk commented Jan 17, 2015

There should be logic in the C source to do that (str_to_reg ?). But all the provider needs to do is return the type from s:clipboard.get() and let the nvim core paste it appropriately, like any other register. s:clipboard.set() just needs to store the regtype in a script-local s:regtype variable, in case it is not using a target-capable clip tool.

@fmoralesc

This comment has been minimized.

Show comment
Hide comment
@fmoralesc

fmoralesc Jan 17, 2015

Contributor

I'm taking a look at do_put() in src/nvim/ops.c and it seems like nvim the unnamed register logic removed is not that extensive. Perhaps it could be implemented usint the provider. At the start of do_put, this was removed:

#ifdef FEAT_CLIPBOARD
    /* Adjust register name for "unnamed" in 'clipboard'. */
    adjust_clip_reg(&regname);
    (void)may_get_selection(regname);
#endif

Now, adjust_clip_reg is this:

/*
 * Adjust the register name pointed to with "rp" for the clipboard being
 * used always and the clipboard being available.
 */
    void
adjust_clip_reg(rp)
    int     *rp;
{
    /* If no reg. specified, and "unnamed" or "unnamedplus" is in 'clipboard',
     * use '*' or '+' reg, respectively. "unnamedplus" prevails. */
    if (*rp == 0 && (clip_unnamed != 0 || clip_unnamed_saved != 0))
    {
    if (clip_unnamed != 0)
        *rp = ((clip_unnamed & CLIP_UNNAMED_PLUS) && clip_plus.available)
                                  ? '+' : '*';
    else
        *rp = ((clip_unnamed_saved & CLIP_UNNAMED_PLUS) && clip_plus.available)
                                  ? '+' : '*';
    }
    if (!clip_star.available && *rp == '*')
    *rp = 0;
    if (!clip_plus.available && *rp == '+')
    *rp = 0;
}

(notice it doesn't seem to link X related functions). may_get_selection() is:

/*
 * When "regname" is a clipboard register, obtain the selection.  If it's not
 * available return zero, otherwise return "regname".
 */
    int
may_get_selection(regname)
    int regname;
{
    if (regname == '*')
    {
    if (!clip_star.available)
        regname = 0;
    else
        clip_get_selection(&clip_star);
    }
    else if (regname == '+')
    {
    if (!clip_plus.available)
        regname = 0;
    else
        clip_get_selection(&clip_plus);
    }
    return regname;
}

Perhaps we could replace clip_get_selection with a call to the provider functions.

Contributor

fmoralesc commented Jan 17, 2015

I'm taking a look at do_put() in src/nvim/ops.c and it seems like nvim the unnamed register logic removed is not that extensive. Perhaps it could be implemented usint the provider. At the start of do_put, this was removed:

#ifdef FEAT_CLIPBOARD
    /* Adjust register name for "unnamed" in 'clipboard'. */
    adjust_clip_reg(&regname);
    (void)may_get_selection(regname);
#endif

Now, adjust_clip_reg is this:

/*
 * Adjust the register name pointed to with "rp" for the clipboard being
 * used always and the clipboard being available.
 */
    void
adjust_clip_reg(rp)
    int     *rp;
{
    /* If no reg. specified, and "unnamed" or "unnamedplus" is in 'clipboard',
     * use '*' or '+' reg, respectively. "unnamedplus" prevails. */
    if (*rp == 0 && (clip_unnamed != 0 || clip_unnamed_saved != 0))
    {
    if (clip_unnamed != 0)
        *rp = ((clip_unnamed & CLIP_UNNAMED_PLUS) && clip_plus.available)
                                  ? '+' : '*';
    else
        *rp = ((clip_unnamed_saved & CLIP_UNNAMED_PLUS) && clip_plus.available)
                                  ? '+' : '*';
    }
    if (!clip_star.available && *rp == '*')
    *rp = 0;
    if (!clip_plus.available && *rp == '+')
    *rp = 0;
}

(notice it doesn't seem to link X related functions). may_get_selection() is:

/*
 * When "regname" is a clipboard register, obtain the selection.  If it's not
 * available return zero, otherwise return "regname".
 */
    int
may_get_selection(regname)
    int regname;
{
    if (regname == '*')
    {
    if (!clip_star.available)
        regname = 0;
    else
        clip_get_selection(&clip_star);
    }
    else if (regname == '+')
    {
    if (!clip_plus.available)
        regname = 0;
    else
        clip_get_selection(&clip_plus);
    }
    return regname;
}

Perhaps we could replace clip_get_selection with a call to the provider functions.

@bfredl

This comment has been minimized.

Show comment
Hide comment
@bfredl

bfredl Jan 17, 2015

Member

@fmoralesc not sure if it Is related to what you're considering or not, but note #1814 will change the unnamed logic somewhat

Member

bfredl commented Jan 17, 2015

@fmoralesc not sure if it Is related to what you're considering or not, but note #1814 will change the unnamed logic somewhat

@fmoralesc

This comment has been minimized.

Show comment
Hide comment
@fmoralesc

fmoralesc Jan 17, 2015

Contributor

I was just checking if neovim hadn't removed code which could be useful here.

Contributor

fmoralesc commented Jan 17, 2015

I was just checking if neovim hadn't removed code which could be useful here.

@dphase

This comment has been minimized.

Show comment
Hide comment
@dphase

dphase Jun 8, 2016

Has anyone come up with a workaround for this on OS X? I didn't realize how often I use block pasting until I stumbled across this issue.

dphase commented Jun 8, 2016

Has anyone come up with a workaround for this on OS X? I didn't realize how often I use block pasting until I stumbled across this issue.

@alok

This comment has been minimized.

Show comment
Hide comment
@alok

alok Jul 16, 2016

I'm also desperate for a fix. I use block-pasting a lot and I use the unnamed clipboard even more.

alok commented Jul 16, 2016

I'm also desperate for a fix. I use block-pasting a lot and I use the unnamed clipboard even more.

@bfredl

This comment has been minimized.

Show comment
Hide comment
@bfredl

bfredl Jul 16, 2016

Member

I hope to find time to work on #4523 again soon... Until then, you could try my nvim-miniyank plugin that try to fix this issue (at least in the most common usage patterns).
You could add to your vimrc:

Plug 'bfredl/nvim-miniyank'
map p <Plug>(miniyank-autoput)
map P <Plug>(miniyank-autoPut)

and try to use ^Vy and p normally with clipboard=unnamed (both within and between instances)
I recently wrote this part of the code, so there could be bugs, but I would be happy for any feedback.

Member

bfredl commented Jul 16, 2016

I hope to find time to work on #4523 again soon... Until then, you could try my nvim-miniyank plugin that try to fix this issue (at least in the most common usage patterns).
You could add to your vimrc:

Plug 'bfredl/nvim-miniyank'
map p <Plug>(miniyank-autoput)
map P <Plug>(miniyank-autoPut)

and try to use ^Vy and p normally with clipboard=unnamed (both within and between instances)
I recently wrote this part of the code, so there could be bugs, but I would be happy for any feedback.

@alok

This comment has been minimized.

Show comment
Hide comment
@alok

alok Jul 17, 2016

@bfredl That fixed my problem. I only really use the default register, so I switched your suggestion to use the startput maps. Thanks!

alok commented Jul 17, 2016

@bfredl That fixed my problem. I only really use the default register, so I switched your suggestion to use the startput maps. Thanks!

ninrod added a commit to ninrod/dotfiles that referenced this issue Sep 8, 2016

ninrod added a commit to ninrod/dotfiles that referenced this issue Sep 8, 2016

@justinmk justinmk changed the title from Block editing and pasting is broken with unnamed clip and not vim compatible as of 01/14/2015 to clipboard=unnamed: block copy/paste Oct 3, 2016

@justinmk justinmk added the clipboard label Oct 9, 2016

@justinmk justinmk modified the milestones: 0.3, 0.2 Nov 27, 2016

razorjack added a commit to razorjack/dotfiles that referenced this issue Mar 4, 2017

@justinmk justinmk modified the milestones: 0.4, unplanned, todo Apr 14, 2018

@dumblob

This comment has been minimized.

Show comment
Hide comment
@dumblob

dumblob May 16, 2018

I'm sorry I know it's a rude question, but I'm stumbling across this issue for quite some time under Windows and would like to ask whether there is anyone working on the support for register types in clipboard or at least on the support for Windows for the nvim-miniyank plugin.

dumblob commented May 16, 2018

I'm sorry I know it's a rude question, but I'm stumbling across this issue for quite some time under Windows and would like to ask whether there is anyone working on the support for register types in clipboard or at least on the support for Windows for the nvim-miniyank plugin.

@bfredl

This comment has been minimized.

Show comment
Hide comment
@bfredl

bfredl May 16, 2018

Member

It is not rude. Fixing windows support for nvim-miniyank should not be too hard, I think we just need to find a good default path. It should really be a "runtime" path, but if there isn't any we can use a "cache" path.

Member

bfredl commented May 16, 2018

It is not rude. Fixing windows support for nvim-miniyank should not be too hard, I think we just need to find a good default path. It should really be a "runtime" path, but if there isn't any we can use a "cache" path.

@dvcrn

This comment has been minimized.

Show comment
Hide comment
@dvcrn

dvcrn Jun 19, 2018

I would like to chime in. Is there a possible fix on the horizon? I'm using miniyank now as well but this really should get fixed in core.

I didn't even know that the behavior in neovim wasn't normal until a couple days ago

dvcrn commented Jun 19, 2018

I would like to chime in. Is there a possible fix on the horizon? I'm using miniyank now as well but this really should get fixed in core.

I didn't even know that the behavior in neovim wasn't normal until a couple days ago

dvcrn added a commit to dvcrn/dotfiles that referenced this issue Jun 19, 2018

vim: Fix odd block pasting behaviour
This is a issue in neovim when using the system clipboard. See [this
issue](neovim/neovim#1822)
miniyank is a plugin that fixes this until it's fixed in core

dvcrn added a commit to dvcrn/dotfiles that referenced this issue Jun 19, 2018

vim: Fix odd block pasting behaviour
This is a issue in neovim when using the system clipboard.
miniyank is a plugin that fixes this until it's fixed in core

See neovim/neovim#1822 for details
@janlazo

This comment has been minimized.

Show comment
Hide comment
@janlazo
Contributor

janlazo commented Jun 19, 2018

Fmancino added a commit to Fmancino/dotfiles that referenced this issue Jul 18, 2018

Neovim: Fix odd block pasting behaviour
This is a issue in neovim when using the system clipboard. See [this
issue](neovim/neovim#1822)
Good chanche to try out the nvim-miniyank plugin!

Fmancino added a commit to Fmancino/dotfiles that referenced this issue Jul 23, 2018

Neovim: Fix odd block pasting behaviour
This is a issue in neovim when using the system clipboard. See [this
issue](neovim/neovim#1822)
Good chanche to try out the nvim-miniyank plugin!

to-yamada added a commit to to-yamada/dotfiles that referenced this issue Oct 1, 2018

neovim に miniyank 追加
* clipboard=unnamed のときに矩形貼り付けがうまく動作しないのを解消
  neovim/neovim#1822
* Denite で yank を遡って貼れるようにした

to-yamada added a commit to to-yamada/dotfiles that referenced this issue Oct 2, 2018

Neovim: Add miniyank
for
* clipboard=unnamed register type fixing
  (neovim/neovim#1822)
* Denite killring
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment