Skip to content

Commit 80a34d4

Browse files
authored
Merge pull request #390 from p-spacek/fix/completion-array
fix: Completion array anyOf
2 parents a18a018 + 252c1e8 commit 80a34d4

File tree

3 files changed

+196
-1
lines changed

3 files changed

+196
-1
lines changed

src/languageservice/services/yamlCompletion.ts

+33-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import { stringifyObject, StringifySettings } from '../utils/json';
3030
import { guessIndentation } from '../utils/indentationGuesser';
3131
import { TextBuffer } from '../utils/textBuffer';
3232
import { setKubernetesParserOption } from '../parser/isKubernetes';
33-
import { ClientCapabilities } from 'vscode-languageserver';
33+
import { ClientCapabilities, MarkupContent } from 'vscode-languageserver';
3434
const localize = nls.loadMessageBundle();
3535

3636
export class YAMLCompletion extends JSONCompletion {
@@ -393,6 +393,25 @@ export class YAMLCompletion extends JSONCompletion {
393393
insertTextFormat: InsertTextFormat.Snippet,
394394
});
395395
this.addSchemaValueCompletions(s.schema.items, separatorAfter, collector, types);
396+
} else if (typeof s.schema.items === 'object' && s.schema.items.anyOf) {
397+
s.schema.items.anyOf
398+
.filter((i) => typeof i === 'object')
399+
.forEach((i: JSONSchema, index) => {
400+
const insertText = `- ${this.getInsertTextForObject(i, separatorAfter).insertText.trimLeft()}`;
401+
//append insertText to documentation
402+
const documentation = this.getDocumentationWithMarkdownText(
403+
`Create an item of an array${s.schema.description === undefined ? '' : '(' + s.schema.description + ')'}`,
404+
insertText
405+
);
406+
collector.add({
407+
kind: super.getSuggestionKind(i.type),
408+
label: '- (array item) ' + (index + 1),
409+
documentation: documentation,
410+
insertText: insertText,
411+
insertTextFormat: InsertTextFormat.Snippet,
412+
});
413+
});
414+
this.addSchemaValueCompletions(s.schema.items, separatorAfter, collector, types);
396415
} else {
397416
this.addSchemaValueCompletions(s.schema.items, separatorAfter, collector, types);
398417
}
@@ -1004,6 +1023,19 @@ export class YAMLCompletion extends JSONCompletion {
10041023
private is_EOL(c: number): boolean {
10051024
return c === 0x0a /* LF */ || c === 0x0d /* CR */;
10061025
}
1026+
1027+
private getDocumentationWithMarkdownText(documentation: string, insertText: string): string | MarkupContent {
1028+
let res: string | MarkupContent = documentation;
1029+
if (super.doesSupportMarkdown()) {
1030+
insertText = insertText
1031+
.replace(/\${[0-9]+[:|](.*)}/g, (s, arg) => {
1032+
return arg;
1033+
})
1034+
.replace(/\$([0-9]+)/g, '');
1035+
res = super.fromMarkup(`${documentation}\n \`\`\`\n${insertText}\n\`\`\``) as MarkupContent;
1036+
}
1037+
return res;
1038+
}
10071039
}
10081040

10091041
const isNumberExp = /^\d+$/;

test/autoCompletion.test.ts

+78
Original file line numberDiff line numberDiff line change
@@ -1730,5 +1730,83 @@ suite('Auto Completion Tests', () => {
17301730
);
17311731
});
17321732
});
1733+
describe('Array completion', () => {
1734+
it('Simple array object completion with "-" without any item', async () => {
1735+
const schema = require(path.join(__dirname, './fixtures/testArrayCompletionSchema.json'));
1736+
languageService.addSchema(SCHEMA_ID, schema);
1737+
const content = 'test_simpleArrayObject:\n -';
1738+
const completion = parseSetup(content, content.length);
1739+
completion.then(function (result) {
1740+
assert.equal(result.items.length, 1);
1741+
assert.equal(result.items[0].label, '- (array item)');
1742+
});
1743+
});
1744+
1745+
it('Simple array object completion without "-" after array item', async () => {
1746+
const schema = require(path.join(__dirname, './fixtures/testArrayCompletionSchema.json'));
1747+
languageService.addSchema(SCHEMA_ID, schema);
1748+
const content = 'test_simpleArrayObject:\n - obj1:\n name: 1\n ';
1749+
const completion = parseSetup(content, content.length);
1750+
completion.then(function (result) {
1751+
assert.equal(result.items.length, 1);
1752+
assert.equal(result.items[0].label, '- (array item)');
1753+
});
1754+
});
1755+
1756+
it('Simple array object completion with "-" after array item', async () => {
1757+
const schema = require(path.join(__dirname, './fixtures/testArrayCompletionSchema.json'));
1758+
languageService.addSchema(SCHEMA_ID, schema);
1759+
const content = 'test_simpleArrayObject:\n - obj1:\n name: 1\n -';
1760+
const completion = parseSetup(content, content.length);
1761+
completion.then(function (result) {
1762+
assert.equal(result.items.length, 1);
1763+
assert.equal(result.items[0].label, '- (array item)');
1764+
});
1765+
});
1766+
1767+
it('Array anyOf two objects completion with "- " without any item', async () => {
1768+
const schema = require(path.join(__dirname, './fixtures/testArrayCompletionSchema.json'));
1769+
languageService.addSchema(SCHEMA_ID, schema);
1770+
const content = 'test_array_anyOf_2objects:\n - ';
1771+
const completion = parseSetup(content, content.length);
1772+
completion.then(function (result) {
1773+
assert.equal(result.items.length, 2);
1774+
assert.equal(result.items[0].label, 'obj1');
1775+
});
1776+
});
1777+
1778+
it('Array anyOf two objects completion with "-" without any item', async () => {
1779+
const schema = require(path.join(__dirname, './fixtures/testArrayCompletionSchema.json'));
1780+
languageService.addSchema(SCHEMA_ID, schema);
1781+
const content = 'test_array_anyOf_2objects:\n -';
1782+
const completion = parseSetup(content, content.length);
1783+
completion.then(function (result) {
1784+
assert.equal(result.items.length, 2);
1785+
assert.equal(result.items[0].label, '- (array item) 1');
1786+
});
1787+
});
1788+
1789+
it('Array anyOf two objects completion without "-" after array item', async () => {
1790+
const schema = require(path.join(__dirname, './fixtures/testArrayCompletionSchema.json'));
1791+
languageService.addSchema(SCHEMA_ID, schema);
1792+
const content = 'test_array_anyOf_2objects:\n - obj1:\n name: 1\n ';
1793+
const completion = parseSetup(content, content.length);
1794+
completion.then(function (result) {
1795+
assert.equal(result.items.length, 2);
1796+
assert.equal(result.items[0].label, '- (array item) 1');
1797+
});
1798+
});
1799+
1800+
it('Array anyOf two objects completion with "-" after array item', async () => {
1801+
const schema = require(path.join(__dirname, './fixtures/testArrayCompletionSchema.json'));
1802+
languageService.addSchema(SCHEMA_ID, schema);
1803+
const content = 'test_array_anyOf_2objects:\n - obj1:\n name: 1\n -';
1804+
const completion = parseSetup(content, content.length);
1805+
completion.then(function (result) {
1806+
assert.equal(result.items.length, 2);
1807+
assert.equal(result.items[0].label, '- (array item) 1');
1808+
});
1809+
});
1810+
});
17331811
});
17341812
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"definitions": {
4+
"obj1": {
5+
"properties": {
6+
"obj1": {
7+
"type": "object"
8+
}
9+
},
10+
"required": [
11+
"obj1"
12+
],
13+
"type": "object"
14+
},
15+
"obj2": {
16+
"properties": {
17+
"obj2": {
18+
"type": "object"
19+
}
20+
},
21+
"required": [
22+
"obj2"
23+
],
24+
"type": "object"
25+
}
26+
},
27+
"properties": {
28+
"test_simpleArrayObject": {
29+
"items": {
30+
"$ref": "#/definitions/obj1"
31+
},
32+
"type": "array"
33+
},
34+
"test_array_anyOf_2objects": {
35+
"items": {
36+
"anyOf": [
37+
{
38+
"$ref": "#/definitions/obj1"
39+
},
40+
{
41+
"$ref": "#/definitions/obj2"
42+
}
43+
]
44+
},
45+
"type": "array"
46+
},
47+
"test_array_anyOf_strAndObj": {
48+
"items": {
49+
"anyOf": [
50+
{
51+
"type": "string"
52+
},
53+
{
54+
"$ref": "#/definitions/obj1"
55+
}
56+
]
57+
},
58+
"type": "array"
59+
},
60+
"test_anyOfObjectAndNull": {
61+
"anyOf": [
62+
{
63+
"$ref": "#/definitions/obj1"
64+
},
65+
{
66+
"type": "null"
67+
}
68+
]
69+
},
70+
"test_anyOfArrAndNull": {
71+
"anyOf": [
72+
{
73+
"type": "array",
74+
"items": {
75+
"type": "string"
76+
}
77+
},
78+
{
79+
"type": "null"
80+
}
81+
]
82+
}
83+
},
84+
"type": "object"
85+
}

0 commit comments

Comments
 (0)