@@ -10,6 +10,7 @@ import * as resources from 'vs/base/common/resources';
10
10
import { ReadableStreamEventPayload } from 'vs/base/common/stream' ;
11
11
import { URI , UriComponents } from 'vs/base/common/uri' ;
12
12
import { transformOutgoingURIs } from 'vs/base/common/uriIpc' ;
13
+ import { getSystemShell } from 'vs/base/node/shell' ;
13
14
import { IServerChannel } from 'vs/base/parts/ipc/common/ipc' ;
14
15
import { IDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnostics' ;
15
16
import { INativeEnvironmentService } from 'vs/platform/environment/common/environment' ;
@@ -27,10 +28,9 @@ import { IEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/co
27
28
import { MergedEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableCollection' ;
28
29
import { deserializeEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableShared' ;
29
30
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' ;
31
32
import { TerminalDataBufferer } from 'vs/workbench/contrib/terminal/common/terminalDataBuffering' ;
32
33
import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment' ;
33
- import { getSystemShell } from 'vs/base/node/shell' ;
34
34
import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment' ;
35
35
import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess' ;
36
36
import { AbstractVariableResolverService } from 'vs/workbench/services/configurationResolver/common/variableResolver' ;
@@ -611,6 +611,22 @@ class Terminal {
611
611
this . rows = rows ;
612
612
return this . process . resize ( cols , rows ) ;
613
613
}
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
+ }
614
630
}
615
631
616
632
// References: - ../../workbench/api/node/extHostTerminalService.ts
@@ -619,6 +635,8 @@ export class TerminalProviderChannel implements IServerChannel<RemoteAgentConnec
619
635
private readonly terminals = new Map < number , Terminal > ( ) ;
620
636
private id = 0 ;
621
637
638
+ private readonly layouts = new Map < string , terminal . ISetTerminalLayoutInfoArgs > ( ) ;
639
+
622
640
public constructor ( private readonly logService : ILogService ) {
623
641
624
642
}
@@ -647,6 +665,8 @@ export class TerminalProviderChannel implements IServerChannel<RemoteAgentConnec
647
665
case '$sendCommandResultToTerminalProcess' : return this . sendCommandResultToTerminalProcess ( args ) ;
648
666
case '$orphanQuestionReply' : return this . orphanQuestionReply ( args [ 0 ] ) ;
649
667
case '$listTerminals' : return this . listTerminals ( args [ 0 ] ) ;
668
+ case '$setTerminalLayoutInfo' : return this . setTerminalLayoutInfo ( args ) ;
669
+ case '$getTerminalLayoutInfo' : return this . getTerminalLayoutInfo ( args ) ;
650
670
}
651
671
652
672
throw new Error ( `Invalid call '${ command } '` ) ;
@@ -839,24 +859,53 @@ export class TerminalProviderChannel implements IServerChannel<RemoteAgentConnec
839
859
// do differently. Maybe it's to reset the terminal dispose timeouts or
840
860
// something like that, but why not do it each time you list?
841
861
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 ) ;
852
863
} ) ) ;
864
+
853
865
// Only returned orphaned terminals so we don't end up attaching to
854
866
// terminals already attached elsewhere.
855
867
return terminals . filter ( ( t ) => t . isOrphan ) ;
856
868
}
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
+ }
857
902
}
858
903
859
904
function transformIncoming ( remoteAuthority : string , uri : UriComponents | undefined ) : URI | undefined {
860
905
const transformer = getUriTransformer ( remoteAuthority ) ;
861
906
return uri ? URI . revive ( transformer . transformIncoming ( uri ) ) : uri ;
862
907
}
908
+
909
+ function isDefined < T > ( t : T | undefined ) : t is T {
910
+ return typeof t !== "undefined" ;
911
+ }
0 commit comments