Skip to content

Commit b0fee20

Browse files
Merge pull request #669 from msivasubramaniaan/fix-auto-completion-on-list-indentation
fixed auto completion provides valid suggetion even though list indentation not proper
2 parents 387a6ef + b2e3391 commit b0fee20

File tree

4 files changed

+70
-9
lines changed

4 files changed

+70
-9
lines changed

src/languageservice/parser/yaml-documents.ts

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,15 @@ export class SingleYAMLDocument extends JSONDocument {
9595
return this.internalDocument.warnings.map(YAMLErrorToYamlDocDiagnostics);
9696
}
9797

98-
getNodeFromPosition(positionOffset: number, textBuffer: TextBuffer): [YamlNode | undefined, boolean] {
98+
getNodeFromPosition(
99+
positionOffset: number,
100+
textBuffer: TextBuffer,
101+
configuredIndentation?: number
102+
): [YamlNode | undefined, boolean] {
99103
const position = textBuffer.getPosition(positionOffset);
100104
const lineContent = textBuffer.getLineContent(position.line);
101105
if (lineContent.trim().length === 0) {
102-
return [this.findClosestNode(positionOffset, textBuffer), true];
106+
return [this.findClosestNode(positionOffset, textBuffer, configuredIndentation), true];
103107
}
104108

105109
let closestNode: Node;
@@ -122,7 +126,7 @@ export class SingleYAMLDocument extends JSONDocument {
122126
return [closestNode, false];
123127
}
124128

125-
findClosestNode(offset: number, textBuffer: TextBuffer): YamlNode {
129+
findClosestNode(offset: number, textBuffer: TextBuffer, configuredIndentation?: number): YamlNode {
126130
let offsetDiff = this.internalDocument.range[2];
127131
let maxOffset = this.internalDocument.range[0];
128132
let closestNode: YamlNode;
@@ -151,34 +155,57 @@ export class SingleYAMLDocument extends JSONDocument {
151155
}
152156

153157
if (indentation === position.character) {
154-
closestNode = this.getProperParentByIndentation(indentation, closestNode, textBuffer);
158+
closestNode = this.getProperParentByIndentation(indentation, closestNode, textBuffer, '', configuredIndentation);
155159
}
156160

157161
return closestNode;
158162
}
159163

160-
private getProperParentByIndentation(indentation: number, node: YamlNode, textBuffer: TextBuffer): YamlNode {
164+
private getProperParentByIndentation(
165+
indentation: number,
166+
node: YamlNode,
167+
textBuffer: TextBuffer,
168+
currentLine: string,
169+
configuredIndentation: number,
170+
rootParent?: YamlNode
171+
): YamlNode {
161172
if (!node) {
162173
return this.internalDocument.contents as Node;
163174
}
175+
configuredIndentation = !configuredIndentation ? 2 : configuredIndentation;
164176
if (isNode(node) && node.range) {
165177
const position = textBuffer.getPosition(node.range[0]);
178+
const lineContent = textBuffer.getLineContent(position.line);
179+
currentLine = currentLine === '' ? lineContent.trim() : currentLine;
180+
if (currentLine.startsWith('-') && indentation === configuredIndentation && currentLine === lineContent.trim()) {
181+
position.character += indentation;
182+
}
166183
if (position.character > indentation && position.character > 0) {
167184
const parent = this.getParent(node);
168185
if (parent) {
169-
return this.getProperParentByIndentation(indentation, parent, textBuffer);
186+
return this.getProperParentByIndentation(
187+
indentation,
188+
parent,
189+
textBuffer,
190+
currentLine,
191+
configuredIndentation,
192+
rootParent
193+
);
170194
}
171195
} else if (position.character < indentation) {
172196
const parent = this.getParent(node);
173197
if (isPair(parent) && isNode(parent.value)) {
174198
return parent.value;
199+
} else if (isPair(rootParent) && isNode(rootParent.value)) {
200+
return rootParent.value;
175201
}
176202
} else {
177203
return node;
178204
}
179205
} else if (isPair(node)) {
206+
rootParent = node;
180207
const parent = this.getParent(node);
181-
return this.getProperParentByIndentation(indentation, parent, textBuffer);
208+
return this.getProperParentByIndentation(indentation, parent, textBuffer, currentLine, configuredIndentation, rootParent);
182209
}
183210
return node;
184211
}

src/languageservice/services/yamlCompletion.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ export class YamlCompletion {
123123
// as we modify AST for completion, we need to use copy of original document
124124
currentDoc = currentDoc.clone();
125125

126-
let [node, foundByClosest] = currentDoc.getNodeFromPosition(offset, textBuffer);
126+
let [node, foundByClosest] = currentDoc.getNodeFromPosition(offset, textBuffer, this.indentation.length);
127127

128128
const currentWord = this.getCurrentWord(document, offset);
129129

test/autoCompletion.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2066,6 +2066,40 @@ describe('Auto Completion Tests', () => {
20662066
expect(completion.items[0].insertText).eq('fooBar:\n name: $1\n aaa:\n - $2');
20672067
});
20682068

2069+
it('auto completion based on the list indentation', async () => {
2070+
languageService.addSchema(SCHEMA_ID, {
2071+
type: 'array',
2072+
items: {
2073+
type: 'object',
2074+
properties: {
2075+
prop1: {
2076+
type: 'string',
2077+
},
2078+
prop2: {
2079+
type: 'string',
2080+
},
2081+
Object: {
2082+
type: 'array',
2083+
items: {
2084+
type: 'object',
2085+
properties: {
2086+
env_prop1: {
2087+
type: 'string',
2088+
},
2089+
},
2090+
},
2091+
},
2092+
},
2093+
},
2094+
});
2095+
2096+
const content = '- prop1: value\n object:\n - env_prop1: value\n ';
2097+
const completion = await parseSetup(content, 49);
2098+
expect(completion.items).lengthOf(2);
2099+
expect(completion.items[0].label).eq('prop2');
2100+
expect(completion.items[0].insertText).eq('prop2: ');
2101+
});
2102+
20692103
it('should complete string which contains number in default value', async () => {
20702104
languageService.addSchema(SCHEMA_ID, {
20712105
type: 'object',

test/yaml-documents.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ objB:
232232

233233
expect(result).is.not.undefined;
234234
expect(isMap(result)).is.true;
235-
expect(((result as YAMLMap).items[0].key as Scalar).value).eqls('foo');
235+
expect(((result as YAMLMap).items[0].key as Scalar).value).eqls('bar');
236236
});
237237
});
238238
});

0 commit comments

Comments
 (0)