parent
f7e4c0aa9e
commit
3a902162b4
|
@ -200,6 +200,7 @@ export interface IPtyService {
|
|||
cwd: string,
|
||||
cols: number,
|
||||
rows: number,
|
||||
unicodeVersion: '6' | '11',
|
||||
env: IProcessEnvironment,
|
||||
executableEnv: IProcessEnvironment,
|
||||
windowsEnableConpty: boolean,
|
||||
|
@ -223,6 +224,7 @@ export interface IPtyService {
|
|||
getCwd(id: number): Promise<string>;
|
||||
getLatency(id: number): Promise<number>;
|
||||
acknowledgeDataEvent(id: number, charCount: number): Promise<void>;
|
||||
setUnicodeVersion(id: number, version: '6' | '11'): Promise<void>;
|
||||
processBinary(id: number, data: string): Promise<void>;
|
||||
/** Confirm the process is _not_ an orphan. */
|
||||
orphanQuestionReply(id: number): Promise<void>;
|
||||
|
@ -485,6 +487,12 @@ export interface ITerminalChildProcess {
|
|||
*/
|
||||
acknowledgeDataEvent(charCount: number): void;
|
||||
|
||||
/**
|
||||
* Sets the unicode version for the process, this drives the size of some characters in the
|
||||
* xterm-headless instance.
|
||||
*/
|
||||
setUnicodeVersion(version: '6' | '11'): Promise<void>;
|
||||
|
||||
getInitialCwd(): Promise<string>;
|
||||
getCwd(): Promise<string>;
|
||||
getLatency(): Promise<number>;
|
||||
|
|
|
@ -20,7 +20,8 @@ export interface IRemoteTerminalProcessReplayEvent {
|
|||
export interface ITerminalSerializer {
|
||||
handleData(data: string): void;
|
||||
handleResize(cols: number, rows: number): void;
|
||||
generateReplayEvent(): IPtyHostProcessReplayEvent;
|
||||
generateReplayEvent(): Promise<IPtyHostProcessReplayEvent>;
|
||||
setUnicodeVersion?(version: '6' | '11'): void;
|
||||
}
|
||||
|
||||
export class TerminalRecorder implements ITerminalSerializer {
|
||||
|
@ -82,7 +83,7 @@ export class TerminalRecorder implements ITerminalSerializer {
|
|||
}
|
||||
}
|
||||
|
||||
generateReplayEvent(): IPtyHostProcessReplayEvent {
|
||||
generateReplayEventSync(): IPtyHostProcessReplayEvent {
|
||||
// normalize entries to one element per data array
|
||||
this._entries.forEach((entry) => {
|
||||
if (entry.data.length > 0) {
|
||||
|
@ -93,4 +94,8 @@ export class TerminalRecorder implements ITerminalSerializer {
|
|||
events: this._entries.map(entry => ({ cols: entry.cols, rows: entry.rows, data: entry.data[0] ?? '' }))
|
||||
};
|
||||
}
|
||||
|
||||
async generateReplayEvent(): Promise<IPtyHostProcessReplayEvent> {
|
||||
return this.generateReplayEventSync();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -178,9 +178,9 @@ export class PtyHostService extends Disposable implements IPtyService {
|
|||
super.dispose();
|
||||
}
|
||||
|
||||
async createProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, executableEnv: IProcessEnvironment, windowsEnableConpty: boolean, shouldPersist: boolean, workspaceId: string, workspaceName: string): Promise<number> {
|
||||
async createProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, unicodeVersion: '6' | '11', env: IProcessEnvironment, executableEnv: IProcessEnvironment, windowsEnableConpty: boolean, shouldPersist: boolean, workspaceId: string, workspaceName: string): Promise<number> {
|
||||
const timeout = setTimeout(() => this._handleUnresponsiveCreateProcess(), HeartbeatConstants.CreateProcessTimeout);
|
||||
const id = await this._proxy.createProcess(shellLaunchConfig, cwd, cols, rows, env, executableEnv, windowsEnableConpty, shouldPersist, workspaceId, workspaceName);
|
||||
const id = await this._proxy.createProcess(shellLaunchConfig, cwd, cols, rows, unicodeVersion, env, executableEnv, windowsEnableConpty, shouldPersist, workspaceId, workspaceName);
|
||||
clearTimeout(timeout);
|
||||
lastPtyId = Math.max(lastPtyId, id);
|
||||
return id;
|
||||
|
@ -221,6 +221,9 @@ export class PtyHostService extends Disposable implements IPtyService {
|
|||
acknowledgeDataEvent(id: number, charCount: number): Promise<void> {
|
||||
return this._proxy.acknowledgeDataEvent(id, charCount);
|
||||
}
|
||||
setUnicodeVersion(id: number, version: '6' | '11'): Promise<void> {
|
||||
return this._proxy.setUnicodeVersion(id, version);
|
||||
}
|
||||
getInitialCwd(id: number): Promise<string> {
|
||||
return this._proxy.getInitialCwd(id);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,8 @@ import { IProcessDataEvent, IProcessReadyEvent, IPtyService, IRawTerminalInstanc
|
|||
import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering';
|
||||
import { escapeNonWindowsPath } from 'vs/platform/terminal/common/terminalEnvironment';
|
||||
import { Terminal as XtermTerminal } from 'xterm-headless';
|
||||
import { SerializeAddon } from 'xterm-addon-serialize';
|
||||
import type { SerializeAddon as XtermSerializeAddon } from 'xterm-addon-serialize';
|
||||
import type { Unicode11Addon as XtermUnicode11Addon } from 'xterm-addon-unicode11';
|
||||
import { IGetTerminalLayoutInfoArgs, IProcessDetails, IPtyHostProcessReplayEvent, ISetTerminalLayoutInfoArgs, ITerminalTabLayoutInfoDto } from 'vs/platform/terminal/common/terminalProcess';
|
||||
import { ITerminalSerializer, TerminalRecorder } from 'vs/platform/terminal/common/terminalRecorder';
|
||||
import { getWindowsBuildNumber } from 'vs/platform/terminal/node/terminalEnvironment';
|
||||
|
@ -24,6 +25,9 @@ import { TerminalProcess } from 'vs/platform/terminal/node/terminalProcess';
|
|||
|
||||
type WorkspaceId = string;
|
||||
|
||||
let SerializeAddon: typeof XtermSerializeAddon;
|
||||
let Unicode11Addon: typeof XtermUnicode11Addon;
|
||||
|
||||
export class PtyService extends Disposable implements IPtyService {
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
|
@ -102,6 +106,7 @@ export class PtyService extends Disposable implements IPtyService {
|
|||
cwd: string,
|
||||
cols: number,
|
||||
rows: number,
|
||||
unicodeVersion: '6' | '11',
|
||||
env: IProcessEnvironment,
|
||||
executableEnv: IProcessEnvironment,
|
||||
windowsEnableConpty: boolean,
|
||||
|
@ -125,7 +130,7 @@ export class PtyService extends Disposable implements IPtyService {
|
|||
if (process.onDidChangeHasChildProcesses) {
|
||||
process.onDidChangeHasChildProcesses(event => this._onProcessDidChangeHasChildProcesses.fire({ id, event }));
|
||||
}
|
||||
const persistentProcess = new PersistentTerminalProcess(id, process, workspaceId, workspaceName, shouldPersist, cols, rows, this._reconnectConstants, this._logService, shellLaunchConfig.icon);
|
||||
const persistentProcess = new PersistentTerminalProcess(id, process, workspaceId, workspaceName, shouldPersist, cols, rows, unicodeVersion, this._reconnectConstants, this._logService, shellLaunchConfig.icon);
|
||||
process.onProcessExit(() => {
|
||||
persistentProcess.dispose();
|
||||
this._ptys.delete(id);
|
||||
|
@ -204,6 +209,9 @@ export class PtyService extends Disposable implements IPtyService {
|
|||
async acknowledgeDataEvent(id: number, charCount: number): Promise<void> {
|
||||
return this._throwIfNoPty(id).acknowledgeDataEvent(charCount);
|
||||
}
|
||||
async setUnicodeVersion(id: number, version: '6' | '11'): Promise<void> {
|
||||
return this._throwIfNoPty(id).setUnicodeVersion(version);
|
||||
}
|
||||
async getLatency(id: number): Promise<number> {
|
||||
return 0;
|
||||
}
|
||||
|
@ -364,6 +372,7 @@ export class PersistentTerminalProcess extends Disposable {
|
|||
readonly shouldPersistTerminal: boolean,
|
||||
cols: number,
|
||||
rows: number,
|
||||
unicodeVersion: '6' | '11',
|
||||
reconnectConstants: IReconnectConstants,
|
||||
private readonly _logService: ILogService,
|
||||
private _icon?: TerminalIcon,
|
||||
|
@ -376,7 +385,8 @@ export class PersistentTerminalProcess extends Disposable {
|
|||
this._serializer = new XtermSerializer(
|
||||
cols,
|
||||
rows,
|
||||
reconnectConstants.scrollback
|
||||
reconnectConstants.scrollback,
|
||||
unicodeVersion
|
||||
);
|
||||
} else {
|
||||
this._serializer = new TerminalRecorder(cols, rows);
|
||||
|
@ -463,6 +473,10 @@ export class PersistentTerminalProcess extends Disposable {
|
|||
this._bufferer.flushBuffer(this._persistentProcessId);
|
||||
return this._terminalProcess.resize(cols, rows);
|
||||
}
|
||||
setUnicodeVersion(version: '6' | '11'): void {
|
||||
this._serializer.setUnicodeVersion?.(version);
|
||||
// TODO: Pass in unicode version in ctor
|
||||
}
|
||||
acknowledgeDataEvent(charCount: number): void {
|
||||
if (this._inReplay) {
|
||||
return;
|
||||
|
@ -479,8 +493,8 @@ export class PersistentTerminalProcess extends Disposable {
|
|||
return this._terminalProcess.getLatency();
|
||||
}
|
||||
|
||||
triggerReplay(): void {
|
||||
const ev = this._serializer.generateReplayEvent();
|
||||
async triggerReplay(): Promise<void> {
|
||||
const ev = await this._serializer.generateReplayEvent();
|
||||
let dataLength = 0;
|
||||
for (const e of ev.events) {
|
||||
dataLength += e.data.length;
|
||||
|
@ -543,8 +557,16 @@ export class PersistentTerminalProcess extends Disposable {
|
|||
|
||||
class XtermSerializer implements ITerminalSerializer {
|
||||
private _xterm: XtermTerminal;
|
||||
constructor(cols: number, rows: number, scrollback: number) {
|
||||
private _unicodeAddon?: XtermUnicode11Addon;
|
||||
|
||||
constructor(
|
||||
cols: number,
|
||||
rows: number,
|
||||
scrollback: number,
|
||||
unicodeVersion: '6' | '11'
|
||||
) {
|
||||
this._xterm = new XtermTerminal({ cols, rows, scrollback });
|
||||
this.setUnicodeVersion(unicodeVersion);
|
||||
}
|
||||
|
||||
handleData(data: string): void {
|
||||
|
@ -555,8 +577,8 @@ class XtermSerializer implements ITerminalSerializer {
|
|||
this._xterm.resize(cols, rows);
|
||||
}
|
||||
|
||||
generateReplayEvent(): IPtyHostProcessReplayEvent {
|
||||
const serialize = new SerializeAddon();
|
||||
async generateReplayEvent(): Promise<IPtyHostProcessReplayEvent> {
|
||||
const serialize = new (await this._getSerializeConstructor());
|
||||
this._xterm.loadAddon(serialize);
|
||||
const serialized = serialize.serialize(this._xterm.getOption('scrollback'));
|
||||
return {
|
||||
|
@ -569,6 +591,34 @@ class XtermSerializer implements ITerminalSerializer {
|
|||
]
|
||||
};
|
||||
}
|
||||
|
||||
async setUnicodeVersion(version: '6' | '11'): Promise<void> {
|
||||
if (this._xterm.unicode.activeVersion === version) {
|
||||
return;
|
||||
}
|
||||
if (version === '11') {
|
||||
this._unicodeAddon = new (await this._getUnicode11Constructor());
|
||||
this._xterm.loadAddon(this._unicodeAddon);
|
||||
} else {
|
||||
this._unicodeAddon?.dispose();
|
||||
this._unicodeAddon = undefined;
|
||||
}
|
||||
this._xterm.unicode.activeVersion = version;
|
||||
}
|
||||
|
||||
async _getUnicode11Constructor(): Promise<typeof Unicode11Addon> {
|
||||
if (!Unicode11Addon) {
|
||||
Unicode11Addon = (await import('xterm-addon-unicode11')).Unicode11Addon;
|
||||
}
|
||||
return Unicode11Addon;
|
||||
}
|
||||
|
||||
async _getSerializeConstructor(): Promise<typeof SerializeAddon> {
|
||||
if (!SerializeAddon) {
|
||||
SerializeAddon = (await import('xterm-addon-serialize')).SerializeAddon;
|
||||
}
|
||||
return SerializeAddon;
|
||||
}
|
||||
}
|
||||
|
||||
function printTime(ms: number): string {
|
||||
|
|
|
@ -470,6 +470,10 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
|
|||
}
|
||||
}
|
||||
|
||||
async setUnicodeVersion(version: '6' | '11'): Promise<void> {
|
||||
// No-op
|
||||
}
|
||||
|
||||
getInitialCwd(): Promise<string> {
|
||||
return Promise.resolve(this._initialCwd);
|
||||
}
|
||||
|
|
|
@ -7,44 +7,44 @@ import * as assert from 'assert';
|
|||
import { ReplayEntry } from 'vs/platform/terminal/common/terminalProcess';
|
||||
import { TerminalRecorder } from 'vs/platform/terminal/common/terminalRecorder';
|
||||
|
||||
function eventsEqual(recorder: TerminalRecorder, expected: ReplayEntry[]) {
|
||||
const actual = recorder.generateReplayEvent().events;
|
||||
async function eventsEqual(recorder: TerminalRecorder, expected: ReplayEntry[]) {
|
||||
const actual = (await recorder.generateReplayEvent()).events;
|
||||
for (let i = 0; i < expected.length; i++) {
|
||||
assert.deepStrictEqual(actual[i], expected[i]);
|
||||
}
|
||||
}
|
||||
|
||||
suite('TerminalRecorder', () => {
|
||||
test('should record dimensions', () => {
|
||||
test('should record dimensions', async () => {
|
||||
const recorder = new TerminalRecorder(1, 2);
|
||||
eventsEqual(recorder, [
|
||||
await eventsEqual(recorder, [
|
||||
{ cols: 1, rows: 2, data: '' }
|
||||
]);
|
||||
recorder.handleData('a');
|
||||
recorder.handleResize(3, 4);
|
||||
eventsEqual(recorder, [
|
||||
await eventsEqual(recorder, [
|
||||
{ cols: 1, rows: 2, data: 'a' },
|
||||
{ cols: 3, rows: 4, data: '' }
|
||||
]);
|
||||
});
|
||||
test('should ignore resize events without data', () => {
|
||||
test('should ignore resize events without data', async () => {
|
||||
const recorder = new TerminalRecorder(1, 2);
|
||||
eventsEqual(recorder, [
|
||||
await eventsEqual(recorder, [
|
||||
{ cols: 1, rows: 2, data: '' }
|
||||
]);
|
||||
recorder.handleResize(3, 4);
|
||||
eventsEqual(recorder, [
|
||||
await eventsEqual(recorder, [
|
||||
{ cols: 3, rows: 4, data: '' }
|
||||
]);
|
||||
});
|
||||
test('should record data and combine it into the previous resize event', () => {
|
||||
test('should record data and combine it into the previous resize event', async () => {
|
||||
const recorder = new TerminalRecorder(1, 2);
|
||||
recorder.handleData('a');
|
||||
recorder.handleData('b');
|
||||
recorder.handleResize(3, 4);
|
||||
recorder.handleData('c');
|
||||
recorder.handleData('d');
|
||||
eventsEqual(recorder, [
|
||||
await eventsEqual(recorder, [
|
||||
{ cols: 1, rows: 2, data: 'ab' },
|
||||
{ cols: 3, rows: 4, data: 'cd' }
|
||||
]);
|
||||
|
|
|
@ -263,7 +263,7 @@ export class ExtHostPseudoterminal implements ITerminalChildProcess {
|
|||
}
|
||||
|
||||
async processBinary(data: string): Promise<void> {
|
||||
// No-op, processBinary is not supported in extextion owned terminals.
|
||||
// No-op, processBinary is not supported in extension owned terminals.
|
||||
}
|
||||
|
||||
acknowledgeDataEvent(charCount: number): void {
|
||||
|
@ -271,6 +271,10 @@ export class ExtHostPseudoterminal implements ITerminalChildProcess {
|
|||
// implemented it will need new pause and resume VS Code APIs.
|
||||
}
|
||||
|
||||
async setUnicodeVersion(version: '6' | '11'): Promise<void> {
|
||||
// No-op, xterm-headless isn't used for extension owned terminals.
|
||||
}
|
||||
|
||||
getInitialCwd(): Promise<string> {
|
||||
return Promise.resolve('');
|
||||
}
|
||||
|
|
|
@ -112,6 +112,10 @@ export class RemotePty extends Disposable implements ITerminalChildProcess {
|
|||
});
|
||||
}
|
||||
|
||||
async setUnicodeVersion(version: '6' | '11'): Promise<void> {
|
||||
return this._remoteTerminalChannel.setUnicodeVersion(this._id, version);
|
||||
}
|
||||
|
||||
async getInitialCwd(): Promise<string> {
|
||||
await this._startBarrier.wait();
|
||||
return this._remoteTerminalChannel.getInitialCwd(this._id);
|
||||
|
|
|
@ -22,7 +22,6 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
|
|||
import { RemotePty } from 'vs/workbench/contrib/terminal/browser/remotePty';
|
||||
import { IRemoteTerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { ICompleteTerminalConfiguration, RemoteTerminalChannelClient, REMOTE_TERMINAL_CHANNEL_NAME } from 'vs/workbench/contrib/terminal/common/remoteTerminalChannel';
|
||||
import { ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
|
||||
import { IHistoryService } from 'vs/workbench/services/history/common/history';
|
||||
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||
|
@ -173,7 +172,7 @@ export class RemoteTerminalService extends Disposable implements IRemoteTerminal
|
|||
return this._remoteTerminalChannel.acceptDetachInstanceReply(requestId, persistentProcessId);
|
||||
}
|
||||
|
||||
async createProcess(shellLaunchConfig: IShellLaunchConfig, configuration: ICompleteTerminalConfiguration, activeWorkspaceRootUri: URI | undefined, cols: number, rows: number, shouldPersist: boolean, configHelper: ITerminalConfigHelper): Promise<ITerminalChildProcess> {
|
||||
async createProcess(shellLaunchConfig: IShellLaunchConfig, configuration: ICompleteTerminalConfiguration, activeWorkspaceRootUri: URI | undefined, cols: number, rows: number, unicodeVersion: '6' | '11', shouldPersist: boolean): Promise<ITerminalChildProcess> {
|
||||
if (!this._remoteTerminalChannel) {
|
||||
throw new Error(`Cannot create remote terminal when there is no remote!`);
|
||||
}
|
||||
|
@ -200,6 +199,7 @@ export class RemoteTerminalService extends Disposable implements IRemoteTerminal
|
|||
shouldPersist,
|
||||
cols,
|
||||
rows,
|
||||
unicodeVersion
|
||||
);
|
||||
const pty = new RemotePty(result.persistentTerminalId, shouldPersist, this._remoteTerminalChannel, this._remoteAgentService, this._logService);
|
||||
this._ptys.set(result.persistentTerminalId, pty);
|
||||
|
|
|
@ -320,7 +320,15 @@ export interface ITerminalFindHost {
|
|||
}
|
||||
|
||||
export interface IRemoteTerminalService extends IOffProcessTerminalService {
|
||||
createProcess(shellLaunchConfig: IShellLaunchConfig, configuration: ICompleteTerminalConfiguration, activeWorkspaceRootUri: URI | undefined, cols: number, rows: number, shouldPersist: boolean, configHelper: ITerminalConfigHelper): Promise<ITerminalChildProcess>;
|
||||
createProcess(
|
||||
shellLaunchConfig: IShellLaunchConfig,
|
||||
configuration: ICompleteTerminalConfiguration,
|
||||
activeWorkspaceRootUri: URI | undefined,
|
||||
cols: number,
|
||||
rows: number,
|
||||
unicodeVersion: '6' | '11',
|
||||
shouldPersist: boolean
|
||||
): Promise<ITerminalChildProcess>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1575,7 +1575,10 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
|||
this._xtermUnicode11 = new Addon();
|
||||
this._xterm.loadAddon(this._xtermUnicode11);
|
||||
}
|
||||
this._xterm.unicode.activeVersion = this._configHelper.config.unicodeVersion;
|
||||
if (this._xterm.unicode.activeVersion !== this._configHelper.config.unicodeVersion) {
|
||||
this._xterm.unicode.activeVersion = this._configHelper.config.unicodeVersion;
|
||||
this._processManager.setUnicodeVersion(this._configHelper.config.unicodeVersion);
|
||||
}
|
||||
}
|
||||
|
||||
updateAccessibilitySupport(): void {
|
||||
|
|
|
@ -124,6 +124,10 @@ export class TerminalProcessExtHostProxy extends Disposable implements ITerminal
|
|||
// Flow control is disabled for extension terminals
|
||||
}
|
||||
|
||||
async setUnicodeVersion(version: '6' | '11'): Promise<void> {
|
||||
// No-op
|
||||
}
|
||||
|
||||
async processBinary(data: string): Promise<void> {
|
||||
// Disabled for extension terminals
|
||||
this._onBinary.fire(data);
|
||||
|
|
|
@ -267,7 +267,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
|
|||
'terminal.integrated.cwd': this._configurationService.getValue(TerminalSettingId.Cwd) as string,
|
||||
'terminal.integrated.detectLocale': terminalConfig.detectLocale
|
||||
};
|
||||
newProcess = await this._remoteTerminalService.createProcess(shellLaunchConfig, configuration, activeWorkspaceRootUri, cols, rows, shouldPersist, this._configHelper);
|
||||
newProcess = await this._remoteTerminalService.createProcess(shellLaunchConfig, configuration, activeWorkspaceRootUri, cols, rows, this._configHelper.config.unicodeVersion, shouldPersist);
|
||||
}
|
||||
if (!this._isDisposed) {
|
||||
this._setupPtyHostListeners(this._remoteTerminalService);
|
||||
|
@ -430,7 +430,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
|
|||
|
||||
const useConpty = this._configHelper.config.windowsEnableConpty && !isScreenReaderModeEnabled;
|
||||
const shouldPersist = this._configHelper.config.enablePersistentSessions && !shellLaunchConfig.isFeatureTerminal;
|
||||
return await localTerminalService.createProcess(shellLaunchConfig, initialCwd, cols, rows, env, useConpty, shouldPersist);
|
||||
return await localTerminalService.createProcess(shellLaunchConfig, initialCwd, cols, rows, this._configHelper.config.unicodeVersion, env, useConpty, shouldPersist);
|
||||
}
|
||||
|
||||
private _setupPtyHostListeners(offProcessTerminalService: IOffProcessTerminalService) {
|
||||
|
@ -492,6 +492,10 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
|
|||
return this.ptyProcessReady.then(() => this._resize(cols, rows));
|
||||
}
|
||||
|
||||
async setUnicodeVersion(version: '6' | '11'): Promise<void> {
|
||||
return this._process?.setUnicodeVersion(version);
|
||||
}
|
||||
|
||||
private _resize(cols: number, rows: number) {
|
||||
if (!this._process) {
|
||||
return;
|
||||
|
@ -756,6 +760,6 @@ class SeamlessRelaunchDataFilter extends Disposable {
|
|||
}
|
||||
|
||||
private _getDataFromRecorder(recorder: TerminalRecorder): string {
|
||||
return recorder.generateReplayEvent().events.filter(e => !!e.data).map(e => e.data).join('');
|
||||
return recorder.generateReplayEventSync().events.filter(e => !!e.data).map(e => e.data).join('');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ export interface ICreateTerminalProcessArguments {
|
|||
shouldPersistTerminal: boolean;
|
||||
cols: number;
|
||||
rows: number;
|
||||
unicodeVersion: '6' | '11';
|
||||
resolverEnv: { [key: string]: string | null; } | undefined
|
||||
}
|
||||
|
||||
|
@ -141,7 +142,7 @@ export class RemoteTerminalChannelClient {
|
|||
return this._channel.call('$restartPtyHost', []);
|
||||
}
|
||||
|
||||
async createProcess(shellLaunchConfig: IShellLaunchConfigDto, configuration: ICompleteTerminalConfiguration, activeWorkspaceRootUri: URI | undefined, shouldPersistTerminal: boolean, cols: number, rows: number): Promise<ICreateTerminalProcessResult> {
|
||||
async createProcess(shellLaunchConfig: IShellLaunchConfigDto, configuration: ICompleteTerminalConfiguration, activeWorkspaceRootUri: URI | undefined, shouldPersistTerminal: boolean, cols: number, rows: number, unicodeVersion: '6' | '11'): Promise<ICreateTerminalProcessResult> {
|
||||
// Be sure to first wait for the remote configuration
|
||||
await this._configurationService.whenRemoteConfigurationLoaded();
|
||||
|
||||
|
@ -196,6 +197,7 @@ export class RemoteTerminalChannelClient {
|
|||
shouldPersistTerminal,
|
||||
cols,
|
||||
rows,
|
||||
unicodeVersion,
|
||||
resolverEnv
|
||||
};
|
||||
return await this._channel.call<ICreateTerminalProcessResult>('$createProcess', args);
|
||||
|
@ -231,6 +233,9 @@ export class RemoteTerminalChannelClient {
|
|||
acknowledgeDataEvent(id: number, charCount: number): Promise<void> {
|
||||
return this._channel.call('$acknowledgeDataEvent', [id, charCount]);
|
||||
}
|
||||
setUnicodeVersion(id: number, version: '6' | '11'): Promise<void> {
|
||||
return this._channel.call('$setUnicodeVersion', [id, version]);
|
||||
}
|
||||
shutdown(id: number, immediate: boolean): Promise<void> {
|
||||
return this._channel.call('$shutdown', [id, immediate]);
|
||||
}
|
||||
|
|
|
@ -101,7 +101,16 @@ export interface IOffProcessTerminalService {
|
|||
|
||||
export const ILocalTerminalService = createDecorator<ILocalTerminalService>('localTerminalService');
|
||||
export interface ILocalTerminalService extends IOffProcessTerminalService {
|
||||
createProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean, shouldPersist: boolean): Promise<ITerminalChildProcess>;
|
||||
createProcess(
|
||||
shellLaunchConfig: IShellLaunchConfig,
|
||||
cwd: string,
|
||||
cols: number,
|
||||
rows: number,
|
||||
unicodeVersion: '6' | '11',
|
||||
env: IProcessEnvironment,
|
||||
windowsEnableConpty: boolean,
|
||||
shouldPersist: boolean
|
||||
): Promise<ITerminalChildProcess>;
|
||||
}
|
||||
|
||||
export type FontWeight = 'normal' | 'bold' | number;
|
||||
|
@ -293,6 +302,7 @@ export interface ITerminalProcessManager extends IDisposable {
|
|||
setDimensions(cols: number, rows: number): Promise<void>;
|
||||
setDimensions(cols: number, rows: number, sync: false): Promise<void>;
|
||||
setDimensions(cols: number, rows: number, sync: true): void;
|
||||
setUnicodeVersion(version: '6' | '11'): Promise<void>;
|
||||
acknowledgeDataEvent(charCount: number): void;
|
||||
processBinary(data: string): void;
|
||||
|
||||
|
|
|
@ -86,6 +86,9 @@ export class LocalPty extends Disposable implements ITerminalChildProcess {
|
|||
}
|
||||
this._localPtyService.acknowledgeDataEvent(this.id, charCount);
|
||||
}
|
||||
setUnicodeVersion(version: '6' | '11'): Promise<void> {
|
||||
return this._localPtyService.setUnicodeVersion(this.id, version);
|
||||
}
|
||||
|
||||
handleData(e: string | IProcessDataEvent) {
|
||||
this._onProcessData.fire(e);
|
||||
|
|
|
@ -146,9 +146,9 @@ export class LocalTerminalService extends Disposable implements ILocalTerminalSe
|
|||
await this._localPtyService.updateIcon(id, icon, color);
|
||||
}
|
||||
|
||||
async createProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean, shouldPersist: boolean): Promise<ITerminalChildProcess> {
|
||||
async createProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, unicodeVersion: '6' | '11', env: IProcessEnvironment, windowsEnableConpty: boolean, shouldPersist: boolean): Promise<ITerminalChildProcess> {
|
||||
const executableEnv = await this._shellEnvironmentService.getShellEnv();
|
||||
const id = await this._localPtyService.createProcess(shellLaunchConfig, cwd, cols, rows, env, executableEnv, windowsEnableConpty, shouldPersist, this._getWorkspaceId(), this._getWorkspaceName());
|
||||
const id = await this._localPtyService.createProcess(shellLaunchConfig, cwd, cols, rows, unicodeVersion, env, executableEnv, windowsEnableConpty, shouldPersist, this._getWorkspaceId(), this._getWorkspaceName());
|
||||
const pty = this._instantiationService.createInstance(LocalPty, id, shouldPersist);
|
||||
this._ptys.set(id, pty);
|
||||
return pty;
|
||||
|
|
|
@ -203,6 +203,10 @@ class TestOutputProcess extends Disposable implements ITerminalChildProcess {
|
|||
public acknowledgeDataEvent(): void {
|
||||
// no-op, flow control not currently implemented
|
||||
}
|
||||
public setUnicodeVersion(): Promise<void> {
|
||||
// no-op
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
public getInitialCwd(): Promise<string> {
|
||||
return Promise.resolve('');
|
||||
|
|
|
@ -1667,7 +1667,7 @@ export class TestLocalTerminalService implements ILocalTerminalService {
|
|||
onDidMoveWindowInstance = Event.None;
|
||||
onDidRequestDetach = Event.None;
|
||||
|
||||
async createProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean, shouldPersist: boolean): Promise<ITerminalChildProcess> { return new TestTerminalChildProcess(shouldPersist); }
|
||||
async createProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, unicodeVersion: '6' | '11', env: IProcessEnvironment, windowsEnableConpty: boolean, shouldPersist: boolean): Promise<ITerminalChildProcess> { return new TestTerminalChildProcess(shouldPersist); }
|
||||
async attachToProcess(id: number): Promise<ITerminalChildProcess | undefined> { throw new Error('Method not implemented.'); }
|
||||
async listProcesses(): Promise<IProcessDetails[]> { throw new Error('Method not implemented.'); }
|
||||
getDefaultSystemShell(osOverride?: OperatingSystem): Promise<string> { throw new Error('Method not implemented.'); }
|
||||
|
@ -1703,6 +1703,7 @@ class TestTerminalChildProcess implements ITerminalChildProcess {
|
|||
input(data: string): void { }
|
||||
resize(cols: number, rows: number): void { }
|
||||
acknowledgeDataEvent(charCount: number): void { }
|
||||
async setUnicodeVersion(version: '6' | '11'): Promise<void> { }
|
||||
async getInitialCwd(): Promise<string> { return ''; }
|
||||
async getCwd(): Promise<string> { return ''; }
|
||||
async getLatency(): Promise<number> { return 0; }
|
||||
|
|
Loading…
Reference in a new issue