From 296fa84d8de6d63edc8417f9a3af2824118cc797 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 24 Apr 2019 15:51:22 +0200 Subject: [PATCH] Fix Microsoft/vscode-remote/issues/1564 --- .../contrib/extensions/common/extensions.ts | 1 + .../electron-browser/extensionsActions.ts | 28 ++++++++++++------- .../electron-browser/extensionsViews.ts | 11 +++++++- .../node/extensionsWorkbenchService.ts | 20 +++++++------ 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/common/extensions.ts b/src/vs/workbench/contrib/extensions/common/extensions.ts index a66dccc55fe..ec1999a2b32 100644 --- a/src/vs/workbench/contrib/extensions/common/extensions.ts +++ b/src/vs/workbench/contrib/extensions/common/extensions.ts @@ -83,6 +83,7 @@ export interface IExtensionsWorkbenchService { _serviceBrand: any; onChange: Event; local: IExtension[]; + installed: IExtension[]; outdated: IExtension[]; queryLocal(server?: IExtensionManagementServer): Promise; queryGallery(token: CancellationToken): Promise>; diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts index 996e4805fa9..48ccc3f4a43 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts @@ -328,9 +328,9 @@ export class RemoteInstallAction extends ExtensionAction { // Installed User Extension && this.extension && this.extension.local && this.extension.type === ExtensionType.User && this.extension.state === ExtensionState.Installed // Local Workspace Extension - && this.extension.server === this.extensionManagementServerService.localExtensionManagementServer && !isUIExtension(this.extension.local.manifest, this.configurationService) + && this.extension.server === this.extensionManagementServerService.localExtensionManagementServer && (isLanguagePackExtension(this.extension.local.manifest) || !isUIExtension(this.extension.local.manifest, this.configurationService)) // Extension does not exist in remote - && !this.extensionsWorkbenchService.local.some(e => areSameExtensions(e.identifier, this.extension.identifier) && e.server === this.extensionManagementServerService.remoteExtensionManagementServer) + && !this.extensionsWorkbenchService.installed.some(e => areSameExtensions(e.identifier, this.extension.identifier) && e.server === this.extensionManagementServerService.remoteExtensionManagementServer) && this.extensionsWorkbenchService.canInstall(this.extension) ) { this.enabled = true; @@ -406,10 +406,10 @@ export class LocalInstallAction extends ExtensionAction { if (this.environmentService.configuration.remoteAuthority // Installed User Extension && this.extension && this.extension.local && this.extension.type === ExtensionType.User && this.extension.state === ExtensionState.Installed - // Remote UI Extension - && this.extension.server === this.extensionManagementServerService.remoteExtensionManagementServer && isUIExtension(this.extension.local.manifest, this.configurationService) + // Remote UI or Language pack Extension + && this.extension.server === this.extensionManagementServerService.remoteExtensionManagementServer && (isLanguagePackExtension(this.extension.local.manifest) || isUIExtension(this.extension.local.manifest, this.configurationService)) // Extension does not exist in local - && !this.extensionsWorkbenchService.local.some(e => areSameExtensions(e.identifier, this.extension.identifier) && e.server === this.extensionManagementServerService.localExtensionManagementServer) + && !this.extensionsWorkbenchService.installed.some(e => areSameExtensions(e.identifier, this.extension.identifier) && e.server === this.extensionManagementServerService.localExtensionManagementServer) && this.extensionsWorkbenchService.canInstall(this.extension) ) { this.enabled = true; @@ -2660,14 +2660,14 @@ export class DisabledLabelAction extends ExtensionAction { update(): void { this.class = `${DisabledLabelAction.Class} hide`; this.label = ''; - if (this.extension && this.extension.local && isLanguagePackExtension(this.extension.local.manifest)) { - return; - } if (this.warningAction.tooltip) { this.class = DisabledLabelAction.Class; this.label = this.warningAction.tooltip; return; } + if (this.extension && this.extension.local && isLanguagePackExtension(this.extension.local.manifest)) { + return; + } if (this.extension && this.extension.local && this._runningExtensions) { const isEnabled = this.extensionEnablementService.isEnabled(this.extension.local); const isExtensionRunning = this._runningExtensions.some(e => areSameExtensions({ id: e.identifier.value }, this.extension.identifier)); @@ -2728,11 +2728,19 @@ export class SystemDisabledWarningAction extends ExtensionAction { !this._runningExtensions || !this.workbenchEnvironmentService.configuration.remoteAuthority || !this.extensionManagementServerService.remoteExtensionManagementServer || - this.extension.state !== ExtensionState.Installed || - isLanguagePackExtension(this.extension.local.manifest) + this.extension.state !== ExtensionState.Installed ) { return; } + if (isLanguagePackExtension(this.extension.local.manifest)) { + if (!this.extensionsWorkbenchService.installed.some(e => areSameExtensions(e.identifier, this.extension.identifier) && e.server !== this.extension.server)) { + this.class = `${SystemDisabledWarningAction.INFO_CLASS}`; + this.tooltip = this.extension.server === this.extensionManagementServerService.localExtensionManagementServer + ? localize('Install language pack also in remote server', "Install the language pack extension on '{0}' to enable it also there.", this.getServerLabel(this.extensionManagementServerService.remoteExtensionManagementServer)) + : localize('Install language pack also locally', "Install the extension locally to enable it also there."); + } + return; + } const runningExtension = this._runningExtensions.filter(e => areSameExtensions({ id: e.identifier.value }, this.extension.identifier))[0]; const runningExtensionServer = runningExtension ? this.extensionManagementServerService.getExtensionManagementServer(runningExtension.extensionLocation) : null; const localExtension = this.extensionsWorkbenchService.local.filter(e => areSameExtensions(e.identifier, this.extension.identifier))[0]; diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts index 63af197676a..623c29529f2 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts @@ -338,11 +338,20 @@ export class ExtensionsListView extends ViewletPanel { const isE1Running = running1 && this.extensionManagementServerService.getExtensionManagementServer(running1.extensionLocation) === e1.server; const running2 = runningExtensionsById.get(ExtensionIdentifier.toKey(e2.identifier.id)); const isE2Running = running2 && this.extensionManagementServerService.getExtensionManagementServer(running2.extensionLocation) === e2.server; - if ((isE1Running && isE2Running) || (!isE1Running && !isE2Running)) { + if ((isE1Running && isE2Running)) { return e1.displayName.localeCompare(e2.displayName); } const isE1LanguagePackExtension = e1.local && isLanguagePackExtension(e1.local.manifest); const isE2LanguagePackExtension = e2.local && isLanguagePackExtension(e2.local.manifest); + if (!isE1Running && !isE2Running) { + if (isE1LanguagePackExtension) { + return -1; + } + if (isE2LanguagePackExtension) { + return 1; + } + return e1.displayName.localeCompare(e2.displayName); + } if ((isE1Running && isE2LanguagePackExtension) || (isE2Running && isE1LanguagePackExtension)) { return e1.displayName.localeCompare(e2.displayName); } diff --git a/src/vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts index c33c39b2e70..25c72b03649 100644 --- a/src/vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts @@ -34,7 +34,7 @@ import * as resources from 'vs/base/common/resources'; import { CancellationToken } from 'vs/base/common/cancellation'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { IFileService } from 'vs/platform/files/common/files'; -import { IExtensionManifest, ExtensionType, ExtensionIdentifierWithVersion, IExtension as IPlatformExtension } from 'vs/platform/extensions/common/extensions'; +import { IExtensionManifest, ExtensionType, ExtensionIdentifierWithVersion, IExtension as IPlatformExtension, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions'; interface IExtensionStateProvider { (extension: Extension): T; @@ -584,15 +584,19 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension } get local(): IExtension[] { - const result = [...this.localExtensions.local]; - if (!this.remoteExtensions) { - return result; - } - result.push(...this.remoteExtensions.local); + const result = [...this.installed]; const byId = groupByExtension(result, r => r.identifier); return byId.reduce((result, extensions) => { result.push(this.getPrimaryExtension(extensions)); return result; }, []); } + get installed(): IExtension[] { + const result = [...this.localExtensions.local]; + if (this.remoteExtensions) { + result.push(...this.remoteExtensions.local); + } + return result; + } + get outdated(): IExtension[] { const allLocal = [...this.localExtensions.local]; if (this.remoteExtensions) { @@ -812,7 +816,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension } return this.installWithProgress(async () => { - const extensionService = extension.server ? extension.server.extensionManagementService : this.extensionService; + const extensionService = extension.server && extension.local && !isLanguagePackExtension(extension.local.manifest) ? extension.server.extensionManagementService : this.extensionService; await extensionService.installFromGallery(gallery); this.checkAndEnableDisabledDependencies(gallery.identifier); return this.local.filter(local => areSameExtensions(local.identifier, gallery.identifier))[0]; @@ -855,7 +859,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension return Promise.reject(new Error(nls.localize('incompatible', "Unable to install extension '{0}' with version '{1}' as it is not compatible with VS Code.", extension.gallery!.identifier.id, version))); } return this.installWithProgress(async () => { - const extensionService = extension.server ? extension.server.extensionManagementService : this.extensionService; + const extensionService = extension.server && extension.local && !isLanguagePackExtension(extension.local.manifest) ? extension.server.extensionManagementService : this.extensionService; await extensionService.installFromGallery(gallery); if (extension.latestVersion !== version) { this.ignoreAutoUpdate(new ExtensionIdentifierWithVersion(gallery.identifier, version));