@@ -19,7 +19,7 @@ import { LanguageSettings } from '../yamlLanguageService';
1919import { ResolvedSchema } from 'vscode-json-languageservice/lib/umd/services/jsonSchemaService' ;
2020import { JSONCompletion } from 'vscode-json-languageservice/lib/umd/services/jsonCompletion' ;
2121import { ClientCapabilities } from 'vscode-languageserver-protocol' ;
22- import { stringifyObject } from '../utils/json' ;
22+ import { stringifyObject , StringifySettings } from '../utils/json' ;
2323const localize = nls . loadMessageBundle ( ) ;
2424
2525export class YAMLCompletion extends JSONCompletion {
@@ -234,6 +234,11 @@ export class YAMLCompletion extends JSONCompletion {
234234 if ( s . node === node && ! s . inverted ) {
235235 const schemaProperties = s . schema . properties ;
236236 if ( schemaProperties ) {
237+ this . collectDefaultSnippets ( s . schema , separatorAfter , collector , {
238+ newLineFirst : false ,
239+ indentFirstObject : false ,
240+ shouldIndentWithTab : false
241+ } , false ) ;
237242 Object . keys ( schemaProperties ) . forEach ( ( key : string ) => {
238243 const propertySchema = schemaProperties [ key ] ;
239244 if ( typeof propertySchema === 'object' && ! propertySchema . deprecationMessage && ! propertySchema [ 'doNotSuggest' ] ) {
@@ -267,6 +272,25 @@ export class YAMLCompletion extends JSONCompletion {
267272 this . addSchemaValueCompletions ( s . schema , separatorAfter , collector , { } ) ;
268273 }
269274 }
275+
276+ // Covers the case when we are showing a snippet in an array
277+ if ( node . type === 'object' && node . parent && node . parent . type === 'array' && s . schema . type !== 'object' ) {
278+ // For some reason the first item in the array needs to be treated differently, otherwise
279+ // the indentation will not be correct
280+ if ( node . properties . length === 1 ) {
281+ this . collectDefaultSnippets ( s . schema , separatorAfter , collector , {
282+ newLineFirst : false ,
283+ indentFirstObject : false ,
284+ shouldIndentWithTab : true
285+ } , false ) ;
286+ } else {
287+ this . collectDefaultSnippets ( s . schema , separatorAfter , collector , {
288+ newLineFirst : false ,
289+ indentFirstObject : true ,
290+ shouldIndentWithTab : false
291+ } , false ) ;
292+ }
293+ }
270294 } ) ;
271295 }
272296
@@ -405,6 +429,17 @@ export class YAMLCompletion extends JSONCompletion {
405429 hasProposals = true ;
406430 } ) ;
407431 }
432+ this . collectDefaultSnippets ( schema , separatorAfter , collector , {
433+ newLineFirst : true ,
434+ indentFirstObject : true ,
435+ shouldIndentWithTab : true
436+ } , schema . type === 'array' ) ;
437+ if ( ! hasProposals && typeof schema . items === 'object' && ! Array . isArray ( schema . items ) ) {
438+ this . addDefaultValueCompletions ( schema . items , separatorAfter , collector , arrayDepth + 1 ) ;
439+ }
440+ }
441+
442+ private collectDefaultSnippets ( schema : JSONSchema , separatorAfter : string , collector : CompletionsCollector , settings : StringifySettings , isArray : boolean ) {
408443 if ( Array . isArray ( schema . defaultSnippets ) ) {
409444 schema . defaultSnippets . forEach ( s => {
410445 let type = schema . type ;
@@ -413,24 +448,13 @@ export class YAMLCompletion extends JSONCompletion {
413448 let insertText : string ;
414449 let filterText : string ;
415450 if ( isDefined ( value ) ) {
416- let type = schema . type ;
417- for ( let i = arrayDepth ; i > 0 ; i -- ) {
418- value = [ value ] ;
419- type = 'array' ;
420- }
421- insertText = this . getInsertTextForSnippetValue ( value , separatorAfter ) ;
451+ insertText = this . getInsertTextForSnippetValue ( value , separatorAfter , settings , isArray ) ;
422452 label = label || this . getLabelForSnippetValue ( value ) ;
423453 } else if ( typeof s . bodyText === 'string' ) {
424454 let prefix = '' , suffix = '' , indent = '' ;
425- for ( let i = arrayDepth ; i > 0 ; i -- ) {
426- prefix = prefix + indent + '[\n' ;
427- suffix = suffix + '\n' + indent + ']' ;
428- indent += '\t' ;
429- type = 'array' ;
430- }
431455 insertText = prefix + indent + s . bodyText . split ( '\n' ) . join ( '\n' + indent ) + suffix + separatorAfter ;
432- label = label || insertText ,
433- filterText = insertText . replace ( / [ \n ] / g, '' ) ; // remove new lines
456+ label = label || insertText ;
457+ filterText = insertText . replace ( / [ \n ] / g, '' ) ; // remove new lines
434458 }
435459 collector . add ( {
436460 kind : this . getSuggestionKind ( type ) ,
@@ -440,26 +464,35 @@ export class YAMLCompletion extends JSONCompletion {
440464 insertTextFormat : InsertTextFormat . Snippet ,
441465 filterText
442466 } ) ;
443- hasProposals = true ;
444467 } ) ;
445468 }
446- if ( ! hasProposals && typeof schema . items === 'object' && ! Array . isArray ( schema . items ) ) {
447- this . addDefaultValueCompletions ( schema . items , separatorAfter , collector , arrayDepth + 1 ) ;
448- }
449469 }
450470
451471 // tslint:disable-next-line:no-any
452- private getInsertTextForSnippetValue ( value : any , separatorAfter : string ) : string {
472+ private getInsertTextForSnippetValue ( value : any , separatorAfter : string , settings : StringifySettings , isArray ?: boolean ) : string {
453473 // tslint:disable-next-line:no-any
454474 const replacer = ( value : any ) => {
455475 if ( typeof value === 'string' ) {
456476 if ( value [ 0 ] === '^' ) {
457477 return value . substr ( 1 ) ;
458478 }
459479 }
460- return JSON . stringify ( value ) ;
480+ return value ;
461481 } ;
462- return stringifyObject ( value , '' , replacer ) + separatorAfter ;
482+ // If it is an array then we need to manually indent the keys
483+ // of that array item
484+ if ( isArray && typeof value === 'object' && value !== null ) {
485+ const fixedObj = { } ;
486+ Object . keys ( value ) . forEach ( ( val , index ) => {
487+ if ( index === 0 && ! val . startsWith ( '-' ) ) {
488+ fixedObj [ `- ${ val } ` ] = value [ val ] ;
489+ } else {
490+ fixedObj [ ` ${ val } ` ] = value [ val ] ;
491+ }
492+ } ) ;
493+ value = fixedObj ;
494+ }
495+ return stringifyObject ( value , '' , replacer , settings ) + separatorAfter ;
463496 }
464497
465498 // tslint:disable-next-line:no-any
@@ -632,7 +665,11 @@ export class YAMLCompletion extends JSONCompletion {
632665 if ( propertySchema . defaultSnippets . length === 1 ) {
633666 const body = propertySchema . defaultSnippets [ 0 ] . body ;
634667 if ( isDefined ( body ) ) {
635- value = this . getInsertTextForSnippetValue ( body , '' ) ;
668+ value = this . getInsertTextForSnippetValue ( body , '' , {
669+ newLineFirst : true ,
670+ indentFirstObject : false ,
671+ shouldIndentWithTab : false
672+ } ) ;
636673 }
637674 }
638675 nValueProposals += propertySchema . defaultSnippets . length ;
0 commit comments