Skip to content

feat(#1549): copy files between multiple nvim instances#3336

Open
Uanela wants to merge 27 commits into
masterfrom
chore/remove-operation-between-instances-protocol
Open

feat(#1549): copy files between multiple nvim instances#3336
Uanela wants to merge 27 commits into
masterfrom
chore/remove-operation-between-instances-protocol

Conversation

@Uanela

@Uanela Uanela commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

Hello @alex-courtis this is simply a variation of what we've been discussing at #3334 I just wanted to show it in practice and is btw the thing that I've been dogfooding, I am thinking in even adding option to download a file directly when an url is on the register (maybe for my own locally if this is too nichy).

Changes

1 - gy - remains as it is, and now supports visual operation which copies a list of comma separated absolute paths
2 - gp - this is used to paste while copying
3 - gx - this is used to paste while cutting.

2026-06-15.00-39-13.mp4

@Uanela Uanela changed the title Variation of #3334 feat: variation of #3334 Jun 14, 2026
@Uanela

Uanela commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator Author

Added gp to automatically download when find a ^http, currently is just local on my machine.

image image

@alex-courtis alex-courtis left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking great, only minor changes required.

Please:

Test cases:

gy

  • copy one /home/alex/src/linux/.mailmap
  • visual copy /home/alex/src/linux/.pylintrc,/home/alex/src/linux/.rustfmt.toml
  • copy root /home/alex/src/linux/
  • visual copy root and other nodes
    root is not copied, however that's OK. This is existing behaviour and arguably a feature, as copying root and other files makes no sense.

ge

  • copy one .mailmap
  • visual copy .pylintrc,.rustfmt
  • copy root linux
  • visual copy root and other nodes, ok, see above

gp

  • paste one /home/alex/src/linux/MAINTAINERS
  • paste many /home/alex/src/linux/COPYING,/home/alex/src/linux/CREDITS
  • FAIL - paste with spaces /home/alex/src/linux/CREDITS, /home/alex/src/linux/Kbuild, /home/alex/src/linux/Kconfig
    [NvimTree] Could not copy /home/alex/src/linux/CREDITS - ENOENT
  • paste one inexistent /home/alex/src/linux/xxx
    [NvimTree] Could not copy /home/alex/src/linux/xxx - ENOENT
  • paste many, one inexistent /home/alex/src/linux/Kbuild,/home/alex/src/linux/xxx,/home/alex/src/linux/MAINTAINERS
    [NvimTree] Could not copy /home/alex/src/linux/xxx - ENOENT
    others copied correctly
  • paste mixed nodes and directories /home/alex/src/linux/zzz/,/home/alex/src/linux/aaa

gx

  • Test cases as per gp
  • Multiple source removed when in same instance /home/alex/src/linux/Kconfig,/home/alex/src/linux/MAINTAINERS
  • Multiple source removed in other instance in the same directory /home/alex/src/linux/.clang-format,/home/alex/src/linux/.clippy.toml

Comment thread lua/nvim-tree/node/init.lua Outdated
end

function Node:get_basename()
if self.name == ".." then

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On further reflection, changing the ".." makes me nervous. Yes it's legacy, however it is present in many places in Clipboard hence we shouldn't change it when building this feature.

Let's keep it localised - please move this method to Clipboard so that it doesn't spread to other functionality.

@alex-courtis

Copy link
Copy Markdown
Member

I am thinking in even adding option to download a file directly when an url is on the register (maybe for my own locally if this is too nichy).

That would be great, I have some use cases for it. Out of scope, future PR please :)

@alex-courtis

Copy link
Copy Markdown
Member

Wild and crazy idea after reading comments on previous PR:

Remove gp: p can handle all the cases

  • If there are files copied or cut in the current instance, paste them as per original Clipboard:paste()
  • Else if the system/register clipboard contains files, paste them as per use_register = true

Clipboard:copy() and :cut() copy to system clipboard

These methods should also work as per gy, copying absolute paths to the system/register clipboard

This is something I've tried to do many times - c a file in one instance and p into another, which of course fails.

gx

This is a niche case, however would need to be retained: we don't have any information in the clipboard to identify cut vs paste hence it must be explicit.

@alex-courtis

alex-courtis commented Jun 17, 2026

Copy link
Copy Markdown
Member

I finally installed the gnome file manager nautilus and inspected the clipboard mime types when copying multiple files:

: ; wl-paste --list-types
x-special/gnome-copied-files
text/plain;charset=utf-8
text/uri-list
application/vnd.portal.filetransfer
application/vnd.portal.files


: ; wl-paste --type text/plain\;charset=utf-8
/home/alex/src/linux/.gitattributes
/home/alex/src/linux/.gitignore
/home/alex/src/linux/.mailmap


: ; wl-paste --type text/uri-list
file:///home/alex/src/linux/.gitattributes
file:///home/alex/src/linux/.gitignore
file:///home/alex/src/linux/.mailmap


: ; wl-paste --type application/vnd.portal.filetransfer
10924863569610452011%


: ; wl-paste --type application/vnd.portal.files
11848482484090875390%


: ; wl-paste --type x-special/gnome-copied-files
copy
file:///home/alex/src/linux/.gitattributes
file:///home/alex/src/linux/.gitignore
file:///home/alex/src/linux/.mailmap%

: ;

Today I think we should at least match the text/plain standard - use newline delimited files instead of comma delimited. Note that there is no newline at the end of the last file. Spaces are not escaped.

text/uri-list is interesting and something that we could do in the future, however I'm not sure how easy or possible it is to set the mime type is within Nvim.

x-special/gnome-copied-files is completely gnome specific, however it inspires the possibly of something like x-special/nvim-tree-copied-files, which we could use to specify the copy/cut operation. Maybe not so useful.

For reference, this is what a gy results in:

: ; wl-paste --list-types
text/plain
text/plain;charset=utf-8
TEXT
STRING
UTF8_STRING

: ; wl-paste --type UTF8_STRING
/home/alex/src/linux/Kbuild,/home/alex/src/linux/Kconfig

: ; wl-paste --type TEXT
/home/alex/src/linux/Kbuild,/home/alex/src/linux/Kconfig

: ; wl-paste --type STRING
/home/alex/src/linux/Kbuild,/home/alex/src/linux/Kconfig

: ; wl-paste --type text/plain
/home/alex/src/linux/Kbuild,/home/alex/src/linux/Kconfig

: ; wl-paste --type text/plain\;charset=utf-8
/home/alex/src/linux/Kbuild,/home/alex/src/linux/Kconfig

: ;

KDE dolpin operates similarly except that it does not copy text/plain

@Uanela

Uanela commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator Author

Wild and crazy idea after reading comments on previous PR:

Remove gp: p can handle all the cases

  • If there are files copied or cut in the current instance, paste them as per original Clipboard:paste()
  • Else if the system/register clipboard contains files, paste them as per use_register = true

Clipboard:copy() and :cut() copy to system clipboard

These methods should also work as per gy, copying absolute paths to the system/register clipboard

This is something I've tried to do many times - c a file in one instance and p into another, which of course fails.

gx

This is a niche case, however would need to be retained: we don't have any information in the clipboard to identify cut vs paste hence it must be explicit.

Makes total sense removing gp and making c and x take text to register.

The only thing is that x would still mean nothing, only when gx it would cut. Or maybe let gp to mean paste while cutting bc to some extent gx sounds like cut paths bc of gy, or even xp or something else.

@Uanela

Uanela commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator Author

I finally installed the gnome file manager nautilus and inspected the clipboard mime types when copying multiple files:

: ; wl-paste --list-types
x-special/gnome-copied-files
text/plain;charset=utf-8
text/uri-list
application/vnd.portal.filetransfer
application/vnd.portal.files


: ; wl-paste --type text/plain\;charset=utf-8
/home/alex/src/linux/.gitattributes
/home/alex/src/linux/.gitignore
/home/alex/src/linux/.mailmap


: ; wl-paste --type text/uri-list
file:///home/alex/src/linux/.gitattributes
file:///home/alex/src/linux/.gitignore
file:///home/alex/src/linux/.mailmap


: ; wl-paste --type application/vnd.portal.filetransfer
10924863569610452011%


: ; wl-paste --type application/vnd.portal.files
11848482484090875390%


: ; wl-paste --type x-special/gnome-copied-files
copy
file:///home/alex/src/linux/.gitattributes
file:///home/alex/src/linux/.gitignore
file:///home/alex/src/linux/.mailmap%

: ;

Today I think we should at least match the text/plain standard - use newline delimited files instead of comma delimited. Note that there is no newline at the end of the last file. Spaces are not escaped.

text/uri-list is interesting and something that we could do in the future, however I'm not sure how easy or possible it is to set the mime type is within Nvim.

x-special/gnome-copied-files is completely gnome specific, however it inspires the possibly of something like x-special/nvim-tree-copied-files, which we could use to specify the copy/cut operation. Maybe not so useful.

For reference, this is what a gy results in:

: ; wl-paste --list-types
text/plain
text/plain;charset=utf-8
TEXT
STRING
UTF8_STRING

: ; wl-paste --type UTF8_STRING
/home/alex/src/linux/Kbuild,/home/alex/src/linux/Kconfig

: ; wl-paste --type TEXT
/home/alex/src/linux/Kbuild,/home/alex/src/linux/Kconfig

: ; wl-paste --type STRING
/home/alex/src/linux/Kbuild,/home/alex/src/linux/Kconfig

: ; wl-paste --type text/plain
/home/alex/src/linux/Kbuild,/home/alex/src/linux/Kconfig

: ; wl-paste --type text/plain\;charset=utf-8
/home/alex/src/linux/Kbuild,/home/alex/src/linux/Kconfig

: ;

KDE dolpin operates similarly except that it does not copy text/plain

That's great.

The unique problem usinf this approach is that it will resamble protocol and hence we won't be able to paste from anywhere else by simply grabbing the absolute path and vice-versa maybe.

This would suite better if we kept bgy to use protocol and keep gy as it is (only add the newline support), because if I visually gy I expect a list of absolute paths not nvim-tree specific thing.

@alex-courtis

Copy link
Copy Markdown
Member

The only thing is that x would still mean nothing, only when gx it would cut. Or maybe let gp to mean paste while cutting bc to some extent gx sounds like cut paths bc of gy, or even xp or something else.

Yeah that's a tricky one, there's no "natural" option. I'm easy for any mapping, however we can't do xp as x is taken.

@alex-courtis

Copy link
Copy Markdown
Member

This would suite better if we kept bgy to use protocol and keep gy as it is (only add the newline support), because if I visually gy I expect a list of absolute paths not nvim-tree specific thing.

Yes, let's just go with newlines for now. This branch is working.

We can add a protocol in the future :)
Remember that we can "break" this in the future as we're defining communication between nvim-tree instances which is not API.

@Uanela

Uanela commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator Author

This would suite better if we kept bgy to use protocol and keep gy as it is (only add the newline support), because if I visually gy I expect a list of absolute paths not nvim-tree specific thing.

Yes, let's just go with newlines for now. This branch is working.

We can add a protocol in the future :)
Remember that we can "break" this in the future as we're defining communication between nvim-tree instances which is not API.

The protocol will break OS level operation, which I think is one of the biggest win for this.

And yes protocol would make this nvim specific but I think it would be cooler to make it work anywhere.

Changes To Be Made

  • Add register operation on c and x
  • Add multline support
  • Remove gx in favor of gp to mean paste while cutting. This avoids ambiguity as p will operate locally and between instances
  • Make p decide whether use the clipboard or the register

Together with those mentioned earlier.

@Uanela Uanela changed the title feat: variation of #3334 feat(#1549): copy files between multiple nvim instances Jun 18, 2026
@Uanela

Uanela commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator Author

All changes made and all test passing.

Concern

  • I c on instance B (it also triggers register, easy to warn on next update) and then go to instance A and c again (erases B thing in register and adds it's content) then I go back to instance B and do p it will paste what is in clipboard because I didn't remove it basically I will need first to clear the clipboard (there ain't no keymaps only api) and then p to paste from instance A. Is kind a GOTCHA moment but maybe is to wrap head around.

Additional changes made, mostly refactor

  • Unified all node attribute copying function to clipboard.copy_node_attribute(n, attribute) so that all 4 could easily be handled with node or nodes
  • Made all copy.basename|filename|path|absolute_path work on visual mode

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

Successfully merging this pull request may close these issues.

2 participants