Skip to content

Commit

Permalink
fix: completion invoke in three different scenarios
Browse files Browse the repository at this point in the history
 - with short nextLine - nested object
 - with a new line inside the object
 - on the first array item
  • Loading branch information
Petr Spacek authored and evidolob committed Dec 16, 2021
1 parent a9e95a4 commit 29376f2
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 5 deletions.
15 changes: 10 additions & 5 deletions src/languageservice/parser/yaml-documents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { TextDocument } from 'vscode-languageserver-textdocument';
import { JSONDocument } from './jsonParser07';
import { Document, isPair, isScalar, LineCounter, visit, YAMLError } from 'yaml';
import { Document, isNode, isPair, isScalar, LineCounter, visit, YAMLError } from 'yaml';
import { ASTNode } from '../jsonASTTypes';
import { defaultOptions, parse as parseYAML, ParserOptions } from './yamlParser07';
import { ErrorCode } from 'vscode-json-languageservice';
Expand Down Expand Up @@ -126,9 +126,9 @@ export class SingleYAMLDocument extends JSONDocument {
if (!range) {
return;
}
const diff = Math.abs(range[2] - offset);
if (maxOffset <= range[0] && diff <= offsetDiff) {
offsetDiff = diff;
const diff = range[2] - offset;
if (maxOffset <= range[0] && diff <= 0 && Math.abs(diff) <= offsetDiff) {
offsetDiff = Math.abs(diff);
maxOffset = range[0];
closestNode = node;
}
Expand All @@ -155,11 +155,16 @@ export class SingleYAMLDocument extends JSONDocument {
}
if (node.range) {
const position = textBuffer.getPosition(node.range[0]);
if (position.character !== indentation && position.character > 0) {
if (position.character > indentation && position.character > 0) {
const parent = this.getParent(node);
if (parent) {
return this.getProperParentByIndentation(indentation, parent, textBuffer);
}
} else if (position.character < indentation) {
const parent = this.getParent(node);
if (isPair(parent) && isNode(parent.value)) {
return parent.value;
}
} else {
return node;
}
Expand Down
100 changes: 100 additions & 0 deletions test/autoCompletionFix.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,104 @@ objB:
expect(completion.items).length(4);
expect(completion.items.map((it) => it.label)).to.have.members(['NOT', 'attribute', 'operation', 'value']);
});

it('Autocomplete with short nextLine - nested object', async () => {
languageService.addSchema(SCHEMA_ID, {
type: 'object',
properties: {
example: {
type: 'object',
properties: {
sample: {
type: 'object',
properties: {
detail: {
type: 'object',
},
},
},
},
},
a: {
type: 'string',
description: 'short prop name because of distance to the cursor',
},
},
});
const content = 'example:\n sample:\n ';
const completion = await parseSetup(content + '\na: test', 2, 4);
expect(completion.items.length).equal(1);
expect(completion.items[0]).to.be.deep.equal(
createExpectedCompletion('detail', 'detail:\n ', 2, 4, 2, 4, 10, 2, {
documentation: '',
})
);
});

it('Autocomplete with a new line inside the object', async () => {
languageService.addSchema(SCHEMA_ID, {
type: 'object',
properties: {
example: {
type: 'object',
properties: {
sample: {
type: 'object',
properties: {
prop1: {
type: 'string',
},
prop2: {
type: 'string',
},
},
},
},
},
},
});
const content = 'example:\n sample:\n \n prop2: value2';
const completion = await parseSetup(content, 2, 4);
expect(completion.items.length).equal(1);
expect(completion.items[0]).to.be.deep.equal(
createExpectedCompletion('prop1', 'prop1: ', 2, 4, 2, 4, 10, 2, {
documentation: '',
})
);
});

it('Autocomplete on the first array item', async () => {
languageService.addSchema(SCHEMA_ID, {
type: 'object',
properties: {
examples: {
type: 'array',
items: {
type: 'object',
properties: {
sample: {
type: 'object',
properties: {
prop1: {
type: 'string',
},
},
},
},
},
},
},
});
const content = 'examples:\n \n - sample:\n prop1: value1';
const completion = await parseSetup(content, 1, 2);
expect(completion.items.length).equal(1);
expect(completion.items[0]).to.be.deep.equal(
createExpectedCompletion('- (array item)', '- ', 1, 2, 1, 2, 9, 2, {
documentation: {
kind: 'markdown',
value: 'Create an item of an array\n ```\n- \n```',
},
})
);
});
});

0 comments on commit 29376f2

Please sign in to comment.