Skip to content

Commit 9cfb0c7

Browse files
Merge pull request #697 from p-spacek/fix/completion-array-in-the-middle-of-the-empty-text
fix array completion in the middle of the empty text
2 parents b3ba325 + 4df39af commit 9cfb0c7

File tree

3 files changed

+96
-5
lines changed

3 files changed

+96
-5
lines changed

src/languageservice/services/yamlCompletion.ts

+15-2
Original file line numberDiff line numberDiff line change
@@ -324,8 +324,20 @@ export class YamlCompletion {
324324
}
325325
}
326326

327-
const originalNode = node;
327+
let originalNode = node;
328328
if (node) {
329+
// when the array item value is null but the cursor is between '-' and null value (cursor is not at the end of the line)
330+
if (isSeq(node) && node.items.length && isScalar(node.items[0]) && lineContent.includes('-')) {
331+
const nullNode = node.items[0];
332+
if (
333+
nullNode.value === null && // value is null
334+
nullNode.range[0] > offset // cursor is before null
335+
) {
336+
node = nullNode;
337+
originalNode = node;
338+
overwriteRange.end.character += nullNode.range[2] - offset; // extend range to the end of the null element
339+
}
340+
}
329341
if (lineContent.length === 0) {
330342
node = currentDoc.internalDocument.contents as Node;
331343
} else {
@@ -642,7 +654,8 @@ export class YamlCompletion {
642654
const indexOfSlash = sourceText.lastIndexOf('-', node.range[0] - 1);
643655
if (indexOfSlash >= 0) {
644656
// add one space to compensate the '-'
645-
identCompensation = ' ' + sourceText.slice(indexOfSlash + 1, node.range[0]);
657+
const overwriteChars = overwriteRange.end.character - overwriteRange.start.character;
658+
identCompensation = ' ' + sourceText.slice(indexOfSlash + 1, node.range[1] - overwriteChars);
646659
}
647660
}
648661
identCompensation += this.arrayPrefixIndentation;

test/autoCompletion.test.ts

+49-2
Original file line numberDiff line numberDiff line change
@@ -2366,10 +2366,44 @@ describe('Auto Completion Tests', () => {
23662366
});
23672367

23682368
const content = 'test:\n - and\n - - ';
2369-
const completion = await parseSetup(content, 19);
2369+
2370+
const completion = await parseSetup(content, 20);
2371+
expect(completion.items).lengthOf(1);
2372+
expect(completion.items[0]).eql(
2373+
createExpectedCompletion('and', 'and', 2, 6, 2, 6, 12, InsertTextFormat.Snippet, { documentation: undefined })
2374+
);
2375+
});
2376+
2377+
it('should follow $ref in additionalItems: extra space after cursor', async () => {
2378+
languageService.addSchema(SCHEMA_ID, {
2379+
type: 'object',
2380+
properties: {
2381+
test: {
2382+
$ref: '#/definitions/Recur',
2383+
},
2384+
},
2385+
definitions: {
2386+
Recur: {
2387+
type: 'array',
2388+
items: [
2389+
{
2390+
type: 'string',
2391+
enum: ['and'],
2392+
},
2393+
],
2394+
additionalItems: {
2395+
$ref: '#/definitions/Recur',
2396+
},
2397+
},
2398+
},
2399+
});
2400+
2401+
const content = 'test:\n - and\n - - ';
2402+
2403+
const completion = await parseSetup(content, 20);
23702404
expect(completion.items).lengthOf(1);
23712405
expect(completion.items[0]).eql(
2372-
createExpectedCompletion('and', 'and', 2, 4, 2, 5, 12, InsertTextFormat.Snippet, { documentation: undefined })
2406+
createExpectedCompletion('and', 'and', 2, 6, 2, 8, 12, InsertTextFormat.Snippet, { documentation: undefined })
23732407
);
23742408
});
23752409

@@ -2512,6 +2546,19 @@ describe('Auto Completion Tests', () => {
25122546
.then(done, done);
25132547
});
25142548

2549+
it('Simple array object completion without "-" befor array empty item', (done) => {
2550+
const schema = require(path.join(__dirname, './fixtures/testArrayCompletionSchema.json'));
2551+
languageService.addSchema(SCHEMA_ID, schema);
2552+
const content = 'test_simpleArrayObject:\n \n -';
2553+
const completion = parseSetup(content, 'test_simpleArrayObject:\n '.length);
2554+
completion
2555+
.then(function (result) {
2556+
assert.equal(result.items.length, 1);
2557+
assert.equal(result.items[0].label, '- (array item)');
2558+
})
2559+
.then(done, done);
2560+
});
2561+
25152562
it('Array anyOf two objects completion without "-" after array item', (done) => {
25162563
const schema = require(path.join(__dirname, './fixtures/testArrayCompletionSchema.json'));
25172564
languageService.addSchema(SCHEMA_ID, schema);

test/autoCompletionFix.test.ts

+32-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { CompletionList, Position } from 'vscode-languageserver/node';
6+
import { CompletionList, Position, Range } from 'vscode-languageserver/node';
77
import { LanguageHandlers } from '../src/languageserver/handlers/languageHandlers';
88
import { LanguageService } from '../src/languageservice/yamlLanguageService';
99
import { SettingsState, TextDocumentTestManager } from '../src/yamlSettings';
@@ -470,5 +470,36 @@ objB:
470470
expect(completion.items[1].label).to.be.equal('obj1');
471471
expect(completion.items[1].insertText).to.be.equal('obj1:\n prop2: ${1:value}');
472472
});
473+
474+
it('should suggest object array when extra space is after cursor', async () => {
475+
const schema: JSONSchema = {
476+
properties: {
477+
arrayObj: {
478+
type: 'array',
479+
items: {
480+
type: 'object',
481+
properties: {
482+
item1: {
483+
type: 'string',
484+
},
485+
item2: {
486+
type: 'string',
487+
},
488+
},
489+
required: ['item1', 'item2'],
490+
},
491+
},
492+
},
493+
};
494+
languageService.addSchema(SCHEMA_ID, schema);
495+
const content = 'arrayObj:\n - ';
496+
const completion = await parseSetup(content, 1, 4);
497+
498+
expect(completion.items.length).equal(3);
499+
expect(completion.items[1].textEdit).to.be.deep.equal({
500+
newText: 'item1: $1\n item2: $2',
501+
range: Range.create(1, 4, 1, 6), // removes extra spaces after cursor
502+
});
503+
});
473504
});
474505
});

0 commit comments

Comments
 (0)