Skip to content

Commit 13940e6

Browse files
committed
more ExternalTerminalService cleanup
1 parent a57a43d commit 13940e6

2 files changed

Lines changed: 64 additions & 92 deletions

File tree

src/vs/workbench/contrib/externalTerminal/node/externalTerminalService.ts

Lines changed: 61 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -17,42 +17,32 @@ import { IConfigurationRegistry, Extensions, ConfigurationScope } from 'vs/platf
1717
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
1818
import { Registry } from 'vs/platform/registry/common/platform';
1919
import { ITerminalSettings } from 'vs/workbench/contrib/debug/common/debug';
20+
import { optional } from 'vs/platform/instantiation/common/instantiation';
2021

2122

2223
const TERMINAL_TITLE = nls.localize('console.title', "VS Code Console");
2324
export const DEFAULT_TERMINAL_OSX = 'Terminal.app';
2425

25-
enum WinSpawnType {
26-
CMD,
27-
CMDER
28-
}
29-
3026
export class WindowsExternalTerminalService implements IExternalTerminalService {
3127
public _serviceBrand: any;
3228

3329
private static readonly CMD = 'cmd.exe';
3430

3531
constructor(
36-
@IConfigurationService private readonly _configurationService: IConfigurationService
32+
@optional(IConfigurationService) private readonly _configurationService: IConfigurationService
3733
) {
3834
}
3935

4036
public openTerminal(cwd?: string): void {
41-
const configuration = this._configurationService.getValue<IExternalTerminalConfiguration>();
42-
43-
this.spawnTerminal(cp, configuration, processes.getWindowsShell(), cwd);
44-
}
45-
46-
/*
47-
public runInTerminal(title: string, dir: string, args: string[], envVars: env.IProcessEnvironment): Promise<number | undefined> {
48-
const configuration = this._configurationService.getValue<IExternalTerminalConfiguration>();
49-
return this.runInTerminal0(title, dir, args, envVars, configuration.terminal);
37+
if (this._configurationService) {
38+
const configuration = this._configurationService.getValue<IExternalTerminalConfiguration>();
39+
this.spawnTerminal(cp, configuration, processes.getWindowsShell(), cwd);
40+
}
5041
}
51-
*/
5242

5343
public runInTerminal(title: string, dir: string, args: string[], envVars: env.IProcessEnvironment, configuration: ITerminalSettings): Promise<number | undefined> {
5444

55-
const exec = configuration.external.windowsExec || getDefaultTerminalWindows();
45+
const exec = configuration.external.windowsExec || WindowsExternalTerminalService.getDefaultTerminalWindows();
5646

5747
return new Promise<number | undefined>((resolve, reject) => {
5848

@@ -86,8 +76,7 @@ export class WindowsExternalTerminalService implements IExternalTerminalService
8676

8777
private spawnTerminal(spawner: typeof cp, configuration: IExternalTerminalConfiguration, command: string, cwd?: string): Promise<void> {
8878
const terminalConfig = configuration.terminal.external;
89-
const exec = terminalConfig.windowsExec || getDefaultTerminalWindows();
90-
const spawnType = this.getSpawnType(exec);
79+
const exec = terminalConfig.windowsExec || WindowsExternalTerminalService.getDefaultTerminalWindows();
9180

9281
// Make the drive letter uppercase on Windows (see #9448)
9382
if (cwd && cwd[1] === ':') {
@@ -96,7 +85,8 @@ export class WindowsExternalTerminalService implements IExternalTerminalService
9685

9786
// cmder ignores the environment cwd and instead opts to always open in %USERPROFILE%
9887
// unless otherwise specified
99-
if (spawnType === WinSpawnType.CMDER) {
88+
const basename = path.basename(exec).toLowerCase();
89+
if (basename === 'cmder' || basename === 'cmder.exe') {
10090
spawner.spawn(exec, cwd ? [cwd] : undefined);
10191
return Promise.resolve(undefined);
10292
}
@@ -117,12 +107,14 @@ export class WindowsExternalTerminalService implements IExternalTerminalService
117107
});
118108
}
119109

120-
private getSpawnType(exec: string): WinSpawnType {
121-
const basename = path.basename(exec).toLowerCase();
122-
if (basename === 'cmder' || basename === 'cmder.exe') {
123-
return WinSpawnType.CMDER;
110+
private static _DEFAULT_TERMINAL_WINDOWS: string;
111+
112+
public static getDefaultTerminalWindows(): string {
113+
if (!WindowsExternalTerminalService._DEFAULT_TERMINAL_WINDOWS) {
114+
const isWoW64 = !!process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432');
115+
WindowsExternalTerminalService._DEFAULT_TERMINAL_WINDOWS = `${process.env.windir ? process.env.windir : 'C:\\Windows'}\\${isWoW64 ? 'Sysnative' : 'System32'}\\cmd.exe`;
124116
}
125-
return WinSpawnType.CMD;
117+
return WindowsExternalTerminalService._DEFAULT_TERMINAL_WINDOWS;
126118
}
127119
}
128120

@@ -132,21 +124,15 @@ export class MacExternalTerminalService implements IExternalTerminalService {
132124
private static readonly OSASCRIPT = '/usr/bin/osascript'; // osascript is the AppleScript interpreter on OS X
133125

134126
constructor(
135-
@IConfigurationService private readonly _configurationService: IConfigurationService
127+
@optional(IConfigurationService) private readonly _configurationService: IConfigurationService
136128
) { }
137129

138130
public openTerminal(cwd?: string): void {
139-
const configuration = this._configurationService.getValue<IExternalTerminalConfiguration>();
140-
141-
this.spawnTerminal(cp, configuration, cwd);
142-
}
143-
144-
/*
145-
public runInTerminal(title: string, dir: string, args: string[], envVars: env.IProcessEnvironment): Promise<number | undefined> {
146-
const configuration = this._configurationService.getValue<IExternalTerminalConfiguration>();
147-
return this.runInTerminal0(title, dir, args, envVars, configuration.terminal);
131+
if (this._configurationService) {
132+
const configuration = this._configurationService.getValue<IExternalTerminalConfiguration>();
133+
this.spawnTerminal(cp, configuration, cwd);
134+
}
148135
}
149-
*/
150136

151137
public runInTerminal(title: string, dir: string, args: string[], envVars: env.IProcessEnvironment, configuration: ITerminalSettings): Promise<number | undefined> {
152138

@@ -234,26 +220,20 @@ export class LinuxExternalTerminalService implements IExternalTerminalService {
234220
private static readonly WAIT_MESSAGE = nls.localize('press.any.key', "Press any key to continue...");
235221

236222
constructor(
237-
@IConfigurationService private readonly _configurationService: IConfigurationService
223+
@optional(IConfigurationService) private readonly _configurationService: IConfigurationService
238224
) { }
239225

240226
public openTerminal(cwd?: string): void {
241-
const configuration = this._configurationService.getValue<IExternalTerminalConfiguration>();
242-
243-
this.spawnTerminal(cp, configuration, cwd);
244-
}
245-
246-
/*
247-
public runInTerminal(title: string, dir: string, args: string[], envVars: env.IProcessEnvironment): Promise<number | undefined> {
248-
const configuration = this._configurationService.getValue<IExternalTerminalConfiguration>();
249-
return this.runInTerminal0(title, dir, args, envVars, configuration.terminal);
227+
if (this._configurationService) {
228+
const configuration = this._configurationService.getValue<IExternalTerminalConfiguration>();
229+
this.spawnTerminal(cp, configuration, cwd);
230+
}
250231
}
251-
*/
252232

253233
public runInTerminal(title: string, dir: string, args: string[], envVars: env.IProcessEnvironment, configuration: ITerminalSettings): Promise<number | undefined> {
254234

255235
const terminalConfig = configuration.external;
256-
const execPromise = terminalConfig.linuxExec ? Promise.resolve(terminalConfig.linuxExec) : getDefaultTerminalLinuxReady();
236+
const execPromise = terminalConfig.linuxExec ? Promise.resolve(terminalConfig.linuxExec) : LinuxExternalTerminalService.getDefaultTerminalLinuxReady();
257237

258238
return new Promise<number | undefined>((resolve, reject) => {
259239

@@ -309,7 +289,7 @@ export class LinuxExternalTerminalService implements IExternalTerminalService {
309289

310290
private spawnTerminal(spawner: typeof cp, configuration: IExternalTerminalConfiguration, cwd?: string): Promise<void> {
311291
const terminalConfig = configuration.terminal.external;
312-
const execPromise = terminalConfig.linuxExec ? Promise.resolve(terminalConfig.linuxExec) : getDefaultTerminalLinuxReady();
292+
const execPromise = terminalConfig.linuxExec ? Promise.resolve(terminalConfig.linuxExec) : LinuxExternalTerminalService.getDefaultTerminalLinuxReady();
313293

314294
return new Promise<void>((c, e) => {
315295
execPromise.then(exec => {
@@ -320,6 +300,36 @@ export class LinuxExternalTerminalService implements IExternalTerminalService {
320300
});
321301
});
322302
}
303+
304+
private static _DEFAULT_TERMINAL_LINUX_READY: Promise<string>;
305+
306+
public static getDefaultTerminalLinuxReady(): Promise<string> {
307+
if (!LinuxExternalTerminalService._DEFAULT_TERMINAL_LINUX_READY) {
308+
LinuxExternalTerminalService._DEFAULT_TERMINAL_LINUX_READY = new Promise<string>(c => {
309+
if (env.isLinux) {
310+
Promise.all([pfs.exists('/etc/debian_version'), process.lazyEnv || Promise.resolve(undefined)]).then(([isDebian]) => {
311+
if (isDebian) {
312+
c('x-terminal-emulator');
313+
} else if (process.env.DESKTOP_SESSION === 'gnome' || process.env.DESKTOP_SESSION === 'gnome-classic') {
314+
c('gnome-terminal');
315+
} else if (process.env.DESKTOP_SESSION === 'kde-plasma') {
316+
c('konsole');
317+
} else if (process.env.COLORTERM) {
318+
c(process.env.COLORTERM);
319+
} else if (process.env.TERM) {
320+
c(process.env.TERM);
321+
} else {
322+
c('xterm');
323+
}
324+
});
325+
return;
326+
}
327+
328+
c('xterm');
329+
});
330+
}
331+
return LinuxExternalTerminalService._DEFAULT_TERMINAL_LINUX_READY;
332+
}
323333
}
324334

325335
/**
@@ -348,44 +358,6 @@ function quote(args: string[]): string {
348358
return r;
349359
}
350360

351-
let _DEFAULT_TERMINAL_WINDOWS: string | null = null;
352-
export function getDefaultTerminalWindows(): string {
353-
if (!_DEFAULT_TERMINAL_WINDOWS) {
354-
const isWoW64 = !!process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432');
355-
_DEFAULT_TERMINAL_WINDOWS = `${process.env.windir ? process.env.windir : 'C:\\Windows'}\\${isWoW64 ? 'Sysnative' : 'System32'}\\cmd.exe`;
356-
}
357-
return _DEFAULT_TERMINAL_WINDOWS;
358-
}
359-
360-
let _DEFAULT_TERMINAL_LINUX_READY: Promise<string> | null = null;
361-
export function getDefaultTerminalLinuxReady(): Promise<string> {
362-
if (!_DEFAULT_TERMINAL_LINUX_READY) {
363-
_DEFAULT_TERMINAL_LINUX_READY = new Promise<string>(c => {
364-
if (env.isLinux) {
365-
Promise.all([pfs.exists('/etc/debian_version'), process.lazyEnv || Promise.resolve(undefined)]).then(([isDebian]) => {
366-
if (isDebian) {
367-
c('x-terminal-emulator');
368-
} else if (process.env.DESKTOP_SESSION === 'gnome' || process.env.DESKTOP_SESSION === 'gnome-classic') {
369-
c('gnome-terminal');
370-
} else if (process.env.DESKTOP_SESSION === 'kde-plasma') {
371-
c('konsole');
372-
} else if (process.env.COLORTERM) {
373-
c(process.env.COLORTERM);
374-
} else if (process.env.TERM) {
375-
c(process.env.TERM);
376-
} else {
377-
c('xterm');
378-
}
379-
});
380-
return;
381-
}
382-
383-
c('xterm');
384-
});
385-
}
386-
return _DEFAULT_TERMINAL_LINUX_READY;
387-
}
388-
389361
if (env.isWindows) {
390362
registerSingleton(IExternalTerminalService, WindowsExternalTerminalService, true);
391363
} else if (env.isMacintosh) {
@@ -394,7 +366,7 @@ if (env.isWindows) {
394366
registerSingleton(IExternalTerminalService, LinuxExternalTerminalService, true);
395367
}
396368

397-
getDefaultTerminalLinuxReady().then(defaultTerminalLinux => {
369+
LinuxExternalTerminalService.getDefaultTerminalLinuxReady().then(defaultTerminalLinux => {
398370
let configurationRegistry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);
399371
configurationRegistry.registerConfiguration({
400372
id: 'externalTerminal',
@@ -418,7 +390,7 @@ getDefaultTerminalLinuxReady().then(defaultTerminalLinux => {
418390
'terminal.external.windowsExec': {
419391
type: 'string',
420392
description: nls.localize('terminal.external.windowsExec', "Customizes which terminal to run on Windows."),
421-
default: getDefaultTerminalWindows(),
393+
default: WindowsExternalTerminalService.getDefaultTerminalWindows(),
422394
scope: ConfigurationScope.APPLICATION
423395
},
424396
'terminal.external.osxExec': {

src/vs/workbench/contrib/externalTerminal/test/electron-browser/externalTerminalService.test.ts

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

66
import { deepEqual, equal } from 'assert';
7-
import { WindowsExternalTerminalService, LinuxExternalTerminalService, MacExternalTerminalService, DEFAULT_TERMINAL_OSX, getDefaultTerminalWindows, getDefaultTerminalLinuxReady } from 'vs/workbench/contrib/externalTerminal/node/externalTerminalService';
7+
import { WindowsExternalTerminalService, LinuxExternalTerminalService, MacExternalTerminalService, DEFAULT_TERMINAL_OSX } from 'vs/workbench/contrib/externalTerminal/node/externalTerminalService';
88

99
suite('ExternalTerminalService', () => {
1010
let mockOnExit: Function;
@@ -58,7 +58,7 @@ suite('ExternalTerminalService', () => {
5858
let mockSpawner = {
5959
spawn: (command: any, args: any, opts: any) => {
6060
// assert
61-
equal(args[args.length - 1], getDefaultTerminalWindows(), 'terminal should equal expected');
61+
equal(args[args.length - 1], WindowsExternalTerminalService.getDefaultTerminalWindows(), 'terminal should equal expected');
6262
done();
6363
return {
6464
on: (evt: any) => evt
@@ -194,7 +194,7 @@ suite('ExternalTerminalService', () => {
194194
});
195195

196196
test(`LinuxTerminalService - uses default terminal when configuration.terminal.external.linuxExec is undefined`, done => {
197-
getDefaultTerminalLinuxReady().then(defaultTerminalLinux => {
197+
LinuxExternalTerminalService.getDefaultTerminalLinuxReady().then(defaultTerminalLinux => {
198198
let testCwd = 'path/to/workspace';
199199
let mockSpawner = {
200200
spawn: (command: any, args: any, opts: any) => {

0 commit comments

Comments
 (0)