Skip to content

Commit c6cbe70

Browse files
committed
Don't wait for createTerminal when recreating groups
Part of microsoft#185393
1 parent d377d06 commit c6cbe70

File tree

3 files changed

+55
-48
lines changed

3 files changed

+55
-48
lines changed

src/vs/workbench/contrib/terminal/browser/terminal.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,9 @@ export interface ITerminalService extends ITerminalInstanceHost {
228228
safeDisposeTerminal(instance: ITerminalInstance): Promise<void>;
229229

230230
getDefaultInstanceHost(): ITerminalInstanceHost;
231-
getInstanceHost(target: ITerminalLocationOptions | undefined): ITerminalInstanceHost;
231+
getInstanceHost(target: ITerminalLocationOptions | undefined): Promise<ITerminalInstanceHost>;
232232

233-
resolveLocation(location?: ITerminalLocationOptions): TerminalLocation | undefined;
233+
resolveLocation(location?: ITerminalLocationOptions): Promise<TerminalLocation | undefined>;
234234
setNativeDelegate(nativeCalls: ITerminalServiceNativeDelegate): void;
235235

236236
getEditingTerminal(): ITerminalInstance | undefined;
@@ -286,7 +286,7 @@ export interface ISerializedTerminalEditorInput extends ITerminalEditorInputObje
286286
export interface IDeserializedTerminalEditorInput extends ITerminalEditorInputObject {
287287
}
288288

289-
export type ITerminalLocationOptions = TerminalLocation | TerminalEditorLocation | { parentTerminal: ITerminalInstance } | { splitActiveTerminal: boolean };
289+
export type ITerminalLocationOptions = TerminalLocation | TerminalEditorLocation | { parentTerminal: Promise<ITerminalInstance> | ITerminalInstance } | { splitActiveTerminal: boolean };
290290

291291
export interface ICreateTerminalOptions {
292292
/**

src/vs/workbench/contrib/terminal/browser/terminalActions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1038,7 +1038,7 @@ export function registerTerminalActions() {
10381038
const commandService = accessor.get(ICommandService);
10391039
const workspaceContextService = accessor.get(IWorkspaceContextService);
10401040
const options = convertOptionsOrProfileToOptions(optionsOrProfile);
1041-
const activeInstance = c.service.getInstanceHost(options?.location).activeInstance;
1041+
const activeInstance = (await c.service.getInstanceHost(options?.location)).activeInstance;
10421042
if (!activeInstance) {
10431043
return;
10441044
}

src/vs/workbench/contrib/terminal/browser/terminalService.ts

Lines changed: 51 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/c
1919
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
2020
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
2121
import { INotificationService } from 'vs/platform/notification/common/notification';
22-
import { ICreateContributedTerminalProfileOptions, IShellLaunchConfig, ITerminalBackend, ITerminalLaunchError, ITerminalLogService, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalExitReason, TerminalLocation, TerminalLocationString, TitleEventSource } from 'vs/platform/terminal/common/terminal';
22+
import { ICreateContributedTerminalProfileOptions, IPtyHostAttachTarget, IRawTerminalInstanceLayoutInfo, IRawTerminalTabLayoutInfo, IShellLaunchConfig, ITerminalBackend, ITerminalLaunchError, ITerminalLogService, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalExitReason, TerminalLocation, TerminalLocationString, TitleEventSource } from 'vs/platform/terminal/common/terminal';
2323
import { formatMessageForTerminal } from 'vs/platform/terminal/common/terminalStrings';
2424
import { iconForeground } from 'vs/platform/theme/common/colorRegistry';
2525
import { getIconRegistry } from 'vs/platform/theme/common/iconRegistry';
@@ -457,55 +457,61 @@ export class TerminalService implements ITerminalService {
457457

458458
private async _recreateTerminalGroups(layoutInfo?: ITerminalsLayoutInfo): Promise<number> {
459459
let reconnectCounter = 0;
460-
let activeGroup: ITerminalGroup | undefined;
460+
let activeGroup: Promise<ITerminalGroup | undefined> | undefined;
461461
if (layoutInfo) {
462-
for (const groupLayout of layoutInfo.tabs) {
463-
const terminalLayouts = groupLayout.terminals.filter(t => t.terminal && t.terminal.isOrphan);
462+
const tabPromises: Promise<ITerminalGroup | undefined>[] = [];
463+
for (const tabLayout of layoutInfo.tabs) {
464+
const terminalLayouts = tabLayout.terminals.filter(t => t.terminal && t.terminal.isOrphan);
464465
if (terminalLayouts.length) {
465466
reconnectCounter += terminalLayouts.length;
466-
let terminalInstance: ITerminalInstance | undefined;
467-
let group: ITerminalGroup | undefined;
468-
for (const terminalLayout of terminalLayouts) {
469-
const attachPersistentProcess = terminalLayout.terminal!;
470-
if (this._lifecycleService.startupKind !== StartupKind.ReloadedWindow && attachPersistentProcess.type === 'Task') {
471-
continue;
472-
}
473-
mark(`code/terminal/willRecreateTerminal/${attachPersistentProcess.id}-${attachPersistentProcess.pid}`);
474-
if (!terminalInstance) {
475-
// create group and terminal
476-
terminalInstance = await this.createTerminal({
477-
config: { attachPersistentProcess },
478-
location: TerminalLocation.Panel
479-
});
480-
group = this._terminalGroupService.getGroupForInstance(terminalInstance);
481-
if (groupLayout.isActive) {
482-
activeGroup = group;
483-
}
484-
} else {
485-
// add split terminals to this group
486-
terminalInstance = await this.createTerminal({
487-
config: { attachPersistentProcess },
488-
location: { parentTerminal: terminalInstance }
489-
});
490-
}
491-
mark(`code/terminal/didRecreateTerminal/${attachPersistentProcess.id}-${attachPersistentProcess.pid}`);
467+
const promise = this._recreateTerminalGroup(tabLayout, terminalLayouts);
468+
tabPromises.push(promise);
469+
if (tabLayout.isActive) {
470+
activeGroup = promise;
492471
}
493-
const activeInstance = this.instances.find(t => {
494-
return t.shellLaunchConfig.attachPersistentProcess?.id === groupLayout.activePersistentProcessId;
495-
});
472+
const activeInstance = this.instances.find(t => t.shellLaunchConfig.attachPersistentProcess?.id === tabLayout.activePersistentProcessId);
496473
if (activeInstance) {
497474
this.setActiveInstance(activeInstance);
498475
}
499-
group?.resizePanes(groupLayout.terminals.map(terminal => terminal.relativeSize));
500476
}
501477
}
502478
if (layoutInfo.tabs.length) {
503-
this._terminalGroupService.activeGroup = activeGroup;
479+
activeGroup?.then(group => this._terminalGroupService.activeGroup = group);
504480
}
505481
}
506482
return reconnectCounter;
507483
}
508484

485+
private async _recreateTerminalGroup(tabLayout: IRawTerminalTabLayoutInfo<IPtyHostAttachTarget | null>, terminalLayouts: IRawTerminalInstanceLayoutInfo<IPtyHostAttachTarget | null>[]): Promise<ITerminalGroup | undefined> {
486+
let lastInstance: Promise<ITerminalInstance> | undefined;
487+
let group: Promise<ITerminalGroup | undefined> | undefined;
488+
for (const terminalLayout of terminalLayouts) {
489+
const attachPersistentProcess = terminalLayout.terminal!;
490+
if (this._lifecycleService.startupKind !== StartupKind.ReloadedWindow && attachPersistentProcess.type === 'Task') {
491+
continue;
492+
}
493+
mark(`code/terminal/willRecreateTerminal/${attachPersistentProcess.id}-${attachPersistentProcess.pid}`);
494+
if (!lastInstance) {
495+
// create group and terminal
496+
lastInstance = this.createTerminal({
497+
config: { attachPersistentProcess },
498+
location: TerminalLocation.Panel
499+
});
500+
group = lastInstance.then(instance => this._terminalGroupService.getGroupForInstance(instance));
501+
} else {
502+
// TODO: Make parentInstance a promise?
503+
// add split terminals to this group
504+
lastInstance = this.createTerminal({
505+
config: { attachPersistentProcess },
506+
location: { parentTerminal: lastInstance }
507+
});
508+
}
509+
mark(`code/terminal/didRecreateTerminal/${attachPersistentProcess.id}-${attachPersistentProcess.pid}`);
510+
}
511+
group?.then(g => g?.resizePanes(tabLayout.terminals.map(terminal => terminal.relativeSize)));
512+
return group;
513+
}
514+
509515
private _attachProcessLayoutListeners(): void {
510516
this.onDidChangeActiveGroup(() => this._saveState());
511517
this.onDidChangeActiveInstance(() => this._saveState());
@@ -902,15 +908,15 @@ export class TerminalService implements ITerminalService {
902908
return this._terminalGroupService;
903909
}
904910

905-
getInstanceHost(location: ITerminalLocationOptions | undefined): ITerminalInstanceHost {
911+
async getInstanceHost(location: ITerminalLocationOptions | undefined): Promise<ITerminalInstanceHost> {
906912
if (location) {
907913
if (location === TerminalLocation.Editor) {
908914
return this._terminalEditorService;
909915
} else if (typeof location === 'object') {
910916
if ('viewColumn' in location) {
911917
return this._terminalEditorService;
912918
} else if ('parentTerminal' in location) {
913-
return location.parentTerminal.target === TerminalLocation.Editor ? this._terminalEditorService : this._terminalGroupService;
919+
return (await location.parentTerminal).target === TerminalLocation.Editor ? this._terminalEditorService : this._terminalGroupService;
914920
}
915921
} else {
916922
return this._terminalGroupService;
@@ -954,7 +960,7 @@ export class TerminalService implements ITerminalService {
954960

955961
// Launch the contributed profile
956962
if (contributedProfile) {
957-
const resolvedLocation = this.resolveLocation(options?.location);
963+
const resolvedLocation = await this.resolveLocation(options?.location);
958964
let location: TerminalLocation | { viewColumn: number; preserveState?: boolean } | { splitActiveTerminal: boolean } | undefined;
959965
if (splitActiveTerminal) {
960966
location = resolvedLocation === TerminalLocation.Editor ? { viewColumn: SIDE_GROUP } : { splitActiveTerminal: true };
@@ -987,8 +993,8 @@ export class TerminalService implements ITerminalService {
987993
}
988994

989995
this._evaluateLocalCwd(shellLaunchConfig);
990-
const location = this.resolveLocation(options?.location) || this.defaultLocation;
991-
const parent = this._getSplitParent(options?.location);
996+
const location = await this.resolveLocation(options?.location) || this.defaultLocation;
997+
const parent = await this._getSplitParent(options?.location);
992998
this._terminalHasBeenCreated.set(true);
993999
if (parent) {
9941000
return this._splitTerminal(shellLaunchConfig, location, parent);
@@ -1029,7 +1035,7 @@ export class TerminalService implements ITerminalService {
10291035
} else if (splitActiveTerminal && options?.location) {
10301036
let parent = this.activeInstance;
10311037
if (typeof options.location === 'object' && 'parentTerminal' in options.location) {
1032-
parent = options.location.parentTerminal;
1038+
parent = await options.location.parentTerminal;
10331039
}
10341040
if (!parent) {
10351041
throw new Error('Cannot split without an active instance');
@@ -1090,11 +1096,12 @@ export class TerminalService implements ITerminalService {
10901096
return instance;
10911097
}
10921098

1093-
resolveLocation(location?: ITerminalLocationOptions): TerminalLocation | undefined {
1099+
async resolveLocation(location?: ITerminalLocationOptions): Promise<TerminalLocation | undefined> {
10941100
if (location && typeof location === 'object') {
10951101
if ('parentTerminal' in location) {
10961102
// since we don't set the target unless it's an editor terminal, this is necessary
1097-
return !location.parentTerminal.target ? TerminalLocation.Panel : location.parentTerminal.target;
1103+
const parentTerminal = await location.parentTerminal;
1104+
return !parentTerminal.target ? TerminalLocation.Panel : parentTerminal.target;
10981105
} else if ('viewColumn' in location) {
10991106
return TerminalLocation.Editor;
11001107
} else if ('splitActiveTerminal' in location) {
@@ -1105,7 +1112,7 @@ export class TerminalService implements ITerminalService {
11051112
return location;
11061113
}
11071114

1108-
private _getSplitParent(location?: ITerminalLocationOptions): ITerminalInstance | undefined {
1115+
private async _getSplitParent(location?: ITerminalLocationOptions): Promise<ITerminalInstance | undefined> {
11091116
if (location && typeof location === 'object' && 'parentTerminal' in location) {
11101117
return location.parentTerminal;
11111118
} else if (location && typeof location === 'object' && 'splitActiveTerminal' in location) {

0 commit comments

Comments
 (0)