895
896
public registerLinkProvider(provider: vscode.TerminalLinkProvider): vscode.Disposable {
898
>
if (this._linkProviders.size === 1) {
899
>
this._proxy.$startLinkProvider();
900
>
}
901
>
return new VSCodeDisposable(() => {
902
>
this._linkProviders.delete(provider);
903
>
if (this._linkProviders.size === 0) {
904
>
this._proxy.$stopLinkProvider();
905
>
}
906
>
});
907
>
}
908
909
public async $provideLinks(terminalId: number, line: string): Promise<ITerminalLinkDto[]> {
911
>
if (!terminal) {
912
>
return [];
913
>
}
914
>
915
>
// Discard any cached links the terminal has been holding, currently all links are released
916
>
// when new links are provided.
917
>
this._terminalLinkCache.delete(terminalId);
918
>
919
>
const oldToken = this._terminalLinkCancellationSource.get(terminalId);
920
>
oldToken?.dispose(true);
921
>
const cancellationSource = new CancellationTokenSource();
922
>
this._terminalLinkCancellationSource.set(terminalId, cancellationSource);
923
>
924
>
const result: ITerminalLinkDto[] = [];
925
>
const context: vscode.TerminalLinkContext = { terminal: terminal.value, line };
926
>
const promises: vscode.ProviderResult<{ provider: vscode.TerminalLinkProvider; links: vscode.TerminalLink[] }>[] = [];
927
>
928
>
for (const provider of this._linkProviders) {
929
>
promises.push(Promises.withAsyncBody(async r => {
930
>
const cancelSubscription = cancellationSource.token.onCancellationRequested(() => r({ provider, links: [] }));
931
>
try {
932
>
const links = (await provider.provideTerminalLinks(context, cancellationSource.token)) || [];
933
>
if (!cancellationSource.token.isCancellationRequested) {
934
r({ provider, links });
935
}
937
>
cancelSubscription.dispose();
938
>
}
939
>
}));
940
>
}
941
>
942
>
const provideResults = await Promise.all(promises);
943
>
944
>
if (cancellationSource.token.isCancellationRequested) {
945
>
return [];
946
>
}
947
948
const cacheLinkMap = new Map<number, ICachedLinkEntry>();