Skip to content

Commit 87e1650

Browse files
committed
Call getDefaultShell via ext host on web
Part of microsoft#75795
1 parent c62e57f commit 87e1650

9 files changed

Lines changed: 44 additions & 34 deletions

File tree

src/vs/workbench/api/browser/mainThreadTerminalService.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceS
99
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
1010
import { UriComponents, URI } from 'vs/base/common/uri';
1111
import { StopWatch } from 'vs/base/common/stopwatch';
12+
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
1213

1314
@extHostNamedCustomer(MainContext.MainThreadTerminalService)
1415
export class MainThreadTerminalService implements MainThreadTerminalServiceShape {
@@ -22,10 +23,13 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
2223

2324
constructor(
2425
extHostContext: IExtHostContext,
25-
@ITerminalService private readonly _terminalService: ITerminalService
26+
@ITerminalService private readonly _terminalService: ITerminalService,
27+
@ITerminalInstanceService readonly terminalInstanceService: ITerminalInstanceService
2628
) {
2729
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTerminalService);
2830
this._remoteAuthority = extHostContext.remoteAuthority;
31+
32+
// ITerminalService listeners
2933
this._toDispose.push(_terminalService.onInstanceCreated((instance) => {
3034
// Delay this message so the TerminalInstance constructor has a chance to finish and
3135
// 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
4448
this._toDispose.push(_terminalService.configHelper.onWorkspacePermissionsChanged(isAllowed => this._onWorkspacePermissionsChanged(isAllowed)));
4549
this._toDispose.push(_terminalService.onRequestAvailableShells(r => this._onRequestAvailableShells(r)));
4650

51+
// ITerminalInstanceService listeners
52+
if (terminalInstanceService.onRequestDefaultShell) {
53+
this._toDispose.push(terminalInstanceService.onRequestDefaultShell(r => this._onRequestDefaultShell(r)));
54+
}
55+
4756
// Set initial ext host state
4857
this._terminalService.terminalInstances.forEach(t => {
4958
this._onTerminalOpened(t);
@@ -278,6 +287,10 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
278287
}
279288

280289
private _onRequestAvailableShells(resolve: (shells: IShellDefinition[]) => void): void {
281-
this._proxy.$requestAvailableShells().then(shells => resolve(shells));
290+
this._proxy.$requestAvailableShells().then(e => resolve(e));
291+
}
292+
293+
private _onRequestDefaultShell(resolve: (defaultShell: string) => void): void {
294+
this._proxy.$requestDefaultShell().then(e => resolve(e));
282295
}
283296
}

src/vs/workbench/api/common/extHost.protocol.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,6 +1129,7 @@ export interface ExtHostTerminalServiceShape {
11291129
$acceptProcessRequestLatency(id: number): number;
11301130
$acceptWorkspacePermissionsChanged(isAllowed: boolean): void;
11311131
$requestAvailableShells(): Promise<IShellDefinitionDto[]>;
1132+
$requestDefaultShell(): Promise<string>;
11321133
}
11331134

11341135
export interface ExtHostSCMShape {

src/vs/workbench/api/node/extHostTerminalService.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,10 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
579579
return detectAvailableShells();
580580
}
581581

582+
public $requestDefaultShell(): Promise<string> {
583+
return Promise.resolve(getDefaultShell(platform.platform));
584+
}
585+
582586
private _onProcessExit(id: number, exitCode: number): void {
583587
// Remove listeners
584588
this._terminalProcesses[id].dispose();

src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -763,25 +763,6 @@ export class TerminalTaskSystem implements ITaskSystem {
763763
return nls.localize('TerminalTaskSystem.terminalName', 'Task - {0}', needsFolderQualification ? task.getQualifiedLabel() : task.configurationProperties.name);
764764
}
765765

766-
private getDefaultShell(platform: Platform.Platform): string {
767-
let defaultShell: string | undefined = undefined;
768-
try {
769-
defaultShell = this.terminalInstanceService.getDefaultShell(platform);
770-
} catch {
771-
// Do nothing
772-
}
773-
if (!defaultShell) {
774-
// Make up a guess for the default shell.
775-
if (platform === Platform.Platform.Windows) {
776-
defaultShell = 'cmd.exe';
777-
} else {
778-
defaultShell = 'bash';
779-
}
780-
console.warn('Cannot get the default shell.');
781-
}
782-
return defaultShell;
783-
}
784-
785766
private async getUserHome(): Promise<URI> {
786767
const env = await this.remoteAgentService.getEnvironment();
787768
if (env) {
@@ -798,7 +779,7 @@ export class TerminalTaskSystem implements ITaskSystem {
798779
let originalCommand = task.command.name;
799780
if (isShellCommand) {
800781
shellLaunchConfig = { name: terminalName, executable: undefined, args: undefined, waitOnExit };
801-
this.terminalInstanceService.mergeDefaultShellPathAndArgs(shellLaunchConfig, this.getDefaultShell(platform), this.terminalService.configHelper, platform);
782+
this.terminalInstanceService.mergeDefaultShellPathAndArgs(shellLaunchConfig, await this.terminalInstanceService.getDefaultShell(), this.terminalService.configHelper, platform);
802783
let shellSpecified: boolean = false;
803784
let shellOptions: ShellConfiguration | undefined = task.command.options && task.command.options.shell;
804785
if (shellOptions) {

src/vs/workbench/contrib/terminal/browser/terminal.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { SearchAddon as XTermSearchAddon } from 'xterm-addon-search';
99
import { ITerminalInstance, IWindowsShellHelper, ITerminalConfigHelper, ITerminalChildProcess, IShellLaunchConfig } from 'vs/workbench/contrib/terminal/common/terminal';
1010
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
1111
import { IProcessEnvironment, Platform } from 'vs/base/common/platform';
12+
import { Event } from 'vs/base/common/event';
1213

1314
export const ITerminalInstanceService = createDecorator<ITerminalInstanceService>('terminalInstanceService');
1415

@@ -20,16 +21,19 @@ export const ITerminalInstanceService = createDecorator<ITerminalInstanceService
2021
export interface ITerminalInstanceService {
2122
_serviceBrand: any;
2223

24+
onRequestDefaultShell?: Event<(defaultShell: string) => void>;
25+
2326
getXtermConstructor(): Promise<typeof XTermTerminal>;
2427
getXtermWebLinksConstructor(): Promise<typeof XTermWebLinksAddon>;
2528
getXtermSearchConstructor(): Promise<typeof XTermSearchAddon>;
2629
createWindowsShellHelper(shellProcessId: number, instance: ITerminalInstance, xterm: XTermTerminal): IWindowsShellHelper;
2730
createTerminalProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean): ITerminalChildProcess;
28-
getDefaultShell(p: Platform): string;
2931
/**
3032
* Merges the default shell path and args into the provided launch configuration
3133
*/
3234
mergeDefaultShellPathAndArgs(shell: IShellLaunchConfig, defaultShell: string, configHelper: ITerminalConfigHelper, platformOverride?: Platform): void;
35+
36+
getDefaultShell(): Promise<string>;
3337
getMainProcessParentEnv(): Promise<IProcessEnvironment>;
3438
}
3539

src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { Terminal as XTermTerminal } from 'xterm';
99
import { WebLinksAddon as XTermWebLinksAddon } from 'xterm-addon-web-links';
1010
import { SearchAddon as XTermSearchAddon } from 'xterm-addon-search';
1111
import { IProcessEnvironment } from 'vs/base/common/platform';
12+
import { Emitter, Event } from 'vs/base/common/event';
1213

1314
let Terminal: typeof XTermTerminal;
1415
let WebLinksAddon: typeof XTermWebLinksAddon;
@@ -17,6 +18,9 @@ let SearchAddon: typeof XTermSearchAddon;
1718
export class TerminalInstanceService implements ITerminalInstanceService {
1819
public _serviceBrand: any;
1920

21+
private readonly _onRequestDefaultShell = new Emitter<(defaultShell: string) => void>();
22+
public get onRequestDefaultShell(): Event<(defaultShell: string) => void> { return this._onRequestDefaultShell.event; }
23+
2024
constructor() { }
2125

2226
public async getXtermConstructor(): Promise<typeof XTermTerminal> {
@@ -48,8 +52,8 @@ export class TerminalInstanceService implements ITerminalInstanceService {
4852
throw new Error('Not implemented');
4953
}
5054

51-
public getDefaultShell(): string {
52-
throw new Error('Not implemented');
55+
public getDefaultShell(): Promise<string> {
56+
return new Promise(r => this._onRequestDefaultShell.fire(r));
5357
}
5458

5559
public async getMainProcessParentEnv(): Promise<IProcessEnvironment> {

src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ export class TerminalProcessManager implements ITerminalProcessManager {
163163

164164
private async _launchProcess(shellLaunchConfig: IShellLaunchConfig, cols: number, rows: number): Promise<ITerminalChildProcess> {
165165
if (!shellLaunchConfig.executable) {
166-
this._terminalInstanceService.mergeDefaultShellPathAndArgs(shellLaunchConfig, this._terminalInstanceService.getDefaultShell(platform.platform), this._configHelper);
166+
this._terminalInstanceService.mergeDefaultShellPathAndArgs(shellLaunchConfig, await this._terminalInstanceService.getDefaultShell(), this._configHelper);
167167
}
168168

169169
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file);

src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,6 @@ export class TerminalInstanceService implements ITerminalInstanceService {
6262
return this._instantiationService.createInstance(TerminalProcess, shellLaunchConfig, cwd, cols, rows, env, windowsEnableConpty);
6363
}
6464

65-
public getDefaultShell(p: Platform): string {
66-
return getDefaultShell(p);
67-
}
68-
6965
public mergeDefaultShellPathAndArgs(shell: IShellLaunchConfig, defaultShell: string, configHelper: ITerminalConfigHelper, platformOverride: Platform = platform): void {
7066
const isWorkspaceShellAllowed = configHelper.checkWorkspaceShellPermissions(platformOverride === Platform.Windows ? OperatingSystem.Windows : (platformOverride === Platform.Mac ? OperatingSystem.Macintosh : OperatingSystem.Linux));
7167
mergeDefaultShellPathAndArgs(
@@ -79,6 +75,12 @@ export class TerminalInstanceService implements ITerminalInstanceService {
7975
);
8076
}
8177

78+
public getDefaultShell(): Promise<string> {
79+
// Don't go via ext host as that would delay terminal start up until after the extension
80+
// host is ready.
81+
return Promise.resolve(getDefaultShell(platform));
82+
}
83+
8284
public async getMainProcessParentEnv(): Promise<IProcessEnvironment> {
8385
if (this._mainProcessParentEnv) {
8486
return this._mainProcessParentEnv;

src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import * as assert from 'assert';
7-
import { Platform, OperatingSystem } from 'vs/base/common/platform';
7+
import { OperatingSystem } from 'vs/base/common/platform';
88
import { TerminalLinkHandler, LineColumnInfo } from 'vs/workbench/contrib/terminal/browser/terminalLinkHandler';
99
import * as strings from 'vs/base/common/strings';
1010
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
@@ -30,6 +30,10 @@ class TestXterm {
3030
}
3131

3232
class MockTerminalInstanceService implements ITerminalInstanceService {
33+
onRequestDefaultShell: any;
34+
getDefaultShell(): Promise<string> {
35+
throw new Error('Method not implemented.');
36+
}
3337
mergeDefaultShellPathAndArgs(): void {
3438
throw new Error('Method not implemented.');
3539
}
@@ -49,9 +53,6 @@ class MockTerminalInstanceService implements ITerminalInstanceService {
4953
createTerminalProcess(): any {
5054
throw new Error('Method not implemented.');
5155
}
52-
getDefaultShell(p: Platform): string {
53-
throw new Error('Method not implemented.');
54-
}
5556
getMainProcessParentEnv(): any {
5657
throw new Error('Method not implemented.');
5758
}

0 commit comments

Comments
 (0)