Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: render examples as yaml on hover #947

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 24 additions & 24 deletions src/languageservice/services/yamlHover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import * as path from 'path';
import { Telemetry } from '../telemetry';
import { convertErrorToTelemetryMsg } from '../utils/objects';
import { ASTNode } from 'vscode-json-languageservice';
import { stringify as stringifyYAML } from 'yaml';

export class YAMLHover {
private shouldHover: boolean;
Expand Down Expand Up @@ -87,11 +88,6 @@ export class YAMLHover {
);

const createHover = (contents: string): Hover => {
if (this.indentation !== undefined) {
const indentationMatchRegex = new RegExp(` {${this.indentation.length}}`, 'g');
contents = contents.replace(indentationMatchRegex, ' ');
}

const markupContent: MarkupContent = {
kind: MarkupKind.Markdown,
value: contents,
Expand Down Expand Up @@ -120,12 +116,12 @@ export class YAMLHover {
matchingSchemas.every((s) => {
if ((s.node === node || (node.type === 'property' && node.valueNode === s.node)) && !s.inverted && s.schema) {
title = title || s.schema.title || s.schema.closestTitle;
markdownDescription = markdownDescription || s.schema.markdownDescription || toMarkdown(s.schema.description);
markdownDescription = markdownDescription || s.schema.markdownDescription || this.toMarkdown(s.schema.description);
if (s.schema.enum) {
if (s.schema.markdownEnumDescriptions) {
markdownEnumDescriptions = s.schema.markdownEnumDescriptions;
} else if (s.schema.enumDescriptions) {
markdownEnumDescriptions = s.schema.enumDescriptions.map(toMarkdown);
markdownEnumDescriptions = s.schema.enumDescriptions.map(this.toMarkdown, this);
} else {
markdownEnumDescriptions = [];
}
Expand All @@ -145,7 +141,7 @@ export class YAMLHover {
markdownDescription = '';
s.schema.anyOf.forEach((childSchema: JSONSchema, index: number) => {
title += childSchema.title || s.schema.closestTitle || '';
markdownDescription += childSchema.markdownDescription || toMarkdown(childSchema.description) || '';
markdownDescription += childSchema.markdownDescription || this.toMarkdown(childSchema.description) || '';
if (index !== s.schema.anyOf.length - 1) {
title += ' || ';
markdownDescription += ' || ';
Expand All @@ -156,15 +152,15 @@ export class YAMLHover {
}
if (s.schema.examples) {
s.schema.examples.forEach((example) => {
markdownExamples.push(JSON.stringify(example, null, 2));
markdownExamples.push(stringifyYAML(example, null, 2));
});
}
}
return true;
});
let result = '';
if (title) {
result = '#### ' + toMarkdown(title);
result = '#### ' + this.toMarkdown(title);
}
if (markdownDescription) {
result = ensureLineBreak(result);
Expand All @@ -182,10 +178,10 @@ export class YAMLHover {
});
}
if (markdownExamples.length !== 0) {
result = ensureLineBreak(result);
result += 'Examples:\n\n';
markdownExamples.forEach((example) => {
result += `* \`\`\`${example}\`\`\`\n`;
result = ensureLineBreak(result);
result += 'Example:\n\n';
result += `\`\`\`yaml\n${example}\`\`\`\n`;
});
}
if (result.length > 0 && schema.schema.url) {
Expand All @@ -197,6 +193,21 @@ export class YAMLHover {
return null;
});
}

// copied from https://github.com/microsoft/vscode-json-languageservice/blob/2ea5ad3d2ffbbe40dea11cfe764a502becf113ce/src/services/jsonHover.ts#L112
private toMarkdown(plain: string | undefined): string | undefined {
if (plain) {
let escaped = plain.replace(/([^\n\r])(\r?\n)([^\n\r])/gm, '$1\n\n$3'); // single new lines to \n\n (Markdown paragraph)
escaped = escaped.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&'); // escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash
if (this.indentation !== undefined) {
// escape indentation whitespace to prevent it from being converted to markdown code blocks.
const indentationMatchRegex = new RegExp(` {${this.indentation.length}}`, 'g');
escaped = escaped.replace(indentationMatchRegex, ' ');
}
return escaped;
}
return undefined;
}
}

interface markdownEnum {
Expand Down Expand Up @@ -226,17 +237,6 @@ function getSchemaName(schema: JSONSchema): string {
return result;
}

// copied from https://github.com/microsoft/vscode-json-languageservice/blob/2ea5ad3d2ffbbe40dea11cfe764a502becf113ce/src/services/jsonHover.ts#L112
function toMarkdown(plain: string): string;
function toMarkdown(plain: string | undefined): string | undefined;
function toMarkdown(plain: string | undefined): string | undefined {
if (plain) {
const res = plain.replace(/([^\n\r])(\r?\n)([^\n\r])/gm, '$1\n\n$3'); // single new lines to \n\n (Markdown paragraph)
return res.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&'); // escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash
}
return undefined;
}

// copied from https://github.com/microsoft/vscode-json-languageservice/blob/2ea5ad3d2ffbbe40dea11cfe764a502becf113ce/src/services/jsonHover.ts#L122
function toMarkdownCodeBlock(content: string): string {
// see https://daringfireball.net/projects/markdown/syntax#precode
Expand Down
23 changes: 19 additions & 4 deletions test/hover.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,14 @@ Source: [${SCHEMA_ID}](file:///${SCHEMA_ID})`
type: 'string',
description: 'should return this description',
enum: ['cat', 'dog'],
examples: ['cat', 'dog'],
examples: [
'cat',
{
animal: {
type: 'dog',
},
},
],
},
},
});
Expand All @@ -613,10 +620,18 @@ Allowed Values:
* \`cat\`
* \`dog\`

Examples:
Example:

\`\`\`yaml
cat
\`\`\`

Example:

* \`\`\`"cat"\`\`\`
* \`\`\`"dog"\`\`\`
\`\`\`yaml
animal:
type: dog
\`\`\`

Source: [${SCHEMA_ID}](file:///${SCHEMA_ID})`
);
Expand Down
Loading