提交 7b37dbd6 编写于 作者: S Sandeep Somavarapu

#15361 Separate extension settings and recommendations

上级 a8f02202
......@@ -285,7 +285,7 @@ export const IExtensionTipsService = createDecorator<IExtensionTipsService>('ext
export interface IExtensionTipsService {
_serviceBrand: any;
getRecommendations(): string[];
getWorkspaceRecommendations(): string[];
getWorkspaceRecommendations(): TPromise<string[]>;
}
export const ExtensionsLabel = localize('extensions', "Extensions");
......
......@@ -4,11 +4,13 @@
*--------------------------------------------------------------------------------------------*/
import { localize } from 'vs/nls';
import * as paths from 'vs/base/common/paths';
import { TPromise } from 'vs/base/common/winjs.base';
import { forEach } from 'vs/base/common/collections';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { match } from 'vs/base/common/glob';
import * as json from 'vs/base/common/json';
import { IExtensionManagementService, IExtensionGalleryService, IExtensionTipsService, LocalExtensionType, EXTENSION_IDENTIFIER_PATTERN } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionsConfiguration, ConfigurationKey } from 'vs/workbench/parts/extensions/common/extensions';
import { IModelService } from 'vs/editor/common/services/modelService';
import { IModel } from 'vs/editor/common/editorCommon';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
......@@ -17,8 +19,13 @@ import { IChoiceService } from 'vs/platform/message/common/message';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ShowRecommendedExtensionsAction, ShowWorkspaceRecommendedExtensionsAction } from 'vs/workbench/parts/extensions/browser/extensionsActions';
import Severity from 'vs/base/common/severity';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { Schemas } from 'vs/base/common/network';
import { IFileService } from 'vs/platform/files/common/files';
interface IExtensionsContent {
recommendations: string[];
}
export class ExtensionTipsService implements IExtensionTipsService {
......@@ -37,7 +44,8 @@ export class ExtensionTipsService implements IExtensionTipsService {
@IChoiceService private choiceService: IChoiceService,
@IExtensionManagementService private extensionsService: IExtensionManagementService,
@IInstantiationService private instantiationService: IInstantiationService,
@IConfigurationService private configurationService: IConfigurationService
@IFileService private fileService: IFileService,
@IWorkspaceContextService private contextService: IWorkspaceContextService
) {
if (!this._galleryService.isEnabled()) {
return;
......@@ -47,15 +55,17 @@ export class ExtensionTipsService implements IExtensionTipsService {
this._suggestWorkspaceRecommendations();
}
getWorkspaceRecommendations(): string[] {
const configuration = this.configurationService.getConfiguration<IExtensionsConfiguration>(ConfigurationKey);
if (configuration.recommendations) {
const regEx = new RegExp(EXTENSION_IDENTIFIER_PATTERN);
return configuration.recommendations.filter((element, position) => {
return configuration.recommendations.indexOf(element) === position && regEx.test(element);
});
}
return configuration.recommendations || [];
getWorkspaceRecommendations(): TPromise<string[]> {
return this.fileService.resolveContent(this.contextService.toResource(paths.join('.vscode', 'extensions.json'))).then(content => {
const extensionsContent = <IExtensionsContent>json.parse(content.value, []);
if (extensionsContent.recommendations) {
const regEx = new RegExp(EXTENSION_IDENTIFIER_PATTERN);
return extensionsContent.recommendations.filter((element, position) => {
return extensionsContent.recommendations.indexOf(element) === position && regEx.test(element);
});
}
return [];
}, err => []);
}
getRecommendations(): string[] {
......@@ -166,36 +176,37 @@ export class ExtensionTipsService implements IExtensionTipsService {
return;
}
const allRecommendations = this.getWorkspaceRecommendations();
if (!allRecommendations.length) {
return;
}
this.extensionsService.getInstalled(LocalExtensionType.User).done(local => {
const recommendations = allRecommendations
.filter(id => local.every(local => `${local.manifest.publisher}.${local.manifest.name}` !== id));
if (!recommendations.length) {
this.getWorkspaceRecommendations().done(allRecommendations => {
if (!allRecommendations.length) {
return;
}
const message = localize('workspaceRecommended', "This workspace has extension recommendations.");
const action = this.instantiationService.createInstance(ShowWorkspaceRecommendedExtensionsAction, ShowWorkspaceRecommendedExtensionsAction.ID, localize('showRecommendations', "Show Recommendations"));
const options = [
action.label,
localize('neverShowAgain', "Don't show again"),
localize('close', "Close")
];
this.extensionsService.getInstalled(LocalExtensionType.User).done(local => {
const recommendations = allRecommendations
.filter(id => local.every(local => `${local.manifest.publisher}.${local.manifest.name}` !== id));
this.choiceService.choose(Severity.Info, message, options).done(choice => {
switch (choice) {
case 0: return action.run();
case 1: return this.storageService.store(storageKey, true, StorageScope.WORKSPACE);
if (!recommendations.length) {
return;
}
const message = localize('workspaceRecommended', "This workspace has extension recommendations.");
const action = this.instantiationService.createInstance(ShowWorkspaceRecommendedExtensionsAction, ShowWorkspaceRecommendedExtensionsAction.ID, localize('showRecommendations', "Show Recommendations"));
const options = [
action.label,
localize('neverShowAgain', "Don't show again"),
localize('close', "Close")
];
this.choiceService.choose(Severity.Info, message, options).done(choice => {
switch (choice) {
case 0: return action.run();
case 1: return this.storageService.store(storageKey, true, StorageScope.WORKSPACE);
}
});
});
});
}
dispose() {
......
......@@ -15,7 +15,7 @@ import Event from 'vs/base/common/event';
import { ActionItem, IActionItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IExtension, ExtensionState, IExtensionsWorkbenchService, VIEWLET_ID, IExtensionsViewlet, ConfigurationKey } from 'vs/workbench/parts/extensions/common/extensions';
import { IExtension, ExtensionState, IExtensionsWorkbenchService, VIEWLET_ID, IExtensionsViewlet } from 'vs/workbench/parts/extensions/common/extensions';
import { ExtensionsConfigurationInitialContent } from 'vs/workbench/parts/extensions/common/extensionsFileTemplate';
import { LocalExtensionType, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
......@@ -1092,7 +1092,7 @@ export class ConfigureWorkspaceRecommendedExtensionsAction extends Action {
}
private getOrCreateExtensionsFile(): TPromise<{ created: boolean, extensionsFileResource: URI }> {
const extensionsFileResource = URI.file(paths.join(this.contextService.getWorkspace().resource.fsPath, '.vscode', `${ConfigurationKey}.json`));
const extensionsFileResource = URI.file(paths.join(this.contextService.getWorkspace().resource.fsPath, '.vscode', 'extensions.json'));
return this.fileService.resolveContent(extensionsFileResource).then(content => {
return { created: false, extensionsFileResource };
......
......@@ -81,5 +81,4 @@ export const ConfigurationKey = 'extensions';
export interface IExtensionsConfiguration {
autoUpdate: boolean;
recommendations: string[];
}
\ No newline at end of file
......@@ -302,17 +302,18 @@ export class ExtensionsViewlet extends Viewlet implements IExtensionsViewlet {
private getWorkspaceRecommendationsModel(query: Query, options: IQueryOptions): TPromise<IPagedModel<IExtension>> {
const value = query.value.replace(/@recommended:workspace/g, '').trim().toLowerCase();
const names = this.tipsService.getWorkspaceRecommendations()
.filter(name => name.toLowerCase().indexOf(value) > -1);
return this.tipsService.getWorkspaceRecommendations()
.then(recommendations => {
const names = recommendations.filter(name => name.toLowerCase().indexOf(value) > -1);
this.telemetryService.publicLog('extensionWorkspaceRecommendations:open', { count: names.length });
this.telemetryService.publicLog('extensionWorkspaceRecommendations:open', { count: names.length });
if (!names.length) {
return TPromise.as(new PagedModel([]));
}
if (!names.length) {
return TPromise.as(new PagedModel([]));
}
return this.extensionsWorkbenchService.queryGallery(assign(options, { names, pageSize: names.length }))
.then(result => new PagedModel(result));
return this.extensionsWorkbenchService.queryGallery(assign(options, { names, pageSize: names.length }))
.then(result => new PagedModel(result));
});
}
private openExtension(extension: IExtension): void {
......
......@@ -40,8 +40,7 @@ export interface IWorkspaceConfigurationKeys extends IConfigurationKeys {
export const WORKSPACE_STANDALONE_CONFIGURATIONS = {
'tasks': `${WORKSPACE_CONFIG_FOLDER_DEFAULT_NAME}/tasks.json`,
'launch': `${WORKSPACE_CONFIG_FOLDER_DEFAULT_NAME}/launch.json`,
'extensions': `${WORKSPACE_CONFIG_FOLDER_DEFAULT_NAME}/extensions.json`
'launch': `${WORKSPACE_CONFIG_FOLDER_DEFAULT_NAME}/launch.json`
};
export interface WorkspaceConfigurationNode {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册