From ffda3a18cc91411bd11396b62396f7ccc5d04388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Wed, 1 Jul 2020 10:51:55 +0200 Subject: [PATCH] fixes #100183 --- extensions/git/src/api/extension.ts | 13 ++++++--- extensions/git/src/util.ts | 12 --------- extensions/github/src/commands.ts | 7 ++--- extensions/github/src/extension.ts | 42 ++++++++++++++++++++--------- extensions/github/src/util.ts | 24 +++++++++++++++++ 5 files changed, 67 insertions(+), 31 deletions(-) create mode 100644 extensions/github/src/util.ts diff --git a/extensions/git/src/api/extension.ts b/extensions/git/src/api/extension.ts index 8d7dc611e62..f7598fe2f8c 100644 --- a/extensions/git/src/api/extension.ts +++ b/extensions/git/src/api/extension.ts @@ -7,7 +7,6 @@ import { Model } from '../model'; import { GitExtension, Repository, API } from './git'; import { ApiRepository, ApiImpl } from './api1'; import { Event, EventEmitter } from 'vscode'; -import { latchEvent } from '../util'; export function deprecated(_target: any, key: string, descriptor: any): void { if (typeof descriptor.value !== 'function') { @@ -26,14 +25,20 @@ export class GitExtensionImpl implements GitExtension { enabled: boolean = false; private _onDidChangeEnablement = new EventEmitter(); - readonly onDidChangeEnablement: Event = latchEvent(this._onDidChangeEnablement.event); + readonly onDidChangeEnablement: Event = this._onDidChangeEnablement.event; private _model: Model | undefined = undefined; set model(model: Model | undefined) { this._model = model; - this.enabled = !!model; + const enabled = !!model; + + if (this.enabled === enabled) { + return; + } + + this.enabled = enabled; this._onDidChangeEnablement.fire(this.enabled); } @@ -73,4 +78,4 @@ export class GitExtensionImpl implements GitExtension { return new ApiImpl(this._model); } -} \ No newline at end of file +} diff --git a/extensions/git/src/util.ts b/extensions/git/src/util.ts index e2ac91ebb19..fb3519e2b5a 100644 --- a/extensions/git/src/util.ts +++ b/extensions/git/src/util.ts @@ -44,18 +44,6 @@ export function filterEvent(event: Event, filter: (e: T) => boolean): Even return (listener: (e: T) => any, thisArgs?: any, disposables?: Disposable[]) => event(e => filter(e) && listener.call(thisArgs, e), null, disposables); } -export function latchEvent(event: Event): Event { - let firstCall = true; - let cache: T; - - return filterEvent(event, value => { - let shouldEmit = firstCall || value !== cache; - firstCall = false; - cache = value; - return shouldEmit; - }); -} - export function anyEvent(...events: Event[]): Event { return (listener: (e: T) => any, thisArgs?: any, disposables?: Disposable[]) => { const result = combinedDisposable(events.map(event => event(i => listener.call(thisArgs, i)))); diff --git a/extensions/github/src/commands.ts b/extensions/github/src/commands.ts index a3f0903615f..dad2982533c 100644 --- a/extensions/github/src/commands.ts +++ b/extensions/github/src/commands.ts @@ -6,9 +6,10 @@ import * as vscode from 'vscode'; import { API as GitAPI } from './typings/git'; import { publishRepository } from './publish'; +import { combinedDisposable } from './util'; -export function registerCommands(gitAPI: GitAPI): vscode.Disposable[] { - const disposables = []; +export function registerCommands(gitAPI: GitAPI): vscode.Disposable { + const disposables: vscode.Disposable[] = []; disposables.push(vscode.commands.registerCommand('github.publish', async () => { try { @@ -18,5 +19,5 @@ export function registerCommands(gitAPI: GitAPI): vscode.Disposable[] { } })); - return disposables; + return combinedDisposable(disposables); } diff --git a/extensions/github/src/extension.ts b/extensions/github/src/extension.ts index 51bb15e01fc..1d562a98c1f 100644 --- a/extensions/github/src/extension.ts +++ b/extensions/github/src/extension.ts @@ -3,23 +3,41 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as vscode from 'vscode'; +import { Disposable, ExtensionContext, extensions } from 'vscode'; import { GithubRemoteSourceProvider } from './remoteSourceProvider'; import { GitExtension } from './typings/git'; import { registerCommands } from './commands'; import { GithubCredentialProviderManager } from './credentialProvider'; +import { dispose, combinedDisposable } from './util'; -export async function activate(context: vscode.ExtensionContext) { - const gitExtension = vscode.extensions.getExtension('vscode.git')!.exports; +export function activate(context: ExtensionContext): void { + const disposables = new Set(); + context.subscriptions.push(combinedDisposable(disposables)); - try { - const gitAPI = gitExtension.getAPI(1); + const init = () => { + try { + const gitAPI = gitExtension.getAPI(1); - context.subscriptions.push(...registerCommands(gitAPI)); - context.subscriptions.push(gitAPI.registerRemoteSourceProvider(new GithubRemoteSourceProvider(gitAPI))); - context.subscriptions.push(new GithubCredentialProviderManager(gitAPI)); - } catch (err) { - console.error('Could not initialize GitHub extension'); - console.warn(err); - } + disposables.add(registerCommands(gitAPI)); + disposables.add(gitAPI.registerRemoteSourceProvider(new GithubRemoteSourceProvider(gitAPI))); + disposables.add(new GithubCredentialProviderManager(gitAPI)); + } catch (err) { + console.error('Could not initialize GitHub extension'); + console.warn(err); + } + }; + + const onDidChangeGitExtensionEnablement = (enabled: boolean) => { + if (!enabled) { + dispose(disposables); + disposables.clear(); + } else { + init(); + } + }; + + + const gitExtension = extensions.getExtension('vscode.git')!.exports; + context.subscriptions.push(gitExtension.onDidChangeEnablement(onDidChangeGitExtensionEnablement)); + onDidChangeGitExtensionEnablement(gitExtension.enabled); } diff --git a/extensions/github/src/util.ts b/extensions/github/src/util.ts new file mode 100644 index 00000000000..60badd28c84 --- /dev/null +++ b/extensions/github/src/util.ts @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; + +export function dispose(arg: vscode.Disposable | Iterable): void { + if (arg instanceof vscode.Disposable) { + arg.dispose(); + } else { + for (const disposable of arg) { + disposable.dispose(); + } + } +} + +export function combinedDisposable(disposables: Iterable): vscode.Disposable { + return { + dispose() { + dispose(disposables); + } + }; +}