Skip to content

Commit 91ee153

Browse files
committed
fix: default value with special chars with anyOf
1 parent 0871dc1 commit 91ee153

File tree

2 files changed

+43
-10
lines changed

2 files changed

+43
-10
lines changed

src/languageservice/services/yamlCompletion.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,7 +1116,7 @@ export class YamlCompletion {
11161116
case 'anyOf': {
11171117
let value = propertySchema.default || propertySchema.const;
11181118
if (value) {
1119-
if (type === 'string') {
1119+
if (type === 'string' || typeof value === 'string') {
11201120
value = convertToStringValue(value);
11211121
}
11221122
insertText += `${indent}${key}: \${${insertIndex++}:${value}}\n`;
@@ -1230,7 +1230,7 @@ export class YamlCompletion {
12301230
case 'string': {
12311231
let snippetValue = JSON.stringify(value);
12321232
snippetValue = snippetValue.substr(1, snippetValue.length - 2); // remove quotes
1233-
snippetValue = this.getInsertTextForPlainText(snippetValue); // escape \ and }
1233+
snippetValue = getInsertTextForPlainText(snippetValue); // escape \ and }
12341234
if (type === 'string') {
12351235
snippetValue = convertToStringValue(snippetValue);
12361236
}
@@ -1243,10 +1243,6 @@ export class YamlCompletion {
12431243
return this.getInsertTextForValue(value, separatorAfter, type);
12441244
}
12451245

1246-
private getInsertTextForPlainText(text: string): string {
1247-
return text.replace(/[\\$}]/g, '\\$&'); // escape $, \ and }
1248-
}
1249-
12501246
// eslint-disable-next-line @typescript-eslint/no-explicit-any
12511247
private getInsertTextForValue(value: any, separatorAfter: string, type: string | string[]): string {
12521248
if (value === null) {
@@ -1259,13 +1255,13 @@ export class YamlCompletion {
12591255
}
12601256
case 'number':
12611257
case 'boolean':
1262-
return this.getInsertTextForPlainText(value + separatorAfter);
1258+
return getInsertTextForPlainText(value + separatorAfter);
12631259
}
12641260
type = Array.isArray(type) ? type[0] : type;
12651261
if (type === 'string') {
12661262
value = convertToStringValue(value);
12671263
}
1268-
return this.getInsertTextForPlainText(value + separatorAfter);
1264+
return getInsertTextForPlainText(value + separatorAfter);
12691265
}
12701266

12711267
private getInsertTemplateForValue(
@@ -1290,14 +1286,14 @@ export class YamlCompletion {
12901286
if (typeof element === 'object') {
12911287
valueTemplate = `${this.getInsertTemplateForValue(element, indent + this.indentation, navOrder, separatorAfter)}`;
12921288
} else {
1293-
valueTemplate = ` \${${navOrder.index++}:${this.getInsertTextForPlainText(element + separatorAfter)}}\n`;
1289+
valueTemplate = ` \${${navOrder.index++}:${getInsertTextForPlainText(element + separatorAfter)}}\n`;
12941290
}
12951291
insertText += `${valueTemplate}`;
12961292
}
12971293
}
12981294
return insertText;
12991295
}
1300-
return this.getInsertTextForPlainText(value + separatorAfter);
1296+
return getInsertTextForPlainText(value + separatorAfter);
13011297
}
13021298

13031299
private addSchemaValueCompletions(
@@ -1669,6 +1665,13 @@ export class YamlCompletion {
16691665
}
16701666
}
16711667

1668+
/**
1669+
* escape $, \ and }
1670+
*/
1671+
function getInsertTextForPlainText(text: string): string {
1672+
return text.replace(/[\\$}]/g, '\\$&'); //
1673+
}
1674+
16721675
const isNumberExp = /^\d+$/;
16731676
function convertToStringValue(param: unknown): string {
16741677
let value: string;
@@ -1681,6 +1684,8 @@ function convertToStringValue(param: unknown): string {
16811684
return value;
16821685
}
16831686

1687+
value = getInsertTextForPlainText(value); // escape $, \ and }
1688+
16841689
if (value === 'true' || value === 'false' || value === 'null' || isNumberExp.test(value)) {
16851690
return `"${value}"`;
16861691
}

test/autoCompletion.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,34 @@ describe('Auto Completion Tests', () => {
931931
);
932932
});
933933

934+
it('Autocompletion should escape $ in defaultValue in anyOf', async () => {
935+
schemaProvider.addSchema(SCHEMA_ID, {
936+
type: 'object',
937+
properties: {
938+
car: {
939+
type: 'object',
940+
required: ['engine'],
941+
properties: {
942+
engine: {
943+
anyOf: [
944+
{
945+
type: 'object',
946+
},
947+
{
948+
type: 'string',
949+
},
950+
],
951+
default: 'type$1234',
952+
},
953+
},
954+
},
955+
},
956+
});
957+
const content = '';
958+
const completion = await parseSetup(content, 0);
959+
expect(completion.items.map((i) => i.insertText)).to.deep.equal(['car:\n engine: ${1:type\\$1234}']);
960+
});
961+
934962
it('Autocompletion should escape colon when indicating map', async () => {
935963
schemaProvider.addSchema(SCHEMA_ID, {
936964
type: 'object',

0 commit comments

Comments
 (0)