Skip to content

Commit

Permalink
Fix extract link def for auto-links
Browse files Browse the repository at this point in the history
  • Loading branch information
mjbvz committed Mar 11, 2024
1 parent ce88065 commit d373028
Show file tree
Hide file tree
Showing 5 changed files with 802 additions and 727 deletions.
19 changes: 12 additions & 7 deletions src/languageFeatures/codeActions/extractLinkDef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { comparePosition, translatePosition } from '../../types/position';
import { makeRange, rangeIntersects } from '../../types/range';
import { getDocUri, getLine, ITextDocument } from '../../types/textDocument';
import { WorkspaceEditBuilder } from '../../util/editBuilder';
import { ExternalHref, HrefKind, InternalHref, LinkDefinitionSet, MdDocumentLinksInfo, MdInlineLink, MdLink, MdLinkDefinition, MdLinkKind, MdLinkProvider } from '../documentLinks';
import { ExternalHref, HrefKind, InternalHref, LinkDefinitionSet, MdAutoLink, MdDocumentLinksInfo, MdInlineLink, MdLink, MdLinkDefinition, MdLinkKind, MdLinkProvider } from '../documentLinks';
import { getExistingDefinitionBlock } from '../organizeLinkDefs';
import { codeActionKindContains } from './util';

Expand Down Expand Up @@ -85,8 +85,11 @@ export class MdExtractLinkDefinitionCodeActionProvider {

// Rewrite all inline occurrences of the link
for (const link of linkInfo.links) {
if (link.kind === MdLinkKind.Link && this.#matchesHref(targetLink.href, link)) {
builder.replace(resource, link.source.targetRange, `[${placeholder}]`);
if (link.kind === MdLinkKind.Link || link.kind === MdLinkKind.AutoLink) {
if (this.#matchesHref(targetLink.href, link)) {
const targetRange = link.kind === MdLinkKind.AutoLink ? link.source.range : link.source.targetRange;
builder.replace(resource, targetRange, `[${placeholder}]`);
}
}
}

Expand Down Expand Up @@ -114,10 +117,12 @@ export class MdExtractLinkDefinitionCodeActionProvider {
};
}

#getLinkTargetText(doc: ITextDocument, link: MdInlineLink) {
const afterHrefRange = makeRange(
translatePosition(link.source.targetRange.start, { characterDelta: 1 }),
translatePosition(link.source.targetRange.end, { characterDelta: -1 }));
#getLinkTargetText(doc: ITextDocument, link: MdInlineLink | MdAutoLink) {
const afterHrefRange = link.kind === MdLinkKind.AutoLink
? link.source.targetRange
: makeRange(
translatePosition(link.source.targetRange.start, { characterDelta: 1 }),
translatePosition(link.source.targetRange.end, { characterDelta: -1 }));
return doc.getText(afterHrefRange);
}

Expand Down
18 changes: 14 additions & 4 deletions src/languageFeatures/documentLinks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,12 @@ export interface MdLinkSource {
}

export enum MdLinkKind {
/** Standard Markdown link syntax: `[text][ref]` or `[text](http://example.com)` */
Link = 1,
/** Link definition: `[def]: http://example.com` */
Definition = 2,
/** Auto link: `<http://example.com>` */
AutoLink = 3,
}

export interface MdInlineLink<HrefType = LinkHref> {
Expand All @@ -168,7 +172,13 @@ export interface MdLinkDefinition {
readonly href: ExternalHref | InternalHref;
}

export type MdLink = MdInlineLink | MdLinkDefinition;
export interface MdAutoLink {
readonly kind: MdLinkKind.AutoLink;
readonly source: MdLinkSource;
readonly href: ExternalHref
}

export type MdLink = MdInlineLink | MdLinkDefinition | MdAutoLink;

function createHref(
sourceDocUri: URI,
Expand Down Expand Up @@ -498,7 +508,7 @@ export class MdLinkComputer {

const link = match[1];
const linkTarget = createHref(docUri, link, this.#workspace);
if (!linkTarget) {
if (linkTarget?.kind !== HrefKind.External) {
continue;
}

Expand All @@ -507,10 +517,10 @@ export class MdLinkComputer {
const hrefEnd = translatePosition(hrefStart, { characterDelta: link.length });
const hrefRange = { start: hrefStart, end: hrefEnd };
yield {
kind: MdLinkKind.Link,
kind: MdLinkKind.AutoLink,
href: linkTarget,
source: {
isAngleBracketLink: true,
isAngleBracketLink: false,
hrefText: link,
resource: docUri,
targetRange: hrefRange,
Expand Down
15 changes: 15 additions & 0 deletions src/test/codeActions/extractLinkDef.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,4 +301,19 @@ suite('Extract link definition code action', () => {
`[def]: http://example.com`,
));
}));

test('Extract should extract entire autolink', withStore(async (store) => {
const doc = new InMemoryDocument(workspacePath('test.md'), joinLines(
`Lorem <https://daringfireball.net/projects/markdown> dolor`,
));
const actions = await getActions(store, doc, { line: 0, character: 20 });
assertActiveActionCount(actions, 1);

const newContent = applyActionEdit(doc, actions[0]);
assert.strictEqual(newContent, joinLines(
`Lorem [def] dolor`,
``,
`[def]: https://daringfireball.net/projects/markdown`,
));
}));
});
23 changes: 23 additions & 0 deletions src/test/documentHighlights.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,4 +270,27 @@ suite('Document highlights', () => {
assertHighlightsEqual(highlights, ...expected);
}
}));

test('Should highlight auto links', withStore(async (store) => {
const doc = new InMemoryDocument(workspacePath('doc.md'), joinLines(
`text [link](http://example.com)`,
`text <http://example.com>`,

));
const workspace = store.add(new InMemoryWorkspace([doc]));

const expected = [
{ range: makeRange(0, 12, 0, 30) },
{ range: makeRange(1, 6, 1, 24) },
];

{
const highlights = await getDocumentHighlights(store, doc, { line: 0, character: 20 }, workspace);
assertHighlightsEqual(highlights, ...expected);
}
{
const highlights = await getDocumentHighlights(store, doc, { line: 1, character: 20 }, workspace);
assertHighlightsEqual(highlights, ...expected);
}
}));
});
Loading

0 comments on commit d373028

Please sign in to comment.