diff --git a/src/vs/workbench/api/electron-browser/mainThreadSCM.ts b/src/vs/workbench/api/electron-browser/mainThreadSCM.ts index f08747986cd..685f6242f9c 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadSCM.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadSCM.ts @@ -62,6 +62,10 @@ class MainThreadSCMResource implements ISCMResource { class MainThreadSCMProvider implements ISCMProvider { + private static ID_HANDLE = 0; + private _id = `scm${MainThreadSCMProvider.ID_HANDLE++}`; + get id(): string { return this._id; } + private _groups: MainThreadSCMResourceGroup[] = []; private _groupsByHandle: { [handle: number]: MainThreadSCMResourceGroup; } = Object.create(null); @@ -77,7 +81,7 @@ class MainThreadSCMProvider implements ISCMProvider { get handle(): number { return this._handle; } get label(): string { return this._label; } - get id(): string { return this._id; } + get contextValue(): string { return this._contextValue; } get commitTemplate(): string | undefined { return this.features.commitTemplate; } get acceptInputCommand(): Command | undefined { return this.features.acceptInputCommand; } @@ -92,7 +96,7 @@ class MainThreadSCMProvider implements ISCMProvider { constructor( private proxy: ExtHostSCMShape, private _handle: number, - private _id: string, + private _contextValue: string, private _label: string, @ISCMService scmService: ISCMService, @ICommandService private commandService: ICommandService diff --git a/src/vs/workbench/parts/scm/electron-browser/scmMenus.ts b/src/vs/workbench/parts/scm/electron-browser/scmMenus.ts index 3e1850b0dc8..c22ee5b75e8 100644 --- a/src/vs/workbench/parts/scm/electron-browser/scmMenus.ts +++ b/src/vs/workbench/parts/scm/electron-browser/scmMenus.ts @@ -34,7 +34,7 @@ export class SCMMenus implements IDisposable { ) { this.contextKeyService = contextKeyService.createScoped(); const scmProviderKey = this.contextKeyService.createKey('scmProvider', void 0); - scmProviderKey.set(provider.id); + scmProviderKey.set(provider.contextValue); this.titleMenu = this.menuService.createMenu(MenuId.SCMTitle, this.contextKeyService); this.disposables.push(this.titleMenu); diff --git a/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts b/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts index 1b84110a573..a7c1eb4f16a 100644 --- a/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts +++ b/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts @@ -11,7 +11,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { chain } from 'vs/base/common/event'; import { memoize } from 'vs/base/common/decorators'; import { onUnexpectedError } from 'vs/base/common/errors'; -import { IDisposable, dispose, empty as EmptyDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { Builder } from 'vs/base/browser/builder'; import { ComposedViewsViewlet, CollapsibleView, IViewletViewOptions, IView, IViewOptions } from 'vs/workbench/parts/views/browser/views'; import { append, $, toggleClass } from 'vs/base/browser/dom'; @@ -68,10 +68,10 @@ function identityProvider(r: ISCMResourceGroup | ISCMResource): string { if (isSCMResource(r)) { const group = r.resourceGroup; const provider = group.provider; - return `${provider.id}/${group.id}/${r.sourceUri.toString()}`; + return `${provider.contextValue}/${group.id}/${r.sourceUri.toString()}`; } else { const provider = r.provider; - return `${provider.id}/${r.id}`; + return `${provider.contextValue}/${r.id}`; } } @@ -226,12 +226,12 @@ function resourceSorter(a: ISCMResource, b: ISCMResource): number { class SourceControlViewDescriptor implements IViewDescriptor { get provider(): ISCMProvider { return this._provider; } - get id(): string { return this._id; } + get id(): string { return this._provider.id; } get name(): string { return this._provider.label; } get ctor(): any { return null; } get location(): ViewLocation { return ViewLocation.SCM; } - constructor(private _id: string, private _provider: ISCMProvider) { + constructor(private _provider: ISCMProvider) { } } @@ -402,9 +402,7 @@ export class SCMViewlet extends ComposedViewsViewlet { // private inputBoxContainer: HTMLElement; // private inputBox: InputBox; - private providerIdHandle = 0; - private providerIds = new Map(); - private providerChangeDisposable: IDisposable = EmptyDisposable; + // private providers = new Map(); private disposables: IDisposable[] = []; constructor( @@ -429,59 +427,43 @@ export class SCMViewlet extends ComposedViewsViewlet { telemetryService, storageService, instantiationService, themeService, contextService, contextKeyService, contextMenuService, extensionService); } - private onDidProvidersChange(): void { - this.providerChangeDisposable.dispose(); - // this.activeProvider = activeProvider; - - const providers = this.scmService.providers; - - if (providers.length === 0) { - return; - } - - const result = providers.map(provider => { - let id = this.providerIds.get(provider); - - if (!id) { - id = `scm${this.providerIdHandle++}`; - this.providerIds.set(provider, id); - } - - const view = new SourceControlViewDescriptor(id, provider); - - return { id, provider, view }; - }); - - // console.log(provider.label); - - ViewsRegistry.registerViews(result.map(r => r.view)); - this.providerChangeDisposable = toDisposable(() => ViewsRegistry.deregisterViews(result.map(r => r.id), ViewLocation.SCM)); - - // if (activeProvider) { - // const disposables = []; - - // // if (activeProvider.onDidChangeCommitTemplate) { - // // disposables.push(activeProvider.onDidChangeCommitTemplate(this.updateInputBox, this)); - // // } - - // const id = activeProvider.id; - // ViewsRegistry.registerViews([new SourceControlViewDescriptor(activeProvider)]); - - // disposables.push({ - // dispose: () => { - // ViewsRegistry.deregisterViews([id], ViewLocation.SCM); - // } - // }); - - // this.providerChangeDisposable = combinedDisposable(disposables); - // } else { - // this.providerChangeDisposable = EmptyDisposable; - // } - - // this.updateInputBox(); - // this.updateTitleArea(); + private onDidAddProvider(provider: ISCMProvider): void { + const view = new SourceControlViewDescriptor(provider); + ViewsRegistry.registerViews([view]); } + private onDidRemoveProvider(provider: ISCMProvider): void { + ViewsRegistry.deregisterViews([provider.id], ViewLocation.SCM); + } + + // private onDidProvidersChange(): void { + // this.activeProvider = activeProvider; + + // if (activeProvider) { + // const disposables = []; + + // // if (activeProvider.onDidChangeCommitTemplate) { + // // disposables.push(activeProvider.onDidChangeCommitTemplate(this.updateInputBox, this)); + // // } + + // const id = activeProvider.id; + // ViewsRegistry.registerViews([new SourceControlViewDescriptor(activeProvider)]); + + // disposables.push({ + // dispose: () => { + // ViewsRegistry.deregisterViews([id], ViewLocation.SCM); + // } + // }); + + // this.providerChangeDisposable = combinedDisposable(disposables); + // } else { + // this.providerChangeDisposable = EmptyDisposable; + // } + + // this.updateInputBox(); + // this.updateTitleArea(); + // } + async create(parent: Builder): TPromise { await super.create(parent); @@ -507,9 +489,9 @@ export class SCMViewlet extends ComposedViewsViewlet { // .filter(e => e.equals(KeyMod.CtrlCmd | KeyCode.Enter) || e.equals(KeyMod.CtrlCmd | KeyCode.KEY_S)) // .on(this.onDidAcceptInput, this, this.disposables); - - this.onDidProvidersChange(); - this.scmService.onDidChangeProviders(this.onDidProvidersChange, this, this.disposables); + this.scmService.onDidAddProvider(this.onDidAddProvider, this, this.disposables); + this.scmService.onDidRemoveProvider(this.onDidRemoveProvider, this, this.disposables); + this.scmService.providers.forEach(p => this.onDidAddProvider(p)); // this.themeService.onThemeChange(this.update, this, this.disposables); // return TPromise.as(null); diff --git a/src/vs/workbench/services/scm/common/scm.ts b/src/vs/workbench/services/scm/common/scm.ts index 116e7e5764f..66cc07504cc 100644 --- a/src/vs/workbench/services/scm/common/scm.ts +++ b/src/vs/workbench/services/scm/common/scm.ts @@ -44,6 +44,7 @@ export interface ISCMResourceGroup { export interface ISCMProvider extends IDisposable { readonly label: string; readonly id: string; + readonly contextValue: string; readonly resources: ISCMResourceGroup[]; readonly onDidChange: Event; readonly count?: number; @@ -63,10 +64,9 @@ export interface ISCMInput { export interface ISCMService { readonly _serviceBrand: any; + readonly onDidAddProvider: Event; + readonly onDidRemoveProvider: Event; readonly onDidChangeProvider: Event; - - // TODO@joao fix name - readonly onDidChangeProviders: Event; readonly providers: ISCMProvider[]; readonly input: ISCMInput; activeProvider: ISCMProvider | undefined; diff --git a/src/vs/workbench/services/scm/common/scmService.ts b/src/vs/workbench/services/scm/common/scmService.ts index 7e02c3a6626..5313e3e0273 100644 --- a/src/vs/workbench/services/scm/common/scmService.ts +++ b/src/vs/workbench/services/scm/common/scmService.ts @@ -45,14 +45,18 @@ export class SCMService implements ISCMService { set activeProvider(provider: ISCMProvider | undefined) { this.setActiveSCMProvider(provider); - this.storageService.store(DefaultSCMProviderIdStorageKey, provider.id, StorageScope.WORKSPACE); + this.storageService.store(DefaultSCMProviderIdStorageKey, provider.contextValue, StorageScope.WORKSPACE); } + private _providerIds = new Set(); private _providers: ISCMProvider[] = []; get providers(): ISCMProvider[] { return [...this._providers]; } - private _onDidChangeProviders = new Emitter(); - get onDidChangeProviders(): Event { return this._onDidChangeProviders.event; } + private _onDidAddProvider = new Emitter(); + get onDidAddProvider(): Event { return this._onDidAddProvider.event; } + + private _onDidRemoveProvider = new Emitter(); + get onDidRemoveProvider(): Event { return this._onDidRemoveProvider.event; } private _onDidChangeProvider = new Emitter(); get onDidChangeProvider(): Event { return this._onDidChangeProvider.event; } @@ -86,15 +90,20 @@ export class SCMService implements ISCMService { } registerSCMProvider(provider: ISCMProvider): IDisposable { + if (this._providerIds.has(provider.id)) { + throw new Error(`SCM Provider ${provider.id} already exists.`); + } + + this._providerIds.add(provider.id); this._providers.push(provider); const defaultProviderId = this.storageService.get(DefaultSCMProviderIdStorageKey, StorageScope.WORKSPACE); - if (this._providers.length === 1 || defaultProviderId === provider.id) { + if (this._providers.length === 1 || defaultProviderId === provider.contextValue) { this.setActiveSCMProvider(provider); } - this._onDidChangeProviders.fire(); + this._onDidAddProvider.fire(provider); return toDisposable(() => { const index = this._providers.indexOf(provider); @@ -103,13 +112,14 @@ export class SCMService implements ISCMService { return; } + this._providerIds.delete(provider.id); this._providers.splice(index, 1); if (this.activeProvider === provider) { this.activeProvider = this._providers[0]; } - this._onDidChangeProviders.fire(); + this._onDidRemoveProvider.fire(provider); }); }