nvim-tree.lua icon indicating copy to clipboard operation
nvim-tree.lua copied to clipboard

copy files between multiple vim instances

Open otavioschwanck opened this issue 3 years ago • 17 comments

i use use neovim instance for each of projects of mine. sometimes i want to copy file from one to another and its really hard to do with nvim-tree clipboard working only current instance

otavioschwanck avatar Aug 23 '22 20:08 otavioschwanck

nvim-tree does not use the system clipboard.

An optional protocol could be developed that uses system clipboard. Something like:

nvim-tree: /path/to/file1, /path/to/file2

This would cause strange results when pasting the clipboard anywhere outside of nvim-tree, and files copied outside of nvim-tree could not be pasted in nvim-tree.

It is highly unlikely that this functionality will be built or accepted.

alex-courtis avatar Aug 27 '22 01:08 alex-courtis

it could be an optional feature that could be enabled, i really dont care about the system clipboard, even the filebrowser from the OS works in this way, and also, nvim-tree could save on a pre-defined register (i think it is shared between vim instances)

otavioschwanck avatar Aug 27 '22 14:08 otavioschwanck

What is the pre-defined register? clipboard register is only shared. The other registers are not shared.

Shougo avatar Aug 27 '22 21:08 Shougo

What is the pre-defined register? clipboard register is only shared. The other registers are not shared.

you are right!

But it could save on a tmp file

otavioschwanck avatar Aug 28 '22 01:08 otavioschwanck

But it could save on a tmp file

That is a viable solution.

alex-courtis avatar Aug 28 '22 02:08 alex-courtis

One can obtain current file name by using expand("%:p") builtin. Then, when copied into a register (clipboard) you can copy it via commandline terminal:


" In vim commandline
:echo setreg("", expand("%:p"))
" Switch to another window
:!cp ...<ctrl+v> ./

hinell avatar Jan 10 '23 09:01 hinell

But it could save on a tmp file

That is a viable solution.

@alex-courtis You are better to keep track of a file path, rather than copying it somehwere temporarily.

hinell avatar Jan 10 '23 09:01 hinell

We already have gy to copy the absolute path. What if we had something like gp to paste from the absolute path?

The second step could be to use m to mark multiple files, then go bgy to copy all absolute paths with \n delimiter and make gp be capable of pasting from multiple paths.

What do you think?

lawrence-laz avatar Jan 29 '23 17:01 lawrence-laz

We already have gy to copy the absolute path. What if we had something like gp to paste from the absolute path?

That's an interesting idea - using absolute paths rather than the "internal clipboard". The question remains: where do these paths come from? The " or + register?

The second step could be to use m to mark multiple files, then go bgy to copy all absolute paths with \n delimiter and make gp be capable of pasting from multiple paths.

Could we not simplify this to something like: m, bcp?

alex-courtis avatar Jan 29 '23 22:01 alex-courtis

We already have gy to copy the absolute path. What if we had something like gp to paste from the absolute path?

That's an interesting idea - using absolute paths rather than the "internal clipboard". The question remains: where do these paths come from? The " or + register?

I'd say they should act the same way as gy currently does, i. e. based on user settings:

local function copy_to_clipboard(content)
  if M.use_system_clipboard == true then
    vim.fn.setreg("+", content)
    vim.fn.setreg('"', content)
    return notify.info(string.format("Copied %s to system clipboard!", content))
  else
    vim.fn.setreg('"', content)
    vim.fn.setreg("1", content)
    return notify.info(string.format("Copied %s to neovim clipboard!", content))
  end
end

The second step could be to use m to mark multiple files, then go bgy to copy all absolute paths with \n delimiter and make gp be capable of pasting from multiple paths.

Could we not simplify this to something like: m, bcp?

That could work too. I just like bgy as I personally find it easier to remember as a variant of gy that works with bookmarks. Also, since both gy and bgy could potentially work with gp interchangeably for single file or multiple files, it would be less confusing to have similar commands maybe. I don't have a strong opinion here though.

lawrence-laz avatar Jan 30 '23 16:01 lawrence-laz

Hi, finally, is this possible? This would be such a useful utility, open vertical tmux pane, open another git project, and then copy files from one project to another like in vscode

jgarciaokode avatar Sep 20 '23 10:09 jgarciaokode

This has not been implemented however we do have the bones of a solution here.

Pull Requests are most gratefully appreciated.

alex-courtis avatar Sep 23 '23 02:09 alex-courtis

This is nowhere PR ready, but maybe someone will find this useful or flesh it out into a PR:

vim.api.nvim_create_autocmd('filetype', {
	pattern = 'NvimTree',
	desc = 'Mappings for NvimTree',
	callback = function()
		-- Yank marked files
		vim.keymap.set('n', 'bgy',
			function()
				local api = require 'nvim-tree.api'
				local marks = api.marks.list()
				if #marks == 0 then
					print('No items marked')
					return
				end
				local absolute_file_paths = ''
				for _, mark in ipairs(marks) do
					absolute_file_paths = absolute_file_paths .. mark.absolute_path .. '\n'
				end
				-- Using system registers for multi-instance support.
				vim.fn.setreg("+", absolute_file_paths)
				print('Yanked ' .. #marks .. ' items')
			end,
			{ remap = true, buffer = true })

		-- Paste files
		vim.keymap.set('n', 'gp',
			function()
				local api = require 'nvim-tree.api'
				local source_paths = {}
				for path in vim.fn.getreg('+'):gmatch('[^\n%s]+') do
					source_paths[#source_paths + 1] = path
				end
				local node = api.tree.get_node_under_cursor()
				local is_folder = node.fs_stat and node.fs_stat.type == 'directory' or false
				local target_path = is_folder and node.absolute_path or
					vim.fn.fnamemodify(node.absolute_path, ":h")
				for _, source_path in ipairs(source_paths) do
					vim.fn.system { 'cp', '-R', source_path, target_path }
				end
				api.tree.reload()
				print('Pasted ' .. #source_paths .. ' items')
			end,
			{ remap = true, buffer = true })
	end
})

output

lawrence-laz avatar Sep 23 '23 08:09 lawrence-laz

Nice work! The concept is proven.

" + does indeed seem the best solution.

  • We could have an if not M.config.filesystem_watchers.enable then around the reload
  • copy-paste.lua could be reused, with the fsstat and vim.loop.fs_copyfile etc.

This can be added everywhere - copy/cut as well as bulk

alex-courtis avatar Sep 24 '23 04:09 alex-courtis

Hi @alex-courtis is this planned to be added? I am currently using the snippet code from @lawrence-laz and it works really well

jugarpeupv avatar Jan 05 '24 11:01 jugarpeupv

Pull Requests are always most gratefully appreciated.

alex-courtis avatar Jan 06 '24 02:01 alex-courtis