diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 7f06347070389..c6741f379541d 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -256,6 +256,19 @@ declare module 'vscode' { //#endregion + //#region scm + export namespace scm { + /** + * The currently active [source control](#SourceControl). + */ + export let activeSourceControl: SourceControl | undefined; + /** + * An [event](#Event) which fires when the active [source control](#SourceControl) has changed. + */ + export const onDidChangeActiveSourceControl: Event; + } + //#endregion + //#region Comments /** * Comments provider related APIs are still in early stages, they may be changed significantly during our API experiments. diff --git a/src/vs/workbench/api/electron-browser/mainThreadSCM.ts b/src/vs/workbench/api/electron-browser/mainThreadSCM.ts index 6bd43da77dc2a..584505b14d73f 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadSCM.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadSCM.ts @@ -263,6 +263,8 @@ export class MainThreadSCM implements MainThreadSCMShape { private _proxy: ExtHostSCMShape; private _repositories: { [handle: number]: ISCMRepository; } = Object.create(null); private _inputDisposables: { [handle: number]: IDisposable; } = Object.create(null); + private _focusDisposables: { [handle: number]: IDisposable; } = Object.create(null); + private _focusedRepository: ISCMRepository | undefined; private _disposables: IDisposable[] = []; constructor( @@ -281,6 +283,10 @@ export class MainThreadSCM implements MainThreadSCMShape { .forEach(id => this._inputDisposables[id].dispose()); this._inputDisposables = Object.create(null); + Object.keys(this._focusDisposables) + .forEach(id => this._focusDisposables[id].dispose()); + this._focusDisposables = Object.create(null); + this._disposables = dispose(this._disposables); } @@ -289,8 +295,21 @@ export class MainThreadSCM implements MainThreadSCMShape { const repository = this.scmService.registerSCMProvider(provider); this._repositories[handle] = repository; + if (!this._focusedRepository) { + this._focusedRepository = repository; + this._proxy.$acceptActiveSourceControlChange(handle); + } + const inputDisposable = repository.input.onDidChange(value => this._proxy.$onInputBoxValueChange(handle, value)); this._inputDisposables[handle] = inputDisposable; + + const focusDisposable = repository.onDidFocus(_ => this.onDidFocus(handle, repository)); + this._focusDisposables[handle] = focusDisposable; + } + + onDidFocus(handle: number, repository: ISCMRepository) { + this._focusedRepository = repository; + this._proxy.$acceptActiveSourceControlChange(handle); } $updateSourceControl(handle: number, features: SCMProviderFeatures): void { @@ -314,6 +333,9 @@ export class MainThreadSCM implements MainThreadSCMShape { this._inputDisposables[handle].dispose(); delete this._inputDisposables[handle]; + this._focusDisposables[handle].dispose(); + delete this._focusDisposables[handle]; + repository.dispose(); delete this._repositories[handle]; } diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 50fe2efe1f6d1..f05ac0a73707f 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -566,6 +566,12 @@ export function createApiFactory( get inputBox() { return extHostSCM.getLastInputBox(extension); }, + get activeSourceControl() { + return extHostSCM.activeSourceControl; + }, + get onDidChangeActiveSourceControl() { + return extHostSCM.onDidChangeActiveSourceControl; + }, createSourceControl(id: string, label: string, rootUri?: vscode.Uri) { return extHostSCM.createSourceControl(extension, id, label, rootUri); } diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index dfef440283760..8b4e21ca8cc25 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -782,6 +782,7 @@ export interface ExtHostTerminalServiceShape { export interface ExtHostSCMShape { $provideOriginalResource(sourceControlHandle: number, uri: UriComponents): TPromise; $onInputBoxValueChange(sourceControlHandle: number, value: string): TPromise; + $acceptActiveSourceControlChange(sourceControlHandle: number): TPromise; $executeResourceCommand(sourceControlHandle: number, groupHandle: number, handle: number): TPromise; $validateInput(sourceControlHandle: number, value: string, cursorPosition: number): TPromise<[string, number] | undefined>; } diff --git a/src/vs/workbench/api/node/extHostSCM.ts b/src/vs/workbench/api/node/extHostSCM.ts index b008b72b086f7..a1ee5be3e9da6 100644 --- a/src/vs/workbench/api/node/extHostSCM.ts +++ b/src/vs/workbench/api/node/extHostSCM.ts @@ -467,9 +467,12 @@ export class ExtHostSCM implements ExtHostSCMShape { private _proxy: MainThreadSCMShape; private _sourceControls: Map = new Map(); private _sourceControlsByExtension: Map = new Map(); - - private _onDidChangeActiveProvider = new Emitter(); - get onDidChangeActiveProvider(): Event { return this._onDidChangeActiveProvider.event; } + private _activeSourceControl: vscode.SourceControl | undefined; + get activeSourceControl(): vscode.SourceControl | undefined { + return this._activeSourceControl; + } + private _onDidChangeActiveSourceControl = new Emitter(); + get onDidChangeActiveSourceControl(): Event { return this._onDidChangeActiveSourceControl.event; } constructor( mainContext: IMainContext, @@ -568,6 +571,22 @@ export class ExtHostSCM implements ExtHostSCMShape { return TPromise.as(null); } + $acceptActiveSourceControlChange(sourceControlHandle: number): TPromise { + this.logService.trace('ExtHostSCM#$acceptActiveSourceControlChange', sourceControlHandle); + const sourceControl = this._sourceControls.get(sourceControlHandle); + + if (!sourceControl) { + return TPromise.as(null); + } + + if (this._activeSourceControl !== sourceControl) { + this._activeSourceControl = sourceControl; + this._onDidChangeActiveSourceControl.fire(this.activeSourceControl); + } + + return TPromise.as(null); + } + async $executeResourceCommand(sourceControlHandle: number, groupHandle: number, handle: number): TPromise { this.logService.trace('ExtHostSCM#$executeResourceCommand', sourceControlHandle, groupHandle, handle);