@@ -290,7 +290,16 @@ export class YAMLCompletion {
290290 if ( index < s . schema . items . length ) {
291291 this . addSchemaValueCompletions ( s . schema . items [ index ] , collector , separatorAfter , true ) ;
292292 }
293- } else {
293+ } else if ( s . schema . items . type === 'object' ) {
294+ collector . add ( {
295+ kind : this . getSuggestionKind ( s . schema . items . type ) ,
296+ label : `- (array item)` ,
297+ documentation : `Create an item of an array${ s . schema . description === undefined ? '' : '(' + s . schema . description + ')' } ` ,
298+ insertText : `- ${ this . getInsertTextForObject ( s . schema . items , separatorAfter ) . insertText . trimLeft ( ) } ` ,
299+ insertTextFormat : InsertTextFormat . Snippet ,
300+ } ) ;
301+ }
302+ else {
294303 this . addSchemaValueCompletions ( s . schema . items , collector , separatorAfter , true ) ;
295304 }
296305 }
@@ -527,6 +536,99 @@ export class YAMLCompletion {
527536 return this . getInsertTextForPlainText ( text + separatorAfter ) ;
528537 }
529538
539+ private getInsertTextForObject ( schema : JSONSchema , separatorAfter : string , indent = '\t' , insertIndex = 1 ) {
540+ let insertText = "" ;
541+ if ( ! schema . properties ) {
542+ insertText = `${ indent } \$${ insertIndex ++ } \n` ;
543+ return { insertText, insertIndex } ;
544+ }
545+
546+ Object . keys ( schema . properties ) . forEach ( ( key : string ) => {
547+ let propertySchema = schema . properties [ key ] ;
548+ let type = Array . isArray ( propertySchema . type ) ? propertySchema . type [ 0 ] : propertySchema . type ;
549+ if ( ! type ) {
550+ if ( propertySchema . properties ) {
551+ type = 'object' ;
552+ }
553+ if ( propertySchema . items ) {
554+ type = 'array' ;
555+ }
556+ }
557+ if ( schema . required && schema . required . indexOf ( key ) > - 1 ) {
558+ switch ( type ) {
559+ case 'boolean' :
560+ case 'string' :
561+ case 'number' :
562+ case 'integer' :
563+ insertText += `${ indent } ${ key } : \$${ insertIndex ++ } \n`
564+ break ;
565+ case 'array' :
566+ let arrayInsertResult = this . getInsertTextForArray ( propertySchema . items , separatorAfter , `${ indent } \t` , insertIndex ++ ) ;
567+ insertIndex = arrayInsertResult . insertIndex ;
568+ insertText += `${ indent } ${ key } :\n${ indent } \t- ${ arrayInsertResult . insertText } \n` ;
569+ break ;
570+ case 'object' :
571+ let objectInsertResult = this . getInsertTextForObject ( propertySchema , separatorAfter , `${ indent } \t` , insertIndex ++ ) ;
572+ insertIndex = objectInsertResult . insertIndex ;
573+ insertText += `${ indent } ${ key } :\n${ objectInsertResult . insertText } \n` ;
574+ break ;
575+ }
576+ } else if ( propertySchema . default !== undefined ) {
577+ switch ( type ) {
578+ case 'boolean' :
579+ case 'string' :
580+ case 'number' :
581+ case 'integer' :
582+ insertText += `${ indent } ${ key } : \${${ insertIndex ++ } :${ propertySchema . default } }\n`
583+ break ;
584+ case 'array' :
585+ case 'object' :
586+ // TODO: support default value for array object
587+ break ;
588+ }
589+ }
590+ } ) ;
591+ if ( insertText . trim ( ) . length === 0 ) {
592+ insertText = `${ indent } \$${ insertIndex ++ } \n` ;
593+ }
594+ insertText = insertText . trimRight ( ) + separatorAfter ;
595+ return { insertText, insertIndex } ;
596+ }
597+
598+ private getInsertTextForArray ( schema : JSONSchema , separatorAfter : string , indent = '\t' , insertIndex = 1 ) {
599+ let insertText = '' ;
600+ if ( ! schema ) {
601+ insertText = `\$${ insertIndex ++ } ` ;
602+ }
603+ let type = Array . isArray ( schema . type ) ? schema . type [ 0 ] : schema . type ;
604+ if ( ! type ) {
605+ if ( schema . properties ) {
606+ type = 'object' ;
607+ }
608+ if ( schema . items ) {
609+ type = 'array' ;
610+ }
611+ }
612+ switch ( schema . type ) {
613+ case 'boolean' :
614+ insertText = `\${${ insertIndex ++ } :false}` ;
615+ break ;
616+ case 'number' :
617+ case 'integer' :
618+ insertText = `\${${ insertIndex ++ } :0}` ;
619+ break ;
620+ case 'string' :
621+ insertText = `\${${ insertIndex ++ } :null}` ;
622+ break ;
623+ case 'object' :
624+ let objectInsertResult = this . getInsertTextForObject ( schema , separatorAfter , `${ indent } \t` , insertIndex ++ ) ;
625+ insertText = objectInsertResult . insertText . trimLeft ( ) ;
626+ insertIndex = objectInsertResult . insertIndex ;
627+ break ;
628+ }
629+ return { insertText, insertIndex } ;
630+ }
631+
530632 private getInsertTextForProperty ( key : string , propertySchema : JSONSchema , addValue : boolean , separatorAfter : string ) : string {
531633
532634 let propertyText = this . getInsertTextForValue ( key , '' ) ;
@@ -536,48 +638,44 @@ export class YAMLCompletion {
536638 let resultText = propertyText + ':' ;
537639
538640 let value ;
539- let nValueProposals = 0 ;
540641 if ( propertySchema ) {
541642 if ( propertySchema . default !== undefined ) {
542643 value = ` \${1:${ propertySchema . default } }`
543644 }
645+ else if ( propertySchema . properties ) {
646+ return `${ resultText } \n${ this . getInsertTextForObject ( propertySchema , separatorAfter ) . insertText } ` ;
647+ }
648+ else if ( propertySchema . items ) {
649+ return `${ resultText } \n\t- ${ this . getInsertTextForArray ( propertySchema . items , separatorAfter ) . insertText } ` ;
650+ }
544651 else {
545- if ( nValueProposals === 0 ) {
546- var type = Array . isArray ( propertySchema . type ) ? propertySchema . type [ 0 ] : propertySchema . type ;
547- if ( ! type ) {
548- if ( propertySchema . properties ) {
549- type = 'object' ;
550- } else if ( propertySchema . items ) {
551- type = 'array' ;
552- }
553- }
554- switch ( type ) {
555- case 'boolean' :
556- value = ' $1' ;
557- break ;
558- case 'string' :
559- value = ' $1' ;
560- break ;
561- case 'object' :
562- value = '\n\t' ;
563- break ;
564- case 'array' :
565- value = '\n\t- ' ;
566- break ;
567- case 'number' :
568- case 'integer' :
569- value = ' ${1:0}' ;
570- break ;
571- case 'null' :
572- value = ' ${1:null}' ;
573- break ;
574- default :
575- return propertyText ;
576- }
652+ var type = Array . isArray ( propertySchema . type ) ? propertySchema . type [ 0 ] : propertySchema . type ;
653+ switch ( type ) {
654+ case 'boolean' :
655+ value = ' $1' ;
656+ break ;
657+ case 'string' :
658+ value = ' $1' ;
659+ break ;
660+ case 'object' :
661+ value = '\n\t' ;
662+ break ;
663+ case 'array' :
664+ value = '\n\t- ' ;
665+ break ;
666+ case 'number' :
667+ case 'integer' :
668+ value = ' ${1:0}' ;
669+ break ;
670+ case 'null' :
671+ value = ' ${1:null}' ;
672+ break ;
673+ default :
674+ return propertyText ;
577675 }
578676 }
579677 }
580- if ( ! value || nValueProposals > 1 ) {
678+ if ( ! value ) {
581679 value = '$1' ;
582680 }
583681 return resultText + value + separatorAfter ;
0 commit comments