parent
8fd777f649
commit
55e72d8d02
|
@ -6,7 +6,7 @@
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import type * as Proto from '../protocol';
|
import type * as Proto from '../protocol';
|
||||||
import { ITypeScriptServiceClient } from '../typescriptService';
|
import { ITypeScriptServiceClient } from '../typescriptService';
|
||||||
import { tagsMarkdownPreview } from '../utils/previewer';
|
import { markdownDocumentation } from '../utils/previewer';
|
||||||
import * as typeConverters from '../utils/typeConverters';
|
import * as typeConverters from '../utils/typeConverters';
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,9 +45,7 @@ class TypeScriptHoverProvider implements vscode.HoverProvider {
|
||||||
if (data.displayString) {
|
if (data.displayString) {
|
||||||
parts.push({ language: 'typescript', value: data.displayString });
|
parts.push({ language: 'typescript', value: data.displayString });
|
||||||
}
|
}
|
||||||
|
parts.push(markdownDocumentation(data.documentation, data.tags));
|
||||||
const tags = tagsMarkdownPreview(data.tags);
|
|
||||||
parts.push(data.documentation + (tags ? '\n\n' + tags : ''));
|
|
||||||
return parts;
|
return parts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
import * as assert from 'assert';
|
import * as assert from 'assert';
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
import { tagsMarkdownPreview } from '../utils/previewer';
|
import { tagsMarkdownPreview, markdownDocumentation } from '../utils/previewer';
|
||||||
|
|
||||||
suite('typescript.previewer', () => {
|
suite('typescript.previewer', () => {
|
||||||
test('Should ignore hyphens after a param tag', async () => {
|
test('Should ignore hyphens after a param tag', async () => {
|
||||||
|
@ -18,5 +18,41 @@ suite('typescript.previewer', () => {
|
||||||
]),
|
]),
|
||||||
'*@param* `a` — b');
|
'*@param* `a` — b');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Should parse url jsdoc @link', async () => {
|
||||||
|
assert.strictEqual(
|
||||||
|
markdownDocumentation('x {@link http://www.example.com/foo} y {@link https://api.jquery.com/bind/#bind-eventType-eventData-handler} z', []).value,
|
||||||
|
'x [http://www.example.com/foo](http://www.example.com/foo) y [https://api.jquery.com/bind/#bind-eventType-eventData-handler](https://api.jquery.com/bind/#bind-eventType-eventData-handler) z');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should parse url jsdoc @link with text', async () => {
|
||||||
|
assert.strictEqual(
|
||||||
|
markdownDocumentation('x {@link http://www.example.com/foo abc xyz} y {@link http://www.example.com/bar|b a z} z', []).value,
|
||||||
|
'x [abc xyz](http://www.example.com/foo) y [b a z](http://www.example.com/bar) z');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should treat @linkcode jsdocs links as monospace', async () => {
|
||||||
|
assert.strictEqual(
|
||||||
|
markdownDocumentation('x {@linkcode http://www.example.com/foo} y {@linkplain http://www.example.com/bar} z', []).value,
|
||||||
|
'x [`http://www.example.com/foo`](http://www.example.com/foo) y [http://www.example.com/bar](http://www.example.com/bar) z');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should parse url jsdoc @link in param tag', async () => {
|
||||||
|
assert.strictEqual(
|
||||||
|
tagsMarkdownPreview([
|
||||||
|
{
|
||||||
|
name: 'param',
|
||||||
|
text: 'a x {@link http://www.example.com/foo abc xyz} y {@link http://www.example.com/bar|b a z} z'
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
'*@param* `a` — x [abc xyz](http://www.example.com/foo) y [b a z](http://www.example.com/bar) z');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should ignore unclosed jsdocs @link', async () => {
|
||||||
|
assert.strictEqual(
|
||||||
|
markdownDocumentation('x {@link http://www.example.com/foo y {@link http://www.example.com/bar bar} z', []).value,
|
||||||
|
'x {@link http://www.example.com/foo y [bar](http://www.example.com/bar) z');
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,24 @@
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import type * as Proto from '../protocol';
|
import type * as Proto from '../protocol';
|
||||||
|
|
||||||
|
function replaceLinks(text: string): string {
|
||||||
|
return text
|
||||||
|
// Http(s) links
|
||||||
|
.replace(/\{@(link|linkplain|linkcode) (https?:\/\/[^ |}]+?)(?:[| ]([^{}\n]+?))?\}/gi, (_, tag: string, link: string, text?: string) => {
|
||||||
|
switch (tag) {
|
||||||
|
case 'linkcode':
|
||||||
|
return `[\`${text ? text.trim() : link}\`](${link})`;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return `[${text ? text.trim() : link}](${link})`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function processInlineTags(text: string): string {
|
||||||
|
return replaceLinks(text);
|
||||||
|
}
|
||||||
|
|
||||||
function getTagBodyText(tag: Proto.JSDocTagInfo): string | undefined {
|
function getTagBodyText(tag: Proto.JSDocTagInfo): string | undefined {
|
||||||
if (!tag.text) {
|
if (!tag.text) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -41,7 +59,7 @@ function getTagBodyText(tag: Proto.JSDocTagInfo): string | undefined {
|
||||||
return makeCodeblock(tag.text);
|
return makeCodeblock(tag.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tag.text;
|
return processInlineTags(tag.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTagDocumentation(tag: Proto.JSDocTagInfo): string | undefined {
|
function getTagDocumentation(tag: Proto.JSDocTagInfo): string | undefined {
|
||||||
|
@ -58,7 +76,7 @@ function getTagDocumentation(tag: Proto.JSDocTagInfo): string | undefined {
|
||||||
if (!doc) {
|
if (!doc) {
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
return label + (doc.match(/\r\n|\n/g) ? ' \n' + doc : ` — ${doc}`);
|
return label + (doc.match(/\r\n|\n/g) ? ' \n' + processInlineTags(doc) : ` — ${processInlineTags(doc)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,8 +89,11 @@ function getTagDocumentation(tag: Proto.JSDocTagInfo): string | undefined {
|
||||||
return label + (text.match(/\r\n|\n/g) ? ' \n' + text : ` — ${text}`);
|
return label + (text.match(/\r\n|\n/g) ? ' \n' + text : ` — ${text}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function plain(parts: Proto.SymbolDisplayPart[]): string {
|
export function plain(parts: Proto.SymbolDisplayPart[] | string): string {
|
||||||
return parts.map(part => part.text).join('');
|
return processInlineTags(
|
||||||
|
typeof parts === 'string'
|
||||||
|
? parts
|
||||||
|
: parts.map(part => part.text).join(''));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function tagsMarkdownPreview(tags: Proto.JSDocTagInfo[]): string {
|
export function tagsMarkdownPreview(tags: Proto.JSDocTagInfo[]): string {
|
||||||
|
@ -80,7 +101,7 @@ export function tagsMarkdownPreview(tags: Proto.JSDocTagInfo[]): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function markdownDocumentation(
|
export function markdownDocumentation(
|
||||||
documentation: Proto.SymbolDisplayPart[],
|
documentation: Proto.SymbolDisplayPart[] | string,
|
||||||
tags: Proto.JSDocTagInfo[]
|
tags: Proto.JSDocTagInfo[]
|
||||||
): vscode.MarkdownString {
|
): vscode.MarkdownString {
|
||||||
const out = new vscode.MarkdownString();
|
const out = new vscode.MarkdownString();
|
||||||
|
@ -90,7 +111,7 @@ export function markdownDocumentation(
|
||||||
|
|
||||||
export function addMarkdownDocumentation(
|
export function addMarkdownDocumentation(
|
||||||
out: vscode.MarkdownString,
|
out: vscode.MarkdownString,
|
||||||
documentation: Proto.SymbolDisplayPart[] | undefined,
|
documentation: Proto.SymbolDisplayPart[] | string | undefined,
|
||||||
tags: Proto.JSDocTagInfo[] | undefined
|
tags: Proto.JSDocTagInfo[] | undefined
|
||||||
): vscode.MarkdownString {
|
): vscode.MarkdownString {
|
||||||
if (documentation) {
|
if (documentation) {
|
||||||
|
|
Loading…
Reference in a new issue