@@ -294,6 +294,13 @@ export class ExtHostPseudoterminal implements ITerminalChildProcess {
294294 }
295295}
296296
297+ let nextLinkId = 1 ;
298+
299+ interface ICachedLinkEntry {
300+ provider : vscode . TerminalLinkProvider ;
301+ link : vscode . TerminalLink ;
302+ }
303+
297304export abstract class BaseExtHostTerminalService implements IExtHostTerminalService , ExtHostTerminalServiceShape {
298305
299306 readonly _serviceBrand : undefined ;
@@ -309,6 +316,7 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
309316 private readonly _bufferer : TerminalDataBufferer ;
310317 private readonly _linkHandlers : Set < vscode . TerminalLinkHandler > = new Set ( ) ;
311318 private readonly _linkProviders : Set < vscode . TerminalLinkProvider > = new Set ( ) ;
319+ private readonly _terminalLinkCache : Map < number , Map < number , ICachedLinkEntry > > = new Map ( ) ;
312320
313321 public get activeTerminal ( ) : ExtHostTerminal | undefined { return this . _activeTerminal ; }
314322 public get terminals ( ) : ExtHostTerminal [ ] { return this . _terminals ; }
@@ -346,8 +354,8 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
346354 return links ;
347355 } ,
348356 handleTerminalLink ( link ) {
349- // TODO: Pass provider ID back to ext host so it can trigger activate/handle
350- return false ;
357+ console . log ( 'Handled link on ext host, tooltip=' + link . tooltip ) ;
358+ return true ;
351359 }
352360 } ) ;
353361 }
@@ -609,35 +617,63 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
609617 return false ;
610618 }
611619
612- public async $provideLinks ( id : number , line : string ) : Promise < ITerminalLinkDto [ ] > {
613- const terminal = this . _getTerminalById ( id ) ;
620+ public async $provideLinks ( terminalId : number , line : string ) : Promise < ITerminalLinkDto [ ] > {
621+ const terminal = this . _getTerminalById ( terminalId ) ;
614622 if ( ! terminal ) {
615623 return [ ] ;
616624 }
617625
626+ // Discard any cached links the terminal has been holding, currently all links are released
627+ // when new links are provided.
628+ this . _terminalLinkCache . delete ( terminalId ) ;
629+
618630 // TODO: Store link activate callback
619631 // TODO: Discard of links when appropriate
620632 const result : ITerminalLinkDto [ ] = [ ] ;
621633 const context : vscode . TerminalLinkContext = { terminal, line } ;
622- const promises : vscode . ProviderResult < vscode . TerminalLink [ ] > [ ] = [ ] ;
634+ const promises : vscode . ProviderResult < { provider : vscode . TerminalLinkProvider , links : vscode . TerminalLink [ ] } > [ ] = [ ] ;
623635 for ( const provider of this . _linkProviders ) {
624- promises . push ( provider . provideTerminalLinks ( context ) ) ;
625- }
626-
627- const allProviderLinks = await Promise . all ( promises ) ;
628- for ( const providerLinks of allProviderLinks ) {
629- if ( providerLinks && providerLinks . length > 0 ) {
630- result . push ( ...providerLinks . map ( l => ( {
631- startIndex : l . startIndex ,
632- length : l . length ,
633- label : l . tooltip
634- } ) ) ) ;
636+ promises . push ( new Promise ( async r => {
637+ const links = ( await provider . provideTerminalLinks ( context ) ) || [ ] ;
638+ r ( { provider, links } ) ;
639+ } ) ) ;
640+ }
641+
642+ const provideResults = await Promise . all ( promises ) ;
643+ const cacheLinkMap = new Map < number , ICachedLinkEntry > ( ) ;
644+ for ( const provideResult of provideResults ) {
645+ if ( provideResult && provideResult . links . length > 0 ) {
646+ result . push ( ...provideResult . links . map ( providerLink => {
647+ const link = {
648+ id : nextLinkId ++ ,
649+ startIndex : providerLink . startIndex ,
650+ length : providerLink . length ,
651+ label : providerLink . tooltip
652+ } ;
653+ cacheLinkMap . set ( link . id , {
654+ provider : provideResult . provider ,
655+ link : providerLink
656+ } ) ;
657+ return link ;
658+ } ) ) ;
635659 }
636660 }
637661
662+ this . _terminalLinkCache . set ( terminalId , cacheLinkMap ) ;
663+
638664 return result ;
639665 }
640666
667+ $activateLink ( terminalId : number , linkId : number ) : void {
668+ const cachedLink = this . _terminalLinkCache . get ( terminalId ) ?. get ( linkId ) ;
669+ if ( ! cachedLink ) {
670+ return ;
671+ }
672+ cachedLink . provider . handleTerminalLink ( cachedLink . link ) ;
673+
674+ // TODO: Handle when result is false
675+ }
676+
641677 private _onProcessExit ( id : number , exitCode : number | undefined ) : void {
642678 this . _bufferer . stopBuffering ( id ) ;
643679
0 commit comments