Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
"native-is-elevated": "0.8.0",
"native-keymap": "^3.3.5",
"native-watchdog": "^1.4.1",
"node-pty": "1.1.0-beta40",
"node-pty": "^1.1.0-beta42",
"open": "^10.1.2",
"tas-client": "0.3.1",
"undici": "^7.9.0",
Expand Down
8 changes: 4 additions & 4 deletions remote/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion remote/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"kerberos": "2.1.1",
"minimist": "^1.2.8",
"native-watchdog": "^1.4.1",
"node-pty": "1.1.0-beta40",
"node-pty": "^1.1.0-beta42",
"tas-client": "0.3.1",
"vscode-oniguruma": "1.7.0",
"vscode-regexpp": "^3.1.0",
Expand Down
38 changes: 0 additions & 38 deletions src/vs/platform/terminal/common/terminalProcess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,41 +69,3 @@ export interface ReplayEntry {
rows: number;
data: string;
}

const enum Constants {
/**
* Writing large amounts of data can be corrupted for some reason, after looking into this is
* appears to be a race condition around writing to the FD which may be based on how powerful
* the hardware is. The workaround for this is to space out when large amounts of data is being
* written to the terminal. See https://github.com/microsoft/vscode/issues/38137
*/
WriteMaxChunkSize = 50,
}

/**
* Splits incoming pty data into chunks to try prevent data corruption that could occur when pasting
* large amounts of data.
*/
export function chunkInput(data: string): string[] {
const chunks: string[] = [];
let nextChunkStartIndex = 0;
for (let i = 0; i < data.length - 1; i++) {
if (
// If the max chunk size is reached
i - nextChunkStartIndex + 1 >= Constants.WriteMaxChunkSize ||
// If the next character is ESC, send the pending data to avoid splitting the escape
// sequence.
data[i + 1] === '\x1b'
) {
chunks.push(data.substring(nextChunkStartIndex, i + 1));
nextChunkStartIndex = i + 1;
// Skip the next character as the chunk would be a single character
i++;
}
}
// Push final chunk
if (nextChunkStartIndex !== data.length) {
chunks.push(data.substring(nextChunkStartIndex));
}
return chunks;
}
60 changes: 8 additions & 52 deletions src/vs/platform/terminal/node/terminalProcess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import { ChildProcessMonitor } from './childProcessMonitor.js';
import { getShellIntegrationInjection, getWindowsBuildNumber, IShellIntegrationConfigInjection } from './terminalEnvironment.js';
import { WindowsShellHelper } from './windowsShellHelper.js';
import { IPty, IPtyForkOptions, IWindowsPtyForkOptions, spawn } from 'node-pty';
import { chunkInput } from '../common/terminalProcess.js';
import { isNumber } from '../../../base/common/types.js';

const enum ShutdownConstants {
Expand Down Expand Up @@ -57,15 +56,6 @@ const enum Constants {
* interval.
*/
KillSpawnSpacingDuration = 50,
/**
* How long to wait between chunk writes.
*/
WriteInterval = 5,
}

interface IWriteObject {
data: string;
isBinary: boolean;
}

const posixShellTypeMap = new Map<string, PosixShellType>([
Expand Down Expand Up @@ -113,8 +103,6 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
private _windowsShellHelper: WindowsShellHelper | undefined;
private _childProcessMonitor: ChildProcessMonitor | undefined;
private _titleInterval: Timeout | undefined;
private _writeQueue: IWriteObject[] = [];
private _writeTimeout: Timeout | undefined;
private _delayedResizer: DelayedResizer | undefined;
private readonly _initialCwd: string;
private readonly _ptyOptions: IPtyForkOptions | IWindowsPtyForkOptions;
Expand Down Expand Up @@ -471,13 +459,15 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
}

input(data: string, isBinary: boolean = false): void {
if (this._store.isDisposed || !this._ptyProcess) {
return;
this._logService.trace('node-pty.IPty#write', data, isBinary);
if (isBinary) {
// TODO: node-pty's write should accept a Buffer, needs https://github.com/microsoft/node-pty/pull/812
// eslint-disable-next-line local/code-no-any-casts, @typescript-eslint/no-explicit-any
this._ptyProcess!.write(Buffer.from(data, 'binary') as any);
} else {
this._ptyProcess!.write(data);
}
this._writeQueue.push(...chunkInput(data).map(e => {
return { isBinary, data: e };
}));
this._startWrite();
this._childProcessMonitor?.handleInput();
}

sendSignal(signal: string): void {
Expand Down Expand Up @@ -522,40 +512,6 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
}
}

private _startWrite(): void {
// Don't write if it's already queued of is there is nothing to write
if (this._writeTimeout !== undefined || this._writeQueue.length === 0) {
return;
}

this._doWrite();

// Don't queue more writes if the queue is empty
if (this._writeQueue.length === 0) {
this._writeTimeout = undefined;
return;
}

// Queue the next write
this._writeTimeout = setTimeout(() => {
this._writeTimeout = undefined;
this._startWrite();
}, Constants.WriteInterval);
}

private _doWrite(): void {
const object = this._writeQueue.shift()!;
this._logService.trace('node-pty.IPty#write', object.data);
if (object.isBinary) {
// TODO: node-pty's write should accept a Buffer, needs https://github.com/microsoft/node-pty/pull/812
// eslint-disable-next-line local/code-no-any-casts, @typescript-eslint/no-explicit-any
this._ptyProcess!.write(Buffer.from(object.data, 'binary') as any);
} else {
this._ptyProcess!.write(object.data);
}
this._childProcessMonitor?.handleInput();
}

resize(cols: number, rows: number): void {
if (this._store.isDisposed) {
return;
Expand Down
41 changes: 0 additions & 41 deletions src/vs/platform/terminal/test/common/terminalProcess.test.ts

This file was deleted.

Loading