Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ba4448e

Browse files
committedMar 2, 2021
Implement terminal layouts
It doesn't mean much until we persist terminals though, I think.
1 parent 058e781 commit ba4448e

File tree

1 file changed

+61
-12
lines changed

1 file changed

+61
-12
lines changed
 

‎lib/vscode/src/vs/server/node/channel.ts

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import * as resources from 'vs/base/common/resources';
1010
import { ReadableStreamEventPayload } from 'vs/base/common/stream';
1111
import { URI, UriComponents } from 'vs/base/common/uri';
1212
import { transformOutgoingURIs } from 'vs/base/common/uriIpc';
13+
import { getSystemShell } from 'vs/base/node/shell';
1314
import { IServerChannel } from 'vs/base/parts/ipc/common/ipc';
1415
import { IDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnostics';
1516
import { INativeEnvironmentService } from 'vs/platform/environment/common/environment';
@@ -27,10 +28,9 @@ import { IEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/co
2728
import { MergedEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableCollection';
2829
import { deserializeEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableShared';
2930
import * as terminal from 'vs/workbench/contrib/terminal/common/remoteTerminalChannel';
30-
import { IShellLaunchConfig, ITerminalEnvironment, ITerminalLaunchError } from 'vs/workbench/contrib/terminal/common/terminal';
31+
import { IShellLaunchConfig, ITerminalEnvironment, ITerminalLaunchError, ITerminalsLayoutInfo } from 'vs/workbench/contrib/terminal/common/terminal';
3132
import { TerminalDataBufferer } from 'vs/workbench/contrib/terminal/common/terminalDataBuffering';
3233
import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
33-
import { getSystemShell } from 'vs/base/node/shell';
3434
import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment';
3535
import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess';
3636
import { AbstractVariableResolverService } from 'vs/workbench/services/configurationResolver/common/variableResolver';
@@ -611,6 +611,22 @@ class Terminal {
611611
this.rows = rows;
612612
return this.process.resize(cols, rows);
613613
}
614+
615+
/**
616+
* Serializable terminal information that can be sent to the client.
617+
*/
618+
public async description(id: number): Promise<terminal.IRemoteTerminalDescriptionDto> {
619+
const cwd = await this.getCwd();
620+
return {
621+
id,
622+
pid: this.pid,
623+
title: this.title,
624+
cwd,
625+
workspaceId: this.workspaceId,
626+
workspaceName: this.workspaceName,
627+
isOrphan: this.isOrphan,
628+
};
629+
}
614630
}
615631

616632
// References: - ../../workbench/api/node/extHostTerminalService.ts
@@ -619,6 +635,8 @@ export class TerminalProviderChannel implements IServerChannel<RemoteAgentConnec
619635
private readonly terminals = new Map<number, Terminal>();
620636
private id = 0;
621637

638+
private readonly layouts = new Map<string, terminal.ISetTerminalLayoutInfoArgs>();
639+
622640
public constructor (private readonly logService: ILogService) {
623641

624642
}
@@ -647,6 +665,8 @@ export class TerminalProviderChannel implements IServerChannel<RemoteAgentConnec
647665
case '$sendCommandResultToTerminalProcess': return this.sendCommandResultToTerminalProcess(args);
648666
case '$orphanQuestionReply': return this.orphanQuestionReply(args[0]);
649667
case '$listTerminals': return this.listTerminals(args[0]);
668+
case '$setTerminalLayoutInfo': return this.setTerminalLayoutInfo(args);
669+
case '$getTerminalLayoutInfo': return this.getTerminalLayoutInfo(args);
650670
}
651671

652672
throw new Error(`Invalid call '${command}'`);
@@ -839,24 +859,53 @@ export class TerminalProviderChannel implements IServerChannel<RemoteAgentConnec
839859
// do differently. Maybe it's to reset the terminal dispose timeouts or
840860
// something like that, but why not do it each time you list?
841861
const terminals = await Promise.all(Array.from(this.terminals).map(async ([id, terminal]) => {
842-
const cwd = await terminal.getCwd();
843-
return {
844-
id,
845-
pid: terminal.pid,
846-
title: terminal.title,
847-
cwd,
848-
workspaceId: terminal.workspaceId,
849-
workspaceName: terminal.workspaceName,
850-
isOrphan: terminal.isOrphan,
851-
};
862+
return terminal.description(id);
852863
}));
864+
853865
// Only returned orphaned terminals so we don't end up attaching to
854866
// terminals already attached elsewhere.
855867
return terminals.filter((t) => t.isOrphan);
856868
}
869+
870+
public async setTerminalLayoutInfo(args: terminal.ISetTerminalLayoutInfoArgs): Promise<void> {
871+
this.layouts.set(args.workspaceId, args);
872+
}
873+
874+
public async getTerminalLayoutInfo(args: terminal.IGetTerminalLayoutInfoArgs): Promise<ITerminalsLayoutInfo | undefined> {
875+
const layout = this.layouts.get(args.workspaceId);
876+
if (!layout) {
877+
return undefined;
878+
}
879+
880+
const tabs = await Promise.all(layout.tabs.map(async (tab) => {
881+
// The terminals are stored by ID so look them up.
882+
const terminals = await Promise.all(tab.terminals.map(async (t) => {
883+
const terminal = this.terminals.get(t.terminal);
884+
if (!terminal) {
885+
return undefined;
886+
}
887+
return {
888+
...t,
889+
terminal: await terminal.description(t.terminal),
890+
};
891+
}));
892+
893+
return {
894+
...tab,
895+
// Filter out terminals that have been killed.
896+
terminals: terminals.filter(isDefined),
897+
};
898+
}));
899+
900+
return { tabs };
901+
}
857902
}
858903

859904
function transformIncoming(remoteAuthority: string, uri: UriComponents | undefined): URI | undefined {
860905
const transformer = getUriTransformer(remoteAuthority);
861906
return uri ? URI.revive(transformer.transformIncoming(uri)) : uri;
862907
}
908+
909+
function isDefined<T>(t: T | undefined): t is T {
910+
return typeof t !== "undefined";
911+
}

0 commit comments

Comments
 (0)
Please sign in to comment.