Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/extensions/browser/configBasedRecommendations.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { IExtensionTipsService, IConfigBasedExtensionTip } from '../../../../platform/extensionManagement/common/extensionManagement.js';
7
import { ExtensionRecommendations, ExtensionRecommendation } from './extensionRecommendations.js';
8
import { localize } from '../../../../nls.js';
9
import { ExtensionRecommendationReason } from '../../../services/extensionRecommendations/common/extensionRecommendations.js';
10
import { IWorkspaceContextService, IWorkspaceFoldersChangeEvent } from '../../../../platform/workspace/common/workspace.js';
11
import { Emitter } from '../../../../base/common/event.js';
12
13
type ConfigBasedExtensionRecommendation = ExtensionRecommendation & { whenNotInstalled: string[] | undefined };
14
15
export class ConfigBasedRecommendations extends ExtensionRecommendations {
16
17
private importantTips: IConfigBasedExtensionTip[] = [];
18
private otherTips: IConfigBasedExtensionTip[] = [];
19
20
private _onDidChangeRecommendations = this._register(new Emitter<void>());
21
readonly onDidChangeRecommendations = this._onDidChangeRecommendations.event;
22
23
private _otherRecommendations: ConfigBasedExtensionRecommendation[] = [];
24
get otherRecommendations(): ReadonlyArray<ConfigBasedExtensionRecommendation> { return this._otherRecommendations; }
25
26
private _importantRecommendations: ConfigBasedExtensionRecommendation[] = [];
27
get importantRecommendations(): ReadonlyArray<ConfigBasedExtensionRecommendation> { return this._importantRecommendations; }
28
29
get recommendations(): ReadonlyArray<ConfigBasedExtensionRecommendation> { return [...this.importantRecommendations, ...this.otherRecommendations]; }
30
31
constructor(
32
@IExtensionTipsService private readonly extensionTipsService: IExtensionTipsService,
33
@IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService,
34
) {
35
super();
36
}
37
38
protected async doActivate(): Promise<void> {
39
await this.fetch();
40
this._register(this.workspaceContextService.onDidChangeWorkspaceFolders(e => this.onWorkspaceFoldersChanged(e)));
41
}
42
43
private async fetch(): Promise<void> {
44
const workspace = this.workspaceContextService.getWorkspace();
45
const importantTips: Map<string, IConfigBasedExtensionTip> = new Map<string, IConfigBasedExtensionTip>();
46
const otherTips: Map<string, IConfigBasedExtensionTip> = new Map<string, IConfigBasedExtensionTip>();
47
for (const folder of workspace.folders) {
48
const configBasedTips = await this.extensionTipsService.getConfigBasedTips(folder.uri);
49
for (const tip of configBasedTips) {
50
if (tip.important) {
51
importantTips.set(tip.extensionId, tip);
52
} else {
53
otherTips.set(tip.extensionId, tip);
54
}
55
}
56
}
57
this.importantTips = [...importantTips.values()];
58
this.otherTips = [...otherTips.values()].filter(tip => !importantTips.has(tip.extensionId));
59
this._otherRecommendations = this.otherTips.map(tip => this.toExtensionRecommendation(tip));
60
this._importantRecommendations = this.importantTips.map(tip => this.toExtensionRecommendation(tip));
61
}
62
63
private async onWorkspaceFoldersChanged(event: IWorkspaceFoldersChangeEvent): Promise<void> {
64
if (event.added.length) {
65
const oldImportantRecommended = this.importantTips;
66
await this.fetch();
67
// Suggest only if at least one of the newly added recommendations was not suggested before
68
if (this.importantTips.some(current => oldImportantRecommended.every(old => current.extensionId !== old.extensionId))) {
69
this._onDidChangeRecommendations.fire();
70
}
71
}
72
}
73
74
private toExtensionRecommendation(tip: IConfigBasedExtensionTip): ConfigBasedExtensionRecommendation {
75
return {
76
extension: tip.extensionId,
77
reason: {
78
reasonId: ExtensionRecommendationReason.WorkspaceConfig,
79
reasonText: localize('exeBasedRecommendation', "This extension is recommended because of the current workspace configuration")
80
},
81
whenNotInstalled: tip.whenNotInstalled
82
};
83
}
84
85
}
86
87