diff --git a/src/languageservice/services/yamlCompletion.ts b/src/languageservice/services/yamlCompletion.ts index af89fbf5..b5e49beb 100644 --- a/src/languageservice/services/yamlCompletion.ts +++ b/src/languageservice/services/yamlCompletion.ts @@ -175,6 +175,15 @@ export class YamlCompletion { try { const schema = await this.schemaService.getSchemaForResource(document.uri, currentDoc); if (!schema || schema.errors.length) { + if (position.line === 0 && position.character === 0 && !textBuffer.getLineContent(0).includes('# yaml-language-server')) { + const inlineSchemaCompletion = { + kind: CompletionItemKind.Text, + label: 'Inline schema', + insertText: '# yaml-language-server: $schema=', + insertTextFormat: InsertTextFormat.PlainText, + }; + result.items.push(inlineSchemaCompletion); + } return result; } diff --git a/test/autoCompletion.test.ts b/test/autoCompletion.test.ts index 857cfc44..2df434dd 100644 --- a/test/autoCompletion.test.ts +++ b/test/autoCompletion.test.ts @@ -1588,6 +1588,52 @@ describe('Auto Completion Tests', () => { }); assert.strictEqual(result.items.length, 3, `Expecting 3 items in completion but found ${result.items.length}`); }); + + const inlineSchemaLabel = 'Inline schema'; + + it('should provide modeline completion on first character with no schema associated and no modeline yet', async () => { + const testTextDocument = setupSchemaIDTextDocument('', path.join(__dirname, 'test.yaml')); + yamlSettings.documents = new TextDocumentTestManager(); + (yamlSettings.documents as TextDocumentTestManager).set(testTextDocument); + const result = await languageHandler.completionHandler({ + position: testTextDocument.positionAt(0), + textDocument: testTextDocument, + }); + assert.strictEqual(result.items.length, 1, `Expecting 1 item in completion but found ${result.items.length}`); + assert.strictEqual(result.items[0].label, inlineSchemaLabel); + }); + + it('should not provide modeline completion on first character when schema is associated', async () => { + const specificSchemaId = path.join(__dirname, 'test.yaml'); + const testTextDocument = setupSchemaIDTextDocument('', specificSchemaId); + languageService.addSchema(specificSchemaId, { + type: 'object', + properties: { + name: { + type: 'string', + }, + }, + }); + yamlSettings.documents = new TextDocumentTestManager(); + (yamlSettings.documents as TextDocumentTestManager).set(testTextDocument); + const result = await languageHandler.completionHandler({ + position: testTextDocument.positionAt(0), + textDocument: testTextDocument, + }); + assert.strictEqual(result.items.length, 1, `Expecting 1 item in completion but found ${result.items.length}`); + assert.notStrictEqual(result.items[0].label, inlineSchemaLabel); + }); + + it('should not provide modeline completion on first character when modeline already present', async () => { + const testTextDocument = setupSchemaIDTextDocument('# yaml-language-server', path.join(__dirname, 'test.yaml')); + yamlSettings.documents = new TextDocumentTestManager(); + (yamlSettings.documents as TextDocumentTestManager).set(testTextDocument); + const result = await languageHandler.completionHandler({ + position: testTextDocument.positionAt(0), + textDocument: testTextDocument, + }); + assert.strictEqual(result.items.length, 0, `Expecting 0 item in completion but found ${result.items.length}`); + }); }); describe('Configuration based indentation', () => {