diff --git a/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts b/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts index 899cbf7f5249b675fa19b670e24e3dd2934aa33c..48d1cd513b4a63e5a6a9d29ee100c31763a7d567 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts @@ -8,12 +8,15 @@ import * as platform from 'vs/base/common/platform'; import { EDITOR_FONT_DEFAULTS, IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; -import { ITerminalConfiguration, ITerminalFont, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, TERMINAL_CONFIG_SECTION, DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, MINIMUM_LETTER_SPACING, LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalConfiguration, ITerminalFont, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, TERMINAL_CONFIG_SECTION, DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, MINIMUM_LETTER_SPACING, LinuxDistro, IShellLaunchConfig } from 'vs/workbench/contrib/terminal/common/terminal'; import Severity from 'vs/base/common/severity'; import { Terminal as XTermTerminal } from 'xterm'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IBrowserTerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminal'; import { Emitter, Event } from 'vs/base/common/event'; +import { basename } from 'vs/base/common/path'; +import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { ExtensionType } from 'vs/platform/extensions/common/extensions'; const MINIMUM_FONT_SIZE = 6; const MAXIMUM_FONT_SIZE = 25; @@ -35,7 +38,7 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper { public constructor( private readonly _linuxDistro: LinuxDistro, @IConfigurationService private readonly _configurationService: IConfigurationService, - @IConfigurationService private readonly _workspaceConfigurationService: IConfigurationService, + @IExtensionManagementService private readonly _extensionManagementService: IExtensionManagementService, @INotificationService private readonly _notificationService: INotificationService, @IStorageService private readonly _storageService: IStorageService ) { @@ -174,9 +177,9 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper { public checkWorkspaceShellPermissions(osOverride: platform.OperatingSystem = platform.OS): boolean { // Check whether there is a workspace setting const platformKey = osOverride === platform.OperatingSystem.Windows ? 'windows' : osOverride === platform.OperatingSystem.Macintosh ? 'osx' : 'linux'; - const shellConfigValue = this._workspaceConfigurationService.inspect(`terminal.integrated.shell.${platformKey}`); - const shellArgsConfigValue = this._workspaceConfigurationService.inspect(`terminal.integrated.shellArgs.${platformKey}`); - const envConfigValue = this._workspaceConfigurationService.inspect<{ [key: string]: string }>(`terminal.integrated.env.${platformKey}`); + const shellConfigValue = this._configurationService.inspect(`terminal.integrated.shell.${platformKey}`); + const shellArgsConfigValue = this._configurationService.inspect(`terminal.integrated.shellArgs.${platformKey}`); + const envConfigValue = this._configurationService.inspect<{ [key: string]: string }>(`terminal.integrated.env.${platformKey}`); // Check if workspace setting exists and whether it's whitelisted let isWorkspaceShellAllowed: boolean | undefined = false; @@ -244,4 +247,48 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper { } return r; } + + private readonly NO_RECOMMENDATIONS_KEY = 'terminalConfigHelper/launchRecommendationsIgnore'; + private recommendationsShown = false; + + public async showRecommendations(shellLaunchConfig: IShellLaunchConfig): Promise { + if (this.recommendationsShown) { + return; + } + this.recommendationsShown = true; + + if (platform.isWindows && shellLaunchConfig.executable && basename(shellLaunchConfig.executable).toLowerCase() === 'wsl.exe') { + if (this._storageService.getBoolean(this.NO_RECOMMENDATIONS_KEY, StorageScope.WORKSPACE, false)) { + return; + } + + if (! await this.isExtensionInstalled('ms-vscode-remote.remote-wsl')) { + this._notificationService.prompt( + Severity.Info, + nls.localize( + 'useWslExtension.title', + "Use the 'Remote WSL' extension for developping in WSL . Click [here]({0}) to learn more.", + 'https://go.microsoft.com/fwlink/?linkid=2097212' + ), + [ + { + label: nls.localize('doNotShowAgain', "Don't Show Again"), + run: () => { + this._storageService.store(this.NO_RECOMMENDATIONS_KEY, true, StorageScope.WORKSPACE); + } + } + ], + { + sticky: true + } + ); + } + } + } + + private isExtensionInstalled(id: string): Promise { + return this._extensionManagementService.getInstalled(ExtensionType.User).then(extensions => { + return extensions.some(e => e.identifier.id === id); + }); + } } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index 5bbb0612709505165f3a25c27d1b34d79a42bd73..3d6317a6078510f1e3c87dc6b9fbfb4a9b2d82ff 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -197,6 +197,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { const lastActiveWorkspace = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) : null; const envFromConfigValue = this._workspaceConfigurationService.inspect(`terminal.integrated.env.${platformKey}`); const isWorkspaceShellAllowed = this._configHelper.checkWorkspaceShellPermissions(); + this._configHelper.showRecommendations(shellLaunchConfig); const baseEnv = this._configHelper.config.inheritEnv ? process.env as platform.IProcessEnvironment : await this._terminalInstanceService.getMainProcessParentEnv(); const env = terminalEnvironment.createTerminalEnvironment(shellLaunchConfig, lastActiveWorkspace, envFromConfigValue, this._configurationResolverService, isWorkspaceShellAllowed, this._productService.version, this._configHelper.config.setLocaleVariables, baseEnv); diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index dfd828343974dfa781ce492a834253e836fd42d4..c126bf709783bdbc38ab7faa6fd74380c3891287 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -122,6 +122,7 @@ export interface ITerminalConfigHelper { /** Sets whether a workspace shell configuration is allowed or not */ setWorkspaceShellAllowed(isAllowed: boolean): void; checkWorkspaceShellPermissions(osOverride?: OperatingSystem): boolean; + showRecommendations(shellLaunchConfig: IShellLaunchConfig): void; } export interface ITerminalFont {