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

Bundle tree view #513

Merged
merged 6 commits into from
May 9, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@
"text-buffer": "^13.18.6",
"timecop": "file:./packages/timecop",
"tree-sitter": "0.20.0",
"tree-view": "https://codeload.github.com/atom/tree-view/legacy.tar.gz/refs/tags/v0.229.1",
"tree-view": "file:packages/tree-view",
"typescript-simple": "github:pulsar-edit/typescript-simple#ccb03e558217030e8f261339281f1d69147934f7",
"underscore-plus": "^1.7.0",
"update-package-dependencies": "file:./packages/update-package-dependencies",
Expand Down Expand Up @@ -226,7 +226,7 @@
"symbols-view": "0.118.4",
"tabs": "file:./packages/tabs",
"timecop": "file:./packages/timecop",
"tree-view": "0.229.1",
"tree-view": "file:./packages/tree-view",
"update-package-dependencies": "file:./packages/update-package-dependencies",
"welcome": "file:./packages/welcome",
"whitespace": "file:./packages/whitespace",
Expand Down
4 changes: 1 addition & 3 deletions packages/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ See [RFC 003](https://github.com/atom/atom/blob/master/docs/rfcs/003-consolidate
| **symbols-view** | [`pulsar-edit/symbols-view`][symbols-view] | |
| **tabs** | [`./tabs`](./tabs) | |
| **timecop** | [`./timecop`](./timecop) | |
| **tree-view** | [`pulsar-edit/tree-view`][tree-view] | |
| **tree-view** | [`./tree-view`](./tree-view) | |
| **update-package-dependencies** | [`./update-package-dependencies`](./update-package-dependencies) | |
| **welcome** | [`./welcome`](./welcome) | |
| **whitespace** | [`./whitespace`](./whitespace) | |
Expand All @@ -103,9 +103,7 @@ See [RFC 003](https://github.com/atom/atom/blob/master/docs/rfcs/003-consolidate
[find-and-replace]: https://github.com/pulsar-edit/find-and-replace
[fuzzy-finder]: https://github.com/pulsar-edit/fuzzy-finder
[github]: https://github.com/pulsar-edit/github
[keybinding-resolver]: https://github.com/pulsar-edit/keybinding-resolver
[notifications]: https://github.com/pulsar-edit/notifications
[snippets]: https://github.com/pulsar-edit/snippets
[spell-check]: https://github.com/pulsar-edit/spell-check
[symbols-view]: https://github.com/pulsar-edit/symbols-view
[tree-view]: https://github.com/pulsar-edit/tree-view
1 change: 1 addition & 0 deletions packages/tree-view/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
53 changes: 53 additions & 0 deletions packages/tree-view/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Tree View package

Explore and open files in the current project.

Press <kbd>ctrl-\\</kbd> or <kbd>cmd-\\</kbd> to open/close the tree view and
<kbd>alt-\\</kbd> or <kbd>ctrl-0</kbd> to focus it.

When the tree view has focus you can press <kbd>a</kbd>, <kbd>shift-a</kbd>,
<kbd>m</kbd>, or <kbd>delete</kbd> to add, move or delete files and folders.

To move the Tree view to the opposite side, select and drag the Tree view dock to the other side.

![](https://f.cloud.github.com/assets/671378/2241932/6d9cface-9ceb-11e3-9026-31d5011d889d.png)

## API
This package provides a service that you can use in other Pulsar packages.
To use it, include `tree-view` in the `consumedServices` section of your
`package.json`:

``` json
{
"name": "my-package",
"consumedServices": {
"tree-view": {
"versions": {
"^1.0.0": "consumeTreeView"
}
}
}
}
```

Then, in your package's main module, call methods on the service:

``` coffee
module.exports =
activate: -> # ...

consumeTreeView: (treeView) ->
selectedPaths = treeView.selectedPaths()
# Do something with the paths...
```

The `tree-view` API has two methods:
* `selectedPaths()` - Returns the paths to the selected tree view entries.
* `entryForPath(entryPath)` - Returns a tree view entry for the given path.

## Customization
The tree view displays icons next to files. These icons are customizable by
installing a package that provides an `atom.file-icons` service.

The `atom.file-icons` service must provide the following methods:
* `iconClassForPath(path)` - Returns a CSS class name to add to the file view.
88 changes: 88 additions & 0 deletions packages/tree-view/keymaps/tree-view.cson
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
'.platform-darwin':
'cmd-\\': 'tree-view:toggle'
'cmd-k cmd-b': 'tree-view:toggle'
'cmd-|': 'tree-view:reveal-active-file'
'ctrl-0': 'tree-view:toggle-focus'

'.platform-win32, .platform-linux':
'ctrl-\\': 'tree-view:toggle'
'ctrl-k ctrl-b': 'tree-view:toggle'
'ctrl-|': 'tree-view:reveal-active-file'
'alt-\\': 'tree-view:toggle-focus'

'.platform-darwin .tree-view':
'cmd-c': 'tree-view:copy'
'cmd-x': 'tree-view:cut'
'cmd-v': 'tree-view:paste'
'ctrl-f': 'tree-view:expand-item'
'ctrl-b': 'tree-view:collapse-directory'
'cmd-k right': 'tree-view:open-selected-entry-right'
'cmd-k l': 'tree-view:open-selected-entry-right'
'cmd-k left': 'tree-view:open-selected-entry-left'
'cmd-k h': 'tree-view:open-selected-entry-left'
'cmd-k up': 'tree-view:open-selected-entry-up'
'cmd-k k': 'tree-view:open-selected-entry-up'
'cmd-k down': 'tree-view:open-selected-entry-down'
'cmd-k j': 'tree-view:open-selected-entry-down'
'cmd-1': 'tree-view:open-selected-entry-in-pane-1'
'cmd-2': 'tree-view:open-selected-entry-in-pane-2'
'cmd-3': 'tree-view:open-selected-entry-in-pane-3'
'cmd-4': 'tree-view:open-selected-entry-in-pane-4'
'cmd-5': 'tree-view:open-selected-entry-in-pane-5'
'cmd-6': 'tree-view:open-selected-entry-in-pane-6'
'cmd-7': 'tree-view:open-selected-entry-in-pane-7'
'cmd-8': 'tree-view:open-selected-entry-in-pane-8'
'cmd-9': 'tree-view:open-selected-entry-in-pane-9'

'.platform-win32 .tree-view, .platform-linux .tree-view':
'ctrl-c': 'tree-view:copy'
'ctrl-x': 'tree-view:cut'
'ctrl-v': 'tree-view:paste'
'ctrl-k right': 'tree-view:open-selected-entry-right'
'ctrl-k l': 'tree-view:open-selected-entry-right'
'ctrl-k left': 'tree-view:open-selected-entry-left'
'ctrl-k h': 'tree-view:open-selected-entry-left'
'ctrl-k up': 'tree-view:open-selected-entry-up'
'ctrl-k k': 'tree-view:open-selected-entry-up'
'ctrl-k down': 'tree-view:open-selected-entry-down'
'ctrl-k j': 'tree-view:open-selected-entry-down'
'ctrl-1': 'tree-view:open-selected-entry-in-pane-1'
'ctrl-2': 'tree-view:open-selected-entry-in-pane-2'
'ctrl-3': 'tree-view:open-selected-entry-in-pane-3'
'ctrl-4': 'tree-view:open-selected-entry-in-pane-4'
'ctrl-5': 'tree-view:open-selected-entry-in-pane-5'
'ctrl-6': 'tree-view:open-selected-entry-in-pane-6'
'ctrl-7': 'tree-view:open-selected-entry-in-pane-7'
'ctrl-8': 'tree-view:open-selected-entry-in-pane-8'
'ctrl-9': 'tree-view:open-selected-entry-in-pane-9'

'.tree-view':
'right': 'tree-view:expand-item'
'ctrl-]': 'tree-view:expand-item'
'l': 'tree-view:expand-item'
'left': 'tree-view:collapse-directory'
'ctrl-[': 'tree-view:collapse-directory'
'alt-ctrl-]': 'tree-view:recursive-expand-directory'
'alt-right': 'tree-view:recursive-expand-directory'
'alt-ctrl-[': 'tree-view:recursive-collapse-directory'
'alt-left': 'tree-view:recursive-collapse-directory'
'h': 'tree-view:collapse-directory'
'enter': 'tree-view:open-selected-entry'
'escape': 'tree-view:unfocus'
'ctrl-C': 'tree-view:copy-full-path'
'm': 'tree-view:move'
'f2': 'tree-view:move'
'a': 'tree-view:add-file'
'shift-a': 'tree-view:add-folder'
'd': 'tree-view:duplicate'
'delete': 'tree-view:remove'
'backspace': 'tree-view:remove'
'k': 'core:move-up'
'j': 'core:move-down'
'i': 'tree-view:toggle-vcs-ignored-files'
'home': 'core:move-to-top'
'end': 'core:move-to-bottom'

'.tree-view-dialog atom-text-editor[mini]':
'enter': 'core:confirm'
'escape': 'core:cancel'
60 changes: 60 additions & 0 deletions packages/tree-view/lib/add-dialog.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
path = require 'path'
fs = require 'fs-plus'
Dialog = require './dialog'
{repoForPath} = require './helpers'

module.exports =
class AddDialog extends Dialog
constructor: (initialPath, isCreatingFile) ->
@isCreatingFile = isCreatingFile

if fs.isFileSync(initialPath)
directoryPath = path.dirname(initialPath)
else
directoryPath = initialPath

relativeDirectoryPath = directoryPath
[@rootProjectPath, relativeDirectoryPath] = atom.project.relativizePath(directoryPath)
relativeDirectoryPath += path.sep if relativeDirectoryPath.length > 0

super
prompt: "Enter the path for the new " + if isCreatingFile then "file." else "folder."
initialPath: relativeDirectoryPath
select: false
iconClass: if isCreatingFile then 'icon-file-add' else 'icon-file-directory-create'

onDidCreateFile: (callback) ->
@emitter.on('did-create-file', callback)

onDidCreateDirectory: (callback) ->
@emitter.on('did-create-directory', callback)

onConfirm: (newPath) ->
newPath = newPath.replace(/\s+$/, '') # Remove trailing whitespace
endsWithDirectorySeparator = newPath[newPath.length - 1] is path.sep
unless path.isAbsolute(newPath)
unless @rootProjectPath?
@showError("You must open a directory to create a file with a relative path")
return

newPath = path.join(@rootProjectPath, newPath)

return unless newPath

try
if fs.existsSync(newPath)
@showError("'#{newPath}' already exists.")
else if @isCreatingFile
if endsWithDirectorySeparator
@showError("File names must not end with a '#{path.sep}' character.")
else
fs.writeFileSync(newPath, '')
repoForPath(newPath)?.getPathStatus(newPath)
@emitter.emit('did-create-file', newPath)
@close()
else
fs.makeTreeSync(newPath)
@emitter.emit('did-create-directory', newPath)
@cancel()
catch error
@showError("#{error.message}.")
36 changes: 36 additions & 0 deletions packages/tree-view/lib/add-projects-view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module.exports =
class AddProjectView {
constructor () {
this.element = document.createElement('div')
this.element.id = 'add-projects-view'

this.icon = document.createElement('div')
this.icon.classList.add('icon', 'icon-large', 'icon-telescope')
this.element.appendChild(this.icon)

this.description = document.createElement('div')
this.description.classList.add('description')
this.description.innerText = 'Your project is currently empty'
this.element.appendChild(this.description)

this.addProjectsButton = document.createElement('button')
this.addProjectsButton.classList.add('btn', 'btn-primary')
this.addProjectsButton.innerText = 'Add folders'
this.addProjectsButton.addEventListener('click', () => {
atom.pickFolder(paths => {
if (paths) {
atom.project.setPaths(paths)
}
})
})
this.element.appendChild(this.addProjectsButton)

this.reopenProjectButton = document.createElement('button')
this.reopenProjectButton.classList.add('btn')
this.reopenProjectButton.innerText = 'Reopen a project'
this.reopenProjectButton.addEventListener('click', () => {
atom.commands.dispatch(this.element, 'application:reopen-project')
})
this.element.appendChild(this.reopenProjectButton)
}
}
48 changes: 48 additions & 0 deletions packages/tree-view/lib/copy-dialog.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
path = require 'path'
fs = require 'fs-plus'
Dialog = require './dialog'
{repoForPath} = require "./helpers"

module.exports =
class CopyDialog extends Dialog
constructor: (@initialPath, {@onCopy}) ->
super
prompt: 'Enter the new path for the duplicate.'
initialPath: atom.project.relativize(@initialPath)
select: true
iconClass: 'icon-arrow-right'

onConfirm: (newPath) ->
newPath = newPath.replace(/\s+$/, '') # Remove trailing whitespace
unless path.isAbsolute(newPath)
[rootPath] = atom.project.relativizePath(@initialPath)
newPath = path.join(rootPath, newPath)
return unless newPath

if @initialPath is newPath
@close()
return

if fs.existsSync(newPath)
@showError("'#{newPath}' already exists.")
return

activeEditor = atom.workspace.getActiveTextEditor()
activeEditor = null unless activeEditor?.getPath() is @initialPath
try
if fs.isDirectorySync(@initialPath)
fs.copySync(@initialPath, newPath)
@onCopy?({initialPath: @initialPath, newPath: newPath})
else
fs.copy @initialPath, newPath, =>
@onCopy?({initialPath: @initialPath, newPath: newPath})
atom.workspace.open newPath,
activatePane: true
initialLine: activeEditor?.getLastCursor().getBufferRow()
initialColumn: activeEditor?.getLastCursor().getBufferColumn()
if repo = repoForPath(newPath)
repo.getPathStatus(@initialPath)
repo.getPathStatus(newPath)
@close()
catch error
@showError("#{error.message}.")
23 changes: 23 additions & 0 deletions packages/tree-view/lib/default-file-icons.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
fs = require 'fs-plus'
path = require 'path'

class DefaultFileIcons
iconClassForPath: (filePath) ->
extension = path.extname(filePath)

if fs.isSymbolicLinkSync(filePath)
'icon-file-symlink-file'
else if fs.isReadmePath(filePath)
'icon-book'
else if fs.isCompressedExtension(extension)
'icon-file-zip'
else if fs.isImageExtension(extension)
'icon-file-media'
else if fs.isPdfExtension(extension)
'icon-file-pdf'
else if fs.isBinaryExtension(extension)
'icon-file-binary'
else
'icon-file-text'

module.exports = new DefaultFileIcons
Loading