@@ -37,6 +37,7 @@ import { indexOf, isInComment, isMapContainsEmptyPair } from '../utils/astUtils'
3737import { isModeline } from './modelineUtil' ;
3838import { getSchemaTypeName , isAnyOfAllOfOneOfType , isPrimitiveType } from '../utils/schemaUtils' ;
3939import { YamlNode } from '../jsonASTTypes' ;
40+ import { SettingsState } from '../../yamlSettings' ;
4041
4142const localize = nls . loadMessageBundle ( ) ;
4243
@@ -74,6 +75,7 @@ export class YamlCompletion {
7475 private completionEnabled = true ;
7576 private configuredIndentation : string | undefined ;
7677 private yamlVersion : YamlVersion ;
78+ private isSingleQuote : boolean ;
7779 private indentation : string ;
7880 private arrayPrefixIndentation = '' ;
7981 private supportsMarkdown : boolean | undefined ;
@@ -87,12 +89,13 @@ export class YamlCompletion {
8789 private readonly telemetry ?: Telemetry
8890 ) { }
8991
90- configure ( languageSettings : LanguageSettings ) : void {
92+ configure ( languageSettings : LanguageSettings , yamlSettings ?: SettingsState ) : void {
9193 if ( languageSettings ) {
9294 this . completionEnabled = languageSettings . completion ;
9395 }
9496 this . customTags = languageSettings . customTags ;
9597 this . yamlVersion = languageSettings . yamlVersion ;
98+ this . isSingleQuote = yamlSettings ?. yamlFormatterSettings ?. singleQuote || false ;
9699 this . configuredIndentation = languageSettings . indentation ;
97100 this . disableDefaultProperties = languageSettings . disableDefaultProperties ;
98101 this . parentSkeletonSelectedFirst = languageSettings . parentSkeletonSelectedFirst ;
@@ -622,7 +625,7 @@ export class YamlCompletion {
622625 } ;
623626
624627 result . items . forEach ( ( completionItem ) => {
625- if ( isParentCompletionItem ( completionItem ) ) {
628+ if ( this . isParentCompletionItem ( completionItem ) ) {
626629 const indent = completionItem . parent . indent || '' ;
627630
628631 const reindexedTexts = reindexText ( completionItem . parent . insertTexts ) ;
@@ -1021,7 +1024,7 @@ export class YamlCompletion {
10211024 if ( propertySchema . const ) {
10221025 if ( ! value ) {
10231026 value = this . getInsertTextForGuessedValue ( propertySchema . const , '' , type ) ;
1024- value = evaluateTab1Symbol ( value ) ; // prevent const being selected after snippet insert
1027+ value = this . evaluateTab1Symbol ( value ) ; // prevent const being selected after snippet insert
10251028 value = ' ' + value ;
10261029 }
10271030 nValueProposals ++ ;
@@ -1117,7 +1120,7 @@ export class YamlCompletion {
11171120 let value = propertySchema . default || propertySchema . const ;
11181121 if ( value ) {
11191122 if ( type === 'string' ) {
1120- value = convertToStringValue ( value ) ;
1123+ value = this . convertToStringValue ( value ) ;
11211124 }
11221125 insertText += `${ indent } ${ key } : \${${ insertIndex ++ } :${ value } }\n` ;
11231126 } else {
@@ -1165,7 +1168,7 @@ export class YamlCompletion {
11651168 } : \${${ insertIndex ++ } :${ propertySchema . default } }\n`;
11661169 break ;
11671170 case 'string' :
1168- insertText += `${ indent } ${ key } : \${${ insertIndex ++ } :${ convertToStringValue ( propertySchema . default ) } }\n` ;
1171+ insertText += `${ indent } ${ key } : \${${ insertIndex ++ } :${ this . convertToStringValue ( propertySchema . default ) } }\n` ;
11691172 break ;
11701173 case 'array' :
11711174 case 'object' :
@@ -1232,7 +1235,7 @@ export class YamlCompletion {
12321235 snippetValue = snippetValue . substr ( 1 , snippetValue . length - 2 ) ; // remove quotes
12331236 snippetValue = this . getInsertTextForPlainText ( snippetValue ) ; // escape \ and }
12341237 if ( type === 'string' ) {
1235- snippetValue = convertToStringValue ( snippetValue ) ;
1238+ snippetValue = this . convertToStringValue ( snippetValue ) ;
12361239 }
12371240 return '${1:' + snippetValue + '}' + separatorAfter ;
12381241 }
@@ -1263,7 +1266,7 @@ export class YamlCompletion {
12631266 }
12641267 type = Array . isArray ( type ) ? type [ 0 ] : type ;
12651268 if ( type === 'string' ) {
1266- value = convertToStringValue ( value ) ;
1269+ value = this . convertToStringValue ( value ) ;
12671270 }
12681271 return this . getInsertTextForPlainText ( value + separatorAfter ) ;
12691272 }
@@ -1667,65 +1670,67 @@ export class YamlCompletion {
16671670
16681671 return 0 ;
16691672 }
1670- }
16711673
1672- const isNumberExp = / ^ \d + $ / ;
1673- function convertToStringValue ( param : unknown ) : string {
1674- let value : string ;
1675- if ( typeof param === 'string' ) {
1676- value = param ;
1677- } else {
1678- value = '' + param ;
1679- }
1680- if ( value . length === 0 ) {
1681- return value ;
1682- }
1674+ isNumberExp = / ^ \d + $ / ;
1675+ convertToStringValue ( param : unknown ) : string {
1676+ let value : string ;
1677+ if ( typeof param === 'string' ) {
1678+ //support YAML spec 1.1 boolean values
1679+ const quote = this . isSingleQuote ? `'` : `"` ;
1680+ value = [ 'on' , 'off' , 'true' , 'false' , 'yes' , 'no' ] . includes ( param . toLowerCase ( ) ) ? `${ quote } ${ param } ${ quote } ` : param ;
1681+ } else {
1682+ value = '' + param ;
1683+ }
1684+ if ( value . length === 0 ) {
1685+ return value ;
1686+ }
16831687
1684- if ( value === 'true' || value === 'false' || value === 'null' || isNumberExp . test ( value ) ) {
1685- return `"${ value } "` ;
1686- }
1688+ if ( value === 'true' || value === 'false' || value === 'null' || this . isNumberExp . test ( value ) ) {
1689+ return `"${ value } "` ;
1690+ }
16871691
1688- if ( value . indexOf ( '"' ) !== - 1 ) {
1689- value = value . replace ( doubleQuotesEscapeRegExp , '"' ) ;
1690- }
1692+ if ( value . indexOf ( '"' ) !== - 1 ) {
1693+ value = value . replace ( doubleQuotesEscapeRegExp , '"' ) ;
1694+ }
16911695
1692- let doQuote = ! isNaN ( parseInt ( value ) ) || value . charAt ( 0 ) === '@' ;
1696+ let doQuote = ! isNaN ( parseInt ( value ) ) || value . charAt ( 0 ) === '@' ;
1697+
1698+ if ( ! doQuote ) {
1699+ // need to quote value if in `foo: bar`, `foo : bar` (mapping) or `foo:` (partial map) format
1700+ // but `foo:bar` and `:bar` (colon without white-space after it) are just plain string
1701+ let idx = value . indexOf ( ':' , 0 ) ;
1702+ for ( ; idx > 0 && idx < value . length ; idx = value . indexOf ( ':' , idx + 1 ) ) {
1703+ if ( idx === value . length - 1 ) {
1704+ // `foo:` (partial map) format
1705+ doQuote = true ;
1706+ break ;
1707+ }
16931708
1694- if ( ! doQuote ) {
1695- // need to quote value if in `foo: bar`, `foo : bar` (mapping) or `foo:` (partial map) format
1696- // but `foo:bar` and `:bar` (colon without white-space after it) are just plain string
1697- let idx = value . indexOf ( ':' , 0 ) ;
1698- for ( ; idx > 0 && idx < value . length ; idx = value . indexOf ( ':' , idx + 1 ) ) {
1699- if ( idx === value . length - 1 ) {
1700- // `foo:` (partial map) format
1701- doQuote = true ;
1702- break ;
1709+ // there are only two valid kinds of white-space in yaml: space or tab
1710+ // ref: https://yaml.org/spec/1.2.1/#id2775170
1711+ const nextChar = value . charAt ( idx + 1 ) ;
1712+ if ( nextChar === '\t' || nextChar === ' ' ) {
1713+ doQuote = true ;
1714+ break ;
1715+ }
17031716 }
1717+ }
17041718
1705- // there are only two valid kinds of white-space in yaml: space or tab
1706- // ref: https://yaml.org/spec/1.2.1/#id2775170
1707- const nextChar = value . charAt ( idx + 1 ) ;
1708- if ( nextChar === '\t' || nextChar === ' ' ) {
1709- doQuote = true ;
1710- break ;
1711- }
1719+ if ( doQuote ) {
1720+ value = `"${ value } "` ;
17121721 }
1713- }
17141722
1715- if ( doQuote ) {
1716- value = `"${ value } "` ;
1723+ return value ;
17171724 }
17181725
1719- return value ;
1720- }
1721-
1722- /**
1723- * simplify `{$1:value}` to `value`
1724- */
1725- function evaluateTab1Symbol ( value : string ) : string {
1726- return value . replace ( / \$ \{ 1 : ( .* ) \} / , '$1' ) ;
1727- }
1726+ /**
1727+ * simplify `{$1:value}` to `value`
1728+ */
1729+ evaluateTab1Symbol ( value : string ) : string {
1730+ return value . replace ( / \$ \{ 1 : ( .* ) \} / , '$1' ) ;
1731+ }
17281732
1729- function isParentCompletionItem ( item : CompletionItemBase ) : item is CompletionItem {
1730- return 'parent' in item ;
1733+ isParentCompletionItem ( item : CompletionItemBase ) : item is CompletionItem {
1734+ return 'parent' in item ;
1735+ }
17311736}
0 commit comments