提交 7f94f0d9 编写于 作者: D Daniel Imms

Move some ptyProcessReady usage inside proc manager

Part of #100709
上级 417b7803
......@@ -357,9 +357,6 @@ export function registerTerminalActions() {
const codeEditorService = accessor.get(ICodeEditorService);
const notificationService = accessor.get(INotificationService);
const instance = terminalService.getActiveOrCreateInstance();
await instance.processReady;
const editor = codeEditorService.getActiveCodeEditor();
if (!editor || !editor.hasModel()) {
return;
......@@ -372,6 +369,7 @@ export function registerTerminalActions() {
}
// TODO: Convert this to ctrl+c, ctrl+v for pwsh?
const instance = terminalService.getActiveOrCreateInstance();
const path = await terminalService.preparePathForTerminalAsync(uri.fsPath, instance.shellLaunchConfig.executable, instance.title, instance.shellType);
instance.sendText(path, true);
return terminalService.showPanel();
......
......@@ -859,8 +859,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
}
// Send it to the process
await this._processManager.ptyProcessReady;
this._processManager.write(text);
return this._processManager.write(text);
}
public setVisible(visible: boolean): void {
......@@ -938,26 +937,26 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
this._processManager.onProcessOverrideDimensions(e => this.setDimensions(e, true));
this._processManager.onProcessResolvedShellLaunchConfig(e => this._setResolvedShellLaunchConfig(e));
this._processManager.onEnvironmentVariableInfoChanged(e => this._onEnvironmentVariableInfoChanged(e));
this._processManager.onPtyDisconnect(() => {
this._safeSetOption('disableStdin', true);
this._onTitleChanged.fire(this);
});
this._processManager.onPtyReconnect(() => {
this._safeSetOption('disableStdin', false);
this._onTitleChanged.fire(this);
});
this._processManager.onProcessShellTypeChanged(type => this.setShellType(type));
if (this._shellLaunchConfig.name) {
this.setTitle(this._shellLaunchConfig.name, TitleEventSource.Api);
} else {
// Only listen for process title changes when a name is not provided
if (this._configHelper.config.experimentalUseTitleEvent) {
this._processManager.ptyProcessReady.then(() => {
this._terminalInstanceService.getDefaultShellAndArgs(false).then(e => {
this.setTitle(e.shell, TitleEventSource.Sequence);
});
// Set the title to the first event if the sequence hasn't set it yet
Event.once(this._processManager.onProcessTitle)(e => {
if (!this._title) {
this.setTitle(this._title, TitleEventSource.Sequence);
}
});
// Listen to xterm.js' sequence title change event, trigger this async to ensure
// xterm is constructed since this is called from TerminalInstance's ctor
setTimeout(() => {
this._xtermReadyPromise.then(xterm => {
this._messageTitleDisposable = xterm.onTitleChange(e => this._onTitleChange(e));
this._messageTitleDisposable = xterm.onTitleChange(e => {
console.log('set from sequence');
this._onTitleChange(e);
});
});
});
} else {
......@@ -965,8 +964,14 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
this._messageTitleDisposable = this._processManager.onProcessTitle(title => this.setTitle(title ? title : '', TitleEventSource.Process));
}
}
this._processManager.onProcessShellTypeChanged(type => {
this.setShellType(type);
this._processManager.onPtyDisconnect(() => {
this._safeSetOption('disableStdin', true);
this._onTitleChanged.fire(this);
});
this._processManager.onPtyReconnect(() => {
this._safeSetOption('disableStdin', false);
this._onTitleChanged.fire(this);
});
}
......@@ -1167,19 +1172,21 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
this._shellLaunchConfig = shell; // Must be done before calling _createProcess()
// Kill and clear up the process, making the process manager ready for a new process
this._processManager.dispose();
// this._processManager.dispose();
// Launch the process unless this is only a renderer.
// In the renderer only cases, we still need to set the title correctly.
const oldTitle = this._title;
this._createProcessManager();
// const oldTitle = this._title;
// this._createProcessManager();
if (oldTitle !== this._title) {
this.setTitle(this._title, TitleEventSource.Process);
}
// TODO: Is this needed anymore?
// if (oldTitle !== this._title) {
// this.setTitle(this._title, TitleEventSource.Process);
// }
this._processManager.onProcessData(data => this._onProcessData(data));
this._createProcess();
this._processManager.relaunch(this._shellLaunchConfig, this._cols, this._rows, this._accessibilityService.isScreenReaderOptimized());
// this._processManager.onProcessData(data => this._onProcessData(data));
// this._createProcess();
this._xtermTypeAhead?.reset(this._processManager);
}
......@@ -1456,10 +1463,9 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
if (immediate) {
// do not await, call setDimensions synchronously
this._processManager.setDimensions(cols, rows);
this._processManager.setDimensions(cols, rows, true);
} else {
await this._processManager.ptyProcessReady;
this._processManager.setDimensions(cols, rows);
await this._processManager.setDimensions(cols, rows);
}
}
......
......@@ -52,6 +52,7 @@ enum ProcessType {
*/
export class TerminalProcessManager extends Disposable implements ITerminalProcessManager {
public processState: ProcessState = ProcessState.UNINITIALIZED;
// TODO: This will cause problems when the process manager is reused
public ptyProcessReady: Promise<void>;
public shellProcessId: number | undefined;
public remoteAuthority: string | undefined;
......@@ -99,10 +100,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
public get environmentVariableInfo(): IEnvironmentVariableInfo | undefined { return this._environmentVariableInfo; }
public get persistentProcessId(): number | undefined { return this._process?.id; }
public get shouldPersist(): boolean { return this._process ? this._process.shouldPersist : false; }
public get hasWrittenData(): boolean {
return this._hasWrittenData;
}
public get hasWrittenData(): boolean { return this._hasWrittenData; }
private readonly _localTerminalService?: ILocalTerminalService;
......@@ -133,7 +131,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
c(undefined);
});
});
this.ptyProcessReady.then(async () => await this.getLatency());
this.getLatency();
this._ackDataBufferer = new AckDataBufferer(e => this._process?.acknowledgeDataEvent(e));
}
......@@ -209,6 +207,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
this._process = await this._remoteTerminalService.createProcess(shellLaunchConfig, activeWorkspaceRootUri, cols, rows, shouldPersist, this._configHelper);
}
if (!this._isDisposed) {
// TODO: Prevent double attach
this._setupPtyHostListeners(this._remoteTerminalService);
}
} else {
......@@ -228,6 +227,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
this._process = await this._launchLocalProcess(this._localTerminalService, shellLaunchConfig, cols, rows, this.userHome, isScreenReaderModeEnabled);
}
if (!this._isDisposed) {
// TODO: Prevent double attach
this._setupPtyHostListeners(this._localTerminalService);
}
}
......@@ -254,6 +254,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
this._process.onProcessReady((e: { pid: number, cwd: string }) => {
this.shellProcessId = e.pid;
this._initialCwd = e.cwd;
console.log('fire ready!');
this._onProcessReady.fire();
if (this._preLaunchInputQueue.length > 0 && this._process) {
......@@ -288,6 +289,12 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
return undefined;
}
public async relaunch(shellLaunchConfig: IShellLaunchConfig, cols: number, rows: number, isScreenReaderModeEnabled: boolean): Promise<ITerminalLaunchError | undefined> {
console.log('relaunch!', shellLaunchConfig);
return this.createProcess(shellLaunchConfig, cols, rows, isScreenReaderModeEnabled);
// return undefined;
}
// Fetch any extension environment additions and apply them
private async _setupEnvVariableInfo(activeWorkspaceRootUri: URI | undefined, shellLaunchConfig: IShellLaunchConfig): Promise<platform.IProcessEnvironment> {
const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux');
......@@ -389,14 +396,25 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
}));
}
public setDimensions(cols: number, rows: number): void {
public setDimensions(cols: number, rows: number, sync: boolean | undefined): Promise<void>;
public setDimensions(cols: number, rows: number, sync: true): void;
public setDimensions(cols: number, rows: number, sync?: boolean): Promise<void> | void {
if (!this._process) {
return;
}
if (sync) {
this._resize(cols, rows);
return;
}
return this.ptyProcessReady.then(() => this._resize(cols, rows));
}
private _resize(cols: number, rows: number) {
// The child process could already be terminated
try {
this._process.resize(cols, rows);
this._process!.resize(cols, rows);
} catch (error) {
// We tried to write to a closed pipe / channel.
if (error.code !== 'EPIPE' && error.code !== 'ERR_IPC_CHANNEL_CLOSED') {
......@@ -405,7 +423,8 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
}
}
public write(data: string): void {
public async write(data: string): Promise<void> {
await this.ptyProcessReady;
this._hasWrittenData = true;
if (this.shellProcessId || this._processType === ProcessType.ExtensionTerminal) {
if (this._process) {
......
......@@ -262,8 +262,10 @@ export interface ITerminalProcessManager extends IDisposable {
dispose(immediate?: boolean): void;
detachFromProcess(): void;
createProcess(shellLaunchConfig: IShellLaunchConfig, cols: number, rows: number, isScreenReaderModeEnabled: boolean): Promise<ITerminalLaunchError | undefined>;
relaunch(shellLaunchConfig: IShellLaunchConfig, cols: number, rows: number, isScreenReaderModeEnabled: boolean): Promise<ITerminalLaunchError | undefined>;
write(data: string): void;
setDimensions(cols: number, rows: number): void;
setDimensions(cols: number, rows: number, sync: boolean | undefined): Promise<void>;
setDimensions(cols: number, rows: number, sync: true): void;
acknowledgeDataEvent(charCount: number): void;
getInitialCwd(): Promise<string>;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册