Browse Source

Adds autolink support in plain text (as footnotes)

main
Eric Amodio 5 years ago
parent
commit
947b988c69
2 changed files with 66 additions and 28 deletions
  1. +63
    -22
      src/annotations/autolinks.ts
  2. +3
    -6
      src/git/formatters/commitFormatter.ts

+ 63
- 22
src/annotations/autolinks.ts View File

@ -9,14 +9,16 @@ import { GlyphChars } from '../constants';
const numRegex = /<num>/g;
const superscripts = ['\u00B9', '\u00B2', '\u00B3', '\u2074', '\u2075', '\u2076', '\u2077', '\u2078', '\u2079'];
export interface CacheableAutolinkReference extends AutolinkReference {
linkify?: ((text: string) => string) | null;
linkify?: ((text: string, markdown: boolean) => string) | null;
messageMarkdownRegex?: RegExp;
messageRegex?: RegExp;
}
export interface DynamicAutolinkReference {
linkify: (text: string) => string;
linkify: (text: string, markdown: boolean) => string;
}
function isDynamic(ref: AutolinkReference | DynamicAutolinkReference): ref is DynamicAutolinkReference {
@ -85,11 +87,16 @@ export class Autolinks implements Disposable {
}
@debug({ args: false })
linkify(text: string, remotes?: GitRemote[], issues?: Map<number, Issue | Promises.CancellationError | undefined>) {
linkify(
text: string,
markdown: boolean,
remotes?: GitRemote[],
issues?: Map<number, Issue | Promises.CancellationError | undefined>
) {
for (const ref of this._references) {
if (this.ensureAutolinkCached(ref, issues)) {
if (ref.linkify != null) {
text = ref.linkify(text);
text = ref.linkify(text, markdown);
}
}
}
@ -101,7 +108,7 @@ export class Autolinks implements Disposable {
for (const ref of r.provider.autolinks) {
if (this.ensureAutolinkCached(ref, issues)) {
if (ref.linkify != null) {
text = ref.linkify(text);
text = ref.linkify(text, markdown);
}
}
}
@ -126,32 +133,66 @@ export class Autolinks implements Disposable {
}
if (issues == null || issues.size === 0) {
const markdown = `[$1](${ref.url.replace(numRegex, '$2')}${
const replacement = `[$1](${ref.url.replace(numRegex, '$2')}${
ref.title ? ` "${ref.title.replace(numRegex, '$2')}"` : ''
})`;
ref.linkify = (text: string) => text.replace(ref.messageMarkdownRegex!, markdown);
ref.linkify = (text: string, markdown: boolean) =>
!markdown ? text : text.replace(ref.messageMarkdownRegex!, replacement);
return true;
}
ref.linkify = (text: string) =>
text.replace(ref.messageMarkdownRegex!, (substring, linkText, number) => {
ref.linkify = (text: string, markdown: boolean) => {
if (markdown) {
return text.replace(ref.messageMarkdownRegex!, (substring, linkText, number) => {
const issue = issues?.get(Number(number));
return `[${linkText}](${ref.url.replace(numRegex, number)}${
ref.title
? ` "${ref.title.replace(numRegex, number)}${
issue instanceof Promises.CancellationError
? `\n${GlyphChars.Dash.repeat(2)}\nDetails timed out`
: issue
? `\n${GlyphChars.Dash.repeat(2)}\n${issue.title.replace(
/([")])/g,
'\\$1'
)}\n${issue.closed ? 'Closed' : 'Opened'}, ${Dates.getFormatter(
issue.closedDate ?? issue.date
).fromNow()}`
: ''
}"`
: ''
})`;
});
}
let footnotes: string[] | undefined;
let superscript;
text = text.replace(ref.messageRegex!, (substring, linkText, number) => {
const issue = issues?.get(Number(number));
if (issue == null) return linkText;
return `[${linkText}](${ref.url.replace(numRegex, number)}${
ref.title
? ` "${ref.title.replace(numRegex, number)}${
issue instanceof Promises.CancellationError
? `\n${GlyphChars.Dash.repeat(2)}\nDetails timed out`
: issue
? `\n${GlyphChars.Dash.repeat(2)}\n${issue.title.replace(/([")])/g, '\\$1')}\n${
issue.closed ? 'Closed' : 'Opened'
}, ${Dates.getFormatter(issue.closedDate ?? issue.date).fromNow()}`
: ''
}"`
: ''
})`;
if (footnotes === undefined) {
footnotes = [];
}
superscript = superscripts[footnotes.length];
footnotes.push(
`${superscript} ${
issue instanceof Promises.CancellationError
? 'Details timed out'
: issue
? `${issue.title} ${GlyphChars.Dot} ${
issue.closed ? 'Closed' : 'Opened'
}, ${Dates.getFormatter(issue.closedDate ?? issue.date).fromNow()}`
: ''
}`
);
return `${linkText}${superscript}`;
});
return footnotes == null || footnotes.length === 0 ? text : `${text}\n\n${footnotes.join('\n')}`;
};
} catch (ex) {
Logger.error(
ex,

+ 3
- 6
src/git/formatters/commitFormatter.ts View File

@ -349,19 +349,16 @@ export class CommitFormatter extends Formatter {
message = emojify(message);
message = this._padOrTruncate(message, this._options.tokenOptions.message);
if (!this._options.markdown) {
return message;
}
if (Container.config.hovers.autolinks.enabled) {
message = Container.autolinks.linkify(
Strings.escapeMarkdown(message, { quoted: true }),
this._options.markdown ? Strings.escapeMarkdown(message, { quoted: true }) : message,
this._options.markdown ?? false,
this._options.remotes,
this._options.autolinkedIssues
);
}
return `\n> ${message}`;
return this._options.markdown ? `\n> ${message}` : message;
}
get pullRequest() {

Loading…
Cancel
Save