setting 'extensions.showTips' with bells and whistles, nicer eventing in config service
This commit is contained in:
parent
c169d6b0b3
commit
6bd9a98c8c
6 changed files with 70 additions and 16 deletions
|
@ -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 */
|
||||
));
|
||||
));
|
||||
|
||||
|
||||
(<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() { } };
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue