Skip to content

Commit 679e1ca

Browse files
committed
add multi-root file viewer
1 parent 4f12bc1 commit 679e1ca

File tree

3 files changed

+92
-1
lines changed

3 files changed

+92
-1
lines changed

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,11 @@
232232
{
233233
"id": "bazelTaskOutline",
234234
"name": "Bazel Run Targets"
235+
},
236+
{
237+
"id": "rootFileViewer",
238+
"name": "Root File Viewer",
239+
"when": "isMultiRoot"
235240
}
236241
]
237242
},

src/extension.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { registerLSClient } from './loggingTCPServer';
2121
import { ProjectViewManager } from './projectViewManager';
2222
import { BazelRunTargetProvider } from './provider/bazelRunTargetProvider';
2323
import { BazelTaskProvider } from './provider/bazelTaskProvider';
24+
import { RootFileViewProvider } from './provider/rootFileViewProvider';
2425
import {
2526
getWorkspaceRoot,
2627
initBazelProjectFile,
@@ -45,6 +46,10 @@ export async function activate(context: ExtensionContext) {
4546
BazelRunTargetProvider.instance
4647
);
4748
tasks.registerTaskProvider('bazel', new BazelTaskProvider());
49+
window.registerTreeDataProvider(
50+
'rootFileViewer',
51+
RootFileViewProvider.instance
52+
);
4853

4954
BazelLanguageServerTerminal.trace('extension activated');
5055

@@ -66,6 +71,11 @@ export async function activate(context: ExtensionContext) {
6671
'isBazelWorkspaceRoot',
6772
isBazelWorkspaceRoot()
6873
);
74+
commands.executeCommand(
75+
'setContext',
76+
'isMultiRoot',
77+
workspace.workspaceFile?.fsPath.includes('code-workspace')
78+
);
6979
// create .eclipse/.bazelproject file if DNE
7080
if (isBazelWorkspaceRoot()) {
7181
initBazelProjectFile();
@@ -134,7 +144,7 @@ export async function activate(context: ExtensionContext) {
134144
registerLSClient();
135145
}
136146

137-
export function deactivate() {}
147+
export function deactivate() { }
138148

139149
function syncProjectView(): void {
140150
if (!isRedhatJavaReady()) {
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import path from 'path';
2+
import {
3+
Event,
4+
EventEmitter,
5+
FileSystemWatcher,
6+
ProviderResult,
7+
RelativePattern,
8+
ThemeIcon,
9+
TreeDataProvider,
10+
TreeItem,
11+
TreeItemCollapsibleState,
12+
Uri,
13+
workspace,
14+
} from 'vscode';
15+
import { getWorkspaceRoot } from '../util';
16+
17+
const WORKSPACE_ROOT = getWorkspaceRoot();
18+
19+
export class RootFileViewProvider implements TreeDataProvider<string> {
20+
private static _instance: RootFileViewProvider;
21+
22+
private _filesWatcher: FileSystemWatcher;
23+
private _onDidChangeTreeData: EventEmitter<string | undefined | void> =
24+
new EventEmitter<string | undefined | void>();
25+
readonly onDidChangeTreeData: Event<string | undefined | void> =
26+
this._onDidChangeTreeData.event;
27+
28+
private constructor() {
29+
this._filesWatcher = workspace.createFileSystemWatcher(
30+
new RelativePattern(WORKSPACE_ROOT, '*')
31+
);
32+
this._filesWatcher.onDidChange((f) => this._onDidChangeTreeData.fire());
33+
this._filesWatcher.onDidCreate((f) => this._onDidChangeTreeData.fire());
34+
this._filesWatcher.onDidDelete((f) => this._onDidChangeTreeData.fire());
35+
}
36+
37+
public static get instance(): RootFileViewProvider {
38+
if (!this._instance) {
39+
this._instance = new RootFileViewProvider();
40+
}
41+
return this._instance;
42+
}
43+
44+
getTreeItem(element: string): TreeItem | Thenable<TreeItem> {
45+
return new FileItem(element);
46+
}
47+
getChildren(element?: string | undefined): ProviderResult<string[]> {
48+
if (!element) {
49+
return workspace.fs
50+
.readDirectory(Uri.file(WORKSPACE_ROOT))
51+
.then((val) => {
52+
return val.filter((v) => v[1] === 1).map((v) => v[0]);
53+
});
54+
}
55+
return [];
56+
}
57+
}
58+
59+
class FileItem extends TreeItem {
60+
constructor(fileName: string, collapsibleState?: TreeItemCollapsibleState) {
61+
super(fileName, collapsibleState);
62+
this.command = {
63+
title: fileName,
64+
command: 'vscode.open',
65+
arguments: [`${WORKSPACE_ROOT}${path.sep}${fileName}`],
66+
};
67+
switch (fileName.split('.').reverse()[0]) {
68+
case 'json':
69+
this.iconPath = new ThemeIcon('json');
70+
break;
71+
default:
72+
this.iconPath = new ThemeIcon('file');
73+
break;
74+
}
75+
}
76+
}

0 commit comments

Comments
 (0)