mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 21:09:43 +00:00
parent
f25827e3cd
commit
17783a09e5
|
@ -15,6 +15,7 @@ const localize = nls.loadMessageBundle();
|
|||
|
||||
export interface ExternalLinkTarget {
|
||||
readonly kind: 'external';
|
||||
|
||||
readonly uri: vscode.Uri;
|
||||
}
|
||||
|
||||
|
@ -30,12 +31,18 @@ export interface InternalLinkTarget {
|
|||
export interface ReferenceLinkTarget {
|
||||
readonly kind: 'reference';
|
||||
|
||||
readonly fromResource: vscode.Uri;
|
||||
|
||||
readonly ref: string;
|
||||
readonly position: vscode.Position;
|
||||
}
|
||||
|
||||
export interface DefinitionLinkTarget {
|
||||
readonly kind: 'definition';
|
||||
|
||||
readonly fromResource: vscode.Uri;
|
||||
|
||||
readonly ref: string;
|
||||
readonly target: ExternalLinkTarget | InternalLinkTarget;
|
||||
}
|
||||
|
||||
|
@ -271,23 +278,26 @@ export class MdLinkProvider implements vscode.DocumentLinkProvider {
|
|||
sourceRange: new vscode.Range(linkStart, linkEnd),
|
||||
target: {
|
||||
kind: 'reference',
|
||||
fromResource: document.uri,
|
||||
ref: reference,
|
||||
position: link.linkRange.start
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public *getDefinitionLinks(document: SkinnyTextDocument): Iterable<LinkData> {
|
||||
const definitions = this.getDefinitions(document);
|
||||
for (const definition of definitions.values()) {
|
||||
for (const [ref, definition] of definitions) {
|
||||
try {
|
||||
const target = parseLink(document, definition.link);
|
||||
if (target) {
|
||||
yield {
|
||||
sourceRange: definition.linkRange,
|
||||
target: {
|
||||
fromResource: document.uri,
|
||||
ref,
|
||||
kind: 'definition',
|
||||
target
|
||||
}
|
||||
|
|
|
@ -68,16 +68,29 @@ export class MdReferencesProvider extends Disposable implements vscode.Reference
|
|||
}
|
||||
|
||||
private async getReferencesToLink(document: SkinnyTextDocument, position: vscode.Position, context: vscode.ReferenceContext): Promise<vscode.Location[] | undefined> {
|
||||
const links = (await Promise.all(await this._linkCache.getAll())).flat();
|
||||
const links = (await this._linkCache.getAll()).flat();
|
||||
|
||||
const docLinks = await this.linkProvider.getInlineLinks(document);
|
||||
const docLinks = await this.linkProvider.getAllLinks(document);
|
||||
const sourceLink = docLinks.find(link => link.sourceRange.contains(position));
|
||||
|
||||
if (sourceLink?.target.kind === 'reference') {
|
||||
const references: vscode.Location[] = [];
|
||||
|
||||
for (const link of links) {
|
||||
if (link.target.kind === 'reference' || link.target.kind === 'definition') {
|
||||
if (link.target.ref === sourceLink.target.ref && link.target.fromResource.fsPath === document.uri.fsPath) {
|
||||
references.push(new vscode.Location(document.uri, link.sourceRange));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return references;
|
||||
}
|
||||
|
||||
if (sourceLink?.target.kind !== 'internal') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
let targetDoc = await this.workspaceContents.getMarkdownDocument(sourceLink.target.path);
|
||||
if (!targetDoc) {
|
||||
// We don't think the file exists. If it doesn't already have an extension, try tacking on a `.md` and using that instead
|
||||
|
|
|
@ -22,8 +22,8 @@ function getReferences(doc: InMemoryDocument, pos: vscode.Position, workspaceCon
|
|||
return provider.provideReferences(doc, pos, { includeDeclaration: true }, noopToken);
|
||||
}
|
||||
|
||||
suite('markdown references', () => {
|
||||
test('Should not return references when not on header', async () => {
|
||||
suite('markdown: find all references', () => {
|
||||
test('Should not return references when not on header or link', async () => {
|
||||
const doc = new InMemoryDocument(workspaceFile('doc.md'), joinLines(
|
||||
`# abc`,
|
||||
``,
|
||||
|
@ -287,4 +287,59 @@ suite('markdown references', () => {
|
|||
assert.deepStrictEqual(ref.range.start.line, 2);
|
||||
}
|
||||
});
|
||||
|
||||
suite('Reference links', () => {
|
||||
test('Should find reference links within file', async () => {
|
||||
const docUri = workspaceFile('doc.md');
|
||||
const doc = new InMemoryDocument(docUri, joinLines(
|
||||
`[link 1][abc]`,
|
||||
``,
|
||||
`[abc]: https://example.com`,
|
||||
));
|
||||
|
||||
const refs = await getReferences(doc, new vscode.Position(0, 12), new InMemoryWorkspaceMarkdownDocuments([doc]));
|
||||
assert.deepStrictEqual(refs!.length, 2);
|
||||
|
||||
{
|
||||
const ref = refs![0];
|
||||
assert.deepStrictEqual(ref.uri.toString(), docUri.toString());
|
||||
assert.deepStrictEqual(ref.range.start.line, 0);
|
||||
}
|
||||
{
|
||||
const ref = refs![1];
|
||||
assert.deepStrictEqual(ref.uri.toString(), docUri.toString());
|
||||
assert.deepStrictEqual(ref.range.start.line, 2);
|
||||
}
|
||||
});
|
||||
|
||||
test('Should not find reference links across files', async () => {
|
||||
const docUri = workspaceFile('doc.md');
|
||||
const doc = new InMemoryDocument(docUri, joinLines(
|
||||
`[link 1][abc]`,
|
||||
``,
|
||||
`[abc]: https://example.com`,
|
||||
));
|
||||
|
||||
const refs = await getReferences(doc, new vscode.Position(0, 12), new InMemoryWorkspaceMarkdownDocuments([
|
||||
doc,
|
||||
new InMemoryDocument(workspaceFile('other.md'), joinLines(
|
||||
`[link 1][abc]`,
|
||||
``,
|
||||
`[abc]: https://example.com?bad`,
|
||||
))
|
||||
]));
|
||||
assert.deepStrictEqual(refs!.length, 2);
|
||||
|
||||
{
|
||||
const ref = refs![0];
|
||||
assert.deepStrictEqual(ref.uri.toString(), docUri.toString());
|
||||
assert.deepStrictEqual(ref.range.start.line, 0);
|
||||
}
|
||||
{
|
||||
const ref = refs![1];
|
||||
assert.deepStrictEqual(ref.uri.toString(), docUri.toString());
|
||||
assert.deepStrictEqual(ref.range.start.line, 2);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue