From 4d4e92713c21d5d7105f08d5a34d654334482bc1 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 26 Jul 2021 15:45:12 +0200 Subject: [PATCH] improve hover messages in remote workspace --- .../extensions/browser/extensionEditor.ts | 10 +++++- .../extensions/browser/extensionsActions.ts | 36 ++++++++++++++----- .../extensionsActions.test.ts | 6 ++-- .../extensionsWorkbenchService.test.ts | 2 +- .../browser/extensionEnablementService.ts | 2 ++ .../extensionEnablementService.test.ts | 4 +-- 6 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index fc6e017d634..09d7f4d95f4 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -470,7 +470,15 @@ export class ExtensionEditor extends EditorPane { const statusIconActionBar = disposables.add(new ActionBar(template.status, { animated: false })); statusIconActionBar.push(extensionStatus, { icon: true, label: false }); } - append(append(template.status, $('.status-text')), renderMarkdown(new MarkdownString(status.message.value, { isTrusted: true, supportThemeIcons: true }))); + append(append(template.status, $('.status-text')), + renderMarkdown(new MarkdownString(status.message.value, { isTrusted: true, supportThemeIcons: true }), { + actionHandler: { + callback: (content) => { + this.openerService.open(content, { allowCommands: true }).catch(onUnexpectedError); + }, + disposeables: disposables + } + })); } }; updateStatus(); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index 379edd41665..054eefb3ec0 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -2018,7 +2018,7 @@ export class ExtensionStatusAction extends ExtensionAction { if (this.extension.gallery.webExtension) { message = new MarkdownString(localize('user disabled', "You have configured the '{0}' extension to be disabled in {1}. To enable it, please open user settings and remove it from `remote.extensionKind` setting.", this.extension.displayName || this.extension.identifier.id, productName)); } else { - message = new MarkdownString(`${localize('not web tooltip', "The '{0}' extension is not available in {1}", this.extension.displayName || this.extension.identifier.id, productName)} ([${localize('learn more', "learn more")}](https://aka.ms/vscode-remote-codespaces#_why-is-an-extension-not-installable-in-the-browser)).`); + message = new MarkdownString(`${localize('not web tooltip', "The '{0}' extension is not available in {1}.", this.extension.displayName || this.extension.identifier.id, productName)} [${localize('learn more', "Learn More")}](https://aka.ms/vscode-remote-codespaces#_why-is-an-extension-not-installable-in-the-browser)`); } this.updateStatus({ icon: infoIcon, message }, true); return; @@ -2086,14 +2086,32 @@ export class ExtensionStatusAction extends ExtensionAction { // Extension is disabled by extension kind if (this.extension.enablementState === EnablementState.DisabledByExtensionKind) { if (!this.extensionsWorkbenchService.installed.some(e => areSameExtensions(e.identifier, this.extension!.identifier) && e.server !== this.extension!.server)) { - const server = this.extensionManagementServerService.localExtensionManagementServer === this.extension.server ? this.extensionManagementServerService.remoteExtensionManagementServer : this.extensionManagementServerService.localExtensionManagementServer; let message; - if (server) { - message = new MarkdownString(localize('Install in other server to enable', "Install the extension on '{0}' to enable.", server.label)); - } else { - message = new MarkdownString(localize('disabled because of extension kind', "This extension has defined that it cannot run on the remote server")); + // Extension on Local Server + if (this.extensionManagementServerService.localExtensionManagementServer === this.extension.server) { + if (this.extensionManifestPropertiesService.prefersExecuteOnWorkspace(this.extension.local.manifest)) { + if (this.extensionManagementServerService.remoteExtensionManagementServer) { + message = new MarkdownString(`${localize('Install in remote server to enable', "This extension is disabled in this workspace because it is defined to run in the Remote Extension Host. Please install the extension in '{0}' to enable.", this.extensionManagementServerService.remoteExtensionManagementServer.label)} [${localize('learn more', "Learn More")}](https://aka.ms/vscode-remote/developing-extensions/architecture)`); + } + } + } + // Extension on Remote Server + else if (this.extensionManagementServerService.remoteExtensionManagementServer === this.extension.server) { + if (this.extensionManifestPropertiesService.prefersExecuteOnUI(this.extension.local.manifest)) { + if (this.extensionManagementServerService.localExtensionManagementServer) { + message = new MarkdownString(`${localize('Install in local server to enable', "This extension is disabled in this workspace because it is defined to run in the Local Extension Host. Please install the extension locally to enable.", this.extensionManagementServerService.remoteExtensionManagementServer.label)} [${localize('learn more', "Learn More")}](https://aka.ms/vscode-remote/developing-extensions/architecture)`); + } else if (isWeb) { + message = new MarkdownString(`${localize('Cannot be enabled', "This extension is disabled because it is not supported in {0}.", localize({ key: 'vscode web', comment: ['VS Code Web is the name of the product'] }, "VS Code Web"))} [${localize('learn more', "Learn More")}](https://aka.ms/vscode-remote/developing-extensions/architecture)`); + } + } + } + // Extension on Web Server + else if (this.extensionManagementServerService.webExtensionManagementServer === this.extension.server) { + message = new MarkdownString(`${localize('Cannot be enabled', "This extension is disabled because it is not supported in {0}.", localize({ key: 'vscode web', comment: ['VS Code Web is the name of the product'] }, "VS Code Web"))} [${localize('learn more', "Learn More")}](https://aka.ms/vscode-remote/developing-extensions/architecture)`); + } + if (message) { + this.updateStatus({ icon: warningIcon, message }, true); } - this.updateStatus({ icon: warningIcon, message }, true); return; } } @@ -2114,14 +2132,14 @@ export class ExtensionStatusAction extends ExtensionAction { const runningExtensionServer = runningExtension ? this.extensionManagementServerService.getExtensionManagementServer(toExtension(runningExtension)) : null; if (this.extension.server === this.extensionManagementServerService.localExtensionManagementServer && runningExtensionServer === this.extensionManagementServerService.remoteExtensionManagementServer) { if (this.extensionManifestPropertiesService.prefersExecuteOnWorkspace(this.extension.local!.manifest)) { - this.updateStatus({ icon: infoIcon, message: new MarkdownString(localize('disabled locally', "Extension is enabled on '{0}' and disabled locally.", this.extensionManagementServerService.remoteExtensionManagementServer.label)) }, true); + this.updateStatus({ icon: infoIcon, message: new MarkdownString(`${localize('enabled remotely', "This extension is enabled in the Remote Extension Host because it prefers to run there.")} [${localize('learn more', "Learn More")}](https://aka.ms/vscode-remote/developing-extensions/architecture)`) }, true); } return; } if (this.extension.server === this.extensionManagementServerService.remoteExtensionManagementServer && runningExtensionServer === this.extensionManagementServerService.localExtensionManagementServer) { if (this.extensionManifestPropertiesService.prefersExecuteOnUI(this.extension.local!.manifest)) { - this.updateStatus({ icon: infoIcon, message: new MarkdownString(localize('disabled remotely', "Extension is enabled locally and disabled on '{0}'.", this.extensionManagementServerService.remoteExtensionManagementServer.label)) }, true); + this.updateStatus({ icon: infoIcon, message: new MarkdownString(`${localize('enabled locally', "This extension is enabled in the Local Extension Host because it prefers to run there.")} [${localize('learn more', "Learn More")}](https://aka.ms/vscode-remote/developing-extensions/architecture)`) }, true); } return; } diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts index 1ef04955b3c..26ab102d984 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts @@ -1606,7 +1606,8 @@ suite('RemoteInstallAction', () => { const workbenchService: IExtensionsWorkbenchService = instantiationService.createInstance(ExtensionsWorkbenchService); instantiationService.set(IExtensionsWorkbenchService, workbenchService); - await instantiationService.get(IWorkbenchExtensionEnablementService).setEnablement([localWorkspaceExtension], EnablementState.DisabledGlobally); + const remoteWorkspaceExtension = aLocalExtension('a', { extensionKind: ['workspace'] }, { location: URI.file(`pub.a`).with({ scheme: Schemas.vscodeRemote }) }); + await instantiationService.get(IWorkbenchExtensionEnablementService).setEnablement([remoteWorkspaceExtension], EnablementState.DisabledGlobally); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(aGalleryExtension('a', { identifier: localWorkspaceExtension.identifier }))); const testObject: ExtensionsActions.InstallAction = instantiationService.createInstance(ExtensionsActions.RemoteInstallAction, false); instantiationService.createInstance(ExtensionContainers, [testObject]); @@ -2054,7 +2055,8 @@ suite('LocalInstallAction', () => { const workbenchService: IExtensionsWorkbenchService = instantiationService.createInstance(ExtensionsWorkbenchService); instantiationService.set(IExtensionsWorkbenchService, workbenchService); - await instantiationService.get(IWorkbenchExtensionEnablementService).setEnablement([remoteUIExtension], EnablementState.DisabledGlobally); + const localUIExtension = aLocalExtension('a', { extensionKind: ['ui'] }, { location: URI.file(`pub.a`) }); + await instantiationService.get(IWorkbenchExtensionEnablementService).setEnablement([localUIExtension], EnablementState.DisabledGlobally); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(aGalleryExtension('a', { identifier: remoteUIExtension.identifier }))); const testObject: ExtensionsActions.InstallAction = instantiationService.createInstance(ExtensionsActions.LocalInstallAction); instantiationService.createInstance(ExtensionContainers, [testObject]); diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts index dc4b8a46d29..fbbf5a174b0 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts @@ -1298,7 +1298,7 @@ suite('ExtensionsWorkbenchServiceTest', () => { const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([remoteExtension])); instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService); instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService)); - await instantiationService.get(IWorkbenchExtensionEnablementService).setEnablement([localExtension], EnablementState.DisabledGlobally); + await instantiationService.get(IWorkbenchExtensionEnablementService).setEnablement([remoteExtension], EnablementState.DisabledGlobally); testObject = await aWorkbenchService(); const actual = await testObject.queryLocal(); diff --git a/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts b/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts index 93f5bedd714..c284d7e3608 100644 --- a/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts +++ b/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts @@ -152,6 +152,8 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench throw new Error(localize('cannot change disablement environment', "Cannot change enablement of {0} extension because it is disabled in environment", extension.manifest.displayName || extension.identifier.id)); case EnablementState.DisabledByVirtualWorkspace: throw new Error(localize('cannot change enablement virtual workspace', "Cannot change enablement of {0} extension because it does not support virtual workspaces", extension.manifest.displayName || extension.identifier.id)); + case EnablementState.DisabledByExtensionKind: + throw new Error(localize('cannot change enablement extension kind', "Cannot change enablement of {0} extension because of its extension kind", extension.manifest.displayName || extension.identifier.id)); case EnablementState.DisabledByExtensionDependency: if (donotCheckDependencies) { break; diff --git a/src/vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test.ts b/src/vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test.ts index 258594b0dea..4e265c3a881 100644 --- a/src/vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test.ts +++ b/src/vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test.ts @@ -689,7 +689,7 @@ suite('ExtensionEnablementService Test', () => { instantiationService.stub(IExtensionManagementServerService, aMultiExtensionManagementServerService(instantiationService)); const localWorkspaceExtension = aLocalExtension2('pub.a', { extensionKind: ['workspace'] }, { location: URI.file(`pub.a`) }); testObject = new TestExtensionEnablementService(instantiationService); - assert.strictEqual(testObject.canChangeEnablement(localWorkspaceExtension), true); + assert.strictEqual(testObject.canChangeEnablement(localWorkspaceExtension), false); }); test('test canChangeEnablement return true for local ui extension', () => { @@ -735,7 +735,7 @@ suite('ExtensionEnablementService Test', () => { instantiationService.stub(IExtensionManagementServerService, aMultiExtensionManagementServerService(instantiationService)); const localWorkspaceExtension = aLocalExtension2('pub.a', { extensionKind: ['ui'] }, { location: URI.file(`pub.a`).with({ scheme: Schemas.vscodeRemote }) }); testObject = new TestExtensionEnablementService(instantiationService); - assert.strictEqual(testObject.canChangeEnablement(localWorkspaceExtension), true); + assert.strictEqual(testObject.canChangeEnablement(localWorkspaceExtension), false); }); test('test canChangeEnablement return true for remote workspace extension', () => {