mirror of
https://github.com/Microsoft/vscode
synced 2024-09-13 21:55:38 +00:00
Fixing references on header when looking at file extensions
This commit is contained in:
parent
8a6a300216
commit
6b573340bd
|
@ -9,17 +9,10 @@ import { Slugifier } from '../slugify';
|
||||||
import { TableOfContents, TocEntry } from '../tableOfContents';
|
import { TableOfContents, TocEntry } from '../tableOfContents';
|
||||||
import { Disposable } from '../util/dispose';
|
import { Disposable } from '../util/dispose';
|
||||||
import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents';
|
import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents';
|
||||||
import { InternalHref, LinkHref, MdLink, MdLinkProvider } from './documentLinkProvider';
|
import { InternalHref, MdLink, MdLinkProvider } from './documentLinkProvider';
|
||||||
import { MdWorkspaceCache } from './workspaceCache';
|
import { MdWorkspaceCache } from './workspaceCache';
|
||||||
|
|
||||||
|
|
||||||
function isLinkToHeader(target: LinkHref, header: TocEntry, headerDocument: vscode.Uri, slugifier: Slugifier): target is InternalHref {
|
|
||||||
return target.kind === 'internal'
|
|
||||||
&& target.path.fsPath === headerDocument.fsPath
|
|
||||||
&& slugifier.fromHeading(target.fragment).value === header.slug.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A link in a markdown file.
|
* A link in a markdown file.
|
||||||
*/
|
*/
|
||||||
|
@ -121,15 +114,10 @@ export class MdReferencesProvider extends Disposable implements vscode.Reference
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const link of links) {
|
for (const link of links) {
|
||||||
if (isLinkToHeader(link.href, header, document.uri, this.slugifier)) {
|
if (link.href.kind === 'internal'
|
||||||
references.push({
|
&& this.looksLikeLinkToDoc(link.href, document)
|
||||||
kind: 'link',
|
&& this.slugifier.fromHeading(link.href.fragment).value === header.slug.value
|
||||||
isTriggerLocation: false,
|
) {
|
||||||
isDefinition: false,
|
|
||||||
location: new vscode.Location(link.sourceResource, link.sourceRange),
|
|
||||||
fragmentLocation: getFragmentLocation(link),
|
|
||||||
});
|
|
||||||
} else if (link.kind === 'definition' && isLinkToHeader(link.href, header, document.uri, this.slugifier)) {
|
|
||||||
references.push({
|
references.push({
|
||||||
kind: 'link',
|
kind: 'link',
|
||||||
isTriggerLocation: false,
|
isTriggerLocation: false,
|
||||||
|
@ -194,10 +182,7 @@ export class MdReferencesProvider extends Disposable implements vscode.Reference
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const matchesFilePart = link.href.path.fsPath === targetDoc.uri.fsPath
|
if (!this.looksLikeLinkToDoc(link.href, targetDoc)) {
|
||||||
|| uri.Utils.extname(link.href.path) === '' && link.href.path.with({ path: link.href.path.path + '.md' }).fsPath === targetDoc.uri.fsPath;
|
|
||||||
|
|
||||||
if (!matchesFilePart) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,6 +216,11 @@ export class MdReferencesProvider extends Disposable implements vscode.Reference
|
||||||
return references;
|
return references;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private looksLikeLinkToDoc(href: InternalHref, targetDoc: SkinnyTextDocument) {
|
||||||
|
return href.path.fsPath === targetDoc.uri.fsPath
|
||||||
|
|| uri.Utils.extname(href.path) === '' && href.path.with({ path: href.path.path + '.md' }).fsPath === targetDoc.uri.fsPath;
|
||||||
|
}
|
||||||
|
|
||||||
private * getReferencesToReferenceLink(allLinks: Iterable<MdLink>, sourceLink: MdLink): Iterable<MdReference> {
|
private * getReferencesToReferenceLink(allLinks: Iterable<MdLink>, sourceLink: MdLink): Iterable<MdReference> {
|
||||||
if (sourceLink.href.kind !== 'reference') {
|
if (sourceLink.href.kind !== 'reference') {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -215,6 +215,37 @@ suite('markdown: find all references', () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Should find references without requiring file extensions', async () => {
|
||||||
|
const docUri = workspacePath('doc.md');
|
||||||
|
const other1Uri = workspacePath('other.md');
|
||||||
|
|
||||||
|
const doc = new InMemoryDocument(docUri, joinLines(
|
||||||
|
`# a B c`,
|
||||||
|
``,
|
||||||
|
`[link 1](#a-b-c)`,
|
||||||
|
));
|
||||||
|
const refs = await getReferences(doc, new vscode.Position(2, 10), new InMemoryWorkspaceMarkdownDocuments([
|
||||||
|
doc,
|
||||||
|
new InMemoryDocument(other1Uri, joinLines(
|
||||||
|
`[not link](#a-b-c)`,
|
||||||
|
`[not link](/doc.md#a-b-z)`,
|
||||||
|
`[with ext](/doc.md#a-b-c)`,
|
||||||
|
`[without ext](/doc#a-b-c)`,
|
||||||
|
`[rel with ext](./doc.md#a-b-c)`,
|
||||||
|
`[rel without ext](./doc#a-b-c)`,
|
||||||
|
)),
|
||||||
|
]));
|
||||||
|
|
||||||
|
assertReferencesEqual(refs!,
|
||||||
|
{ uri: docUri, line: 0 }, // Header definition
|
||||||
|
{ uri: docUri, line: 2 },
|
||||||
|
{ uri: other1Uri, line: 2 }, // Other with ext
|
||||||
|
{ uri: other1Uri, line: 3 }, // Other without ext
|
||||||
|
{ uri: other1Uri, line: 4 }, // Other relative link with ext
|
||||||
|
{ uri: other1Uri, line: 5 }, // Other relative link without ext
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
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 = workspacePath('doc.md');
|
const docUri = workspacePath('doc.md');
|
||||||
const other1Uri = workspacePath('sub', 'other.md');
|
const other1Uri = workspacePath('sub', 'other.md');
|
||||||
|
|
|
@ -149,4 +149,62 @@ suite('markdown: rename', () => {
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Rename on header should pick up links across files', async () => {
|
||||||
|
const uri = workspacePath('doc.md');
|
||||||
|
const otherUri = workspacePath('other.md');
|
||||||
|
const doc = new InMemoryDocument(uri, joinLines(
|
||||||
|
`### A b C`, // rename here
|
||||||
|
`[text](#a-b-c)`,
|
||||||
|
));
|
||||||
|
|
||||||
|
const edit = await getRenameEdits(doc, new vscode.Position(0, 0), "New Header", new InMemoryWorkspaceMarkdownDocuments([
|
||||||
|
doc,
|
||||||
|
new InMemoryDocument(otherUri, joinLines(
|
||||||
|
`[text](#a-b-c)`, // Should not find this
|
||||||
|
`[text](./doc.md#a-b-c)`, // But should find this
|
||||||
|
`[text](./doc#a-b-c)`, // And this
|
||||||
|
))
|
||||||
|
]));
|
||||||
|
assertEditsEqual(edit!, {
|
||||||
|
uri: uri, edits: [
|
||||||
|
new vscode.TextEdit(new vscode.Range(0, 4, 0, 9), 'New Header'),
|
||||||
|
new vscode.TextEdit(new vscode.Range(1, 8, 1, 13), 'new-header'),
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
uri: otherUri, edits: [
|
||||||
|
new vscode.TextEdit(new vscode.Range(1, 16, 1, 21), 'new-header'),
|
||||||
|
new vscode.TextEdit(new vscode.Range(2, 13, 2, 18), 'new-header'),
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Rename on link should pick up links across files', async () => {
|
||||||
|
const uri = workspacePath('doc.md');
|
||||||
|
const otherUri = workspacePath('other.md');
|
||||||
|
const doc = new InMemoryDocument(uri, joinLines(
|
||||||
|
`### A b C`,
|
||||||
|
`[text](#a-b-c)`, // rename here
|
||||||
|
));
|
||||||
|
|
||||||
|
const edit = await getRenameEdits(doc, new vscode.Position(1, 10), "New Header", new InMemoryWorkspaceMarkdownDocuments([
|
||||||
|
doc,
|
||||||
|
new InMemoryDocument(otherUri, joinLines(
|
||||||
|
`[text](#a-b-c)`, // Should not find this
|
||||||
|
`[text](./doc.md#a-b-c)`, // But should find this
|
||||||
|
`[text](./doc#a-b-c)`, // And this
|
||||||
|
))
|
||||||
|
]));
|
||||||
|
assertEditsEqual(edit!, {
|
||||||
|
uri: uri, edits: [
|
||||||
|
new vscode.TextEdit(new vscode.Range(0, 4, 0, 9), 'New Header'),
|
||||||
|
new vscode.TextEdit(new vscode.Range(1, 8, 1, 13), 'new-header'),
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
uri: otherUri, edits: [
|
||||||
|
new vscode.TextEdit(new vscode.Range(1, 16, 1, 21), 'new-header'),
|
||||||
|
new vscode.TextEdit(new vscode.Range(2, 13, 2, 18), 'new-header'),
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue