提交 7c96cd3c 编写于 作者: M Matt Bierner 提交者: GitHub

Support Fragments for intra document markdown editor links (#19639)

Adds support for editor links with fragements for markdown. This jumps to the correct header location if one can be found
上级 9b8f344a
......@@ -9,7 +9,6 @@ import * as vscode from 'vscode';
import * as path from 'path';
import { MarkdownEngine } from './markdownEngine';
import { TableOfContentProvider } from './tableOfContentsProvider';
export default class MarkdownDocumentLinkProvider implements vscode.DocumentLinkProvider {
......@@ -22,8 +21,6 @@ export default class MarkdownDocumentLinkProvider implements vscode.DocumentLink
const base = path.dirname(document.uri.fsPath);
const text = document.getText();
const toc = new TableOfContentProvider(this.engine, document);
this._linkPattern.lastIndex = 0;
let match: RegExpMatchArray | null;
while ((match = this._linkPattern.exec(text))) {
......@@ -35,7 +32,7 @@ export default class MarkdownDocumentLinkProvider implements vscode.DocumentLink
try {
results.push(new vscode.DocumentLink(
new vscode.Range(linkStart, linkEnd),
this.normalizeLink(link, base, toc)));
this.normalizeLink(document, link, base)));
} catch (e) {
// noop
}
......@@ -44,26 +41,22 @@ export default class MarkdownDocumentLinkProvider implements vscode.DocumentLink
return results;
}
private normalizeLink(link: string, base: string, toc: TableOfContentProvider): vscode.Uri {
let uri = vscode.Uri.parse(link);
if (!uri.scheme) {
if (uri.fragment && !uri.path) {
// local link
const line = toc.lookup(uri.fragment);
if (!isNaN(line)) {
return vscode.Uri.parse(`command:revealLine?${encodeURIComponent(JSON.stringify({ lineNumber: line, at: 'top' }))}`);
}
}
private normalizeLink(document: vscode.TextDocument, link: string, base: string): vscode.Uri {
const uri = vscode.Uri.parse(link);
if (uri.scheme) {
return uri;
}
// assume it must be a file
let file;
if (uri.path[0] === '/') {
file = path.join(vscode.workspace.rootPath, uri.path);
} else {
file = path.join(base, uri.path);
}
uri = vscode.Uri.file(file);
// assume it must be a file
let resourcePath;
if (!uri.path) {
resourcePath = document.uri.path;
} else if (uri.path[0] === '/') {
resourcePath = path.join(vscode.workspace.rootPath, uri.path);
} else {
resourcePath = path.join(base, uri.path);
}
return uri;
return vscode.Uri.parse(`command:_markdown.openDocumentLink?${encodeURIComponent(JSON.stringify({ fragment: uri.fragment, path: resourcePath }))}`);
}
}
......@@ -12,7 +12,7 @@ import { MarkdownEngine } from './markdownEngine';
import DocumentLinkProvider from './documentLinkProvider';
import MDDocumentSymbolProvider from './documentSymbolProvider';
import { MDDocumentContentProvider, getMarkdownUri, isMarkdownFile } from './previewContentProvider';
import { TableOfContentProvider } from './tableOfContentsProvider';
interface IPackageInfo {
name: string;
......@@ -70,6 +70,28 @@ export function activate(context: vscode.ExtensionContext) {
});
}));
context.subscriptions.push(vscode.commands.registerCommand('_markdown.openDocumentLink', (args) => {
const tryRevealLine = (editor: vscode.TextEditor) => {
if (editor && args.fragment) {
const toc = new TableOfContentProvider(engine, editor.document);
const line = toc.lookup(args.fragment);
if (!isNaN(line)) {
return editor.revealRange(
new vscode.Range(line, 0, line, 0),
vscode.TextEditorRevealType.AtTop);
}
}
};
if (vscode.window.activeTextEditor && vscode.window.activeTextEditor.document.uri.path === args.path) {
return tryRevealLine(vscode.window.activeTextEditor);
} else {
const resource = vscode.Uri.file(args.path);
vscode.workspace.openTextDocument(resource)
.then(vscode.window.showTextDocument)
.then(tryRevealLine, _ => vscode.commands.executeCommand('vscode.open', resource));
}
}));
context.subscriptions.push(vscode.workspace.onDidSaveTextDocument(document => {
if (isMarkdownFile(document)) {
const uri = getMarkdownUri(document.uri);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册