blob: 4a1c8fd85a60b1705f473548fb774dd92c11b0d2 (
plain)
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
102
103
104
105
106
107
|
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only
import * as vscode from 'vscode';
export interface Project {
folder: vscode.WorkspaceFolder;
dispose(): void;
}
export class ProjectManager<ProjectType extends Project> {
protected readonly _disposables: vscode.Disposable[] = [];
projects = new Set<ProjectType>();
private readonly _addEmitter = new vscode.EventEmitter<ProjectType>();
private readonly _removeEmitter = new vscode.EventEmitter<ProjectType>();
private _newProjectCallback: (
folder: vscode.WorkspaceFolder,
context: vscode.ExtensionContext
) => Promise<ProjectType | undefined>;
constructor(
readonly context: vscode.ExtensionContext,
newProjectCallback: (
folder: vscode.WorkspaceFolder,
context: vscode.ExtensionContext
) => Promise<ProjectType | undefined>
) {
this._newProjectCallback = newProjectCallback;
this.watchProjects(context);
}
public addProject(project: ProjectType) {
this.projects.add(project);
}
public removeProject(project: ProjectType) {
this._removeEmitter.fire(project);
this.projects.delete(project);
}
public set newProjectCallback(
callback: (
folder: vscode.WorkspaceFolder,
context: vscode.ExtensionContext
) => Promise<ProjectType | undefined>
) {
this._newProjectCallback = callback;
}
public get newProjectCallback() {
return this._newProjectCallback;
}
public getProjects() {
return this.projects;
}
public getProject(folder: vscode.WorkspaceFolder): ProjectType | undefined {
return Array.from(this.projects).find(
(project) => project.folder === folder
);
}
public get onProjectAdded() {
return this._addEmitter.event;
}
public get onProjectRemoved() {
return this._removeEmitter.event;
}
protected watchProjects(context: vscode.ExtensionContext) {
vscode.workspace.onDidChangeWorkspaceFolders(async (event) => {
for (const folder of event.removed) {
const project = this.getProject(folder);
if (!project) {
continue;
}
project.dispose();
this.removeProject(project);
}
for (const folder of event.added) {
const project = await this._newProjectCallback(folder, context);
if (!project) {
continue;
}
this.addProject(project);
this._addEmitter.fire(project);
}
});
}
public findProjectContainingFile(uri: vscode.Uri) {
return Array.from(this.projects).find((project) => {
const ret = uri.toString().startsWith(project.folder.uri.toString());
return ret;
});
}
dispose() {
for (const project of this.projects) {
project.dispose();
}
this.projects.clear();
for (const d of this._disposables) {
d.dispose();
}
}
}
|