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

Merge pull request #65569 from Microsoft/tyriar/conpty

Add terminal ConPTY support on Windows
......@@ -25,6 +25,11 @@ declare module 'node-pty' {
uid?: number;
gid?: number;
encoding?: string;
/**
* Whether to use the experimental ConPTY system on Windows. This setting will be ignored on
* non-Windows.
*/
experimentalUseConpty?: boolean;
}
/**
......
......@@ -413,7 +413,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
// Fork the process and listen for messages
this._logService.debug(`Terminal process launching on ext host`, shellLaunchConfig, initialCwd, cols, rows, env);
this._terminalProcesses[id] = new TerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env);
this._terminalProcesses[id] = new TerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, terminalConfig.get('windowsEnableConpty'));
this._terminalProcesses[id].onProcessIdReady(pid => this._proxy.$sendProcessPid(id, pid));
this._terminalProcesses[id].onProcessTitleChanged(title => this._proxy.$sendProcessTitle(id, title));
this._terminalProcesses[id].onProcessData(data => this._proxy.$sendProcessData(id, data));
......
......@@ -102,6 +102,7 @@ export interface ITerminalConfiguration {
showExitAlert: boolean;
experimentalBufferImpl: 'JsArray' | 'TypedArray';
splitCwd: 'workspaceRoot' | 'initial' | 'inherited';
windowsEnableConpty: boolean;
}
export interface ITerminalConfigHelper {
......
......@@ -397,6 +397,11 @@ configurationRegistry.registerConfiguration({
],
default: 'inherited'
},
'terminal.integrated.windowsEnableConpty': {
description: nls.localize('terminal.integrated.windowsEnableConpty', "Whether to use ConPTY for Windows terminal process communication (requires Windows 10 build number 17692+). The default is to enable this on Windows 10 build number 17692+. Winpty will be used if this is false."),
type: 'boolean',
default: true
}
}
});
......
......@@ -133,7 +133,7 @@ export class TerminalProcessManager implements ITerminalProcessManager {
terminalEnvironment.addTerminalEnvironmentKeys(env, platform.locale, this._configHelper.config.setLocaleVariables);
this._logService.debug(`Terminal process launching`, shellLaunchConfig, this.initialCwd, cols, rows, env);
this._process = new TerminalProcess(shellLaunchConfig, this.initialCwd, cols, rows, env);
this._process = new TerminalProcess(shellLaunchConfig, this.initialCwd, cols, rows, env, this._configHelper.config.windowsEnableConpty);
}
this.processState = ProcessState.LAUNCHING;
......
......@@ -18,6 +18,8 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
private _ptyProcess: pty.IPty;
private _currentTitle: string = '';
private _processStartupComplete: Promise<void>;
private _isDisposed: boolean = false;
private _titleInterval: number = -1;
private readonly _onProcessData = new Emitter<string>();
public get onProcessData(): Event<string> { return this._onProcessData.event; }
......@@ -33,7 +35,8 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
cwd: string,
cols: number,
rows: number,
env: platform.IProcessEnvironment
env: platform.IProcessEnvironment,
windowsEnableConpty: boolean
) {
let shellName: string;
if (os.platform() === 'win32') {
......@@ -49,7 +52,8 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
cwd,
env,
cols,
rows
rows,
experimentalUseConpty: windowsEnableConpty
};
try {
......@@ -86,6 +90,9 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
}
public dispose(): void {
this._isDisposed = true;
window.clearInterval(this._titleInterval);
this._titleInterval = -1;
this._onProcessData.dispose();
this._onProcessExit.dispose();
this._onProcessIdReady.dispose();
......@@ -98,7 +105,7 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
this._sendProcessTitle();
}, 0);
// Setup polling
setInterval(() => {
this._titleInterval = window.setInterval(() => {
if (this._currentTitle !== this._ptyProcess.process) {
this._sendProcessTitle();
}
......@@ -118,6 +125,9 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
// Wait to kill to process until the start up code has run. This prevents us from firing a process exit before a
// process start.
this._processStartupComplete.then(() => {
if (this._isDisposed) {
return;
}
// Attempt to kill the pty, it may have already been killed at this
// point but we want to make sure
try {
......@@ -135,6 +145,9 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
}
private _sendProcessTitle(): void {
if (this._isDisposed) {
return;
}
this._currentTitle = this._ptyProcess.process;
this._onProcessTitleChanged.fire(this._currentTitle);
}
......@@ -148,10 +161,16 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
}
public input(data: string): void {
if (this._isDisposed) {
return;
}
this._ptyProcess.write(data);
}
public resize(cols: number, rows: number): void {
if (this._isDisposed) {
return;
}
// Ensure that cols and rows are always >= 1, this prevents a native
// exception in winpty.
this._ptyProcess.resize(Math.max(cols, 1), Math.max(rows, 1));
......
......@@ -5988,10 +5988,10 @@ node-pre-gyp@^0.10.0:
semver "^5.3.0"
tar "^4"
node-pty@0.7.8:
version "0.7.8"
resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.7.8.tgz#9ed2f01f84263acc96982876e734aa75490bf3d8"
integrity sha512-2c2tZtGnvIJUWw8fDipxO953Mytqc5/IdRZK+YF52NtFMNTuWCQ41QDLEx76W64MEZkfDMoZyah6KPmyW1LO7g==
node-pty@0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.8.0.tgz#08bccb633f49e2e3f7245eb56ea6b40f37ccd64f"
integrity sha512-g5ggk3gN4gLrDmAllee5ScFyX3YzpOC/U8VJafha4pE7do0TIE1voiIxEbHSRUOPD1xYqmY+uHhOKAd3avbxGQ==
dependencies:
nan "2.10.0"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册