提交 6bd9a98c 编写于 作者: J Johannes Rieken

setting 'extensions.showTips' with bells and whistles, nicer eventing in config service

上级 c169d6b0
......@@ -5,6 +5,7 @@
import {createDecorator, ServiceIdentifier} from 'vs/platform/instantiation/common/instantiation';
import {IEventEmitter} from 'vs/base/common/eventEmitter';
import Event from 'vs/base/common/event';
import winjs = require('vs/base/common/winjs.base');
export var IConfigurationService = createDecorator<IConfigurationService>('configurationService');
......@@ -21,7 +22,12 @@ export interface IConfigurationService extends IEventEmitter {
/**
* Returns iff the workspace has configuration or not.
*/
hasWorkspaceConfiguration():boolean;
hasWorkspaceConfiguration(): boolean;
/**
* Event that fires when the configuration changes.
*/
onDidUpdateConfiguration: Event<{ config: any }>
}
export class ConfigurationServiceEventTypes {
......
......@@ -19,6 +19,7 @@ import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
import Files = require('vs/platform/files/common/files');
import {IConfigurationRegistry, Extensions} from './configurationRegistry';
import {Registry} from 'vs/platform/platform';
import Event, {fromEventEmitter} from 'vs/base/common/event';
// ---- service abstract implementation
......@@ -43,6 +44,8 @@ interface ILoadConfigResult {
export abstract class ConfigurationService extends eventEmitter.EventEmitter implements IConfigurationService, lifecycle.IDisposable {
public serviceId = IConfigurationService;
public onDidUpdateConfiguration: Event<{ config: any }>;
protected contextService: IWorkspaceContextService;
protected eventService: IEventService;
protected workspaceSettingsRootFolder: string;
......@@ -67,6 +70,8 @@ export abstract class ConfigurationService extends eventEmitter.EventEmitter imp
unbind();
subscription.dispose();
}
this.onDidUpdateConfiguration = fromEventEmitter(this, ConfigurationServiceEventTypes.UPDATED);
}
protected abstract resolveContents(resource: uri[]): winjs.TPromise<IContent[]>;
......@@ -229,6 +234,10 @@ export class NullConfigurationService extends eventEmitter.EventEmitter implemen
public hasWorkspaceConfiguration(): boolean {
return false;
}
public onDidUpdateConfiguration() {
return { dispose() { } };
}
}
export var nullService = new NullConfigurationService();
......@@ -75,7 +75,7 @@ export class ExtensionTipsService implements IExtensionTipsService {
private _onDidChangeTips: Emitter<IExtension[]> = new Emitter<IExtension[]>();
private _tips: { [id: string]: ExtensionTip } = Object.create(null);
private _toDispose: IDisposable[] = [];
private _disposeOnUpdate: IDisposable[] = [];
private _availableExtensions: Promise<ExtensionMap>;
private _extensionData: Promise<ExtensionData>;
......@@ -83,18 +83,13 @@ export class ExtensionTipsService implements IExtensionTipsService {
@IExtensionsService private _extensionService: IExtensionsService,
@IGalleryService private _galleryService: IGalleryService,
@IModelService private _modelService: IModelService,
@IConfigurationService configurationService: IConfigurationService
@IConfigurationService private _configurationService: IConfigurationService
) {
configurationService.loadConfiguration('extensions').then(value => {
if (value && value.experimentalSuggestions === true) {
this._init();
}
}, onUnexpectedError);
this._updateState();
}
dispose() {
this._toDispose = disposeAll(this._toDispose);
this._disposeOnUpdate = disposeAll(this._disposeOnUpdate);
}
get onDidChangeTips(): Event<IExtension[]> {
......@@ -107,7 +102,26 @@ export class ExtensionTipsService implements IExtensionTipsService {
return tips.map(tip => tip.extension);
}
private _init() {
// --- internals
private _updateState(): void {
// check with configuration service and then GO
this._disposeOnUpdate = disposeAll(this._disposeOnUpdate);
this._tips = Object.create(null);
this._onDidChangeTips.fire(this.tips);
this._configurationService.loadConfiguration('extensions').then(value => {
if (value && value.showTips === true) {
this._init();
}
}, onUnexpectedError);
// listen for config changes
this._configurationService.onDidUpdateConfiguration(this._updateState, this, this._disposeOnUpdate);
}
private _init():void {
if (!this._galleryService.isEnabled()) {
return;
......@@ -122,7 +136,7 @@ export class ExtensionTipsService implements IExtensionTipsService {
this._availableExtensions = this._getAvailableExtensions();
// don't suggest what got installed
this._toDispose.push(this._extensionService.onDidInstallExtension(ext => {
this._disposeOnUpdate.push(this._extensionService.onDidInstallExtension(ext => {
const id = `${ext.publisher}.${ext.name}`;
let change = false;
if (delete this._tips[id]) {
......@@ -139,16 +153,16 @@ export class ExtensionTipsService implements IExtensionTipsService {
// such that files you type have bigger impact on the suggest
// order than those you only look at
const modelListener: { [uri: string]: IDisposable } = Object.create(null);
this._toDispose.push({ dispose() { disposeAll(values(modelListener)) } });
this._disposeOnUpdate.push({ dispose() { disposeAll(values(modelListener)) } });
this._toDispose.push(this._modelService.onModelAdded(model => {
this._disposeOnUpdate.push(this._modelService.onModelAdded(model => {
const uri = model.getAssociatedResource();
this._suggestByResource(uri, ExtensionTipReasons.FileOpened);
modelListener[uri.toString()] = model.addListener2(EventType.ModelContentChanged2,
() => this._suggestByResource(uri, ExtensionTipReasons.FileEdited));
}));
this._toDispose.push(this._modelService.onModelRemoved(model => {
this._disposeOnUpdate.push(this._modelService.onModelRemoved(model => {
const subscription = modelListener[model.getAssociatedResource().toString()];
if (subscription) {
subscription.dispose();
......
......@@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import nls = require('vs/nls');
import platform = require('vs/platform/platform');
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import statusbar = require('vs/workbench/browser/parts/statusbar/statusbar');
......@@ -11,6 +12,7 @@ import { IGalleryService } from 'vs/workbench/parts/extensions/common/extensions
import { GalleryService } from 'vs/workbench/parts/extensions/node/vsoGalleryService';
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
import { ExtensionsWorkbenchExtension } from 'vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension';
import ConfigurationRegistry = require('vs/platform/configuration/common/configurationRegistry');
// Register Gallery Service
registerSingleton(IGalleryService, GalleryService);
......@@ -32,4 +34,17 @@ registerSingleton(IGalleryService, GalleryService);
ExtensionTipsStatusbarItem,
statusbar.StatusbarAlignment.LEFT,
9 /* Low Priority */
));
\ No newline at end of file
));
(<ConfigurationRegistry.IConfigurationRegistry>platform.Registry.as(ConfigurationRegistry.Extensions.Configuration)).registerConfiguration({
id: 'extensions',
type: 'object',
properties: {
'extensions.showTips': {
type: 'boolean',
default: false,
description: nls.localize('extConfig', "Suggest extensions based on changed and open files."),
}
}
});
......@@ -97,6 +97,12 @@ export class ExtensionTipsStatusbarItem implements statusbar.IStatusbarItem {
) {
this._extensionTipsService.onDidChangeTips(tips => {
if (tips.length === 0) {
dom.removeClass(this._domNode, 'active');
return;
}
// check for new tips
let hasNewTips = false;
for (let tip of tips) {
......
......@@ -514,4 +514,8 @@ export class TestConfigurationService extends EventEmitter.EventEmitter implemen
public hasWorkspaceConfiguration():boolean {
return false;
}
public onDidUpdateConfiguration() {
return { dispose() { } };
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册