-
Notifications
You must be signed in to change notification settings - Fork 2.5k
/
navigator-tree.ts
101 lines (89 loc) · 3.63 KB
/
navigator-tree.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/********************************************************************************
* Copyright (C) 2017 TypeFox and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import { injectable, inject, postConstruct } from 'inversify';
import { FileTree, DirNode } from '@theia/filesystem/lib/browser';
import { FileStat } from '@theia/filesystem/lib/common';
import URI from '@theia/core/lib/common/uri';
import { TreeNode, CompositeTreeNode, SelectableTreeNode } from '@theia/core/lib/browser';
import { FileNavigatorFilter } from './navigator-filter';
@injectable()
export class FileNavigatorTree extends FileTree {
@inject(FileNavigatorFilter) protected readonly filter: FileNavigatorFilter;
@postConstruct()
protected init(): void {
this.toDispose.push(this.filter.onFilterChanged(() => this.refresh()));
}
async resolveChildren(parent: CompositeTreeNode): Promise<TreeNode[]> {
if (WorkspaceNode.is(parent)) {
return parent.children;
}
return this.filter.filter(super.resolveChildren(parent));
}
protected toNodeId(uri: URI, parent: CompositeTreeNode): string {
const workspaceRootNode = WorkspaceRootNode.find(parent);
if (workspaceRootNode) {
return this.createId(workspaceRootNode, uri);
}
return super.toNodeId(uri, parent);
}
createId(root: WorkspaceRootNode, uri: URI): string {
const id = super.toNodeId(uri, root);
return id === root.id ? id : `${root.id}:${id}`;
}
async createWorkspaceRoot(rootFolder: FileStat, workspaceNode: WorkspaceNode): Promise<WorkspaceRootNode> {
const node = this.toNode(rootFolder, workspaceNode) as WorkspaceRootNode;
Object.assign(node, {
visible: workspaceNode.name !== WorkspaceNode.name,
});
return node;
}
}
export interface WorkspaceNode extends CompositeTreeNode, SelectableTreeNode {
children: WorkspaceRootNode[];
}
export namespace WorkspaceNode {
export const id = 'WorkspaceNodeId';
export const name = 'WorkspaceNode';
export function is(node: TreeNode | undefined): node is WorkspaceNode {
return CompositeTreeNode.is(node) && node.id === WorkspaceNode.id;
}
export function createRoot(multiRootName?: string): WorkspaceNode {
return {
id: WorkspaceNode.id,
name: multiRootName || WorkspaceNode.name,
parent: undefined,
children: [],
visible: false,
selected: false
};
}
}
export interface WorkspaceRootNode extends DirNode {
parent: WorkspaceNode;
}
export namespace WorkspaceRootNode {
export function is(node: Object | undefined): node is WorkspaceRootNode {
return DirNode.is(node) && WorkspaceNode.is(node.parent);
}
export function find(node: TreeNode | undefined): WorkspaceRootNode | undefined {
if (node) {
if (is(node)) {
return node;
}
return find(node.parent);
}
}
}