@@ -19,6 +19,7 @@ import * as path from 'path';
1919import { Telemetry } from '../telemetry' ;
2020import { convertErrorToTelemetryMsg } from '../utils/objects' ;
2121import { ASTNode } from 'vscode-json-languageservice' ;
22+ import { stringify as stringifyYAML } from 'yaml' ;
2223
2324export class YAMLHover {
2425 private shouldHover : boolean ;
@@ -87,11 +88,6 @@ export class YAMLHover {
8788 ) ;
8889
8990 const createHover = ( contents : string ) : Hover => {
90- if ( this . indentation !== undefined ) {
91- const indentationMatchRegex = new RegExp ( ` {${ this . indentation . length } }` , 'g' ) ;
92- contents = contents . replace ( indentationMatchRegex , ' ' ) ;
93- }
94-
9591 const markupContent : MarkupContent = {
9692 kind : MarkupKind . Markdown ,
9793 value : contents ,
@@ -120,12 +116,12 @@ export class YAMLHover {
120116 matchingSchemas . every ( ( s ) => {
121117 if ( ( s . node === node || ( node . type === 'property' && node . valueNode === s . node ) ) && ! s . inverted && s . schema ) {
122118 title = title || s . schema . title || s . schema . closestTitle ;
123- markdownDescription = markdownDescription || s . schema . markdownDescription || toMarkdown ( s . schema . description ) ;
119+ markdownDescription = markdownDescription || s . schema . markdownDescription || this . toMarkdown ( s . schema . description ) ;
124120 if ( s . schema . enum ) {
125121 if ( s . schema . markdownEnumDescriptions ) {
126122 markdownEnumDescriptions = s . schema . markdownEnumDescriptions ;
127123 } else if ( s . schema . enumDescriptions ) {
128- markdownEnumDescriptions = s . schema . enumDescriptions . map ( toMarkdown ) ;
124+ markdownEnumDescriptions = s . schema . enumDescriptions . map ( this . toMarkdown , this ) ;
129125 } else {
130126 markdownEnumDescriptions = [ ] ;
131127 }
@@ -145,7 +141,7 @@ export class YAMLHover {
145141 markdownDescription = '' ;
146142 s . schema . anyOf . forEach ( ( childSchema : JSONSchema , index : number ) => {
147143 title += childSchema . title || s . schema . closestTitle || '' ;
148- markdownDescription += childSchema . markdownDescription || toMarkdown ( childSchema . description ) || '' ;
144+ markdownDescription += childSchema . markdownDescription || this . toMarkdown ( childSchema . description ) || '' ;
149145 if ( index !== s . schema . anyOf . length - 1 ) {
150146 title += ' || ' ;
151147 markdownDescription += ' || ' ;
@@ -156,15 +152,15 @@ export class YAMLHover {
156152 }
157153 if ( s . schema . examples ) {
158154 s . schema . examples . forEach ( ( example ) => {
159- markdownExamples . push ( JSON . stringify ( example , null , 2 ) ) ;
155+ markdownExamples . push ( stringifyYAML ( example , null , 2 ) ) ;
160156 } ) ;
161157 }
162158 }
163159 return true ;
164160 } ) ;
165161 let result = '' ;
166162 if ( title ) {
167- result = '#### ' + toMarkdown ( title ) ;
163+ result = '#### ' + this . toMarkdown ( title ) ;
168164 }
169165 if ( markdownDescription ) {
170166 result = ensureLineBreak ( result ) ;
@@ -182,10 +178,10 @@ export class YAMLHover {
182178 } ) ;
183179 }
184180 if ( markdownExamples . length !== 0 ) {
185- result = ensureLineBreak ( result ) ;
186- result += 'Examples:\n\n' ;
187181 markdownExamples . forEach ( ( example ) => {
188- result += `* \`\`\`${ example } \`\`\`\n` ;
182+ result = ensureLineBreak ( result ) ;
183+ result += 'Example:\n\n' ;
184+ result += `\`\`\`yaml\n${ example } \`\`\`\n` ;
189185 } ) ;
190186 }
191187 if ( result . length > 0 && schema . schema . url ) {
@@ -197,6 +193,21 @@ export class YAMLHover {
197193 return null ;
198194 } ) ;
199195 }
196+
197+ // copied from https://github.com/microsoft/vscode-json-languageservice/blob/2ea5ad3d2ffbbe40dea11cfe764a502becf113ce/src/services/jsonHover.ts#L112
198+ private toMarkdown ( plain : string | undefined ) : string | undefined {
199+ if ( plain ) {
200+ let escaped = plain . replace ( / ( [ ^ \n \r ] ) ( \r ? \n ) ( [ ^ \n \r ] ) / gm, '$1\n\n$3' ) ; // single new lines to \n\n (Markdown paragraph)
201+ escaped = escaped . replace ( / [ \\ ` * _ { } [ \] ( ) # + \- . ! ] / g, '\\$&' ) ; // escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash
202+ if ( this . indentation !== undefined ) {
203+ // escape indentation whitespace to prevent it from being converted to markdown code blocks.
204+ const indentationMatchRegex = new RegExp ( ` {${ this . indentation . length } }` , 'g' ) ;
205+ escaped = escaped . replace ( indentationMatchRegex , ' ' ) ;
206+ }
207+ return escaped ;
208+ }
209+ return undefined ;
210+ }
200211}
201212
202213interface markdownEnum {
@@ -226,17 +237,6 @@ function getSchemaName(schema: JSONSchema): string {
226237 return result ;
227238}
228239
229- // copied from https://github.com/microsoft/vscode-json-languageservice/blob/2ea5ad3d2ffbbe40dea11cfe764a502becf113ce/src/services/jsonHover.ts#L112
230- function toMarkdown ( plain : string ) : string ;
231- function toMarkdown ( plain : string | undefined ) : string | undefined ;
232- function toMarkdown ( plain : string | undefined ) : string | undefined {
233- if ( plain ) {
234- const res = plain . replace ( / ( [ ^ \n \r ] ) ( \r ? \n ) ( [ ^ \n \r ] ) / gm, '$1\n\n$3' ) ; // single new lines to \n\n (Markdown paragraph)
235- return res . replace ( / [ \\ ` * _ { } [ \] ( ) # + \- . ! ] / g, '\\$&' ) ; // escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash
236- }
237- return undefined ;
238- }
239-
240240// copied from https://github.com/microsoft/vscode-json-languageservice/blob/2ea5ad3d2ffbbe40dea11cfe764a502becf113ce/src/services/jsonHover.ts#L122
241241function toMarkdownCodeBlock ( content : string ) : string {
242242 // see https://daringfireball.net/projects/markdown/syntax#precode
0 commit comments