Fix finding references from link without header ref

This commit is contained in:
Matt Bierner 2022-03-30 11:36:08 -07:00
parent ebd490f28e
commit 2754cef4a7
No known key found for this signature in database
GPG key ID: 099C331567E11888
3 changed files with 69 additions and 16 deletions

View file

@ -94,21 +94,32 @@ export class MdReferencesProvider extends Disposable implements vscode.Reference
const references: vscode.Location[] = [];
if (context.includeDeclaration) {
const toc = await TableOfContents.create(this.engine, targetDoc);
const entry = toc.lookup(sourceLink.target.fragment);
if (entry) {
references.push(entry.location);
if (sourceLink.target.fragment) {
const toc = await TableOfContents.create(this.engine, targetDoc);
const entry = toc.lookup(sourceLink.target.fragment);
if (entry) {
references.push(entry.location);
}
}
}
for (const link of links) {
if (link.target.kind === 'internal'
&& link.target.fragment === sourceLink.target.fragment
&& (
link.target.path.fsPath === targetDoc.uri.fsPath
|| uri.Utils.extname(link.target.path) === '' && link.target.path.with({ path: link.target.path.path + '.md' }).fsPath === targetDoc.uri.fsPath
)
) {
if (link.target.kind !== 'internal') {
continue;
}
const matchesFilePart = link.target.path.fsPath === targetDoc.uri.fsPath
|| uri.Utils.extname(link.target.path) === '' && link.target.path.with({ path: link.target.path.path + '.md' }).fsPath === targetDoc.uri.fsPath;
if (!matchesFilePart) {
continue;
}
if (sourceLink.target.fragment) {
if (link.target.fragment === sourceLink.target.fragment) {
references.push(new vscode.Location(link.target.fromResource, link.sourceRange));
}
} else { // Triggered on a link without a fragment so we only require matching the file and ignore fragments
references.push(new vscode.Location(link.target.fromResource, link.sourceRange));
}
}

View file

@ -215,7 +215,7 @@ suite('markdown references', () => {
}
});
test('Should find references from link across files when triggered on link without file extension ', async () => {
test('Should find references from link across files when triggered on link without file extension', async () => {
const docUri = workspaceFile('doc.md');
const other1Uri = workspaceFile('sub', 'other.md');
@ -250,4 +250,41 @@ suite('markdown references', () => {
assert.deepStrictEqual(ref.range.start.line, 1);
}
});
test('Should include header references when triggered on file link', async () => {
const docUri = workspaceFile('doc.md');
const otherUri = workspaceFile('sub', 'other.md');
const doc = new InMemoryDocument(docUri, joinLines(
`[with ext](./sub/other)`,
`[with ext](./sub/other#header)`,
`[without ext](./sub/other.md#no-such-header)`,
));
const refs = await getReferences(doc, new vscode.Position(0, 15), new InMemoryWorkspaceMarkdownDocuments([
doc,
new InMemoryDocument(otherUri, joinLines(
`pre`,
`# header`, // Definition should not be included since we triggered on a file link
`post`,
)),
]));
assert.deepStrictEqual(refs!.length, 3);
{
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, 1);
}
{
const ref = refs![2];
assert.deepStrictEqual(ref.uri.toString(), docUri.toString());
assert.deepStrictEqual(ref.range.start.line, 2);
}
});
});

View file

@ -132,9 +132,14 @@ export class VsCodeMdWorkspaceContents extends Disposable implements MdWorkspace
return matchingDocument;
}
const bytes = await vscode.workspace.fs.readFile(resource);
// // We assume that markdown is in UTF-8
const text = this.utf8Decoder.decode(bytes);
return new InMemoryDocument(resource, text, 0);
try {
const bytes = await vscode.workspace.fs.readFile(resource);
// We assume that markdown is in UTF-8
const text = this.utf8Decoder.decode(bytes);
return new InMemoryDocument(resource, text, 0);
} catch {
return undefined;
}
}
}