Skip to content
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

Support trash instead of delete #202

Open
mo8it opened this issue Mar 25, 2022 · 16 comments
Open

Support trash instead of delete #202

mo8it opened this issue Mar 25, 2022 · 16 comments
Labels
enhancement New feature or request

Comments

@mo8it
Copy link

mo8it commented Mar 25, 2022

Thanks for the awesome plugin!

Adding support for trash instead of rm would be awesome!
Nvim-Tree does this with the D shortcut.

@cseickel cseickel added the enhancement New feature or request label Mar 25, 2022
@cseickel
Copy link
Contributor

This would be a simple one for a custom command. Take a look at :h neo-tree-custom-commands

Something like this should work (from memory, not tested):

   require("neo-tree").setup({
     filesystem = {
       window = {
         mappings = {
           ["D"] = functions(state)
             local node = state.tree:get_node()
             local path = node:get_id()
             vim.fn.system("trash " .. vim.fn.fnameescape(path))
           end
         }
       }
     }
   })

@mo8it
Copy link
Author

mo8it commented Mar 25, 2022

Thanks for your answer, I did go with this:

require("neo-tree").setup({
	filesystem = {
		commands = {
			-- Override delete to use trash instead of rm
			delete = function(state)
				local path = state.tree:get_node().path
				vim.fn.system({ "trash", vim.fn.fnameescape(path) })
			end,
		},
	},
})

It did work and the docs in :h neo-tree-custom-commands were helpful, but now I have the problem that it does not refresh after sending to trash. I did take a look at the code, it does not seem very easy to try to copy everything is done when deleting. No conformation, no output, not sure about symlinks and directories. So, if would implement it, I would really appreciate it ^^

In the mean time: Can you please tell me how to refresh the tree after the operation is done?

Thank you a lot for the quick rely!

@cseickel
Copy link
Contributor

You can use require("neo-tree.sources.manager").refresh(state.name) to refresh:

require("neo-tree").setup({
	filesystem = {
		commands = {
			-- Override delete to use trash instead of rm
			delete = function(state)
				local path = state.tree:get_node().path
				vim.fn.system({ "trash", vim.fn.fnameescape(path) })
                                require("neo-tree.sources.manager").refresh(state.name)
			end,
		},
	},
})

@cseickel
Copy link
Contributor

Looking at the code now, there is some extra niceties happening that is worth having. I will leave this up as an enhancement, but since I don't use trash I'm not the best person to implement it. Hopefully someone else will pick it up.

@mo8it
Copy link
Author

mo8it commented Mar 26, 2022

Refreshing did work. Thank you!

@RaafatTurki RaafatTurki mentioned this issue Aug 8, 2022
4 tasks
@ttytm
Copy link
Contributor

ttytm commented Nov 3, 2022

To extend #202 (comment) the example below adds a confirmation dialog.

What's still open is using the trash when deleting a range of files.

But usually git should lull one into safety without the need for a trash.

delete = function(state)
	local inputs = require "neo-tree.ui.inputs"
	local path = state.tree:get_node().path
	local msg = "Are you sure you want to delete " .. path
	inputs.confirm(msg, function(confirmed)
		if not confirmed then return end

		vim.fn.system { "trash", vim.fn.fnameescape(path) }
		require("neo-tree.sources.manager").refresh(state.name)
	end)
end,

@riodelphino
Copy link

To work with multi selected nodes (in Visual mode), I also extended tobealive's code to below.

-- over write default 'delete' command to 'trash'.
delete = function(state)
	local inputs = require("neo-tree.ui.inputs")
	local path = state.tree:get_node().path
	local msg = "Are you sure you want to trash " .. path
	inputs.confirm(msg, function(confirmed)
		if not confirmed then return end

		vim.fn.system { "trash", vim.fn.fnameescape(path) }
		require("neo-tree.sources.manager").refresh(state.name)
	end)
end,

-- over write default 'delete_visual' command to 'trash' x n.
delete_visual = function(state, selected_nodes)
	local inputs = require("neo-tree.ui.inputs")

	-- get table items count
	function GetTableLen(tbl)
		local len = 0
		for n in pairs(tbl) do
			len = len + 1
		end
		return len
	end

	local count = GetTableLen(selected_nodes)
	local msg = "Are you sure you want to trash " .. count .. " files ?"
	inputs.confirm(msg, function(confirmed)
		if not confirmed then return end
		for _, node in ipairs(selected_nodes) do
			vim.fn.system { "trash", vim.fn.fnameescape(node.path) }
		end
		require("neo-tree.sources.manager").refresh(state.name)
	end)
end,

nvim's reboot is required for that 'refresh' command to work.

Thanks for all your advices.

@sxyazi
Copy link

sxyazi commented May 6, 2023

@riodelphino Thanks for sharing, helped me a lot.
There is a built-in vim.tbl_count function, or #selected_nodes that can be used to simplify the GetTableLen. 😸

@amitlevy21
Copy link

I just deleted 18 hours of work by mistake.
PLEASE, make this the default behavior

Its not reasonable to delete files forever with rm command when working with an editor

@miversen33
Copy link
Collaborator

I just deleted 18 hours of work by mistake. PLEASE, make this the default behavior

Its not reasonable to delete files forever with rm command when working with an editor

I mean... You literally have to confirm you want to delete the thing. So while you may not like to hear this, this is purely on you.

If you select delete, and confirm you do want to delete, you cannot be upset that it was deleted. This idea that your editor should be responsible for the user's mistakes is incorrect. Additionally as was pointed out above, the support to do this is already built into neo-tree.

I will say we should probably put this recipe into the wiki, but IMO that is as far as this should go. Supporting trash is not as easy as it sounds (remember that there are 3 major operating systems, and 2 of them have completely different ways of doing trash support).

At the end of the day, Neovim and in extension Neo-tree are meant to be customized by you the user. Make it what you want. If you want the delete action to send to trash instead of deleting, then do it.

But we should not be changing the default simply because of a mistake confirmed by a few people.

I'm sorry you lost all that work. And I know this will read quite harsh. The intention is not to shame you, but simply to explain my position in saying we should not be changing the default on this behavior. Delete should be delete.

@amitlevy21
Copy link

Thank you for addressing my comment, I appreciate your thoughts and words.

My mistake is that I used visual mode to delete 20+ files, mistakenly the cursor overlapped to the folder which I didn't want to deleted. I'm sure you can understand how easily this can happen to others.

I understand that this is not easy to add support for all OS's, and agree it should be added to the wiki. If this is not going to be supported out of the box it should be mentioned in the README with a big caution notice so each user can address it according to the OS he operates on.

@rafo
Copy link

rafo commented Dec 6, 2023

So while you may not like to hear this, this is purely on you.

Just had a slightly different accident with deleting files #1090

Since shite like this and nasty bugs could happen and implementing a saver delete seems to be problematic, my (sad) solution is to switch back to the much saver nnn integration.

If this is not going to be supported out of the box it should be mentioned in the README with a big caution notice so each user can address it according to the OS he operates on.

@amitlevy21 Yep!

@Mosazghi
Copy link

I get this error:
image

  {
    "nvim-neo-tree/neo-tree.nvim",
    opts = {
      filesystem = {
        commands = {
          -- Override delete to use trash instead of rm
          delete = function(state)
            local inputs = require("neo-tree.ui.inputs")
            local path = state.tree:get_node().path
            local msg = "Are you sure you want to delete "
              .. path
            inputs.confirm(msg, function(confirmed)
              if not confirmed then
                return
              end

              vim.fn.system({
                "trash",
                vim.fn.fnameescape(path),
              })
              require("neo-tree.sources.manager").refresh(
                state.name
              )
            end)
          end,
        },
      },
    },
  },

@riodelphino
Copy link

riodelphino commented Apr 22, 2024

Hi.
I guess you just need trash command installed in your system(OS) by brew.

It passed long time, so now I'm not sure about my and your code.

@Mosazghi
Copy link

Worked!

@HsiuCL
Copy link

HsiuCL commented Jun 5, 2024

When using @riodelphino 's script, I've met with a problem that if there are spaces in the path, the file could not be trashed. After doing some tests, I figured out that vim.fn.system appears to already wrapping the arguments, so there is no need to escape the arguments again.

If anyone encounters the same issue, simply remove the vim.fn.fnameescape and use the path directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants