Skip to content

Commit

Permalink
Fix completion for existing property (#428)
Browse files Browse the repository at this point in the history
* #414 Fix completion for existing property

Signed-off-by: Yevhen Vydolob <[email protected]>

* fix completion

Signed-off-by: Yevhen Vydolob <[email protected]>

* fix merge conflict

Signed-off-by: Yevhen Vydolob <[email protected]>
  • Loading branch information
evidolob authored Mar 25, 2021
1 parent c8a1179 commit 351183d
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 11 deletions.
39 changes: 29 additions & 10 deletions src/languageservice/services/yamlCompletion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { parse as parseYAML } from '../parser/yamlParser07';
import { YAMLSchemaService } from './yamlSchemaService';
import { JSONSchema, JSONSchemaRef } from '../jsonSchema';
import { CompletionsCollector } from 'vscode-json-languageservice';
import { TextDocument } from 'vscode-languageserver-textdocument';
import {
CompletionItem,
CompletionItemKind,
Expand All @@ -20,7 +21,6 @@ import {
TextEdit,
InsertTextFormat,
} from 'vscode-languageserver-types';
import { TextDocument } from 'vscode-languageserver-textdocument';
import * as nls from 'vscode-nls';
import { getLineOffsets, filterInvalidCustomTags, matchOffsetToDocument } from '../utils/arrUtils';
import { LanguageSettings } from '../yamlLanguageService';
Expand Down Expand Up @@ -68,8 +68,9 @@ export class YAMLCompletion extends JSONCompletion {
const completionFix = this.completionHelper(document, position);
const newText = completionFix.newText;
const doc = parseYAML(newText);
const textBuffer = new TextBuffer(document);
if (!this.configuredIndentation) {
const indent = guessIndentation(new TextBuffer(document), 2, true);
const indent = guessIndentation(textBuffer, 2, true);
this.indentation = indent.insertSpaces ? ' '.repeat(indent.tabSize) : '\t';
} else {
this.indentation = this.configuredIndentation;
Expand Down Expand Up @@ -200,7 +201,16 @@ export class YAMLCompletion extends JSONCompletion {
const separatorAfter = '';
if (newSchema) {
// property proposals with schema
this.getPropertyCompletions(newSchema, currentDoc, node, addValue, separatorAfter, collector, document);
this.getPropertyCompletions(
newSchema,
currentDoc,
node,
addValue,
separatorAfter,
collector,
textBuffer,
overwriteRange
);
}

if (!schema && currentWord.length > 0 && document.getText().charAt(offset - currentWord.length - 1) !== '"') {
Expand Down Expand Up @@ -233,9 +243,12 @@ export class YAMLCompletion extends JSONCompletion {
addValue: boolean,
separatorAfter: string,
collector: CompletionsCollector,
document: TextDocument
textBuffer: TextBuffer,
overwriteRange: Range
): void {
const matchingSchemas = doc.getMatchingSchemas(schema.schema);
const existingKey = textBuffer.getText(overwriteRange);
const hasColumn = textBuffer.getLineContent(overwriteRange.start.line).indexOf(':') === -1;
matchingSchemas.forEach((s) => {
if (s.node === node && !s.inverted) {
this.collectDefaultSnippets(s.schema, separatorAfter, collector, {
Expand All @@ -254,23 +267,29 @@ export class YAMLCompletion extends JSONCompletion {
if (node.parent && node.parent.type === 'array' && node.properties.length <= 1) {
// because there is a slash '-' to prevent the properties generated to have the correct
// indent
const sourceText = document.getText();
const sourceText = textBuffer.getText();
const indexOfSlash = sourceText.lastIndexOf('-', node.offset - 1);
if (indexOfSlash >= 0) {
// add one space to compensate the '-'
identCompensation = ' ' + sourceText.slice(indexOfSlash + 1, node.offset);
}
}
collector.add({
kind: CompletionItemKind.Property,
label: key,
insertText: this.getInsertTextForProperty(

let insertText = key;
if (!key.startsWith(existingKey) || hasColumn) {
insertText = this.getInsertTextForProperty(
key,
propertySchema,
addValue,
separatorAfter,
identCompensation + this.indentation
),
);
}

collector.add({
kind: CompletionItemKind.Property,
label: key,
insertText,
insertTextFormat: InsertTextFormat.Snippet,
documentation: propertySchema.description || '',
});
Expand Down
4 changes: 4 additions & 0 deletions src/languageservice/utils/textBuffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,8 @@ export class TextBuffer {
getLineCharCode(lineNumber: number, index: number): number {
return this.doc.getText(Range.create(lineNumber - 1, index - 1, lineNumber - 1, index)).charCodeAt(0);
}

getText(range?: Range): string {
return this.doc.getText(range);
}
}
40 changes: 39 additions & 1 deletion test/autoCompletion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ describe('Auto Completion Tests', () => {
},
},
});
const content = '---\ntimeout: 10\n...\n---\ntime: \n...';
const content = '---\ntimeout: 10\n...\n---\ntime \n...';
const completion = parseSetup(content, 26);
completion
.then(function (result) {
Expand Down Expand Up @@ -1802,6 +1802,44 @@ describe('Auto Completion Tests', () => {
createExpectedCompletion('name', 'name: $1', 2, 0, 2, 0, 10, InsertTextFormat.Snippet, { documentation: '' })
);
});

it('should not provide additional ":" on existing property completion', async () => {
languageService.addSchema(SCHEMA_ID, {
type: 'object',
properties: {
kind: {
type: 'string',
},
},
required: ['kind'],
});

const content = 'kind: 111\n';
const completion = await parseSetup(content, 3);
expect(completion.items).lengthOf(1);
expect(completion.items[0]).eql(
createExpectedCompletion('kind', 'kind', 0, 0, 0, 4, 10, InsertTextFormat.Snippet, { documentation: '' })
);
});

it('should not provide additional ":" on existing property completion when try to complete partial property', async () => {
languageService.addSchema(SCHEMA_ID, {
type: 'object',
properties: {
kind: {
type: 'string',
},
},
required: ['kind'],
});

const content = 'ki: 111\n';
const completion = await parseSetup(content, 1);
expect(completion.items).lengthOf(1);
expect(completion.items[0]).eql(
createExpectedCompletion('kind', 'kind', 0, 0, 0, 2, 10, InsertTextFormat.Snippet, { documentation: '' })
);
});
});
describe('Array completion', () => {
it('Simple array object completion with "-" without any item', async () => {
Expand Down

0 comments on commit 351183d

Please sign in to comment.