diff --git a/src/languageservice/services/yamlCompletion.ts b/src/languageservice/services/yamlCompletion.ts index e0e828798..5283b76a0 100644 --- a/src/languageservice/services/yamlCompletion.ts +++ b/src/languageservice/services/yamlCompletion.ts @@ -814,7 +814,7 @@ export class YamlCompletion { collector, {}, 'property', - Array.isArray(nodeParent.items) + Array.isArray(nodeParent.items) && !isInArray ); } @@ -910,13 +910,8 @@ export class YamlCompletion { if (index < s.schema.items.length) { this.addSchemaValueCompletions(s.schema.items[index], separatorAfter, collector, types, 'value'); } - } else if ( - typeof s.schema.items === 'object' && - (s.schema.items.type === 'object' || isAnyOfAllOfOneOfType(s.schema.items)) - ) { - this.addSchemaValueCompletions(s.schema.items, separatorAfter, collector, types, 'value', true); } else { - this.addSchemaValueCompletions(s.schema.items, separatorAfter, collector, types, 'value'); + this.addSchemaValueCompletions(s.schema.items, separatorAfter, collector, types, 'value', true); } } } @@ -959,7 +954,7 @@ export class YamlCompletion { ); collector.add({ kind: this.getSuggestionKind(schema.type), - label: '- (array item) ' + (schemaType || index), + label: '- (array item) ' + ((schemaType || index) ?? ''), documentation: documentation, insertText: insertText, insertTextFormat: InsertTextFormat.Snippet, @@ -1430,10 +1425,11 @@ export class YamlCompletion { } else if (schema.enumDescriptions && i < schema.enumDescriptions.length) { documentation = schema.enumDescriptions[i]; } + const insertText = (isArray ? '- ' : '') + this.getInsertTextForValue(enm, separatorAfter, schema.type); collector.add({ kind: this.getSuggestionKind(schema.type), label: this.getLabelForValue(enm), - insertText: this.getInsertTextForValue(enm, separatorAfter, schema.type), + insertText, insertTextFormat: InsertTextFormat.Snippet, documentation: documentation, }); diff --git a/test/autoCompletion.test.ts b/test/autoCompletion.test.ts index e0cae5c31..06d580ec9 100644 --- a/test/autoCompletion.test.ts +++ b/test/autoCompletion.test.ts @@ -1488,6 +1488,39 @@ describe('Auto Completion Tests', () => { .then(done, done); }); + it('Array of enum autocomplete on 2nd position without `-` should auto add `-` and `- (array item)`', (done) => { + schemaProvider.addSchema(SCHEMA_ID, { + type: 'object', + properties: { + references: { + type: 'array', + items: { + enum: ['Test'], + }, + }, + }, + }); + const content = 'references:\n - Test\n |\n|'; + const completion = parseSetup(content); + completion + .then(function (result) { + assert.deepEqual( + result.items.map((i) => ({ label: i.label, insertText: i.insertText })), + [ + { + insertText: '- Test', // auto added `- ` + label: 'Test', + }, + { + insertText: '- $1\n', + label: '- (array item) ', + }, + ] + ); + }) + .then(done, done); + }); + it('Array of objects autocomplete with 4 space indentation check', async () => { const languageSettingsSetup = new ServiceSetup().withCompletion().withIndentation(' '); languageService.configure(languageSettingsSetup.languageSettings); @@ -1926,7 +1959,8 @@ describe('Auto Completion Tests', () => { assert.equal(result.items.length, 3, `Expecting 3 items in completion but found ${result.items.length}`); const resultDoc2 = await parseSetup(content, content.length); - assert.equal(resultDoc2.items.length, 0, `Expecting no items in completion but found ${resultDoc2.items.length}`); + assert.equal(resultDoc2.items.length, 1, `Expecting 1 item in completion but found ${resultDoc2.items.length}`); + assert.equal(resultDoc2.items[0].label, '- (array item) '); }); it('should handle absolute path', async () => { diff --git a/test/defaultSnippets.test.ts b/test/defaultSnippets.test.ts index 4066a2da6..7ffaf9d8b 100644 --- a/test/defaultSnippets.test.ts +++ b/test/defaultSnippets.test.ts @@ -91,9 +91,16 @@ describe('Default Snippet Tests', () => { const completion = parseSetup(content, content.length); completion .then(function (result) { - assert.equal(result.items.length, 1); - assert.equal(result.items[0].insertText, '- item1: $1\n item2: $2'); - assert.equal(result.items[0].label, 'My array item'); + assert.deepEqual( + result.items.map((i) => ({ insertText: i.insertText, label: i.label })), + [ + { insertText: '- item1: $1\n item2: $2', label: 'My array item' }, + { + insertText: '- $1\n', + label: '- (array item) ', + }, + ] + ); }) .then(done, done); }); @@ -233,6 +240,19 @@ describe('Default Snippet Tests', () => { .then(done, done); }); + it('Snippet in string schema should autocomplete on same line (snippet is defined in body property)', (done) => { + const content = 'arrayStringValueSnippet:\n - |\n|'; + const completion = parseSetup(content); + completion + .then(function (result) { + assert.deepEqual( + result.items.map((i) => ({ label: i.label, insertText: i.insertText })), + [{ insertText: 'banana', label: 'Banana' }] + ); + }) + .then(done, done); + }); + it('Snippet in boolean schema should autocomplete on same line', (done) => { const content = 'boolean: | |'; // len: 10, pos: 9 const completion = parseSetup(content); @@ -266,7 +286,7 @@ describe('Default Snippet Tests', () => { const completion = parseSetup(content); completion .then(function (result) { - assert.equal(result.items.length, 15); // This is just checking the total number of snippets in the defaultSnippets.json + assert.equal(result.items.length, 16); // This is just checking the total number of snippets in the defaultSnippets.json assert.equal(result.items[4].label, 'longSnippet'); // eslint-disable-next-line assert.equal( diff --git a/test/fixtures/defaultSnippets.json b/test/fixtures/defaultSnippets.json index 5d4b69d2a..42ff75d06 100644 --- a/test/fixtures/defaultSnippets.json +++ b/test/fixtures/defaultSnippets.json @@ -110,6 +110,18 @@ } ] }, + "arrayStringValueSnippet": { + "type": "array", + "items": { + "type": "string", + "defaultSnippets": [ + { + "label": "Banana", + "body": "banana" + } + ] + } + }, "arrayObjectSnippet": { "type": "object", "defaultSnippets": [