Use OperatingSystem over Platform in terminal

This prevents the invalid 'web' from possibly being used
This commit is contained in:
Daniel Imms 2021-04-16 07:00:13 -07:00
parent f4b60835ea
commit 328937e7b6
No known key found for this signature in database
GPG key ID: D12BE8272D6284CC
17 changed files with 77 additions and 87 deletions

View file

@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as os from 'os'; import { release, userInfo } from 'os';
import * as platform from 'vs/base/common/platform'; import * as platform from 'vs/base/common/platform';
import { getFirstAvailablePowerShellInstallation } from 'vs/base/node/powershell'; import { getFirstAvailablePowerShellInstallation } from 'vs/base/node/powershell';
import * as processes from 'vs/base/node/processes'; import * as processes from 'vs/base/node/processes';
@ -11,10 +11,10 @@ import * as processes from 'vs/base/node/processes';
/** /**
* Gets the detected default shell for the _system_, not to be confused with VS Code's _default_ * Gets the detected default shell for the _system_, not to be confused with VS Code's _default_
* shell that the terminal uses by default. * shell that the terminal uses by default.
* @param p The platform to detect the shell of. * @param os The platform to detect the shell of.
*/ */
export async function getSystemShell(p: platform.Platform, env: platform.IProcessEnvironment): Promise<string> { export async function getSystemShell(os: platform.OperatingSystem, env: platform.IProcessEnvironment): Promise<string> {
if (p === platform.Platform.Windows) { if (os === platform.OperatingSystem.Windows) {
if (platform.isWindows) { if (platform.isWindows) {
return getSystemShellWindows(); return getSystemShellWindows();
} }
@ -22,11 +22,11 @@ export async function getSystemShell(p: platform.Platform, env: platform.IProces
return processes.getWindowsShell(env); return processes.getWindowsShell(env);
} }
return getSystemShellUnixLike(p, env); return getSystemShellUnixLike(os, env);
} }
export function getSystemShellSync(p: platform.Platform, env: platform.IProcessEnvironment): string { export function getSystemShellSync(os: platform.OperatingSystem, env: platform.IProcessEnvironment): string {
if (p === platform.Platform.Windows) { if (os === platform.OperatingSystem.Windows) {
if (platform.isWindows) { if (platform.isWindows) {
return getSystemShellWindowsSync(env); return getSystemShellWindowsSync(env);
} }
@ -34,13 +34,13 @@ export function getSystemShellSync(p: platform.Platform, env: platform.IProcessE
return processes.getWindowsShell(env); return processes.getWindowsShell(env);
} }
return getSystemShellUnixLike(p, env); return getSystemShellUnixLike(os, env);
} }
let _TERMINAL_DEFAULT_SHELL_UNIX_LIKE: string | null = null; let _TERMINAL_DEFAULT_SHELL_UNIX_LIKE: string | null = null;
function getSystemShellUnixLike(p: platform.Platform, env: platform.IProcessEnvironment): string { function getSystemShellUnixLike(os: platform.OperatingSystem, env: platform.IProcessEnvironment): string {
// Only use $SHELL for the current OS // Only use $SHELL for the current OS
if (platform.isLinux && p === platform.Platform.Mac || platform.isMacintosh && p === platform.Platform.Linux) { if (platform.isLinux && os === platform.OperatingSystem.Macintosh || platform.isMacintosh && os === platform.OperatingSystem.Linux) {
return '/bin/bash'; return '/bin/bash';
} }
@ -55,7 +55,7 @@ function getSystemShellUnixLike(p: platform.Platform, env: platform.IProcessEnvi
try { try {
// It's possible for $SHELL to be unset, this API reads /etc/passwd. See https://github.com/github/codespaces/issues/1639 // It's possible for $SHELL to be unset, this API reads /etc/passwd. See https://github.com/github/codespaces/issues/1639
// Node docs: "Throws a SystemError if a user has no username or homedir." // Node docs: "Throws a SystemError if a user has no username or homedir."
unixLikeTerminal = os.userInfo().shell; unixLikeTerminal = userInfo().shell;
} catch (err) { } } catch (err) { }
} }
@ -86,7 +86,7 @@ function getSystemShellWindowsSync(env: platform.IProcessEnvironment): string {
return _TERMINAL_DEFAULT_SHELL_WINDOWS; return _TERMINAL_DEFAULT_SHELL_WINDOWS;
} }
const isAtLeastWindows10 = platform.isWindows && parseFloat(os.release()) >= 10; const isAtLeastWindows10 = platform.isWindows && parseFloat(release()) >= 10;
const is32ProcessOn64Windows = env.hasOwnProperty('PROCESSOR_ARCHITEW6432'); const is32ProcessOn64Windows = env.hasOwnProperty('PROCESSOR_ARCHITEW6432');
const powerShellPath = `${env['windir']}\\${is32ProcessOn64Windows ? 'Sysnative' : 'System32'}\\WindowsPowerShell\\v1.0\\powershell.exe`; const powerShellPath = `${env['windir']}\\${is32ProcessOn64Windows ? 'Sysnative' : 'System32'}\\WindowsPowerShell\\v1.0\\powershell.exe`;
return isAtLeastWindows10 ? powerShellPath : processes.getWindowsShell(env); return isAtLeastWindows10 ? powerShellPath : processes.getWindowsShell(env);

View file

@ -6,7 +6,7 @@
import * as path from 'path'; import * as path from 'path';
import { spawn } from 'child_process'; import { spawn } from 'child_process';
import { generateUuid } from 'vs/base/common/uuid'; import { generateUuid } from 'vs/base/common/uuid';
import { IProcessEnvironment, isWindows, platform } from 'vs/base/common/platform'; import { IProcessEnvironment, isWindows, OS } from 'vs/base/common/platform';
import { ILogService } from 'vs/platform/log/common/log'; import { ILogService } from 'vs/platform/log/common/log';
import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
import { isLaunchedFromCli } from 'vs/platform/environment/node/argvHelper'; import { isLaunchedFromCli } from 'vs/platform/environment/node/argvHelper';
@ -77,7 +77,7 @@ async function doResolveUnixShellEnv(logService: ILogService): Promise<typeof pr
}; };
logService.trace('getUnixShellEnvironment#env', env); logService.trace('getUnixShellEnvironment#env', env);
const systemShellUnix = await getSystemShell(platform, env); const systemShellUnix = await getSystemShell(OS, env);
logService.trace('getUnixShellEnvironment#shell', systemShellUnix); logService.trace('getUnixShellEnvironment#shell', systemShellUnix);
let command = `'${process.execPath}' -p '"${mark}" + JSON.stringify(process.env) + "${mark}"'`; let command = `'${process.execPath}' -p '"${mark}" + JSON.stringify(process.env) + "${mark}"'`;

View file

@ -5,7 +5,7 @@
import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { Event } from 'vs/base/common/event'; import { Event } from 'vs/base/common/event';
import { IProcessEnvironment, Platform } from 'vs/base/common/platform'; import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform';
import { URI, UriComponents } from 'vs/base/common/uri'; import { URI, UriComponents } from 'vs/base/common/uri';
import { IGetTerminalLayoutInfoArgs, IProcessDetails, IPtyHostProcessReplayEvent, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess'; import { IGetTerminalLayoutInfoArgs, IProcessDetails, IPtyHostProcessReplayEvent, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess';
@ -95,7 +95,7 @@ export interface IOffProcessTerminalService {
attachToProcess(id: number): Promise<ITerminalChildProcess | undefined>; attachToProcess(id: number): Promise<ITerminalChildProcess | undefined>;
listProcesses(): Promise<IProcessDetails[]>; listProcesses(): Promise<IProcessDetails[]>;
getDefaultSystemShell(platformOverride?: Platform): Promise<string>; getDefaultSystemShell(osOverride?: OperatingSystem): Promise<string>;
getShellEnvironment(): Promise<IProcessEnvironment>; getShellEnvironment(): Promise<IProcessEnvironment>;
setTerminalLayoutInfo(layoutInfo?: ITerminalsLayoutInfoById): Promise<void>; setTerminalLayoutInfo(layoutInfo?: ITerminalsLayoutInfoById): Promise<void>;
getTerminalLayoutInfo(): Promise<ITerminalsLayoutInfo | undefined>; getTerminalLayoutInfo(): Promise<ITerminalsLayoutInfo | undefined>;
@ -161,7 +161,7 @@ export interface IPtyService {
/** Confirm the process is _not_ an orphan. */ /** Confirm the process is _not_ an orphan. */
orphanQuestionReply(id: number): Promise<void>; orphanQuestionReply(id: number): Promise<void>;
getDefaultSystemShell(platformOverride?: Platform): Promise<string>; getDefaultSystemShell(osOverride?: OperatingSystem): Promise<string>;
getShellEnvironment(): Promise<IProcessEnvironment>; getShellEnvironment(): Promise<IProcessEnvironment>;
setTerminalLayoutInfo(args: ISetTerminalLayoutInfoArgs): Promise<void>; setTerminalLayoutInfo(args: ISetTerminalLayoutInfoArgs): Promise<void>;
getTerminalLayoutInfo(args: IGetTerminalLayoutInfoArgs): Promise<ITerminalsLayoutInfo | undefined>; getTerminalLayoutInfo(args: IGetTerminalLayoutInfoArgs): Promise<ITerminalsLayoutInfo | undefined>;

View file

@ -9,7 +9,7 @@ import { IPtyService, IProcessDataEvent, IShellLaunchConfig, ITerminalDimensions
import { Client } from 'vs/base/parts/ipc/node/ipc.cp'; import { Client } from 'vs/base/parts/ipc/node/ipc.cp';
import { FileAccess } from 'vs/base/common/network'; import { FileAccess } from 'vs/base/common/network';
import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc'; import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc';
import { IProcessEnvironment, Platform } from 'vs/base/common/platform'; import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform';
import { Emitter } from 'vs/base/common/event'; import { Emitter } from 'vs/base/common/event';
import { LogLevelChannelClient } from 'vs/platform/log/common/logIpc'; import { LogLevelChannelClient } from 'vs/platform/log/common/logIpc';
import { IGetTerminalLayoutInfoArgs, IProcessDetails, IPtyHostProcessReplayEvent, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess'; import { IGetTerminalLayoutInfoArgs, IProcessDetails, IPtyHostProcessReplayEvent, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess';
@ -192,8 +192,8 @@ export class PtyHostService extends Disposable implements IPtyService {
return this._proxy.orphanQuestionReply(id); return this._proxy.orphanQuestionReply(id);
} }
getDefaultSystemShell(platformOverride?: Platform): Promise<string> { getDefaultSystemShell(osOverride?: OperatingSystem): Promise<string> {
return this._proxy.getDefaultSystemShell(platformOverride); return this._proxy.getDefaultSystemShell(osOverride);
} }
getShellEnvironment(): Promise<IProcessEnvironment> { getShellEnvironment(): Promise<IProcessEnvironment> {
return this._proxy.getShellEnvironment(); return this._proxy.getShellEnvironment();

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { IProcessEnvironment, platform, Platform } from 'vs/base/common/platform'; import { IProcessEnvironment, OperatingSystem, OS } from 'vs/base/common/platform';
import { IPtyService, IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, LocalReconnectConstants, ITerminalsLayoutInfo, IRawTerminalInstanceLayoutInfo, ITerminalTabLayoutInfoById, ITerminalInstanceLayoutInfoById, TerminalShellType } from 'vs/platform/terminal/common/terminal'; import { IPtyService, IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, LocalReconnectConstants, ITerminalsLayoutInfo, IRawTerminalInstanceLayoutInfo, ITerminalTabLayoutInfoById, ITerminalInstanceLayoutInfoById, TerminalShellType } from 'vs/platform/terminal/common/terminal';
import { AutoOpenBarrier, Queue, RunOnceScheduler } from 'vs/base/common/async'; import { AutoOpenBarrier, Queue, RunOnceScheduler } from 'vs/base/common/async';
import { Emitter } from 'vs/base/common/event'; import { Emitter } from 'vs/base/common/event';
@ -164,8 +164,8 @@ export class PtyService extends Disposable implements IPtyService {
return this._throwIfNoPty(id).orphanQuestionReply(); return this._throwIfNoPty(id).orphanQuestionReply();
} }
async getDefaultSystemShell(platformOverride: Platform = platform): Promise<string> { async getDefaultSystemShell(osOverride: OperatingSystem = OS): Promise<string> {
return getSystemShell(platformOverride, process.env); return getSystemShell(osOverride, process.env);
} }
async getShellEnvironment(): Promise<IProcessEnvironment> { async getShellEnvironment(): Promise<IProcessEnvironment> {

View file

@ -41,7 +41,7 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService {
// Getting the SystemShell is an async operation, however, the ExtHost terminal service is mostly synchronous // Getting the SystemShell is an async operation, however, the ExtHost terminal service is mostly synchronous
// and the API `vscode.env.shell` is also synchronous. The default shell _should_ be set when extensions are // and the API `vscode.env.shell` is also synchronous. The default shell _should_ be set when extensions are
// starting up but if not, we run getSystemShellSync below which gets a sane default. // starting up but if not, we run getSystemShellSync below which gets a sane default.
getSystemShell(platform.platform, process.env as platform.IProcessEnvironment).then(s => this._defaultShell = s); getSystemShell(platform.OS, process.env as platform.IProcessEnvironment).then(s => this._defaultShell = s);
this._updateLastActiveWorkspace(); this._updateLastActiveWorkspace();
this._variableResolverPromise = this._updateVariableResolver(); this._variableResolverPromise = this._updateVariableResolver();
@ -83,7 +83,7 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService {
return terminalEnvironment.getDefaultShell( return terminalEnvironment.getDefaultShell(
fetchSetting, fetchSetting,
this._defaultShell ?? getSystemShellSync(platform.platform, process.env as platform.IProcessEnvironment), this._defaultShell ?? getSystemShellSync(platform.OS, process.env as platform.IProcessEnvironment),
process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'), process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'),
process.env.windir, process.env.windir,
terminalEnvironment.createVariableResolver(this._lastActiveWorkspace, this._variableResolver), terminalEnvironment.createVariableResolver(this._lastActiveWorkspace, this._variableResolver),

View file

@ -1016,7 +1016,7 @@ export class TerminalTaskSystem implements ITaskSystem {
} else { } else {
const defaultProfile = await this.terminalProfileResolverService.getDefaultProfile({ const defaultProfile = await this.terminalProfileResolverService.getDefaultProfile({
allowAutomationShell: true, allowAutomationShell: true,
platform, os: Platform.OS,
remoteAuthority: this.environmentService.remoteAuthority remoteAuthority: this.environmentService.remoteAuthority
}); });
defaultConfig = { defaultConfig = {

View file

@ -6,7 +6,7 @@
import { Emitter } from 'vs/base/common/event'; import { Emitter } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle'; import { Disposable } from 'vs/base/common/lifecycle';
import { revive } from 'vs/base/common/marshalling'; import { revive } from 'vs/base/common/marshalling';
import { IProcessEnvironment, Platform } from 'vs/base/common/platform'; import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform';
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
import { ICommandService } from 'vs/platform/commands/common/commands'; import { ICommandService } from 'vs/platform/commands/common/commands';
@ -189,8 +189,8 @@ export class RemoteTerminalService extends Disposable implements IRemoteTerminal
}); });
} }
public async getDefaultSystemShell(platformOverride?: Platform): Promise<string> { public async getDefaultSystemShell(osOverride?: OperatingSystem): Promise<string> {
return this._remoteTerminalChannel?.getDefaultSystemShell(platformOverride) || ''; return this._remoteTerminalChannel?.getDefaultSystemShell(osOverride) || '';
} }
public async getShellEnvironment(): Promise<IProcessEnvironment> { public async getShellEnvironment(): Promise<IProcessEnvironment> {

View file

@ -250,7 +250,8 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
// Resolve just the icon ahead of time so that it shows up immediately in the tabs // Resolve just the icon ahead of time so that it shows up immediately in the tabs
if (!this.shellLaunchConfig.executable) { if (!this.shellLaunchConfig.executable) {
this._terminalProfileResolverService.resolveIcon(this._shellLaunchConfig); // TODO: This will pass in the wrong OS for the remote case
this._terminalProfileResolverService.resolveIcon(this._shellLaunchConfig, platform.OS);
} }
this._initDimensions(); this._initDimensions();

View file

@ -232,7 +232,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
} else { } else {
await this._terminalProfileResolverService.resolveShellLaunchConfig(shellLaunchConfig, { await this._terminalProfileResolverService.resolveShellLaunchConfig(shellLaunchConfig, {
remoteAuthority: this.remoteAuthority, remoteAuthority: this.remoteAuthority,
platform: this._osToPlatform(this.os) os: this.os
}); });
newProcess = await this._remoteTerminalService.createProcess(shellLaunchConfig, activeWorkspaceRootUri, cols, rows, shouldPersist, this._configHelper); newProcess = await this._remoteTerminalService.createProcess(shellLaunchConfig, activeWorkspaceRootUri, cols, rows, shouldPersist, this._configHelper);
} }
@ -371,7 +371,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
): Promise<ITerminalChildProcess> { ): Promise<ITerminalChildProcess> {
await this._terminalProfileResolverService.resolveShellLaunchConfig(shellLaunchConfig, { await this._terminalProfileResolverService.resolveShellLaunchConfig(shellLaunchConfig, {
remoteAuthority: undefined, remoteAuthority: undefined,
platform: platform.platform os: platform.OS
}); });
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file); const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file);
@ -547,14 +547,6 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
this.environmentVariableInfo = this._instantiationService.createInstance(EnvironmentVariableInfoStale, diff, this._instanceId); this.environmentVariableInfo = this._instantiationService.createInstance(EnvironmentVariableInfoStale, diff, this._instanceId);
this._onEnvironmentVariableInfoChange.fire(this.environmentVariableInfo); this._onEnvironmentVariableInfoChange.fire(this.environmentVariableInfo);
} }
private _osToPlatform(os: platform.OperatingSystem) {
switch (os) {
case platform.OperatingSystem.Linux: return platform.Platform.Linux;
case platform.OperatingSystem.Macintosh: return platform.Platform.Mac;
case platform.OperatingSystem.Windows: return platform.Platform.Windows;
}
}
} }
class AckDataBufferer { class AckDataBufferer {

View file

@ -12,14 +12,14 @@ import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspac
import { IRemoteTerminalService, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { IRemoteTerminalService, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { IHistoryService } from 'vs/workbench/services/history/common/history';
import { IProcessEnvironment, platform, Platform } from 'vs/base/common/platform'; import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform';
import { IShellLaunchConfig } from 'vs/platform/terminal/common/terminal'; import { IShellLaunchConfig } from 'vs/platform/terminal/common/terminal';
import { IShellLaunchConfigResolveOptions, ITerminalProfile, ITerminalProfileResolverService } from 'vs/workbench/contrib/terminal/common/terminal'; import { IShellLaunchConfigResolveOptions, ITerminalProfile, ITerminalProfileResolverService } from 'vs/workbench/contrib/terminal/common/terminal';
import * as path from 'vs/base/common/path'; import * as path from 'vs/base/common/path';
import { Codicon } from 'vs/base/common/codicons'; import { Codicon } from 'vs/base/common/codicons';
export interface IProfileContextProvider { export interface IProfileContextProvider {
getDefaultSystemShell: (remoteAuthority: string | undefined, platform: Platform) => Promise<string>; getDefaultSystemShell: (remoteAuthority: string | undefined, os: OperatingSystem) => Promise<string>;
getShellEnvironment: (remoteAuthority: string | undefined) => Promise<IProcessEnvironment>; getShellEnvironment: (remoteAuthority: string | undefined) => Promise<IProcessEnvironment>;
} }
@ -39,12 +39,12 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro
) { ) {
} }
resolveIcon(shellLaunchConfig: IShellLaunchConfig): void { resolveIcon(shellLaunchConfig: IShellLaunchConfig, os: OperatingSystem): void {
if (shellLaunchConfig.executable) { if (shellLaunchConfig.executable) {
return; return;
} }
const defaultProfile = this._getRealDefaultProfile(true, platform); const defaultProfile = this._getRealDefaultProfile(true, os);
if (defaultProfile) { if (defaultProfile) {
shellLaunchConfig.icon = defaultProfile.icon; shellLaunchConfig.icon = defaultProfile.icon;
} }
@ -93,7 +93,7 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro
} }
// Return the real default profile if it exists and is valid // Return the real default profile if it exists and is valid
const defaultProfile = await this._getRealDefaultProfile(false, options.platform); const defaultProfile = await this._getRealDefaultProfile(false, options.os);
if (defaultProfile) { if (defaultProfile) {
return defaultProfile; return defaultProfile;
} }
@ -103,10 +103,10 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro
return this._getFallbackDefaultProfile(options); return this._getFallbackDefaultProfile(options);
} }
private _getRealDefaultProfile(sync: true, platform: Platform): ITerminalProfile | undefined; private _getRealDefaultProfile(sync: true, os: OperatingSystem): ITerminalProfile | undefined;
private _getRealDefaultProfile(sync: false, platform: Platform): Promise<ITerminalProfile | undefined>; private _getRealDefaultProfile(sync: false, os: OperatingSystem): Promise<ITerminalProfile | undefined>;
private _getRealDefaultProfile(sync: boolean, platform: Platform): ITerminalProfile | undefined | Promise<ITerminalProfile | undefined> { private _getRealDefaultProfile(sync: boolean, os: OperatingSystem): ITerminalProfile | undefined | Promise<ITerminalProfile | undefined> {
const defaultProfileName = this._configurationService.getValue(`terminal.integrated.defaultProfile.${this._getPlatformKey(platform)}`); const defaultProfileName = this._configurationService.getValue(`terminal.integrated.defaultProfile.${this._getOsKey(os)}`);
if (defaultProfileName && typeof defaultProfileName === 'string') { if (defaultProfileName && typeof defaultProfileName === 'string') {
if (sync) { if (sync) {
const profiles = this._terminalService.getAvailableProfiles(); const profiles = this._terminalService.getAvailableProfiles();
@ -123,15 +123,15 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro
private async _getFallbackDefaultProfile(options: IShellLaunchConfigResolveOptions): Promise<ITerminalProfile> { private async _getFallbackDefaultProfile(options: IShellLaunchConfigResolveOptions): Promise<ITerminalProfile> {
let executable: string; let executable: string;
let args: string | string[] | undefined; let args: string | string[] | undefined;
const shellSetting = this._configurationService.getValue(`terminal.integrated.shell.${this._getPlatformKey(options.platform)}`); const shellSetting = this._configurationService.getValue(`terminal.integrated.shell.${this._getOsKey(options.os)}`);
if (this._isValidShell(shellSetting)) { if (this._isValidShell(shellSetting)) {
executable = shellSetting; executable = shellSetting;
const shellArgsSetting = this._configurationService.getValue(`terminal.integrated.shellArgs.${this._getPlatformKey(options.platform)}`); const shellArgsSetting = this._configurationService.getValue(`terminal.integrated.shellArgs.${this._getOsKey(options.os)}`);
if (this._isValidShellArgs(shellArgsSetting, options.platform)) { if (this._isValidShellArgs(shellArgsSetting, options.os)) {
args = shellArgsSetting || []; args = shellArgsSetting || [];
} }
} else { } else {
executable = await this._context.getDefaultSystemShell(options.remoteAuthority, options.platform); executable = await this._context.getDefaultSystemShell(options.remoteAuthority, options.os);
} }
const icon = this._guessProfileIcon(executable); const icon = this._guessProfileIcon(executable);
@ -145,7 +145,7 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro
} }
private _getAutomationShellProfile(options: IShellLaunchConfigResolveOptions): ITerminalProfile | undefined { private _getAutomationShellProfile(options: IShellLaunchConfigResolveOptions): ITerminalProfile | undefined {
const automationShell = this._configurationService.getValue(`terminal.integrated.automationShell.${this._getPlatformKey(options.platform)}`); const automationShell = this._configurationService.getValue(`terminal.integrated.automationShell.${this._getOsKey(options.os)}`);
if (!automationShell || typeof automationShell !== 'string') { if (!automationShell || typeof automationShell !== 'string') {
return undefined; return undefined;
} }
@ -156,7 +156,7 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro
} }
private async _resolveProfile(profile: ITerminalProfile, options: IShellLaunchConfigResolveOptions): Promise<ITerminalProfile> { private async _resolveProfile(profile: ITerminalProfile, options: IShellLaunchConfigResolveOptions): Promise<ITerminalProfile> {
if (options.platform === Platform.Windows) { if (options.os === OperatingSystem.Windows) {
// Change Sysnative to System32 if the OS is Windows but NOT WoW64. It's // Change Sysnative to System32 if the OS is Windows but NOT WoW64. It's
// safe to assume that this was used by accident as Sysnative does not // safe to assume that this was used by accident as Sysnative does not
// exist and will break the terminal in non-WoW64 environments. // exist and will break the terminal in non-WoW64 environments.
@ -171,7 +171,7 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro
} }
// Convert / to \ on Windows for convenience // Convert / to \ on Windows for convenience
if (profile.path && options.platform === Platform.Windows) { if (profile.path) {
profile.path = profile.path.replace(/\//g, '\\'); profile.path = profile.path.replace(/\//g, '\\');
} }
} }
@ -205,12 +205,11 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro
return value; return value;
} }
private _getPlatformKey(platform: Platform): string { private _getOsKey(os: OperatingSystem): string {
switch (platform) { switch (os) {
case Platform.Linux: return 'linux'; case OperatingSystem.Linux: return 'linux';
case Platform.Mac: return 'osx'; case OperatingSystem.Macintosh: return 'osx';
case Platform.Windows: return 'windows'; case OperatingSystem.Windows: return 'windows';
default: return '';
} }
} }
@ -236,11 +235,11 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro
return typeof shell === 'string'; return typeof shell === 'string';
} }
private _isValidShellArgs(shellArgs: unknown, platform: Platform): shellArgs is string | string[] | undefined { private _isValidShellArgs(shellArgs: unknown, os: OperatingSystem): shellArgs is string | string[] | undefined {
if (shellArgs === undefined) { if (shellArgs === undefined) {
return true; return true;
} }
if (platform === Platform.Windows && typeof shellArgs === 'string') { if (os === OperatingSystem.Windows && typeof shellArgs === 'string') {
return true; return true;
} }
if (Array.isArray(shellArgs) && shellArgs.every(e => typeof e === 'string')) { if (Array.isArray(shellArgs) && shellArgs.every(e => typeof e === 'string')) {
@ -263,12 +262,12 @@ export class BrowserTerminalProfileResolverService extends BaseTerminalProfileRe
) { ) {
super( super(
{ {
getDefaultSystemShell: async (remoteAuthority, platform) => { getDefaultSystemShell: async (remoteAuthority, os) => {
if (!remoteAuthority) { if (!remoteAuthority) {
// Just return basic values, this is only for serverless web and wouldn't be used // Just return basic values, this is only for serverless web and wouldn't be used
return platform === Platform.Windows ? 'pwsh' : 'bash'; return os === OperatingSystem.Windows ? 'pwsh' : 'bash';
} }
return remoteTerminalService.getDefaultSystemShell(platform); return remoteTerminalService.getDefaultSystemShell(os);
}, },
getShellEnvironment: async (remoteAuthority) => { getShellEnvironment: async (remoteAuthority) => {
if (!remoteAuthority) { if (!remoteAuthority) {

View file

@ -21,7 +21,7 @@ import { IEnvironmentVariableService, ISerializableEnvironmentVariableCollection
import { IProcessDataEvent, IShellLaunchConfig, IShellLaunchConfigDto, ITerminalDimensionsOverride, ITerminalEnvironment, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalShellType } from 'vs/platform/terminal/common/terminal'; import { IProcessDataEvent, IShellLaunchConfig, IShellLaunchConfigDto, ITerminalDimensionsOverride, ITerminalEnvironment, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalShellType } from 'vs/platform/terminal/common/terminal';
import { ITerminalConfiguration, TERMINAL_CONFIG_SECTION } from 'vs/workbench/contrib/terminal/common/terminal'; import { ITerminalConfiguration, TERMINAL_CONFIG_SECTION } from 'vs/workbench/contrib/terminal/common/terminal';
import { IGetTerminalLayoutInfoArgs, IProcessDetails, IPtyHostProcessReplayEvent, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess'; import { IGetTerminalLayoutInfoArgs, IProcessDetails, IPtyHostProcessReplayEvent, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess';
import { IProcessEnvironment, Platform } from 'vs/base/common/platform'; import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform';
export const REMOTE_TERMINAL_CHANNEL_NAME = 'remoteterminal'; export const REMOTE_TERMINAL_CHANNEL_NAME = 'remoteterminal';
@ -256,8 +256,8 @@ export class RemoteTerminalChannelClient {
return this._channel.call('$sendCommandResult', [reqId, isError, payload]); return this._channel.call('$sendCommandResult', [reqId, isError, payload]);
} }
public getDefaultSystemShell(platformOverride?: Platform): Promise<string> { public getDefaultSystemShell(osOverride?: OperatingSystem): Promise<string> {
return this._channel.call('$getDefaultSystemShell', [platformOverride]); return this._channel.call('$getDefaultSystemShell', [osOverride]);
} }
public getShellEnvironment(): Promise<IProcessEnvironment> { public getShellEnvironment(): Promise<IProcessEnvironment> {

View file

@ -7,7 +7,7 @@ import * as nls from 'vs/nls';
import { Event } from 'vs/base/common/event'; import { Event } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle'; import { IDisposable } from 'vs/base/common/lifecycle';
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IProcessEnvironment, OperatingSystem, Platform } from 'vs/base/common/platform'; import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform';
import { IExtensionPointDescriptor } from 'vs/workbench/services/extensions/common/extensionsRegistry'; import { IExtensionPointDescriptor } from 'vs/workbench/services/extensions/common/extensionsRegistry';
import { IProcessDataEvent, IShellLaunchConfig, ITerminalDimensions, ITerminalDimensionsOverride, ITerminalEnvironment, ITerminalLaunchError, TerminalShellType } from 'vs/platform/terminal/common/terminal'; import { IProcessDataEvent, IShellLaunchConfig, ITerminalDimensions, ITerminalDimensionsOverride, ITerminalEnvironment, ITerminalLaunchError, TerminalShellType } from 'vs/platform/terminal/common/terminal';
import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable'; import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable';
@ -83,7 +83,7 @@ export interface ITerminalProfileResolverService {
/** /**
* Resolves the icon of a shell launch config if this will use the default profile * Resolves the icon of a shell launch config if this will use the default profile
*/ */
resolveIcon(shellLaunchConfig: IShellLaunchConfig): void; resolveIcon(shellLaunchConfig: IShellLaunchConfig, os: OperatingSystem): void;
resolveShellLaunchConfig(shellLaunchConfig: IShellLaunchConfig, options: IShellLaunchConfigResolveOptions): Promise<void>; resolveShellLaunchConfig(shellLaunchConfig: IShellLaunchConfig, options: IShellLaunchConfigResolveOptions): Promise<void>;
getDefaultProfile(options: IShellLaunchConfigResolveOptions): Promise<ITerminalProfile>; getDefaultProfile(options: IShellLaunchConfigResolveOptions): Promise<ITerminalProfile>;
getDefaultShell(options: IShellLaunchConfigResolveOptions): Promise<string>; getDefaultShell(options: IShellLaunchConfigResolveOptions): Promise<string>;
@ -93,9 +93,7 @@ export interface ITerminalProfileResolverService {
export interface IShellLaunchConfigResolveOptions { export interface IShellLaunchConfigResolveOptions {
remoteAuthority: string | undefined; remoteAuthority: string | undefined;
// TODO: Pass remote authority in so that local and remote terminals can be resolved correctly os: OperatingSystem;
// TODO: Consider converting to OperatingSystem such that it's not possible to pass Platform.web in
platform: Platform;
allowAutomationShell?: boolean; allowAutomationShell?: boolean;
} }

View file

@ -7,7 +7,7 @@ import { ConfigurationScope, IConfigurationNode } from 'vs/platform/configuratio
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
import { EDITOR_FONT_DEFAULTS } from 'vs/editor/common/config/editorOptions'; import { EDITOR_FONT_DEFAULTS } from 'vs/editor/common/config/editorOptions';
import { DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, TerminalCursorStyle, DEFAULT_COMMANDS_TO_SKIP_SHELL, SUGGESTIONS_FONT_WEIGHT, MINIMUM_FONT_WEIGHT, MAXIMUM_FONT_WEIGHT, DEFAULT_LOCAL_ECHO_EXCLUDE } from 'vs/workbench/contrib/terminal/common/terminal'; import { DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, TerminalCursorStyle, DEFAULT_COMMANDS_TO_SKIP_SHELL, SUGGESTIONS_FONT_WEIGHT, MINIMUM_FONT_WEIGHT, MAXIMUM_FONT_WEIGHT, DEFAULT_LOCAL_ECHO_EXCLUDE } from 'vs/workbench/contrib/terminal/common/terminal';
import { isMacintosh, isWindows, Platform } from 'vs/base/common/platform'; import { isMacintosh, isWindows, OperatingSystem } from 'vs/base/common/platform';
import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { IJSONSchema } from 'vs/base/common/jsonSchema';
const terminalProfileSchema: IJSONSchema = { const terminalProfileSchema: IJSONSchema = {
@ -684,9 +684,9 @@ export function getNoDefaultTerminalShellConfiguration(): IConfigurationNode {
localize('terminal.integrated.shell.windows.noDefault', "The path of the shell that the terminal uses on Windows. [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration).")); localize('terminal.integrated.shell.windows.noDefault', "The path of the shell that the terminal uses on Windows. [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration)."));
} }
export async function getTerminalShellConfiguration(getSystemShell: (p: Platform) => Promise<string>): Promise<IConfigurationNode> { export async function getTerminalShellConfiguration(getSystemShell: (os: OperatingSystem) => Promise<string>): Promise<IConfigurationNode> {
return getTerminalShellConfigurationStub( return getTerminalShellConfigurationStub(
localize('terminal.integrated.shell.linux', "The path of the shell that the terminal uses on Linux (default: {0}). [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration).", await getSystemShell(Platform.Linux)), localize('terminal.integrated.shell.linux', "The path of the shell that the terminal uses on Linux (default: {0}). [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration).", await getSystemShell(OperatingSystem.Linux)),
localize('terminal.integrated.shell.osx', "The path of the shell that the terminal uses on macOS (default: {0}). [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration).", await getSystemShell(Platform.Mac)), localize('terminal.integrated.shell.osx', "The path of the shell that the terminal uses on macOS (default: {0}). [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration).", await getSystemShell(OperatingSystem.Macintosh)),
localize('terminal.integrated.shell.windows', "The path of the shell that the terminal uses on Windows (default: {0}). [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration).", await getSystemShell(Platform.Windows))); localize('terminal.integrated.shell.windows', "The path of the shell that the terminal uses on Windows (default: {0}). [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration).", await getSystemShell(OperatingSystem.Windows)));
} }

View file

@ -14,7 +14,7 @@ import { getTerminalShellConfiguration } from 'vs/workbench/contrib/terminal/com
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { getSystemShell } from 'vs/base/node/shell'; import { getSystemShell } from 'vs/base/node/shell';
import { process } from 'vs/base/parts/sandbox/electron-sandbox/globals'; import { process } from 'vs/base/parts/sandbox/electron-sandbox/globals';
import { Platform } from 'vs/base/common/platform'; import { OperatingSystem } from 'vs/base/common/platform';
import { ElectronTerminalProfileResolverService } from 'vs/workbench/contrib/terminal/electron-sandbox/terminalProfileResolverService'; import { ElectronTerminalProfileResolverService } from 'vs/workbench/contrib/terminal/electron-sandbox/terminalProfileResolverService';
import { ITerminalProfileResolverService } from 'vs/workbench/contrib/terminal/common/terminal'; import { ITerminalProfileResolverService } from 'vs/workbench/contrib/terminal/common/terminal';
@ -30,5 +30,5 @@ workbenchRegistry.registerWorkbenchContribution(TerminalNativeContribution, Life
// Register configurations // Register configurations
const configurationRegistry = Registry.as<IConfigurationRegistry>(Extensions.Configuration); const configurationRegistry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);
const systemShell = async (p: Platform) => getSystemShell(p, await process.shellEnv()); const systemShell = async (os: OperatingSystem) => getSystemShell(os, await process.shellEnv());
getTerminalShellConfiguration(systemShell).then(config => configurationRegistry.registerConfiguration(config)); getTerminalShellConfiguration(systemShell).then(config => configurationRegistry.registerConfiguration(config));

View file

@ -5,7 +5,7 @@
import { Emitter } from 'vs/base/common/event'; import { Emitter } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle'; import { Disposable } from 'vs/base/common/lifecycle';
import { IProcessEnvironment, Platform } from 'vs/base/common/platform'; import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ILabelService } from 'vs/platform/label/common/label'; import { ILabelService } from 'vs/platform/label/common/label';
@ -126,8 +126,8 @@ export class LocalTerminalService extends Disposable implements ILocalTerminalSe
this._localPtyService.reduceConnectionGraceTime(); this._localPtyService.reduceConnectionGraceTime();
} }
public async getDefaultSystemShell(platformOverride?: Platform): Promise<string> { public async getDefaultSystemShell(osOverride?: OperatingSystem): Promise<string> {
return this._localPtyService.getDefaultSystemShell(platformOverride); return this._localPtyService.getDefaultSystemShell(osOverride);
} }
public async getShellEnvironment(): Promise<IProcessEnvironment> { public async getShellEnvironment(): Promise<IProcessEnvironment> {

View file

@ -62,7 +62,7 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { ViewletDescriptor, Viewlet } from 'vs/workbench/browser/viewlet'; import { ViewletDescriptor, Viewlet } from 'vs/workbench/browser/viewlet';
import { IViewlet } from 'vs/workbench/common/viewlet'; import { IViewlet } from 'vs/workbench/common/viewlet';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { IProcessEnvironment, isLinux, isWindows, Platform } from 'vs/base/common/platform'; import { IProcessEnvironment, isLinux, isWindows, OperatingSystem } from 'vs/base/common/platform';
import { LabelService } from 'vs/workbench/services/label/common/labelService'; import { LabelService } from 'vs/workbench/services/label/common/labelService';
import { Part } from 'vs/workbench/browser/part'; import { Part } from 'vs/workbench/browser/part';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
@ -1555,7 +1555,7 @@ export class TestLocalTerminalService implements ILocalTerminalService {
} }
async attachToProcess(id: number): Promise<ITerminalChildProcess | undefined> { throw new Error('Method not implemented.'); } async attachToProcess(id: number): Promise<ITerminalChildProcess | undefined> { throw new Error('Method not implemented.'); }
async listProcesses(): Promise<IProcessDetails[]> { throw new Error('Method not implemented.'); } async listProcesses(): Promise<IProcessDetails[]> { throw new Error('Method not implemented.'); }
getDefaultSystemShell(platformOverride?: Platform): Promise<string> { throw new Error('Method not implemented.'); } getDefaultSystemShell(osOverride?: OperatingSystem): Promise<string> { throw new Error('Method not implemented.'); }
getShellEnvironment(): Promise<IProcessEnvironment> { throw new Error('Method not implemented.'); } getShellEnvironment(): Promise<IProcessEnvironment> { throw new Error('Method not implemented.'); }
async setTerminalLayoutInfo(argsOrLayout?: ISetTerminalLayoutInfoArgs | ITerminalsLayoutInfoById) { throw new Error('Method not implemented.'); } async setTerminalLayoutInfo(argsOrLayout?: ISetTerminalLayoutInfoArgs | ITerminalsLayoutInfoById) { throw new Error('Method not implemented.'); }
async getTerminalLayoutInfo(): Promise<ITerminalsLayoutInfo | undefined> { throw new Error('Method not implemented.'); } async getTerminalLayoutInfo(): Promise<ITerminalsLayoutInfo | undefined> { throw new Error('Method not implemented.'); }