提交 bf38fbef 编写于 作者: D Daniel Imms

Remove sync fs call in terminal.ts start up

Fixes #16378
上级 0c89d399
......@@ -23,31 +23,33 @@ import { asFileEditorInput } from 'vs/workbench/common/editor';
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
import { KEYBINDING_CONTEXT_TERMINAL_NOT_FOCUSED } from 'vs/workbench/parts/terminal/common/terminal';
import { DEFAULT_TERMINAL_WINDOWS, DEFAULT_TERMINAL_LINUX, DEFAULT_TERMINAL_OSX } from 'vs/workbench/parts/execution/electron-browser/terminal';
let configurationRegistry = <IConfigurationRegistry>Registry.as(Extensions.Configuration);
configurationRegistry.registerConfiguration({
'id': 'externalTerminal',
'order': 100,
'title': nls.localize('terminalConfigurationTitle', "External Terminal"),
'type': 'object',
'properties': {
'terminal.external.windowsExec': {
'type': 'string',
'description': nls.localize('terminal.external.windowsExec', "Customizes which terminal to run on Windows."),
'default': DEFAULT_TERMINAL_WINDOWS
},
'terminal.external.osxExec': {
'type': 'string',
'description': nls.localize('terminal.external.osxExec', "Customizes which terminal application to run on OS X."),
'default': DEFAULT_TERMINAL_OSX
},
'terminal.external.linuxExec': {
'type': 'string',
'description': nls.localize('terminal.external.linuxExec', "Customizes which terminal to run on Linux."),
'default': DEFAULT_TERMINAL_LINUX
import { DEFAULT_TERMINAL_WINDOWS, DEFAULT_TERMINAL_LINUX_READY, DEFAULT_TERMINAL_OSX } from 'vs/workbench/parts/execution/electron-browser/terminal';
DEFAULT_TERMINAL_LINUX_READY.then(defaultTerminalLinux => {
let configurationRegistry = <IConfigurationRegistry>Registry.as(Extensions.Configuration);
configurationRegistry.registerConfiguration({
'id': 'externalTerminal',
'order': 100,
'title': nls.localize('terminalConfigurationTitle', "External Terminal"),
'type': 'object',
'properties': {
'terminal.external.windowsExec': {
'type': 'string',
'description': nls.localize('terminal.external.windowsExec', "Customizes which terminal to run on Windows."),
'default': DEFAULT_TERMINAL_WINDOWS
},
'terminal.external.osxExec': {
'type': 'string',
'description': nls.localize('terminal.external.osxExec', "Customizes which terminal application to run on OS X."),
'default': DEFAULT_TERMINAL_OSX
},
'terminal.external.linuxExec': {
'type': 'string',
'description': nls.localize('terminal.external.linuxExec', "Customizes which terminal to run on Linux."),
'default': defaultTerminalLinux
}
}
}
});
});
export class OpenConsoleAction extends Action {
......
......@@ -2,25 +2,35 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import fs = require('fs');
'use strict';
import env = require('vs/base/common/platform');
import * as pfs from 'vs/base/node/pfs';
import { TPromise } from 'vs/base/common/winjs.base';
let defaultTerminalLinux = 'xterm';
if (env.isLinux) {
if (fs.existsSync('/etc/debian_version')) {
defaultTerminalLinux = 'x-terminal-emulator';
} else if (process.env.DESKTOP_SESSION === 'gnome' || process.env.DESKTOP_SESSION === 'gnome-classic') {
defaultTerminalLinux = 'gnome-terminal';
} else if (process.env.DESKTOP_SESSION === 'kde-plasma') {
defaultTerminalLinux = 'konsole';
} else if (process.env.COLORTERM) {
defaultTerminalLinux = process.env.COLORTERM;
} else if (process.env.TERM) {
defaultTerminalLinux = process.env.TERM;
export const DEFAULT_TERMINAL_LINUX_READY = new TPromise<string>(c => {
if (env.isLinux) {
pfs.exists('/etc/debian_version').then(isDebian => {
console.log('isDebian' + isDebian);
if (isDebian) {
c('x-terminal-emulator');
} else if (process.env.DESKTOP_SESSION === 'gnome' || process.env.DESKTOP_SESSION === 'gnome-classic') {
c('gnome-terminal');
} else if (process.env.DESKTOP_SESSION === 'kde-plasma') {
c('konsole');
} else if (process.env.COLORTERM) {
c(process.env.COLORTERM);
} else if (process.env.TERM) {
c(process.env.TERM);
} else {
c('xterm');
}
});
return;
}
}
export const DEFAULT_TERMINAL_LINUX = defaultTerminalLinux;
c('xterm');
});
export const DEFAULT_TERMINAL_OSX = 'Terminal.app';
......
......@@ -13,7 +13,7 @@ import errors = require('vs/base/common/errors');
import { TPromise } from 'vs/base/common/winjs.base';
import { ITerminalService } from 'vs/workbench/parts/execution/common/execution';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ITerminalConfiguration, DEFAULT_TERMINAL_WINDOWS, DEFAULT_TERMINAL_LINUX, DEFAULT_TERMINAL_OSX } from 'vs/workbench/parts/execution/electron-browser/terminal';
import { ITerminalConfiguration, DEFAULT_TERMINAL_WINDOWS, DEFAULT_TERMINAL_LINUX_READY, DEFAULT_TERMINAL_OSX } from 'vs/workbench/parts/execution/electron-browser/terminal';
import uri from 'vs/base/common/uri';
import { IProcessEnvironment } from 'vs/base/common/platform';
......@@ -216,62 +216,66 @@ export class LinuxTerminalService implements ITerminalService {
const configuration = this._configurationService.getConfiguration<ITerminalConfiguration>();
const terminalConfig = configuration.terminal.external;
const exec = terminalConfig.linuxExec || DEFAULT_TERMINAL_LINUX;
const execPromise = terminalConfig.linuxExec ? TPromise.as(terminalConfig.linuxExec) : DEFAULT_TERMINAL_LINUX_READY;
return new TPromise<void>((c, e) => {
let termArgs: string[] = [];
//termArgs.push('--title');
//termArgs.push(`"${TERMINAL_TITLE}"`);
if (exec.indexOf('gnome-terminal') >= 0) {
termArgs.push('-x');
} else {
termArgs.push('-e');
}
termArgs.push('bash');
termArgs.push('-c');
execPromise.then(exec => {
if (exec.indexOf('gnome-terminal') >= 0) {
termArgs.push('-x');
} else {
termArgs.push('-e');
}
termArgs.push('bash');
termArgs.push('-c');
const bashCommand = `${quote(args)}; echo; read -p "${LinuxTerminalService.WAIT_MESSAGE}" -n1;`;
termArgs.push(`''${bashCommand}''`); // wrapping argument in two sets of ' because node is so "friendly" that it removes one set...
const bashCommand = `${quote(args)}; echo; read -p "${LinuxTerminalService.WAIT_MESSAGE}" -n1;`;
termArgs.push(`''${bashCommand}''`); // wrapping argument in two sets of ' because node is so "friendly" that it removes one set...
// merge environment variables into a copy of the process.env
const env = extendObject(extendObject({}, process.env), envVars);
// merge environment variables into a copy of the process.env
const env = extendObject(extendObject({}, process.env), envVars);
const options: any = {
cwd: dir,
env: env
};
const options: any = {
cwd: dir,
env: env
};
let stderr = '';
const cmd = cp.spawn(exec, termArgs, options);
cmd.on('error', e);
cmd.stderr.on('data', (data) => {
stderr += data.toString();
});
cmd.on('exit', (code: number) => {
if (code === 0) { // OK
c(null);
} else {
if (stderr) {
const lines = stderr.split('\n', 1);
e(new Error(lines[0]));
let stderr = '';
const cmd = cp.spawn(exec, termArgs, options);
cmd.on('error', e);
cmd.stderr.on('data', (data) => {
stderr += data.toString();
});
cmd.on('exit', (code: number) => {
if (code === 0) { // OK
c(null);
} else {
e(new Error(nls.localize('linux.term.failed', "'{0}' failed with exit code {1}", exec, code)));
if (stderr) {
const lines = stderr.split('\n', 1);
e(new Error(lines[0]));
} else {
e(new Error(nls.localize('linux.term.failed', "'{0}' failed with exit code {1}", exec, code)));
}
}
}
});
});
});
}
private spawnTerminal(spawner, configuration: ITerminalConfiguration, cwd?: string): TPromise<void> {
const terminalConfig = configuration.terminal.external;
const exec = terminalConfig.linuxExec || DEFAULT_TERMINAL_LINUX;
const execPromise = terminalConfig.linuxExec ? TPromise.as(terminalConfig.linuxExec) : DEFAULT_TERMINAL_LINUX_READY;
const env = cwd ? { cwd: cwd } : void 0;
return new TPromise<void>((c, e) => {
const child = spawner.spawn(exec, [], env);
child.on('error', e);
child.on('exit', () => c(null));
execPromise.then(exec => {
const child = spawner.spawn(exec, [], env);
child.on('error', e);
child.on('exit', () => c(null));
});
});
}
}
......
......@@ -7,7 +7,7 @@
import { deepEqual, equal } from 'assert';
import { WinTerminalService, LinuxTerminalService, MacTerminalService } from 'vs/workbench/parts/execution/electron-browser/terminalService';
import { DEFAULT_TERMINAL_WINDOWS, DEFAULT_TERMINAL_LINUX, DEFAULT_TERMINAL_OSX } from 'vs/workbench/parts/execution/electron-browser/terminal';
import { DEFAULT_TERMINAL_WINDOWS, DEFAULT_TERMINAL_LINUX_READY, DEFAULT_TERMINAL_OSX } from 'vs/workbench/parts/execution/electron-browser/terminal';
suite('Execution - TerminalService', () => {
let mockOnExit;
......@@ -196,26 +196,27 @@ suite('Execution - TerminalService', () => {
});
test(`LinuxTerminalService - uses default terminal when configuration.terminal.external.linuxExec is undefined`, done => {
let testCwd = 'path/to/workspace';
let mockSpawner = {
spawn: (command, args, opts) => {
// assert
equal(command, DEFAULT_TERMINAL_LINUX, 'terminal should equal expected');
done();
return {
on: (evt) => evt
};
}
};
mockConfig.terminal.external.linuxExec = undefined;
let testService = new LinuxTerminalService(mockConfig);
(<any>testService).spawnTerminal(
mockSpawner,
mockConfig,
testCwd,
mockOnExit,
mockOnError
);
DEFAULT_TERMINAL_LINUX_READY.then(defaultTerminalLinux => {
let testCwd = 'path/to/workspace';
let mockSpawner = {
spawn: (command, args, opts) => {
// assert
equal(command, defaultTerminalLinux, 'terminal should equal expected');
done();
return {
on: (evt) => evt
};
}
};
mockConfig.terminal.external.linuxExec = undefined;
let testService = new LinuxTerminalService(mockConfig);
(<any>testService).spawnTerminal(
mockSpawner,
mockConfig,
testCwd,
mockOnExit,
mockOnError
);
});
});
});
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册