提交 87e16500 编写于 作者: D Daniel Imms

Call getDefaultShell via ext host on web

Part of #75795
上级 c62e57fe
......@@ -9,6 +9,7 @@ import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceS
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
......@@ -44,6 +48,11 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
this._toDispose.push(_terminalService.configHelper.onWorkspacePermissionsChanged(isAllowed => this._onWorkspacePermissionsChanged(isAllowed)));
this._toDispose.push(_terminalService.onRequestAvailableShells(r => this._onRequestAvailableShells(r)));
// ITerminalInstanceService listeners
if (terminalInstanceService.onRequestDefaultShell) {
this._toDispose.push(terminalInstanceService.onRequestDefaultShell(r => this._onRequestDefaultShell(r)));
}
// Set initial ext host state
this._terminalService.terminalInstances.forEach(t => {
this._onTerminalOpened(t);
......@@ -278,6 +287,10 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
}
private _onRequestAvailableShells(resolve: (shells: IShellDefinition[]) => void): void {
this._proxy.$requestAvailableShells().then(shells => resolve(shells));
this._proxy.$requestAvailableShells().then(e => resolve(e));
}
private _onRequestDefaultShell(resolve: (defaultShell: string) => void): void {
this._proxy.$requestDefaultShell().then(e => resolve(e));
}
}
......@@ -1129,6 +1129,7 @@ export interface ExtHostTerminalServiceShape {
$acceptProcessRequestLatency(id: number): number;
$acceptWorkspacePermissionsChanged(isAllowed: boolean): void;
$requestAvailableShells(): Promise<IShellDefinitionDto[]>;
$requestDefaultShell(): Promise<string>;
}
export interface ExtHostSCMShape {
......
......@@ -579,6 +579,10 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
return detectAvailableShells();
}
public $requestDefaultShell(): Promise<string> {
return Promise.resolve(getDefaultShell(platform.platform));
}
private _onProcessExit(id: number, exitCode: number): void {
// Remove listeners
this._terminalProcesses[id].dispose();
......
......@@ -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) {
......@@ -798,7 +779,7 @@ export class TerminalTaskSystem implements ITaskSystem {
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);
this.terminalInstanceService.mergeDefaultShellPathAndArgs(shellLaunchConfig, await this.terminalInstanceService.getDefaultShell(), this.terminalService.configHelper, platform);
let shellSpecified: boolean = false;
let shellOptions: ShellConfiguration | undefined = task.command.options && task.command.options.shell;
if (shellOptions) {
......
......@@ -9,6 +9,7 @@ import { SearchAddon as XTermSearchAddon } from 'xterm-addon-search';
import { ITerminalInstance, IWindowsShellHelper, ITerminalConfigHelper, ITerminalChildProcess, IShellLaunchConfig } from 'vs/workbench/contrib/terminal/common/terminal';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IProcessEnvironment, Platform } from 'vs/base/common/platform';
import { Event } from 'vs/base/common/event';
export const ITerminalInstanceService = createDecorator<ITerminalInstanceService>('terminalInstanceService');
......@@ -20,16 +21,19 @@ export const ITerminalInstanceService = createDecorator<ITerminalInstanceService
export interface ITerminalInstanceService {
_serviceBrand: any;
onRequestDefaultShell?: Event<(defaultShell: string) => void>;
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;
getDefaultShell(): Promise<string>;
getMainProcessParentEnv(): Promise<IProcessEnvironment>;
}
......
......@@ -9,6 +9,7 @@ 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 _onRequestDefaultShell = new Emitter<(defaultShell: string) => void>();
public get onRequestDefaultShell(): Event<(defaultShell: string) => void> { return this._onRequestDefaultShell.event; }
constructor() { }
public async getXtermConstructor(): Promise<typeof XTermTerminal> {
......@@ -48,8 +52,8 @@ export class TerminalInstanceService implements ITerminalInstanceService {
throw new Error('Not implemented');
}
public getDefaultShell(): string {
throw new Error('Not implemented');
public getDefaultShell(): Promise<string> {
return new Promise(r => this._onRequestDefaultShell.fire(r));
}
public async getMainProcessParentEnv(): Promise<IProcessEnvironment> {
......
......@@ -163,7 +163,7 @@ 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);
this._terminalInstanceService.mergeDefaultShellPathAndArgs(shellLaunchConfig, await this._terminalInstanceService.getDefaultShell(), this._configHelper);
}
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file);
......
......@@ -62,10 +62,6 @@ export class TerminalInstanceService implements ITerminalInstanceService {
return this._instantiationService.createInstance(TerminalProcess, shellLaunchConfig, cwd, cols, rows, env, windowsEnableConpty);
}
public getDefaultShell(p: Platform): string {
return getDefaultShell(p);
}
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(
......@@ -79,6 +75,12 @@ export class TerminalInstanceService implements ITerminalInstanceService {
);
}
public getDefaultShell(): Promise<string> {
// Don't go via ext host as that would delay terminal start up until after the extension
// host is ready.
return Promise.resolve(getDefaultShell(platform));
}
public async getMainProcessParentEnv(): Promise<IProcessEnvironment> {
if (this._mainProcessParentEnv) {
return this._mainProcessParentEnv;
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
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';
......@@ -30,6 +30,10 @@ class TestXterm {
}
class MockTerminalInstanceService implements ITerminalInstanceService {
onRequestDefaultShell: any;
getDefaultShell(): Promise<string> {
throw new Error('Method not implemented.');
}
mergeDefaultShellPathAndArgs(): void {
throw new Error('Method not implemented.');
}
......@@ -49,9 +53,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.
先完成此消息的编辑!
想要评论请 注册