Skip to content
This repository has been 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 all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
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
43 changes: 33 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,48 @@ 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) ->
for selectedPath in selectedPaths
@emitter.emit 'will-delete-entry', {pathToDelete: selectedPath}
return 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