mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 21:09:43 +00:00
parent
362d345448
commit
fdf23dc5f9
|
@ -13,9 +13,9 @@ import { isMarkdownFile } from '../util/file';
|
|||
|
||||
|
||||
export interface OpenDocumentLinkArgs {
|
||||
readonly path: string;
|
||||
readonly path: {};
|
||||
readonly fragment: string;
|
||||
readonly fromResource: any;
|
||||
readonly fromResource: {};
|
||||
}
|
||||
|
||||
enum OpenMarkdownLinks {
|
||||
|
@ -29,13 +29,13 @@ export class OpenDocumentLinkCommand implements Command {
|
|||
|
||||
public static createCommandUri(
|
||||
fromResource: vscode.Uri,
|
||||
path: string,
|
||||
path: vscode.Uri,
|
||||
fragment: string,
|
||||
): vscode.Uri {
|
||||
return vscode.Uri.parse(`command:${OpenDocumentLinkCommand.id}?${encodeURIComponent(JSON.stringify(<OpenDocumentLinkArgs>{
|
||||
path: encodeURIComponent(path),
|
||||
path: path.toJSON(),
|
||||
fragment,
|
||||
fromResource: encodeURIComponent(fromResource.toString(true)),
|
||||
fromResource: fromResource.toJSON(),
|
||||
}))}`);
|
||||
}
|
||||
|
||||
|
@ -44,25 +44,28 @@ export class OpenDocumentLinkCommand implements Command {
|
|||
) { }
|
||||
|
||||
public async execute(args: OpenDocumentLinkArgs) {
|
||||
const fromResource = vscode.Uri.parse(decodeURIComponent(args.fromResource));
|
||||
const targetPath = decodeURIComponent(args.path);
|
||||
const targetResource = vscode.Uri.file(targetPath);
|
||||
return OpenDocumentLinkCommand.execute(this.engine, args);
|
||||
}
|
||||
|
||||
public static async execute(engine: MarkdownEngine, args: OpenDocumentLinkArgs) {
|
||||
const fromResource = vscode.Uri.parse('').with(args.fromResource);
|
||||
const targetResource = vscode.Uri.parse('').with(args.path);
|
||||
const column = this.getViewColumn(fromResource);
|
||||
try {
|
||||
return await this.tryOpen(targetResource, args, column);
|
||||
return await this.tryOpen(engine, targetResource, args, column);
|
||||
} catch {
|
||||
if (extname(targetResource.path) === '') {
|
||||
return this.tryOpen(targetResource.with({ path: targetResource.path + '.md' }), args, column);
|
||||
return this.tryOpen(engine, targetResource.with({ path: targetResource.path + '.md' }), args, column);
|
||||
}
|
||||
await vscode.commands.executeCommand('vscode.open', targetResource, column);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private async tryOpen(resource: vscode.Uri, args: OpenDocumentLinkArgs, column: vscode.ViewColumn) {
|
||||
private static async tryOpen(engine: MarkdownEngine, resource: vscode.Uri, args: OpenDocumentLinkArgs, column: vscode.ViewColumn) {
|
||||
if (vscode.window.activeTextEditor && isMarkdownFile(vscode.window.activeTextEditor.document)) {
|
||||
if (vscode.window.activeTextEditor.document.uri.fsPath === resource.fsPath) {
|
||||
return this.tryRevealLine(vscode.window.activeTextEditor, args.fragment);
|
||||
return this.tryRevealLine(engine, vscode.window.activeTextEditor, args.fragment);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,10 +76,10 @@ export class OpenDocumentLinkCommand implements Command {
|
|||
|
||||
return vscode.workspace.openTextDocument(resource)
|
||||
.then(document => vscode.window.showTextDocument(document, column))
|
||||
.then(editor => this.tryRevealLine(editor, args.fragment));
|
||||
.then(editor => this.tryRevealLine(engine, editor, args.fragment));
|
||||
}
|
||||
|
||||
private getViewColumn(resource: vscode.Uri): vscode.ViewColumn {
|
||||
private static getViewColumn(resource: vscode.Uri): vscode.ViewColumn {
|
||||
const config = vscode.workspace.getConfiguration('markdown', resource);
|
||||
const openLinks = config.get<OpenMarkdownLinks>('links.openLocation', OpenMarkdownLinks.currentGroup);
|
||||
switch (openLinks) {
|
||||
|
@ -88,18 +91,22 @@ export class OpenDocumentLinkCommand implements Command {
|
|||
}
|
||||
}
|
||||
|
||||
private async tryRevealLine(editor: vscode.TextEditor, fragment?: string) {
|
||||
private static async tryRevealLine(engine: MarkdownEngine, editor: vscode.TextEditor, fragment?: string) {
|
||||
if (editor && fragment) {
|
||||
const toc = new TableOfContentsProvider(this.engine, editor.document);
|
||||
const toc = new TableOfContentsProvider(engine, editor.document);
|
||||
const entry = await toc.lookup(fragment);
|
||||
if (entry) {
|
||||
return editor.revealRange(new vscode.Range(entry.line, 0, entry.line, 0), vscode.TextEditorRevealType.AtTop);
|
||||
const lineStart = new vscode.Range(entry.line, 0, entry.line, 0);
|
||||
editor.selection = new vscode.Selection(lineStart.start, lineStart.end);
|
||||
return editor.revealRange(lineStart, vscode.TextEditorRevealType.AtTop);
|
||||
}
|
||||
const lineNumberFragment = fragment.match(/^L(\d+)$/i);
|
||||
if (lineNumberFragment) {
|
||||
const line = +lineNumberFragment[1] - 1;
|
||||
if (!isNaN(line)) {
|
||||
return editor.revealRange(new vscode.Range(line, 0, line, 0), vscode.TextEditorRevealType.AtTop);
|
||||
const lineStart = new vscode.Range(line, 0, line, 0);
|
||||
editor.selection = new vscode.Selection(lineStart.start, lineStart.end);
|
||||
return editor.revealRange(lineStart, vscode.TextEditorRevealType.AtTop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ import MarkdownWorkspaceSymbolProvider from './features/workspaceSymbolProvider'
|
|||
import { Logger } from './logger';
|
||||
import { MarkdownEngine } from './markdownEngine';
|
||||
import { getMarkdownExtensionContributions } from './markdownExtensions';
|
||||
import { ExtensionContentSecurityPolicyArbiter, PreviewSecuritySelector, ContentSecurityPolicyArbiter } from './security';
|
||||
import { loadDefaultTelemetryReporter, TelemetryReporter } from './telemetryReporter';
|
||||
import { ContentSecurityPolicyArbiter, ExtensionContentSecurityPolicyArbiter, PreviewSecuritySelector } from './security';
|
||||
import { githubSlugifier } from './slugify';
|
||||
import { loadDefaultTelemetryReporter, TelemetryReporter } from './telemetryReporter';
|
||||
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
|
@ -33,7 +33,7 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
|
||||
const contentProvider = new MarkdownContentProvider(engine, context, cspArbiter, contributions, logger);
|
||||
const symbolProvider = new MDDocumentSymbolProvider(engine);
|
||||
const previewManager = new MarkdownPreviewManager(contentProvider, logger, contributions);
|
||||
const previewManager = new MarkdownPreviewManager(contentProvider, logger, contributions, engine);
|
||||
context.subscriptions.push(previewManager);
|
||||
|
||||
context.subscriptions.push(registerMarkdownLanguageFeatures(symbolProvider, engine));
|
||||
|
|
|
@ -14,8 +14,7 @@ const localize = nls.loadMessageBundle();
|
|||
function parseLink(
|
||||
document: vscode.TextDocument,
|
||||
link: string,
|
||||
base: string
|
||||
): { uri: vscode.Uri, tooltip?: string } {
|
||||
): { uri: vscode.Uri, tooltip?: string } | undefined {
|
||||
const externalSchemeUri = getUriForLinkWithKnownExternalScheme(link);
|
||||
if (externalSchemeUri) {
|
||||
// Normalize VS Code links to target currently running version
|
||||
|
@ -29,24 +28,43 @@ function parseLink(
|
|||
// Use a fake scheme to avoid parse warnings
|
||||
const tempUri = vscode.Uri.parse(`vscode-resource:${link}`);
|
||||
|
||||
let resourcePath = tempUri.path;
|
||||
if (!tempUri.path && document.uri.scheme === 'file') {
|
||||
resourcePath = document.uri.path;
|
||||
let resourceUri: vscode.Uri | undefined;
|
||||
if (!tempUri.path) {
|
||||
resourceUri = document.uri;
|
||||
} else if (tempUri.path[0] === '/') {
|
||||
const root = vscode.workspace.getWorkspaceFolder(document.uri);
|
||||
const root = getWorkspaceFolder(document);
|
||||
if (root) {
|
||||
resourcePath = path.join(root.uri.fsPath, tempUri.path);
|
||||
resourceUri = vscode.Uri.joinPath(root, tempUri.path);
|
||||
}
|
||||
} else {
|
||||
resourcePath = base ? path.join(base, tempUri.path) : tempUri.path;
|
||||
if (document.uri.scheme === Schemes.untitled) {
|
||||
const root = getWorkspaceFolder(document);
|
||||
if (root) {
|
||||
resourceUri = vscode.Uri.joinPath(root, tempUri.path);
|
||||
}
|
||||
} else {
|
||||
const base = document.uri.with({ path: path.dirname(document.uri.fsPath) });
|
||||
resourceUri = vscode.Uri.joinPath(base, tempUri.path);
|
||||
}
|
||||
}
|
||||
|
||||
if (!resourceUri) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
resourceUri = resourceUri.with({ fragment: tempUri.fragment });
|
||||
|
||||
return {
|
||||
uri: OpenDocumentLinkCommand.createCommandUri(document.uri, resourcePath, tempUri.fragment),
|
||||
uri: OpenDocumentLinkCommand.createCommandUri(document.uri, resourceUri, tempUri.fragment),
|
||||
tooltip: localize('documentLink.tooltip', 'Follow link')
|
||||
};
|
||||
}
|
||||
|
||||
function getWorkspaceFolder(document: vscode.TextDocument) {
|
||||
return vscode.workspace.getWorkspaceFolder(document.uri)?.uri
|
||||
|| vscode.workspace.workspaceFolders?.[0]?.uri;
|
||||
}
|
||||
|
||||
function matchAll(
|
||||
pattern: RegExp,
|
||||
text: string
|
||||
|
@ -62,7 +80,6 @@ function matchAll(
|
|||
|
||||
function extractDocumentLink(
|
||||
document: vscode.TextDocument,
|
||||
base: string,
|
||||
pre: number,
|
||||
link: string,
|
||||
matchIndex: number | undefined
|
||||
|
@ -71,11 +88,14 @@ function extractDocumentLink(
|
|||
const linkStart = document.positionAt(offset);
|
||||
const linkEnd = document.positionAt(offset + link.length);
|
||||
try {
|
||||
const { uri, tooltip } = parseLink(document, link, base);
|
||||
const linkData = parseLink(document, link);
|
||||
if (!linkData) {
|
||||
return undefined;
|
||||
}
|
||||
const documentLink = new vscode.DocumentLink(
|
||||
new vscode.Range(linkStart, linkEnd),
|
||||
uri);
|
||||
documentLink.tooltip = tooltip;
|
||||
linkData.uri);
|
||||
documentLink.tooltip = linkData.tooltip;
|
||||
return documentLink;
|
||||
} catch (e) {
|
||||
return undefined;
|
||||
|
@ -91,27 +111,25 @@ export default class LinkProvider implements vscode.DocumentLinkProvider {
|
|||
document: vscode.TextDocument,
|
||||
_token: vscode.CancellationToken
|
||||
): vscode.DocumentLink[] {
|
||||
const base = document.uri.scheme === 'file' ? path.dirname(document.uri.fsPath) : '';
|
||||
const text = document.getText();
|
||||
|
||||
return [
|
||||
...this.providerInlineLinks(text, document, base),
|
||||
...this.provideReferenceLinks(text, document, base)
|
||||
...this.providerInlineLinks(text, document),
|
||||
...this.provideReferenceLinks(text, document)
|
||||
];
|
||||
}
|
||||
|
||||
private providerInlineLinks(
|
||||
text: string,
|
||||
document: vscode.TextDocument,
|
||||
base: string
|
||||
): vscode.DocumentLink[] {
|
||||
const results: vscode.DocumentLink[] = [];
|
||||
for (const match of matchAll(this.linkPattern, text)) {
|
||||
const matchImage = match[4] && extractDocumentLink(document, base, match[3].length + 1, match[4], match.index);
|
||||
const matchImage = match[4] && extractDocumentLink(document, match[3].length + 1, match[4], match.index);
|
||||
if (matchImage) {
|
||||
results.push(matchImage);
|
||||
}
|
||||
const matchLink = extractDocumentLink(document, base, match[1].length, match[5], match.index);
|
||||
const matchLink = extractDocumentLink(document, match[1].length, match[5], match.index);
|
||||
if (matchLink) {
|
||||
results.push(matchLink);
|
||||
}
|
||||
|
@ -122,7 +140,6 @@ export default class LinkProvider implements vscode.DocumentLinkProvider {
|
|||
private provideReferenceLinks(
|
||||
text: string,
|
||||
document: vscode.TextDocument,
|
||||
base: string
|
||||
): vscode.DocumentLink[] {
|
||||
const results: vscode.DocumentLink[] = [];
|
||||
|
||||
|
@ -159,8 +176,10 @@ export default class LinkProvider implements vscode.DocumentLinkProvider {
|
|||
|
||||
for (const definition of definitions.values()) {
|
||||
try {
|
||||
const { uri } = parseLink(document, definition.link, base);
|
||||
results.push(new vscode.DocumentLink(definition.linkRange, uri));
|
||||
const linkData = parseLink(document, definition.link);
|
||||
if (linkData) {
|
||||
results.push(new vscode.DocumentLink(definition.linkRange, linkData.uri));
|
||||
}
|
||||
} catch (e) {
|
||||
// noop
|
||||
}
|
||||
|
|
|
@ -3,20 +3,20 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as path from 'path';
|
||||
|
||||
import { Logger } from '../logger';
|
||||
import { MarkdownContentProvider } from './previewContentProvider';
|
||||
import { Disposable } from '../util/dispose';
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { OpenDocumentLinkCommand, resolveLinkToMarkdownFile } from '../commands/openDocumentLink';
|
||||
import { Logger } from '../logger';
|
||||
import { MarkdownContributionProvider } from '../markdownExtensions';
|
||||
import { Disposable } from '../util/dispose';
|
||||
import { isMarkdownFile } from '../util/file';
|
||||
import { normalizeResource, WebviewResourceProvider } from '../util/resources';
|
||||
import { getVisibleLine, TopmostLineMonitor } from '../util/topmostLineMonitor';
|
||||
import { MarkdownPreviewConfigurationManager } from './previewConfig';
|
||||
import { MarkdownContributionProvider } from '../markdownExtensions';
|
||||
import { isMarkdownFile } from '../util/file';
|
||||
import { resolveLinkToMarkdownFile } from '../commands/openDocumentLink';
|
||||
import { WebviewResourceProvider, normalizeResource } from '../util/resources';
|
||||
import { MarkdownContentProvider } from './previewContentProvider';
|
||||
import { MarkdownEngine } from '../markdownEngine';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
interface WebviewMessage {
|
||||
|
@ -123,6 +123,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
|
|||
resource: vscode.Uri,
|
||||
startingScroll: StartingScrollLocation | undefined,
|
||||
private readonly delegate: MarkdownPreviewDelegate,
|
||||
private readonly engine: MarkdownEngine,
|
||||
private readonly _contentProvider: MarkdownContentProvider,
|
||||
private readonly _previewConfigurations: MarkdownPreviewConfigurationManager,
|
||||
private readonly _logger: Logger,
|
||||
|
@ -407,7 +408,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
|
|||
}
|
||||
}
|
||||
|
||||
vscode.commands.executeCommand('_markdown.openDocumentLink', { path: hrefPath, fragment, fromResource: this.resource });
|
||||
OpenDocumentLinkCommand.execute(this.engine, { path: hrefPath, fragment, fromResource: this.resource.toJSON() });
|
||||
}
|
||||
|
||||
//#region WebviewResourceProvider
|
||||
|
@ -452,8 +453,9 @@ export class StaticMarkdownPreview extends Disposable implements ManagedMarkdown
|
|||
previewConfigurations: MarkdownPreviewConfigurationManager,
|
||||
logger: Logger,
|
||||
contributionProvider: MarkdownContributionProvider,
|
||||
engine: MarkdownEngine,
|
||||
): StaticMarkdownPreview {
|
||||
return new StaticMarkdownPreview(webview, resource, contentProvider, previewConfigurations, logger, contributionProvider);
|
||||
return new StaticMarkdownPreview(webview, resource, contentProvider, previewConfigurations, logger, contributionProvider, engine);
|
||||
}
|
||||
|
||||
private readonly preview: MarkdownPreview;
|
||||
|
@ -465,13 +467,14 @@ export class StaticMarkdownPreview extends Disposable implements ManagedMarkdown
|
|||
private readonly _previewConfigurations: MarkdownPreviewConfigurationManager,
|
||||
logger: Logger,
|
||||
contributionProvider: MarkdownContributionProvider,
|
||||
engine: MarkdownEngine,
|
||||
) {
|
||||
super();
|
||||
|
||||
this.preview = this._register(new MarkdownPreview(this._webviewPanel, resource, undefined, {
|
||||
getAdditionalState: () => { return {}; },
|
||||
openPreviewLinkToMarkdownFile: () => { /* todo */ }
|
||||
}, contentProvider, _previewConfigurations, logger, contributionProvider));
|
||||
}, engine, contentProvider, _previewConfigurations, logger, contributionProvider));
|
||||
|
||||
this._register(this._webviewPanel.onDidDispose(() => {
|
||||
this.dispose();
|
||||
|
@ -548,9 +551,10 @@ export class DynamicMarkdownPreview extends Disposable implements ManagedMarkdow
|
|||
logger: Logger,
|
||||
topmostLineMonitor: TopmostLineMonitor,
|
||||
contributionProvider: MarkdownContributionProvider,
|
||||
engine: MarkdownEngine,
|
||||
): DynamicMarkdownPreview {
|
||||
return new DynamicMarkdownPreview(webview, input,
|
||||
contentProvider, previewConfigurations, logger, topmostLineMonitor, contributionProvider);
|
||||
contentProvider, previewConfigurations, logger, topmostLineMonitor, contributionProvider, engine);
|
||||
}
|
||||
|
||||
public static create(
|
||||
|
@ -560,7 +564,8 @@ export class DynamicMarkdownPreview extends Disposable implements ManagedMarkdow
|
|||
previewConfigurations: MarkdownPreviewConfigurationManager,
|
||||
logger: Logger,
|
||||
topmostLineMonitor: TopmostLineMonitor,
|
||||
contributionProvider: MarkdownContributionProvider
|
||||
contributionProvider: MarkdownContributionProvider,
|
||||
engine: MarkdownEngine,
|
||||
): DynamicMarkdownPreview {
|
||||
const webview = vscode.window.createWebviewPanel(
|
||||
DynamicMarkdownPreview.viewType,
|
||||
|
@ -568,7 +573,7 @@ export class DynamicMarkdownPreview extends Disposable implements ManagedMarkdow
|
|||
previewColumn, { enableFindWidget: true, });
|
||||
|
||||
return new DynamicMarkdownPreview(webview, input,
|
||||
contentProvider, previewConfigurations, logger, topmostLineMonitor, contributionProvider);
|
||||
contentProvider, previewConfigurations, logger, topmostLineMonitor, contributionProvider, engine);
|
||||
}
|
||||
|
||||
private constructor(
|
||||
|
@ -579,6 +584,7 @@ export class DynamicMarkdownPreview extends Disposable implements ManagedMarkdow
|
|||
private readonly _logger: Logger,
|
||||
private readonly _topmostLineMonitor: TopmostLineMonitor,
|
||||
private readonly _contributionProvider: MarkdownContributionProvider,
|
||||
private readonly _engine: MarkdownEngine,
|
||||
) {
|
||||
super();
|
||||
|
||||
|
@ -729,6 +735,7 @@ export class DynamicMarkdownPreview extends Disposable implements ManagedMarkdow
|
|||
this.update(link, fragment ? new StartingScrollFragment(fragment) : undefined);
|
||||
}
|
||||
},
|
||||
this._engine,
|
||||
this._contentProvider,
|
||||
this._previewConfigurations,
|
||||
this._logger,
|
||||
|
|
|
@ -5,10 +5,11 @@
|
|||
|
||||
import * as vscode from 'vscode';
|
||||
import { Logger } from '../logger';
|
||||
import { MarkdownEngine } from '../markdownEngine';
|
||||
import { MarkdownContributionProvider } from '../markdownExtensions';
|
||||
import { disposeAll, Disposable } from '../util/dispose';
|
||||
import { Disposable, disposeAll } from '../util/dispose';
|
||||
import { TopmostLineMonitor } from '../util/topmostLineMonitor';
|
||||
import { DynamicMarkdownPreview, StaticMarkdownPreview, ManagedMarkdownPreview } from './preview';
|
||||
import { DynamicMarkdownPreview, ManagedMarkdownPreview, StaticMarkdownPreview } from './preview';
|
||||
import { MarkdownPreviewConfigurationManager } from './previewConfig';
|
||||
import { MarkdownContentProvider } from './previewContentProvider';
|
||||
|
||||
|
@ -68,7 +69,8 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
|
|||
public constructor(
|
||||
private readonly _contentProvider: MarkdownContentProvider,
|
||||
private readonly _logger: Logger,
|
||||
private readonly _contributions: MarkdownContributionProvider
|
||||
private readonly _contributions: MarkdownContributionProvider,
|
||||
private readonly _engine: MarkdownEngine,
|
||||
) {
|
||||
super();
|
||||
this._register(vscode.window.registerWebviewPanelSerializer(DynamicMarkdownPreview.viewType, this));
|
||||
|
@ -145,7 +147,8 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
|
|||
this._previewConfigurations,
|
||||
this._logger,
|
||||
this._topmostLineMonitor,
|
||||
this._contributions);
|
||||
this._contributions,
|
||||
this._engine);
|
||||
|
||||
this.registerDynamicPreview(preview);
|
||||
}
|
||||
|
@ -160,7 +163,8 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
|
|||
this._contentProvider,
|
||||
this._previewConfigurations,
|
||||
this._logger,
|
||||
this._contributions);
|
||||
this._contributions,
|
||||
this._engine);
|
||||
this.registerStaticPreview(preview);
|
||||
}
|
||||
|
||||
|
@ -179,7 +183,8 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
|
|||
this._previewConfigurations,
|
||||
this._logger,
|
||||
this._topmostLineMonitor,
|
||||
this._contributions);
|
||||
this._contributions,
|
||||
this._engine);
|
||||
|
||||
this.setPreviewActiveContext(true);
|
||||
this._activePreview = preview;
|
||||
|
|
|
@ -70,7 +70,7 @@ export namespace MarkdownContributions {
|
|||
|
||||
const previewStyles = getContributedStyles(contributions, extension);
|
||||
const previewScripts = getContributedScripts(contributions, extension);
|
||||
const previewResourceRoots = previewStyles.length || previewScripts.length ? [vscode.Uri.file(extension.extensionPath)] : [];
|
||||
const previewResourceRoots = previewStyles.length || previewScripts.length ? [extension.extensionUri] : [];
|
||||
const markdownItPlugins = getContributedMarkdownItPlugins(contributions, extension);
|
||||
|
||||
return {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
import * as assert from 'assert';
|
||||
import 'mocha';
|
||||
import * as vscode from 'vscode';
|
||||
import { joinLines } from './util';
|
||||
|
||||
const testFileA = workspaceFile('a.md');
|
||||
|
||||
|
@ -75,7 +76,7 @@ suite('Markdown Document links', () => {
|
|||
await executeLink(link);
|
||||
|
||||
assertActiveDocumentUri(workspaceFile('sub', 'c.md'));
|
||||
assert.strictEqual( vscode.window.activeTextEditor!.selection.start.line, 1);
|
||||
assert.strictEqual(vscode.window.activeTextEditor!.selection.start.line, 1);
|
||||
});
|
||||
|
||||
test('Should navigate to fragment by line', async () => {
|
||||
|
@ -85,7 +86,39 @@ suite('Markdown Document links', () => {
|
|||
await executeLink(link);
|
||||
|
||||
assertActiveDocumentUri(workspaceFile('sub', 'c.md'));
|
||||
assert.strictEqual( vscode.window.activeTextEditor!.selection.start.line, 1);
|
||||
assert.strictEqual(vscode.window.activeTextEditor!.selection.start.line, 1);
|
||||
});
|
||||
|
||||
test('Should navigate to fragment within current file', async () => {
|
||||
await withFileContents(testFileA, joinLines(
|
||||
'[](a#header)',
|
||||
'[](#header)',
|
||||
'# Header'));
|
||||
|
||||
const links = await getLinksForFile(testFileA);
|
||||
{
|
||||
await executeLink(links[0]);
|
||||
assertActiveDocumentUri(workspaceFile('a.md'));
|
||||
assert.strictEqual(vscode.window.activeTextEditor!.selection.start.line, 2);
|
||||
}
|
||||
{
|
||||
await executeLink(links[1]);
|
||||
assertActiveDocumentUri(workspaceFile('a.md'));
|
||||
assert.strictEqual(vscode.window.activeTextEditor!.selection.start.line, 2);
|
||||
}
|
||||
});
|
||||
|
||||
test('Should navigate to fragment within current untitled file', async () => {
|
||||
const testFile = workspaceFile('x.md').with({ scheme: 'untitled' });
|
||||
await withFileContents(testFile, joinLines(
|
||||
'[](#second)',
|
||||
'# Second'));
|
||||
|
||||
const [link] = await getLinksForFile(testFile);
|
||||
await executeLink(link);
|
||||
|
||||
assertActiveDocumentUri(testFile);
|
||||
assert.strictEqual(vscode.window.activeTextEditor!.selection.start.line, 1);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
8
extensions/markdown-language-features/src/test/util.ts
Normal file
8
extensions/markdown-language-features/src/test/util.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as os from 'os';
|
||||
|
||||
export const joinLines = (...args: string[]) =>
|
||||
args.join(os.platform() === 'win32' ? '\r\n' : '\n');
|
|
@ -9,6 +9,7 @@ export const Schemes = {
|
|||
http: 'http:',
|
||||
https: 'https:',
|
||||
file: 'file:',
|
||||
untitled: 'untitled',
|
||||
mailto: 'mailto:',
|
||||
data: 'data:',
|
||||
vscode: 'vscode:',
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
[b](b)
|
||||
[b](b.md)
|
||||
[b](./b.md)
|
||||
[b](/b.md)
|
|
@ -1 +1,3 @@
|
|||
![](./a)
|
||||
# b
|
||||
|
||||
[](./a)
|
|
@ -1,2 +1,6 @@
|
|||
# First
|
||||
# Second
|
||||
|
||||
[b](/b.md)
|
||||
[b](../b.md)
|
||||
[b](./../b.md)
|
||||
|
|
Loading…
Reference in a new issue