@@ -37,6 +37,7 @@ import { indexOf, isInComment, isMapContainsEmptyPair } from '../utils/astUtils'
37
37
import { isModeline } from './modelineUtil' ;
38
38
import { getSchemaTypeName , isAnyOfAllOfOneOfType , isPrimitiveType } from '../utils/schemaUtils' ;
39
39
import { YamlNode } from '../jsonASTTypes' ;
40
+ import { SettingsState } from '../../yamlSettings' ;
40
41
41
42
const localize = nls . loadMessageBundle ( ) ;
42
43
@@ -74,6 +75,7 @@ export class YamlCompletion {
74
75
private completionEnabled = true ;
75
76
private configuredIndentation : string | undefined ;
76
77
private yamlVersion : YamlVersion ;
78
+ private isSingleQuote : boolean ;
77
79
private indentation : string ;
78
80
private arrayPrefixIndentation = '' ;
79
81
private supportsMarkdown : boolean | undefined ;
@@ -87,12 +89,13 @@ export class YamlCompletion {
87
89
private readonly telemetry ?: Telemetry
88
90
) { }
89
91
90
- configure ( languageSettings : LanguageSettings ) : void {
92
+ configure ( languageSettings : LanguageSettings , yamlSettings ?: SettingsState ) : void {
91
93
if ( languageSettings ) {
92
94
this . completionEnabled = languageSettings . completion ;
93
95
}
94
96
this . customTags = languageSettings . customTags ;
95
97
this . yamlVersion = languageSettings . yamlVersion ;
98
+ this . isSingleQuote = yamlSettings ?. yamlFormatterSettings ?. singleQuote || false ;
96
99
this . configuredIndentation = languageSettings . indentation ;
97
100
this . disableDefaultProperties = languageSettings . disableDefaultProperties ;
98
101
this . parentSkeletonSelectedFirst = languageSettings . parentSkeletonSelectedFirst ;
@@ -622,7 +625,7 @@ export class YamlCompletion {
622
625
} ;
623
626
624
627
result . items . forEach ( ( completionItem ) => {
625
- if ( isParentCompletionItem ( completionItem ) ) {
628
+ if ( this . isParentCompletionItem ( completionItem ) ) {
626
629
const indent = completionItem . parent . indent || '' ;
627
630
628
631
const reindexedTexts = reindexText ( completionItem . parent . insertTexts ) ;
@@ -1021,7 +1024,7 @@ export class YamlCompletion {
1021
1024
if ( propertySchema . const ) {
1022
1025
if ( ! value ) {
1023
1026
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
1025
1028
value = ' ' + value ;
1026
1029
}
1027
1030
nValueProposals ++ ;
@@ -1117,7 +1120,7 @@ export class YamlCompletion {
1117
1120
let value = propertySchema . default || propertySchema . const ;
1118
1121
if ( value ) {
1119
1122
if ( type === 'string' ) {
1120
- value = convertToStringValue ( value ) ;
1123
+ value = this . convertToStringValue ( value ) ;
1121
1124
}
1122
1125
insertText += `${ indent } ${ key } : \${${ insertIndex ++ } :${ value } }\n` ;
1123
1126
} else {
@@ -1165,7 +1168,7 @@ export class YamlCompletion {
1165
1168
} : \${${ insertIndex ++ } :${ propertySchema . default } }\n`;
1166
1169
break ;
1167
1170
case 'string' :
1168
- insertText += `${ indent } ${ key } : \${${ insertIndex ++ } :${ convertToStringValue ( propertySchema . default ) } }\n` ;
1171
+ insertText += `${ indent } ${ key } : \${${ insertIndex ++ } :${ this . convertToStringValue ( propertySchema . default ) } }\n` ;
1169
1172
break ;
1170
1173
case 'array' :
1171
1174
case 'object' :
@@ -1232,7 +1235,7 @@ export class YamlCompletion {
1232
1235
snippetValue = snippetValue . substr ( 1 , snippetValue . length - 2 ) ; // remove quotes
1233
1236
snippetValue = this . getInsertTextForPlainText ( snippetValue ) ; // escape \ and }
1234
1237
if ( type === 'string' ) {
1235
- snippetValue = convertToStringValue ( snippetValue ) ;
1238
+ snippetValue = this . convertToStringValue ( snippetValue ) ;
1236
1239
}
1237
1240
return '${1:' + snippetValue + '}' + separatorAfter ;
1238
1241
}
@@ -1263,7 +1266,7 @@ export class YamlCompletion {
1263
1266
}
1264
1267
type = Array . isArray ( type ) ? type [ 0 ] : type ;
1265
1268
if ( type === 'string' ) {
1266
- value = convertToStringValue ( value ) ;
1269
+ value = this . convertToStringValue ( value ) ;
1267
1270
}
1268
1271
return this . getInsertTextForPlainText ( value + separatorAfter ) ;
1269
1272
}
@@ -1667,65 +1670,67 @@ export class YamlCompletion {
1667
1670
1668
1671
return 0 ;
1669
1672
}
1670
- }
1671
1673
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
+ }
1683
1687
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
+ }
1687
1691
1688
- if ( value . indexOf ( '"' ) !== - 1 ) {
1689
- value = value . replace ( doubleQuotesEscapeRegExp , '"' ) ;
1690
- }
1692
+ if ( value . indexOf ( '"' ) !== - 1 ) {
1693
+ value = value . replace ( doubleQuotesEscapeRegExp , '"' ) ;
1694
+ }
1691
1695
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
+ }
1693
1708
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
+ }
1703
1716
}
1717
+ }
1704
1718
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 } "` ;
1712
1721
}
1713
- }
1714
1722
1715
- if ( doQuote ) {
1716
- value = `"${ value } "` ;
1723
+ return value ;
1717
1724
}
1718
1725
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
+ }
1728
1732
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
+ }
1731
1736
}
0 commit comments