Support for @recommended:languages search (#124546)
This commit is contained in:
parent
9224159b00
commit
b157bc7e5c
|
@ -79,6 +79,7 @@ export interface IProductConfiguration {
|
|||
readonly remoteExtensionTips?: { [remoteName: string]: IRemoteExtensionTip; };
|
||||
readonly extensionKeywords?: { [extension: string]: readonly string[]; };
|
||||
readonly keymapExtensionTips?: readonly string[];
|
||||
readonly languageExtensionTips?: readonly string[];
|
||||
readonly trustedExtensionUrlPublicKeys?: { [id: string]: string[]; };
|
||||
|
||||
readonly crashReporter?: {
|
||||
|
|
|
@ -18,6 +18,7 @@ import { ExperimentalRecommendations } from 'vs/workbench/contrib/extensions/bro
|
|||
import { WorkspaceRecommendations } from 'vs/workbench/contrib/extensions/browser/workspaceRecommendations';
|
||||
import { FileBasedRecommendations } from 'vs/workbench/contrib/extensions/browser/fileBasedRecommendations';
|
||||
import { KeymapRecommendations } from 'vs/workbench/contrib/extensions/browser/keymapRecommendations';
|
||||
import { LanguageRecommendations } from 'vs/workbench/contrib/extensions/browser/languageRecommendations';
|
||||
import { ExtensionRecommendation } from 'vs/workbench/contrib/extensions/browser/extensionRecommendations';
|
||||
import { ConfigBasedRecommendations } from 'vs/workbench/contrib/extensions/browser/configBasedRecommendations';
|
||||
import { IExtensionRecommendationNotificationService } from 'vs/platform/extensionRecommendations/common/extensionRecommendations';
|
||||
|
@ -40,6 +41,7 @@ export class ExtensionRecommendationsService extends Disposable implements IExte
|
|||
private readonly exeBasedRecommendations: ExeBasedRecommendations;
|
||||
private readonly dynamicWorkspaceRecommendations: DynamicWorkspaceRecommendations;
|
||||
private readonly keymapRecommendations: KeymapRecommendations;
|
||||
private readonly languageRecommendations: LanguageRecommendations;
|
||||
|
||||
public readonly activationPromise: Promise<void>;
|
||||
private sessionSeed: number;
|
||||
|
@ -66,6 +68,7 @@ export class ExtensionRecommendationsService extends Disposable implements IExte
|
|||
this.exeBasedRecommendations = instantiationService.createInstance(ExeBasedRecommendations);
|
||||
this.dynamicWorkspaceRecommendations = instantiationService.createInstance(DynamicWorkspaceRecommendations);
|
||||
this.keymapRecommendations = instantiationService.createInstance(KeymapRecommendations);
|
||||
this.languageRecommendations = instantiationService.createInstance(LanguageRecommendations);
|
||||
|
||||
if (!this.isEnabled()) {
|
||||
this.sessionSeed = 0;
|
||||
|
@ -90,6 +93,7 @@ export class ExtensionRecommendationsService extends Disposable implements IExte
|
|||
this.fileBasedRecommendations.activate(),
|
||||
this.experimentalRecommendations.activate(),
|
||||
this.keymapRecommendations.activate(),
|
||||
this.languageRecommendations.activate(),
|
||||
]);
|
||||
|
||||
this._register(Event.any(this.workspaceRecommendations.onDidChangeRecommendations, this.configBasedRecommendations.onDidChangeRecommendations, this.extensionRecommendationsManagementService.onDidChangeIgnoredRecommendations)(() => this._onDidChangeRecommendations.fire()));
|
||||
|
@ -127,6 +131,7 @@ export class ExtensionRecommendationsService extends Disposable implements IExte
|
|||
...this.fileBasedRecommendations.recommendations,
|
||||
...this.workspaceRecommendations.recommendations,
|
||||
...this.keymapRecommendations.recommendations,
|
||||
...this.languageRecommendations.recommendations,
|
||||
];
|
||||
|
||||
for (const { extensionId, reason } of allRecommendations) {
|
||||
|
@ -185,6 +190,10 @@ export class ExtensionRecommendationsService extends Disposable implements IExte
|
|||
return this.toExtensionRecommendations(this.keymapRecommendations.recommendations);
|
||||
}
|
||||
|
||||
getLanguageRecommendations(): string[] {
|
||||
return this.toExtensionRecommendations(this.languageRecommendations.recommendations);
|
||||
}
|
||||
|
||||
async getWorkspaceRecommendations(): Promise<string[]> {
|
||||
if (!this.isEnabled()) {
|
||||
return [];
|
||||
|
|
|
@ -23,7 +23,7 @@ import { IConfigurationRegistry, Extensions as ConfigurationExtensions, Configur
|
|||
import * as jsonContributionRegistry from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
|
||||
import { ExtensionsConfigurationSchema, ExtensionsConfigurationSchemaId } from 'vs/workbench/contrib/extensions/common/extensionsFileTemplate';
|
||||
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IInstantiationService, ServicesAccessor, optional } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { KeymapExtensions } from 'vs/workbench/contrib/extensions/common/extensionsUtils';
|
||||
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { EditorDescriptor, IEditorRegistry } from 'vs/workbench/browser/editor';
|
||||
|
@ -73,6 +73,7 @@ import { Promises } from 'vs/base/common/async';
|
|||
import { EditorExtensions } from 'vs/workbench/common/editor';
|
||||
import { WORKSPACE_TRUST_EXTENSION_SUPPORT } from 'vs/workbench/services/workspaces/common/workspaceTrust';
|
||||
import { ExtensionsCompletionItemsProvider } from 'vs/workbench/contrib/extensions/browser/extensionsCompletionItemsProvider';
|
||||
import { ITASExperimentService } from 'vs/workbench/services/experiment/common/experimentService';
|
||||
|
||||
// Singletons
|
||||
registerSingleton(IExtensionsWorkbenchService, ExtensionsWorkbenchService);
|
||||
|
@ -378,6 +379,8 @@ interface IExtensionActionOptions extends IAction2Options {
|
|||
|
||||
class ExtensionsContributions extends Disposable implements IWorkbenchContribution {
|
||||
|
||||
private tasExperimentService?: ITASExperimentService;
|
||||
|
||||
constructor(
|
||||
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
|
||||
@IExtensionGalleryService extensionGalleryService: IExtensionGalleryService,
|
||||
|
@ -388,6 +391,7 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi
|
|||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IDialogService private readonly dialogService: IDialogService,
|
||||
@ICommandService private readonly commandService: ICommandService,
|
||||
@optional(ITASExperimentService) tasExperimentService: ITASExperimentService,
|
||||
) {
|
||||
super();
|
||||
const hasGalleryContext = CONTEXT_HAS_GALLERY.bindTo(contextKeyService);
|
||||
|
@ -410,6 +414,7 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi
|
|||
hasWebServerContext.set(true);
|
||||
}
|
||||
|
||||
this.tasExperimentService = tasExperimentService;
|
||||
this.registerGlobalActions();
|
||||
this.registerContextMenuActions();
|
||||
this.registerQuickAccessProvider();
|
||||
|
@ -501,7 +506,10 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi
|
|||
id: MenuId.CommandPalette,
|
||||
when: CONTEXT_HAS_GALLERY
|
||||
},
|
||||
run: () => runAction(this.instantiationService.createInstance(SearchExtensionsAction, '@category:"programming languages" @sort:installs '))
|
||||
run: async () => {
|
||||
const recommended = await this.tasExperimentService?.getTreatment<boolean>('recommendedLanguages');
|
||||
runAction(this.instantiationService.createInstance(SearchExtensionsAction, recommended ? '@recommended:languages ' : '@category:"programming languages" @sort:installs '));
|
||||
}
|
||||
});
|
||||
|
||||
this.registerExtensionAction({
|
||||
|
|
|
@ -739,6 +739,11 @@ export class ExtensionsListView extends ViewPane {
|
|||
return this.getKeymapRecommendationsModel(query, options, token);
|
||||
}
|
||||
|
||||
// Language recommendations
|
||||
if (ExtensionsListView.isLanguageRecommendedExtensionsQuery(query.value)) {
|
||||
return this.getLanguageRecommendationsModel(query, options, token);
|
||||
}
|
||||
|
||||
// Exe recommendations
|
||||
if (ExtensionsListView.isExeRecommendedExtensionsQuery(query.value)) {
|
||||
return this.getExeRecommendationsModel(query, options, token);
|
||||
|
@ -803,6 +808,14 @@ export class ExtensionsListView extends ViewPane {
|
|||
return new PagedModel(installableRecommendations);
|
||||
}
|
||||
|
||||
private async getLanguageRecommendationsModel(query: Query, options: IQueryOptions, token: CancellationToken): Promise<IPagedModel<IExtension>> {
|
||||
const value = query.value.replace(/@recommended:languages/g, '').trim().toLowerCase();
|
||||
const recommendations = this.extensionRecommendationsService.getLanguageRecommendations();
|
||||
const installableRecommendations = (await this.getInstallableRecommendations(recommendations, { ...options, source: 'recommendations-languages' }, token))
|
||||
.filter(extension => extension.identifier.id.toLowerCase().indexOf(value) > -1);
|
||||
return new PagedModel(installableRecommendations);
|
||||
}
|
||||
|
||||
private async getExeRecommendationsModel(query: Query, options: IQueryOptions, token: CancellationToken): Promise<IPagedModel<IExtension>> {
|
||||
const exe = query.value.replace(/@exe:/g, '').trim().toLowerCase();
|
||||
const { important, others } = await this.extensionRecommendationsService.getExeBasedRecommendations(exe.startsWith('"') ? exe.substring(1, exe.length - 1) : exe);
|
||||
|
@ -1035,6 +1048,10 @@ export class ExtensionsListView extends ViewPane {
|
|||
return /@recommended:keymaps/i.test(query);
|
||||
}
|
||||
|
||||
static isLanguageRecommendedExtensionsQuery(query: string): boolean {
|
||||
return /@recommended:languages/i.test(query);
|
||||
}
|
||||
|
||||
override focus(): void {
|
||||
super.focus();
|
||||
if (!this.list) {
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ExtensionRecommendations, ExtensionRecommendation } from 'vs/workbench/contrib/extensions/browser/extensionRecommendations';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { ExtensionRecommendationReason } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
|
||||
|
||||
export class LanguageRecommendations extends ExtensionRecommendations {
|
||||
|
||||
private _recommendations: ExtensionRecommendation[] = [];
|
||||
get recommendations(): ReadonlyArray<ExtensionRecommendation> { return this._recommendations; }
|
||||
|
||||
constructor(
|
||||
@IProductService private readonly productService: IProductService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected async doActivate(): Promise<void> {
|
||||
if (this.productService.languageExtensionTips) {
|
||||
this._recommendations = this.productService.languageExtensionTips.map(extensionId => (<ExtensionRecommendation>{
|
||||
extensionId: extensionId.toLowerCase(),
|
||||
reason: {
|
||||
reasonId: ExtensionRecommendationReason.Application,
|
||||
reasonText: ''
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -44,6 +44,7 @@ export interface IExtensionRecommendationsService {
|
|||
getConfigBasedRecommendations(): Promise<{ important: string[], others: string[] }>;
|
||||
getWorkspaceRecommendations(): Promise<string[]>;
|
||||
getKeymapRecommendations(): string[];
|
||||
getLanguageRecommendations(): string[];
|
||||
}
|
||||
|
||||
export type IgnoredRecommendationChangeNotification = {
|
||||
|
|
Loading…
Reference in a new issue