Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.

feat: Add a command to delete items permanently #1373

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ environment:
- ATOM_CHANNEL: beta

install:
- ps: Install-Product node 6
- ps: Install-Product node 12

build_script:
- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/atom/ci/master/build-package.ps1'))
Expand Down
1 change: 1 addition & 0 deletions keymaps/tree-view.cson
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
'shift-a': 'tree-view:add-folder'
'd': 'tree-view:duplicate'
'delete': 'tree-view:remove'
'shift-delete': 'tree-view:remove-permanently'
'backspace': 'tree-view:remove'
'k': 'core:move-up'
'j': 'core:move-down'
Expand Down
3 changes: 2 additions & 1 deletion lib/tree-view-package.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class TreeViewPackage {
'tree-view:add-file': () => this.getTreeViewInstance().add(true),
'tree-view:add-folder': () => this.getTreeViewInstance().add(false),
'tree-view:duplicate': () => this.getTreeViewInstance().copySelectedEntry(),
'tree-view:remove': () => this.getTreeViewInstance().removeSelectedEntries(),
'tree-view:remove': () => this.getTreeViewInstance().removeSelectedEntries(false),
'tree-view:remove-permanently': () => this.getTreeViewInstance().removeSelectedEntries(true),
'tree-view:rename': () => this.getTreeViewInstance().moveSelectedEntry(),
'tree-view:show-current-file-in-file-manager': () => this.getTreeViewInstance().showCurrentFileInFileManager()
}))
Expand Down
41 changes: 31 additions & 10 deletions lib/tree-view.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ _ = require 'underscore-plus'
{BufferedProcess, CompositeDisposable, Emitter} = require 'atom'
{repoForPath, getStyleObject, getFullExtension} = require "./helpers"
fs = require 'fs-plus'
del = require 'del'

AddDialog = require './add-dialog'
MoveDialog = require './move-dialog'
Expand Down Expand Up @@ -612,7 +613,7 @@ class TreeView
@emitter.emit 'entry-copied', {initialPath, newPath}
dialog.attach()

removeSelectedEntries: ->
removeSelectedEntries: (shouldDeletePermanently = false) ->
if @hasFocus()
selectedPaths = @selectedPaths()
selectedEntries = @getSelectedEntries()
Expand All @@ -632,11 +633,13 @@ class TreeView
return

atom.confirm({
message: "Are you sure you want to delete the selected #{if selectedPaths.length > 1 then 'items' else 'item'}?",
message: "Are you sure you want to #{if shouldDeletePermanently then 'permanently ' else ''}delete the selected #{if selectedPaths.length > 1 then 'items' else 'item'}?",
detailedMessage: "You are deleting:\n#{selectedPaths.join('\n')}",
buttons: ['Move to Trash', 'Cancel']
buttons: [(if shouldDeletePermanently then 'Permanently Delete ⚠️' else 'Move to Trash'), 'Cancel']
}, (response) =>
if response is 0 # Move to Trash
if shouldDeletePermanently
return @removeSelectedPathsPermanently(selectedPaths, selectedEntries)
failedDeletions = []
for selectedPath in selectedPaths
# Don't delete entries which no longer exist. This can happen, for example, when:
Expand All @@ -656,28 +659,46 @@ class TreeView
repo.getPathStatus(selectedPath)

if failedDeletions.length > 0
atom.notifications.addError @formatTrashFailureMessage(failedDeletions),
atom.notifications.addError @formatTrashFailureMessage(failedDeletions, false),
description: @formatTrashEnabledMessage()
detail: "#{failedDeletions.join('\n')}"
dismissable: true

# Focus the first parent folder
if firstSelectedEntry = selectedEntries[0]
@selectEntry(firstSelectedEntry.closest('.directory:not(.selected)'))
@updateRoots() if atom.config.get('tree-view.squashDirectoryNames')
@finishRemoval(selectedEntries[0])
)

formatTrashFailureMessage: (failedDeletions) ->
formatTrashFailureMessage: (failedDeletions, shouldDeletePermanently = false) ->
fileText = if failedDeletions.length > 1 then 'files' else 'file'

"The following #{fileText} couldn't be moved to the trash."
"The following #{fileText} couldn't be #{if shouldDeletePermanently then "deleted permanently" else "moved to the trash."}"

formatTrashEnabledMessage: ->
switch process.platform
when 'linux' then 'Is `gvfs-trash` installed?'
when 'darwin' then 'Is Trash enabled on the volume where the files are stored?'
when 'win32' then 'Is there a Recycle Bin on the drive where the files are stored?'

finishRemoval: (firstSelectedEntry) ->
# Focus the first parent folder
if firstSelectedEntry
@selectEntry(firstSelectedEntry.closest('.directory:not(.selected)'))
@updateRoots() if atom.config.get('tree-view.squashDirectoryNames')

removeSelectedPathsPermanently: (selectedPaths, selectedEntries) ->
del(selectedPaths, {force: true})
.then( (deletedPaths) ->
for deletedPath in deletedPaths
@emitter.emit 'entry-deleted', {pathToDelete: deletedPath}
)
.catch((err) ->
atom.notifications.addError @formatTrashFailureMessage(selectedPaths, true),
description: err
dismissable: true
for selectedPath in selectedPaths
@emitter.emit 'delete-entry-failed', {pathToDelete: selectedPath}
)
.finally( -> @finishRemoval(selectedEntries[0]))

# Public: Copy the path of the selected entry element.
# Save the path in localStorage, so that copying from 2 different
# instances of atom works as intended
Expand Down
3 changes: 3 additions & 0 deletions menus/tree-view.cson
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
{'label': 'Rename', 'command': 'tree-view:move'}
{'label': 'Duplicate', 'command': 'tree-view:duplicate'}
{'label': 'Delete', 'command': 'tree-view:remove'}
{'label': 'Delete Permanently', 'command': 'tree-view:remove-permanently'}
{'label': 'Copy', 'command': 'tree-view:copy'}
{'label': 'Cut', 'command': 'tree-view:cut'}
{'label': 'Paste', 'command': 'tree-view:paste'}
Expand Down Expand Up @@ -57,6 +58,7 @@
{'label': 'Rename', 'command': 'tree-view:move'}
{'label': 'Duplicate', 'command': 'tree-view:duplicate'}
{'label': 'Delete', 'command': 'tree-view:remove'}
{'label': 'Delete Permanently', 'command': 'tree-view:remove-permanently'}
{'label': 'Copy', 'command': 'tree-view:copy'}
{'label': 'Cut', 'command': 'tree-view:cut'}
{'label': 'Paste', 'command': 'tree-view:paste'}
Expand Down Expand Up @@ -86,6 +88,7 @@

'.tree-view .multi-select': [
{'label': 'Delete', 'command': 'tree-view:remove'}
{'label': 'Delete Permanently', 'command': 'tree-view:remove-permanently'}
{'label': 'Copy', 'command': 'tree-view:copy'}
{'label': 'Cut', 'command': 'tree-view:cut'}
{'label': 'Paste', 'command': 'tree-view:paste'}
Expand Down
Loading