Skip to content

Commit

Permalink
Merge pull request #151852 from ssigwart/term
Browse files Browse the repository at this point in the history
Fix terminals in editor area not reloading
  • Loading branch information
Tyriar committed Jul 6, 2022
2 parents 8b475a0 + 575c29b commit 4ba0070
Show file tree
Hide file tree
Showing 13 changed files with 65 additions and 6 deletions.
3 changes: 2 additions & 1 deletion src/vs/platform/terminal/common/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ export interface IPtyService extends IPtyHostController {
getProfiles?(workspaceId: string, profiles: unknown, defaultProfile: unknown, includeDetectedProfiles?: boolean): Promise<ITerminalProfile[]>;
getEnvironment(): Promise<IProcessEnvironment>;
getWslPath(original: string): Promise<string>;
getRevivedPtyNewId(id: number): Promise<number | undefined>;
setTerminalLayoutInfo(args: ISetTerminalLayoutInfoArgs): Promise<void>;
getTerminalLayoutInfo(args: IGetTerminalLayoutInfoArgs): Promise<ITerminalsLayoutInfo | undefined>;
reduceConnectionGraceTime(): Promise<void>;
Expand Down Expand Up @@ -459,7 +460,7 @@ export interface IShellLaunchConfig {
/**
* This is a terminal that attaches to an already running terminal.
*/
attachPersistentProcess?: { id: number; pid: number; title: string; titleSource: TitleEventSource; cwd: string; icon?: TerminalIcon; color?: string; hasChildProcesses?: boolean; fixedDimensions?: IFixedTerminalDimensions; environmentVariableCollections?: ISerializableEnvironmentVariableCollections };
attachPersistentProcess?: { id: number; findRevivedId?: boolean; pid: number; title: string; titleSource: TitleEventSource; cwd: string; icon?: TerminalIcon; color?: string; hasChildProcesses?: boolean; fixedDimensions?: IFixedTerminalDimensions; environmentVariableCollections?: ISerializableEnvironmentVariableCollections };

/**
* Whether the terminal process environment should be exactly as provided in
Expand Down
4 changes: 4 additions & 0 deletions src/vs/platform/terminal/node/ptyHostService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,10 @@ export class PtyHostService extends Disposable implements IPtyService {
return this._proxy.getWslPath(original);
}

getRevivedPtyNewId(id: number): Promise<number | undefined> {
return this._proxy.getRevivedPtyNewId(id);
}

setTerminalLayoutInfo(args: ISetTerminalLayoutInfoArgs): Promise<void> {
return this._proxy.setTerminalLayoutInfo(args);
}
Expand Down
9 changes: 9 additions & 0 deletions src/vs/platform/terminal/node/ptyService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,15 @@ export class PtyService extends Disposable implements IPtyService {
});
}

async getRevivedPtyNewId(id: number): Promise<number | undefined> {
try {
return this._revivedPtyIdMap.get(id)?.newId;
} catch (e) {
this._logService.trace(`Couldn't find terminal ID ${id}`, e.message);
}
return undefined;
}

async setTerminalLayoutInfo(args: ISetTerminalLayoutInfoArgs): Promise<void> {
this._workspaceLayoutInfos.set(args.workspaceId, args);
}
Expand Down
1 change: 1 addition & 0 deletions src/vs/server/node/remoteTerminalChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel<
case '$setTerminalLayoutInfo': return this._ptyService.setTerminalLayoutInfo(<ISetTerminalLayoutInfoArgs>args);
case '$serializeTerminalState': return this._ptyService.serializeTerminalState.apply(this._ptyService, args);
case '$reviveTerminalProcesses': return this._ptyService.reviveTerminalProcesses.apply(this._ptyService, args);
case '$getRevivedPtyNewId': return this._ptyService.getRevivedPtyNewId.apply(this._ptyService, args);
case '$setUnicodeVersion': return this._ptyService.setUnicodeVersion.apply(this._ptyService, args);
case '$reduceConnectionGraceTime': return this._reduceConnectionGraceTime();
case '$updateIcon': return this._ptyService.updateIcon.apply(this._ptyService, args);
Expand Down
14 changes: 14 additions & 0 deletions src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,20 @@ class RemoteTerminalBackend extends BaseTerminalBackend implements ITerminalBack
return undefined;
}

async attachToRevivedProcess(id: number): Promise<ITerminalChildProcess | undefined> {
if (!this._remoteTerminalChannel) {
throw new Error(`Cannot create remote terminal when there is no remote!`);
}

try {
const newId = await this._remoteTerminalChannel.getRevivedPtyNewId(id) ?? id;
return await this.attachToProcess(newId);
} catch (e) {
this._logService.trace(`Couldn't attach to process ${e.message}`);
}
return undefined;
}

async listProcesses(): Promise<IProcessDetails[]> {
const terms = this._remoteTerminalChannel ? await this._remoteTerminalChannel.listProcesses() : [];
return terms.map(termDto => {
Expand Down
5 changes: 5 additions & 0 deletions src/vs/workbench/contrib/terminal/browser/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,11 @@ export interface ITerminalInstance {
*/
readonly persistentProcessId: number | undefined;

/**
* The id of a persistent process during the shutdown process
*/
shutdownPersistentProcessId: number | undefined;

/**
* Whether the process should be persisted across reloads.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,8 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor
const inputKey = resource.path;

if ('pid' in deserializedInput) {
const instance = this._terminalInstanceService.createInstance({ attachPersistentProcess: deserializedInput }, TerminalLocation.Editor);
const newDeserializedInput = { ...deserializedInput, findRevivedId: true };
const instance = this._terminalInstanceService.createInstance({ attachPersistentProcess: newDeserializedInput }, TerminalLocation.Editor);
instance.target = TerminalLocation.Editor;
const input = this._instantiationService.createInstance(TerminalEditorInput, resource, instance);
this._registerInstance(inputKey, input, instance);
Expand Down
8 changes: 6 additions & 2 deletions src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {

private readonly _processManager: ITerminalProcessManager;
private readonly _resource: URI;
private _shutdownPersistentProcessId: number | undefined;

// Enables disposal of the xterm onKey
// event when the CwdDetection capability
Expand Down Expand Up @@ -664,8 +665,11 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
return TerminalInstance._lastKnownCanvasDimensions;
}

get persistentProcessId(): number | undefined { return this._processManager.persistentProcessId; }
get shouldPersist(): boolean { return this._processManager.shouldPersist && !this.shellLaunchConfig.isTransient; }
set shutdownPersistentProcessId(shutdownPersistentProcessId: number | undefined) {
this._shutdownPersistentProcessId = shutdownPersistentProcessId;
}
get persistentProcessId(): number | undefined { return this._processManager.persistentProcessId ?? this._shutdownPersistentProcessId; }
get shouldPersist(): boolean { return (this._processManager.shouldPersist || this._shutdownPersistentProcessId !== undefined) && !this.shellLaunchConfig.isTransient; }

/**
* Create xterm.js instance and attach data listeners.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
}
} else {
if (shellLaunchConfig.attachPersistentProcess) {
const result = await backend.attachToProcess(shellLaunchConfig.attachPersistentProcess.id);
const result = shellLaunchConfig.attachPersistentProcess.findRevivedId ? await backend.attachToRevivedProcess(shellLaunchConfig.attachPersistentProcess.id) : await backend.attachToProcess(shellLaunchConfig.attachPersistentProcess.id);
if (result) {
newProcess = result;
} else {
Expand Down
7 changes: 6 additions & 1 deletion src/vs/workbench/contrib/terminal/browser/terminalService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { ILogService } from 'vs/platform/log/common/log';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { ICreateContributedTerminalProfileOptions, IShellLaunchConfig, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalLocation, TerminalLocationString, TitleEventSource } from 'vs/platform/terminal/common/terminal';
import { formatMessageForTerminal } from 'vs/platform/terminal/common/terminalStrings';
import { iconForeground } from 'vs/platform/theme/common/colorRegistry';
import { getIconRegistry } from 'vs/platform/theme/common/iconRegistry';
import { ColorScheme } from 'vs/platform/theme/common/theme';
Expand All @@ -38,7 +39,6 @@ import { getInstanceFromResource, getTerminalUri, parseTerminalUri } from 'vs/wo
import { TerminalViewPane } from 'vs/workbench/contrib/terminal/browser/terminalView';
import { IRemoteTerminalAttachTarget, IStartExtensionTerminalRequest, ITerminalBackend, ITerminalConfigHelper, ITerminalProcessExtHostProxy, ITerminalProfileService, TERMINAL_VIEW_ID } from 'vs/workbench/contrib/terminal/common/terminal';
import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey';
import { formatMessageForTerminal } from 'vs/platform/terminal/common/terminalStrings';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { ACTIVE_GROUP, IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
Expand Down Expand Up @@ -620,8 +620,13 @@ export class TerminalService implements ITerminalService {
return;
}


// Force dispose of all terminal instances
const shouldPersistTerminalsForEvent = this._shouldReviveProcesses(e.reason);
for (const instance of this.instances) {
if (shouldPersistTerminalsForEvent) {
instance.shutdownPersistentProcessId = instance.persistentProcessId;
}
instance.dispose();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,10 @@ export class RemoteTerminalChannelClient implements IPtyHostController {
return this._channel.call('$reviveTerminalProcesses', [state, dateTimeFormatLocate]);
}

getRevivedPtyNewId(id: number): Promise<number | undefined> {
return this._channel.call('$getRevivedPtyNewId', [id]);
}

serializeTerminalState(ids: number[]): Promise<string> {
return this._channel.call('$serializeTerminalState', [ids]);
}
Expand Down
1 change: 1 addition & 0 deletions src/vs/workbench/contrib/terminal/common/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ export interface ITerminalBackend {
onDidRequestDetach: Event<{ requestId: number; workspaceId: string; instanceId: number }>;

attachToProcess(id: number): Promise<ITerminalChildProcess | undefined>;
attachToRevivedProcess(id: number): Promise<ITerminalChildProcess | undefined>;
listProcesses(): Promise<IProcessDetails[]>;
getDefaultSystemShell(osOverride?: OperatingSystem): Promise<string>;
getProfiles(profiles: unknown, defaultProfile: unknown, includeDetectedProfiles?: boolean): Promise<ITerminalProfile[]>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,16 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke
return undefined;
}

async attachToRevivedProcess(id: number): Promise<ITerminalChildProcess | undefined> {
try {
const newId = await this._localPtyService.getRevivedPtyNewId(id) ?? id;
return await this.attachToProcess(newId);
} catch (e) {
this._logService.trace(`Couldn't attach to process ${e.message}`);
}
return undefined;
}

async listProcesses(): Promise<IProcessDetails[]> {
return this._localPtyService.listProcesses();
}
Expand Down

0 comments on commit 4ba0070

Please sign in to comment.