未验证 提交 8bb86a8e 编写于 作者: D Daniel Imms 提交者: GitHub

Merge pull request #75799 from microsoft/tyriar/exthost_shell_calls

Replace getDefaultShell and mergeDefaultShellPathAndArgs with getDefaultShellAndArgs
......@@ -4,11 +4,12 @@
*--------------------------------------------------------------------------------------------*/
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalProcessExtHostProxy, ITerminalProcessExtHostRequest, ITerminalDimensions, EXT_HOST_CREATION_DELAY, IShellDefinition } from 'vs/workbench/contrib/terminal/common/terminal';
import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalProcessExtHostProxy, ITerminalProcessExtHostRequest, ITerminalDimensions, EXT_HOST_CREATION_DELAY } from 'vs/workbench/contrib/terminal/common/terminal';
import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceShape, MainContext, IExtHostContext, ShellLaunchConfigDto } from 'vs/workbench/api/common/extHost.protocol';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { UriComponents, URI } from 'vs/base/common/uri';
import { StopWatch } from 'vs/base/common/stopwatch';
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
@extHostNamedCustomer(MainContext.MainThreadTerminalService)
export class MainThreadTerminalService implements MainThreadTerminalServiceShape {
......@@ -22,10 +23,13 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
constructor(
extHostContext: IExtHostContext,
@ITerminalService private readonly _terminalService: ITerminalService
@ITerminalService private readonly _terminalService: ITerminalService,
@ITerminalInstanceService readonly terminalInstanceService: ITerminalInstanceService
) {
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTerminalService);
this._remoteAuthority = extHostContext.remoteAuthority;
// ITerminalService listeners
this._toDispose.push(_terminalService.onInstanceCreated((instance) => {
// Delay this message so the TerminalInstance constructor has a chance to finish and
// return the ID normally to the extension host. The ID that is passed here will be used
......@@ -42,7 +46,12 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
this._toDispose.push(_terminalService.onActiveInstanceChanged(instance => this._onActiveTerminalChanged(instance ? instance.id : null)));
this._toDispose.push(_terminalService.onInstanceTitleChanged(instance => this._onTitleChanged(instance.id, instance.title)));
this._toDispose.push(_terminalService.configHelper.onWorkspacePermissionsChanged(isAllowed => this._onWorkspacePermissionsChanged(isAllowed)));
this._toDispose.push(_terminalService.onRequestAvailableShells(r => this._onRequestAvailableShells(r)));
this._toDispose.push(_terminalService.onRequestAvailableShells(r => this._proxy.$requestAvailableShells().then(e => r(e))));
// ITerminalInstanceService listeners
if (terminalInstanceService.onRequestDefaultShellAndArgs) {
this._toDispose.push(terminalInstanceService.onRequestDefaultShellAndArgs(r => this._proxy.$requestDefaultShellAndArgs().then(e => r(e.shell, e.args))));
}
// Set initial ext host state
this._terminalService.terminalInstances.forEach(t => {
......@@ -276,8 +285,4 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
}
this._terminalProcesses[terminalId].emitLatency(sum / COUNT);
}
private _onRequestAvailableShells(resolve: (shells: IShellDefinition[]) => void): void {
this._proxy.$requestAvailableShells().then(shells => resolve(shells));
}
}
......@@ -1112,6 +1112,11 @@ export interface IShellDefinitionDto {
path: string;
}
export interface IShellAndArgsDto {
shell: string;
args: string[] | string | undefined;
}
export interface ExtHostTerminalServiceShape {
$acceptTerminalClosed(id: number): void;
$acceptTerminalOpened(id: number, name: string): void;
......@@ -1130,6 +1135,7 @@ export interface ExtHostTerminalServiceShape {
$acceptProcessRequestLatency(id: number): number;
$acceptWorkspacePermissionsChanged(isAllowed: boolean): void;
$requestAvailableShells(): Promise<IShellDefinitionDto[]>;
$requestDefaultShellAndArgs(): Promise<IShellAndArgsDto>;
}
export interface ExtHostSCMShape {
......
......@@ -10,7 +10,7 @@ import { URI, UriComponents } from 'vs/base/common/uri';
import * as platform from 'vs/base/common/platform';
import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
import { Event, Emitter } from 'vs/base/common/event';
import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IMainContext, ShellLaunchConfigDto, IShellDefinitionDto } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IMainContext, ShellLaunchConfigDto, IShellDefinitionDto, IShellAndArgsDto } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostConfiguration, ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration';
import { ILogService } from 'vs/platform/log/common/log';
import { EXT_HOST_CREATION_DELAY, IShellLaunchConfig, ITerminalEnvironment } from 'vs/workbench/contrib/terminal/common/terminal';
......@@ -20,7 +20,7 @@ import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { ExtHostVariableResolverService } from 'vs/workbench/api/node/extHostDebugService';
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
import { getDefaultShell, detectAvailableShells } from 'vs/workbench/contrib/terminal/node/terminal';
import { getSystemShell, detectAvailableShells } from 'vs/workbench/contrib/terminal/node/terminal';
const RENDERER_NO_PROCESS_ID = -1;
......@@ -338,12 +338,22 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
return terminalEnvironment.getDefaultShell(
fetchSetting,
this._isWorkspaceShellAllowed,
getDefaultShell(platform.platform),
getSystemShell(platform.platform),
process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'),
process.env.windir
);
}
private _getDefaultShellArgs(configProvider: ExtHostConfigProvider): string[] | string | undefined {
const fetchSetting = (key: string) => {
const setting = configProvider
.getConfiguration(key.substr(0, key.lastIndexOf('.')))
.inspect<string | string[]>(key.substr(key.lastIndexOf('.') + 1));
return this._apiInspectConfigToPlain<string | string[]>(setting);
};
return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed);
}
public async resolveTerminalRenderer(id: number): Promise<vscode.TerminalRenderer> {
// Check to see if the extension host already knows about this terminal.
for (const terminalRenderer of this._terminalRenderers) {
......@@ -485,20 +495,8 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux');
const configProvider = await this._extHostConfiguration.getConfigProvider();
if (!shellLaunchConfig.executable) {
const fetchSetting = (key: string) => {
const setting = configProvider
.getConfiguration(key.substr(0, key.lastIndexOf('.')))
.inspect<string | string[]>(key.substr(key.lastIndexOf('.') + 1));
return this._apiInspectConfigToPlain<string | string[]>(setting);
};
terminalEnvironment.mergeDefaultShellPathAndArgs(
shellLaunchConfig,
fetchSetting,
isWorkspaceShellAllowed || false,
getDefaultShell(platform.platform),
process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'),
process.env.windir
);
shellLaunchConfig.executable = this.getDefaultShell(configProvider);
shellLaunchConfig.args = this._getDefaultShellArgs(configProvider);
}
// Get the initial cwd
......@@ -579,6 +577,14 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
return detectAvailableShells();
}
public async $requestDefaultShellAndArgs(): Promise<IShellAndArgsDto> {
const configProvider = await this._extHostConfiguration.getConfigProvider();
return Promise.resolve({
shell: this.getDefaultShell(configProvider),
args: this._getDefaultShellArgs(configProvider)
});
}
private _onProcessExit(id: number, exitCode: number): void {
// Remove listeners
this._terminalProcesses[id].dispose();
......
......@@ -10,7 +10,7 @@ import * as pfs from 'vs/base/node/pfs';
import { assign } from 'vs/base/common/objects';
import { ITerminalLauncher, ITerminalSettings } from 'vs/workbench/contrib/debug/common/debug';
import { getPathFromAmdModule } from 'vs/base/common/amd';
import { getDefaultShell } from 'vs/workbench/contrib/terminal/node/terminal';
import { getSystemShell } from 'vs/workbench/contrib/terminal/node/terminal';
const TERMINAL_TITLE = nls.localize('console.title', "VS Code Console");
......@@ -315,13 +315,13 @@ export function prepareCommand(args: DebugProtocol.RunInTerminalRequestArguments
let shell: string;
const shell_config = config.integrated.shell;
if (env.isWindows) {
shell = shell_config.windows || getDefaultShell(env.Platform.Windows);
shell = shell_config.windows || getSystemShell(env.Platform.Windows);
shellType = ShellType.cmd;
} else if (env.isLinux) {
shell = shell_config.linux || getDefaultShell(env.Platform.Linux);
shell = shell_config.linux || getSystemShell(env.Platform.Linux);
shellType = ShellType.bash;
} else if (env.isMacintosh) {
shell = shell_config.osx || getDefaultShell(env.Platform.Mac);
shell = shell_config.osx || getSystemShell(env.Platform.Mac);
shellType = ShellType.bash;
} else {
throw new Error('Unknown platform');
......
......@@ -763,25 +763,6 @@ export class TerminalTaskSystem implements ITaskSystem {
return nls.localize('TerminalTaskSystem.terminalName', 'Task - {0}', needsFolderQualification ? task.getQualifiedLabel() : task.configurationProperties.name);
}
private getDefaultShell(platform: Platform.Platform): string {
let defaultShell: string | undefined = undefined;
try {
defaultShell = this.terminalInstanceService.getDefaultShell(platform);
} catch {
// Do nothing
}
if (!defaultShell) {
// Make up a guess for the default shell.
if (platform === Platform.Platform.Windows) {
defaultShell = 'cmd.exe';
} else {
defaultShell = 'bash';
}
console.warn('Cannot get the default shell.');
}
return defaultShell;
}
private async getUserHome(): Promise<URI> {
const env = await this.remoteAgentService.getEnvironment();
if (env) {
......@@ -797,8 +778,8 @@ export class TerminalTaskSystem implements ITaskSystem {
let terminalName = this.createTerminalName(task);
let originalCommand = task.command.name;
if (isShellCommand) {
shellLaunchConfig = { name: terminalName, executable: undefined, args: undefined, waitOnExit };
this.terminalInstanceService.mergeDefaultShellPathAndArgs(shellLaunchConfig, this.getDefaultShell(platform), this.terminalService.configHelper, platform);
const defaultConfig = await this.terminalInstanceService.getDefaultShellAndArgs();
shellLaunchConfig = { name: terminalName, executable: defaultConfig.shell, args: defaultConfig.args, waitOnExit };
let shellSpecified: boolean = false;
let shellOptions: ShellConfiguration | undefined = task.command.options && task.command.options.shell;
if (shellOptions) {
......
......@@ -6,9 +6,10 @@
import { Terminal as XTermTerminal } from 'xterm';
import { WebLinksAddon as XTermWebLinksAddon } from 'xterm-addon-web-links';
import { SearchAddon as XTermSearchAddon } from 'xterm-addon-search';
import { ITerminalInstance, IWindowsShellHelper, ITerminalConfigHelper, ITerminalChildProcess, IShellLaunchConfig } from 'vs/workbench/contrib/terminal/common/terminal';
import { ITerminalInstance, IWindowsShellHelper, ITerminalConfigHelper, ITerminalChildProcess, IShellLaunchConfig, IDefaultShellAndArgsRequest } from 'vs/workbench/contrib/terminal/common/terminal';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IProcessEnvironment, Platform } from 'vs/base/common/platform';
import { IProcessEnvironment } from 'vs/base/common/platform';
import { Event } from 'vs/base/common/event';
export const ITerminalInstanceService = createDecorator<ITerminalInstanceService>('terminalInstanceService');
......@@ -20,16 +21,15 @@ export const ITerminalInstanceService = createDecorator<ITerminalInstanceService
export interface ITerminalInstanceService {
_serviceBrand: any;
onRequestDefaultShellAndArgs?: Event<IDefaultShellAndArgsRequest>;
getXtermConstructor(): Promise<typeof XTermTerminal>;
getXtermWebLinksConstructor(): Promise<typeof XTermWebLinksAddon>;
getXtermSearchConstructor(): Promise<typeof XTermSearchAddon>;
createWindowsShellHelper(shellProcessId: number, instance: ITerminalInstance, xterm: XTermTerminal): IWindowsShellHelper;
createTerminalProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean): ITerminalChildProcess;
getDefaultShell(p: Platform): string;
/**
* Merges the default shell path and args into the provided launch configuration
*/
mergeDefaultShellPathAndArgs(shell: IShellLaunchConfig, defaultShell: string, configHelper: ITerminalConfigHelper, platformOverride?: Platform): void;
getDefaultShellAndArgs(): Promise<{ shell: string, args: string[] | string | undefined }>;
getMainProcessParentEnv(): Promise<IProcessEnvironment>;
}
......
......@@ -4,11 +4,12 @@
*--------------------------------------------------------------------------------------------*/
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { IWindowsShellHelper, ITerminalChildProcess } from 'vs/workbench/contrib/terminal/common/terminal';
import { IWindowsShellHelper, ITerminalChildProcess, IDefaultShellAndArgsRequest } from 'vs/workbench/contrib/terminal/common/terminal';
import { Terminal as XTermTerminal } from 'xterm';
import { WebLinksAddon as XTermWebLinksAddon } from 'xterm-addon-web-links';
import { SearchAddon as XTermSearchAddon } from 'xterm-addon-search';
import { IProcessEnvironment } from 'vs/base/common/platform';
import { Emitter, Event } from 'vs/base/common/event';
let Terminal: typeof XTermTerminal;
let WebLinksAddon: typeof XTermWebLinksAddon;
......@@ -17,6 +18,9 @@ let SearchAddon: typeof XTermSearchAddon;
export class TerminalInstanceService implements ITerminalInstanceService {
public _serviceBrand: any;
private readonly _onRequestDefaultShellAndArgs = new Emitter<IDefaultShellAndArgsRequest>();
public get onRequestDefaultShellAndArgs(): Event<IDefaultShellAndArgsRequest> { return this._onRequestDefaultShellAndArgs.event; }
constructor() { }
public async getXtermConstructor(): Promise<typeof XTermTerminal> {
......@@ -48,14 +52,11 @@ export class TerminalInstanceService implements ITerminalInstanceService {
throw new Error('Not implemented');
}
public getDefaultShell(): string {
throw new Error('Not implemented');
public getDefaultShellAndArgs(): Promise<{ shell: string, args: string[] | string | undefined }> {
return new Promise(r => this._onRequestDefaultShellAndArgs.fire((shell, args) => r({ shell, args })));
}
public async getMainProcessParentEnv(): Promise<IProcessEnvironment> {
return {};
}
public mergeDefaultShellPathAndArgs(): void {
}
}
\ No newline at end of file
......@@ -163,7 +163,9 @@ export class TerminalProcessManager implements ITerminalProcessManager {
private async _launchProcess(shellLaunchConfig: IShellLaunchConfig, cols: number, rows: number): Promise<ITerminalChildProcess> {
if (!shellLaunchConfig.executable) {
this._terminalInstanceService.mergeDefaultShellPathAndArgs(shellLaunchConfig, this._terminalInstanceService.getDefaultShell(platform.platform), this._configHelper);
const defaultConfig = await this._terminalInstanceService.getDefaultShellAndArgs();
shellLaunchConfig.executable = defaultConfig.shell;
shellLaunchConfig.args = defaultConfig.args;
}
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file);
......
......@@ -789,4 +789,8 @@ export interface ITerminalChildProcess {
getInitialCwd(): Promise<string>;
getCwd(): Promise<string>;
getLatency(): Promise<number>;
}
export interface IDefaultShellAndArgsRequest {
(shell: string, args: string[] | string | undefined): void;
}
\ No newline at end of file
......@@ -192,7 +192,7 @@ export function getDefaultShell(
return executable;
}
function getDefaultShellArgs(
export function getDefaultShellArgs(
fetchSetting: (key: string) => { user: string | string[] | undefined, value: string | string[] | undefined, default: string | string[] | undefined },
isWorkspaceShellAllowed: boolean,
platformOverride: platform.Platform = platform.platform
......@@ -203,19 +203,6 @@ function getDefaultShellArgs(
return args;
}
export function mergeDefaultShellPathAndArgs(
shell: IShellLaunchConfig,
fetchSetting: (key: string) => { user: string | string[] | undefined, value: string | string[] | undefined, default: string | string[] | undefined },
isWorkspaceShellAllowed: boolean,
defaultShell: string,
isWoW64: boolean,
windir: string | undefined,
platformOverride: platform.Platform = platform.platform
): void {
shell.executable = getDefaultShell(fetchSetting, isWorkspaceShellAllowed, defaultShell, isWoW64, windir, platformOverride);
shell.args = getDefaultShellArgs(fetchSetting, isWorkspaceShellAllowed, platformOverride);
}
export function createTerminalEnvironment(
shellLaunchConfig: IShellLaunchConfig,
lastActiveWorkspace: IWorkspaceFolder | null,
......
......@@ -8,7 +8,7 @@ import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/co
import { Registry } from 'vs/platform/registry/common/platform';
import { Platform } from 'vs/base/common/platform';
export function registerShellConfiguration(getDefaultShell?: (p: Platform) => string): void {
export function registerShellConfiguration(getSystemShell?: (p: Platform) => string): void {
const configurationRegistry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);
configurationRegistry.registerConfiguration({
id: 'terminal',
......@@ -18,24 +18,24 @@ export function registerShellConfiguration(getDefaultShell?: (p: Platform) => st
properties: {
'terminal.integrated.shell.linux': {
markdownDescription:
getDefaultShell
? nls.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).", getDefaultShell(Platform.Linux))
getSystemShell
? nls.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).", getSystemShell(Platform.Linux))
: nls.localize('terminal.integrated.shell.linux.noDefault', "The path of the shell that the terminal uses on Linux. [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration)."),
type: ['string', 'null'],
default: null
},
'terminal.integrated.shell.osx': {
markdownDescription:
getDefaultShell
? nls.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).", getDefaultShell(Platform.Mac))
getSystemShell
? nls.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).", getSystemShell(Platform.Mac))
: nls.localize('terminal.integrated.shell.osx.noDefault', "The path of the shell that the terminal uses on macOS. [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration)."),
type: ['string', 'null'],
default: null
},
'terminal.integrated.shell.windows': {
markdownDescription:
getDefaultShell
? nls.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).", getDefaultShell(Platform.Windows))
getSystemShell
? nls.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).", getSystemShell(Platform.Windows))
: nls.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)."),
type: ['string', 'null'],
default: null
......
......@@ -6,11 +6,11 @@
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { TerminalInstanceService } from 'vs/workbench/contrib/terminal/electron-browser/terminalInstanceService';
import { getDefaultShell } from 'vs/workbench/contrib/terminal/node/terminal';
import { getSystemShell } from 'vs/workbench/contrib/terminal/node/terminal';
import { registerShellConfiguration } from 'vs/workbench/contrib/terminal/common/terminalShellConfig';
import { TerminalNativeService } from 'vs/workbench/contrib/terminal/electron-browser/terminalNativeService';
import { ITerminalNativeService } from 'vs/workbench/contrib/terminal/common/terminal';
registerShellConfiguration(getDefaultShell);
registerShellConfiguration(getSystemShell);
registerSingleton(ITerminalNativeService, TerminalNativeService, true);
registerSingleton(ITerminalInstanceService, TerminalInstanceService, true);
......@@ -4,19 +4,20 @@
*--------------------------------------------------------------------------------------------*/
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { ITerminalInstance, IWindowsShellHelper, IShellLaunchConfig, ITerminalChildProcess, ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal';
import { ITerminalInstance, IWindowsShellHelper, IShellLaunchConfig, ITerminalChildProcess, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY } from 'vs/workbench/contrib/terminal/common/terminal';
import { WindowsShellHelper } from 'vs/workbench/contrib/terminal/node/windowsShellHelper';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IProcessEnvironment, Platform, isLinux, isMacintosh, isWindows, OperatingSystem, platform } from 'vs/base/common/platform';
import { IProcessEnvironment, isLinux, isMacintosh, isWindows, platform } from 'vs/base/common/platform';
import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess';
import { getDefaultShell } from 'vs/workbench/contrib/terminal/node/terminal';
import { getSystemShell } from 'vs/workbench/contrib/terminal/node/terminal';
import { Terminal as XTermTerminal } from 'xterm';
import { WebLinksAddon as XTermWebLinksAddon } from 'xterm-addon-web-links';
import { SearchAddon as XTermSearchAddon } from 'xterm-addon-search';
import { readFile } from 'vs/base/node/pfs';
import { basename } from 'vs/base/common/path';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { mergeDefaultShellPathAndArgs } from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
import { getDefaultShell, getDefaultShellArgs } from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage';
let Terminal: typeof XTermTerminal;
let WebLinksAddon: typeof XTermWebLinksAddon;
......@@ -29,7 +30,8 @@ export class TerminalInstanceService implements ITerminalInstanceService {
constructor(
@IInstantiationService private readonly _instantiationService: IInstantiationService,
@IConfigurationService private readonly _configurationService: IConfigurationService
@IConfigurationService private readonly _configurationService: IConfigurationService,
@IStorageService private readonly _storageService: IStorageService
) {
}
......@@ -62,21 +64,24 @@ export class TerminalInstanceService implements ITerminalInstanceService {
return this._instantiationService.createInstance(TerminalProcess, shellLaunchConfig, cwd, cols, rows, env, windowsEnableConpty);
}
public getDefaultShell(p: Platform): string {
return getDefaultShell(p);
private _isWorkspaceShellAllowed(): boolean {
return this._storageService.getBoolean(IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, StorageScope.WORKSPACE, false);
}
public mergeDefaultShellPathAndArgs(shell: IShellLaunchConfig, defaultShell: string, configHelper: ITerminalConfigHelper, platformOverride: Platform = platform): void {
const isWorkspaceShellAllowed = configHelper.checkWorkspaceShellPermissions(platformOverride === Platform.Windows ? OperatingSystem.Windows : (platformOverride === Platform.Mac ? OperatingSystem.Macintosh : OperatingSystem.Linux));
mergeDefaultShellPathAndArgs(
shell,
public getDefaultShellAndArgs(): Promise<{ shell: string, args: string[] | string | undefined }> {
const isWorkspaceShellAllowed = this._isWorkspaceShellAllowed();
const shell = getDefaultShell(
(key) => this._configurationService.inspect(key),
isWorkspaceShellAllowed,
defaultShell,
getSystemShell(platform),
process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'),
process.env.windir,
platformOverride
process.env.windir
);
const args = getDefaultShellArgs(
(key) => this._configurationService.inspect(key),
isWorkspaceShellAllowed
);
return Promise.resolve({ shell, args });
}
public async getMainProcessParentEnv(): Promise<IProcessEnvironment> {
......
......@@ -11,10 +11,15 @@ import { LinuxDistro, IShellDefinition } from 'vs/workbench/contrib/terminal/com
import { coalesce } from 'vs/base/common/arrays';
import { normalize, basename } from 'vs/base/common/path';
export function getDefaultShell(p: platform.Platform): string {
/**
* Gets the detected default shell for the _system_, not to be confused with VS Code's _default_
* shell that the terminal uses by default.
* @param p The platform to detect the shell of.
*/
export function getSystemShell(p: platform.Platform): string {
if (p === platform.Platform.Windows) {
if (platform.isWindows) {
return getTerminalDefaultShellWindows();
return getSystemShellWindows();
}
// Don't detect Windows shell when not on Windows
return processes.getWindowsShell();
......@@ -23,11 +28,11 @@ export function getDefaultShell(p: platform.Platform): string {
if (platform.isLinux && p === platform.Platform.Mac || platform.isMacintosh && p === platform.Platform.Linux) {
return '/bin/bash';
}
return getTerminalDefaultShellUnixLike();
return getSystemShellUnixLike();
}
let _TERMINAL_DEFAULT_SHELL_UNIX_LIKE: string | null = null;
function getTerminalDefaultShellUnixLike(): string {
function getSystemShellUnixLike(): string {
if (!_TERMINAL_DEFAULT_SHELL_UNIX_LIKE) {
let unixLikeTerminal = 'sh';
if (!platform.isWindows && process.env.SHELL) {
......@@ -46,7 +51,7 @@ function getTerminalDefaultShellUnixLike(): string {
}
let _TERMINAL_DEFAULT_SHELL_WINDOWS: string | null = null;
function getTerminalDefaultShellWindows(): string {
function getSystemShellWindows(): string {
if (!_TERMINAL_DEFAULT_SHELL_WINDOWS) {
const isAtLeastWindows10 = platform.isWindows && parseFloat(os.release()) >= 10;
const is32ProcessOn64Windows = process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432');
......
......@@ -4,10 +4,11 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { Platform, OperatingSystem } from 'vs/base/common/platform';
import { OperatingSystem } from 'vs/base/common/platform';
import { TerminalLinkHandler, LineColumnInfo } from 'vs/workbench/contrib/terminal/browser/terminalLinkHandler';
import * as strings from 'vs/base/common/strings';
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { Event } from 'vs/base/common/event';
class TestTerminalLinkHandler extends TerminalLinkHandler {
public get localLinkRegex(): RegExp {
......@@ -30,7 +31,8 @@ class TestXterm {
}
class MockTerminalInstanceService implements ITerminalInstanceService {
mergeDefaultShellPathAndArgs(): void {
onRequestDefaultShellAndArgs?: Event<any> | undefined;
getDefaultShellAndArgs(): Promise<{ shell: string; args: string | string[] | undefined; }> {
throw new Error('Method not implemented.');
}
_serviceBrand: any;
......@@ -49,9 +51,6 @@ class MockTerminalInstanceService implements ITerminalInstanceService {
createTerminalProcess(): any {
throw new Error('Method not implemented.');
}
getDefaultShell(p: Platform): string {
throw new Error('Method not implemented.');
}
getMainProcessParentEnv(): any {
throw new Error('Method not implemented.');
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册