Skip to content

Commit d2da7e9

Browse files
committed
1 parent 1d177e2 commit d2da7e9

3 files changed

Lines changed: 42 additions & 17 deletions

File tree

src/vs/editor/contrib/links/getLinks.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { IModelService } from 'vs/editor/common/services/modelService';
1313
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
1414
import { isDisposable, Disposable } from 'vs/base/common/lifecycle';
1515
import { coalesce } from 'vs/base/common/arrays';
16+
import { assertType } from 'vs/base/common/types';
1617

1718
export class Link implements ILink {
1819

@@ -152,10 +153,13 @@ export function getLinks(model: ITextModel, token: CancellationToken): Promise<L
152153

153154

154155
CommandsRegistry.registerCommand('_executeLinkProvider', async (accessor, ...args): Promise<ILink[]> => {
155-
const [uri] = args;
156-
if (!(uri instanceof URI)) {
157-
return [];
156+
let [uri, resolveCount] = args;
157+
assertType(uri instanceof URI);
158+
159+
if (typeof resolveCount !== 'number') {
160+
resolveCount = 0;
158161
}
162+
159163
const model = accessor.get(IModelService).getModel(uri);
160164
if (!model) {
161165
return [];
@@ -164,6 +168,12 @@ CommandsRegistry.registerCommand('_executeLinkProvider', async (accessor, ...arg
164168
if (!list) {
165169
return [];
166170
}
171+
172+
// resolve links
173+
for (let i = 0; i < Math.min(resolveCount, list.links.length); i++) {
174+
await list.links[i].resolve(CancellationToken.None);
175+
}
176+
167177
const result = list.links.slice(0);
168178
list.dispose();
169179
return result;

src/vs/workbench/api/common/extHostApiCommands.ts

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -228,10 +228,15 @@ const newCommands: ApiCommand[] = [
228228
}
229229
return typeConverters.WorkspaceEdit.to(value);
230230
})
231+
),
232+
// --- links
233+
new ApiCommand(
234+
'vscode.executeLinkProvider', '_executeLinkProvider', 'Execute document link provider.',
235+
[ApiCommandArgument.Uri, new ApiCommandArgument('linkResolveCount', '(optional) Number of links that should be resolved, only when links are unresolved.', v => typeof v === 'number' || typeof v === 'undefined', v => v)],
236+
new ApiCommandResult<modes.ILink[], vscode.DocumentLink[]>('A promise that resolves to an array of DocumentLink-instances.', value => value.map(typeConverters.DocumentLink.to))
231237
)
232238
];
233239

234-
235240
//#endregion
236241

237242

@@ -289,13 +294,6 @@ export class ExtHostApiCommands {
289294
returns: 'A promise that resolves to an array of CodeLens-instances.'
290295
});
291296

292-
this._register('vscode.executeLinkProvider', this._executeDocumentLinkProvider, {
293-
description: 'Execute document link provider.',
294-
args: [
295-
{ name: 'uri', description: 'Uri of a text document', constraint: URI }
296-
],
297-
returns: 'A promise that resolves to an array of DocumentLink-instances.'
298-
});
299297
this._register('vscode.executeDocumentColorProvider', this._executeDocumentColorProvider, {
300298
description: 'Execute document color provider.',
301299
args: [
@@ -478,12 +476,6 @@ export class ExtHostApiCommands {
478476
typeConverters.Range.to(item.range),
479477
item.command ? this._commands.converter.fromInternal(item.command) : undefined);
480478
}));
481-
482-
}
483-
484-
private _executeDocumentLinkProvider(resource: URI): Promise<vscode.DocumentLink[] | undefined> {
485-
return this._commands.executeCommand<modes.ILink[]>('_executeLinkProvider', resource)
486-
.then(tryMapWith(typeConverters.DocumentLink.to));
487479
}
488480
}
489481

src/vs/workbench/test/browser/api/extHostApiCommands.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,29 @@ suite('ExtHostLanguageFeatureCommands', function () {
10111011
});
10121012
});
10131013

1014+
test('What\'s the condition for DocumentLink target to be undefined? #106308', async function () {
1015+
disposables.push(extHost.registerDocumentLinkProvider(nullExtensionDescription, defaultSelector, <vscode.DocumentLinkProvider>{
1016+
provideDocumentLinks(): any {
1017+
return [new types.DocumentLink(new types.Range(0, 0, 0, 20), undefined)];
1018+
},
1019+
resolveDocumentLink(link) {
1020+
link.target = URI.parse('foo:bar');
1021+
return link;
1022+
}
1023+
}));
1024+
1025+
await rpcProtocol.sync();
1026+
1027+
const links1 = await commands.executeCommand<vscode.DocumentLink[]>('vscode.executeLinkProvider', model.uri);
1028+
assert.equal(links1.length, 1);
1029+
assert.equal(links1[0].target, undefined);
1030+
1031+
const links2 = await commands.executeCommand<vscode.DocumentLink[]>('vscode.executeLinkProvider', model.uri, 1000);
1032+
assert.equal(links2.length, 1);
1033+
assert.equal(links2[0].target!.toString(), URI.parse('foo:bar').toString());
1034+
1035+
});
1036+
10141037

10151038
test('Color provider', function () {
10161039

0 commit comments

Comments
 (0)