Clipboard integration with RegisterModified

mawww just committed a new RegisterModified hook to Kakoune, which means clipboard integration (at least for writing to the clipboard) can be much simpler. For example, to integrate with the X11 clipboard:

hook global RegisterModified '"' %{
    nop %sh{
        printf %s "$kak_main_reg_dquote" | xsel --input --clipboard
    }
}

If you’d rather use tmux than x11, you can change that line of shell-script to:

tmux set-buffer "$kak_main_reg_dquote"

On macOS, pipe to pbcopy. On Cygwin, pipe into /dev/clipboard.

Unlike the traditional approaches of hooking the y, d, and c keys, this only fires when they’re used with a default register, and it also handles corner-cases like :set-register dquote foo.

Notably, it doesn’t handle multiple-selections very well, because xsel (and the like) only support copying a single bytestring to the clipboard. Even if we had a tool that could copy multiple formats (a plain-text version and an encoded list-of-strings version) Kakoune doesn’t have a RegisterRead hook yet, so it wouldn’t be able to paste them anyway.

I wonder if maybe Kakoune’s rc/windowing/* scripts should be extended to include a *-clipboard-copy command that would try to do the right thing in each situation, in the same way they all have *-terminal command.

4 Likes

For X11 / Wayland, there is XDG_SESSION_TYPE we could use with xsel, xclip and wl-clipboard.

This is pretty neat. Seems like we could use this for more than clipboard registration but also to define our own “special” registers. ie. I could configure register “t” to send the yanked text to a Kitty terminal; or maybe register “c” would evaluate the selected code with a particular interpreter. Granted those things can be done with commands as well, but would there be an advantage/disadvantage to using registers for them instead?

1 Like

I think it would be possible to do the multiple format stuff with xclip actually; it supports specifying “target atoms”, which in practice I believe means having multiple selections in the clipboard at a time, of different MIME types. If you eschew xsel in favor of xclip and some sort of bytestrings in the clipboard you could perhaps get something working for multiple selections.

One advantage would be that a lot more parts of Kakoune integrate with registers than integrate with commands. Where most commands would probably just use %val{selection}, registers work with yanking and deleting and :set-register and probably other things too.

One disadvantage would be that plugins probably use might use arbitrary letter-registers for their own purposes. My plugins often use "c to store some kind of count, and if your plugin sends everything written to "c to an external interpreter, things could get quite confusing.

Possibly RegisterModified hooks should be disabled for every register named in the -save-regs option of execute-keys or evaluate-commands, but I’m guessing that doesn’t happen right now.

So far as I can tell, xclip will let you write to a specific format (for example, one of the manpage examples is "copy the contents of index.html to the clipboard as text/html), but I don’t think you can copy multiple alternative formats at the same time. For example, I tried:

xclip -t image/jpeg something.jpg -t text/html something.html

…and afterward the clipboard only advertised the text/html format, which contained the JPEG file.

It’s tantalisingly close, though.

Thats a great idea, that would probably fix most of the performance issue I worry about with this feature.

2 Likes

I was hoping to use tmux buffer as yank ring, but looks like following hook executed several times per one yank operation so there are 3 same entries in tmux buffer list after each yank.

hook global RegisterModified '"' %{
    nop %sh{
        tmux setb "$kak_main_reg_dquote"
    }
}

Quick fix is to give a buffer name like tmux setb -b kak "$kak_main_reg_dquote" but it breaks a yank ring behavior.

Do you have some other yank-related mappings or hooks?

I just started up kak -n and executed:

buffer *debug*
hook global RegisterModified '"' %{ echo -debug yanked %reg{dquote} }

…and every time I press y, I get exactly one debug message.

You’re right, it must be some plugin…

I found that exec -save-regs '"' ... triggers the hook, is it expected? Seems a number of plugins use this technique.

Edit: looks like any execute-keys triggers the hook.

Done, thanks fo the idea @Screwtapello

1 Like

As mawww’s reply suggests, he’s committed a change that avoids triggering RegisterModified when saved registers are restored after an exec or eval command completes.

" is one of the registers exec saves by default, so yes - before this most recent commit, I would expect exec or exec -save-regs '"' to trigger the RegisterModified hook, but that problem should be fixed now.

I confess I haven’t actually tested it myself, though, so I’d be interested to hear if it’s actually fixed for you.

I’ve tested with latest master, can confirm exec -save-regs '"' doesn’t trigger the RegisterModified. My hook with tmux buffer works as expected one entry per one yank.

1 Like