diff --git a/server/gx-workflow-ls-format2/src/schema/definitions.ts b/server/gx-workflow-ls-format2/src/schema/definitions.ts index 45b13e9..93e8e83 100644 --- a/server/gx-workflow-ls-format2/src/schema/definitions.ts +++ b/server/gx-workflow-ls-format2/src/schema/definitions.ts @@ -195,12 +195,16 @@ export class EnumSchemaNode implements SchemaNode { return false; } + public get canBeAny(): boolean { + return this.name === "Any"; + } + public get typeRef(): string { return this._schemaEnum.name; } public matchesType(typeName: string): boolean { - return this.name === "Any" || this.symbols.includes(typeName); + return this.canBeAny || this.symbols.includes(typeName); } //Override toString for debugging purposes diff --git a/server/gx-workflow-ls-format2/src/services/completionService.ts b/server/gx-workflow-ls-format2/src/services/completionService.ts index feb374a..1b53c7e 100644 --- a/server/gx-workflow-ls-format2/src/services/completionService.ts +++ b/server/gx-workflow-ls-format2/src/services/completionService.ts @@ -25,6 +25,12 @@ export class GxFormat2CompletionService { const offset = textBuffer.getOffsetAt(position); let node = nodeManager.getNodeFromOffset(offset); + if (node === undefined && !textBuffer.isEmpty()) { + // Do not suggest completions if we cannot find a node at the current position + // If the document is empty, we can still suggest the root properties + return Promise.resolve(result); + } + const nodePath = nodeManager.getPathFromNode(node); let schemaNode = this.schemaNodeResolver.resolveSchemaContext(nodePath); if (schemaNode === undefined) { @@ -53,6 +59,8 @@ export class GxFormat2CompletionService { const position = textBuffer.getPosition(offset); const isPositionAfterColon = textBuffer.isPositionAfterToken(position, ":"); if (schemaNode instanceof EnumSchemaNode) { + if (schemaNode.canBeAny) return result; + schemaNode.symbols .filter((v) => v.startsWith(currentWord)) .forEach((value) => { diff --git a/server/gx-workflow-ls-format2/tests/integration/completion.test.ts b/server/gx-workflow-ls-format2/tests/integration/completion.test.ts index e1c8e81..d5b7f16 100644 --- a/server/gx-workflow-ls-format2/tests/integration/completion.test.ts +++ b/server/gx-workflow-ls-format2/tests/integration/completion.test.ts @@ -354,4 +354,30 @@ report: const completionLabels = getCompletionItemsLabels(completions); expect(completionLabels).toEqual(EXPECTED_COMPLETION_LABELS); }); + + it("should not suggest properties when the type of the property is 'Any'", async () => { + const template = ` +class: GalaxyWorkflow +creator: + $`; + const { contents, position } = parseTemplate(template); + + const completions = await getCompletions(contents, position); + + expect(completions?.items).toHaveLength(0); + }); + + it("should not suggest any properties when the indent is not correct", async () => { + const template = ` +class: GalaxyWorkflow +inputs: + My input: + $`; // Incorrect indent + + const { contents, position } = parseTemplate(template); + + const completions = await getCompletions(contents, position); + + expect(completions?.items).toHaveLength(0); + }); }); diff --git a/server/packages/yaml-language-service/src/parser/yamlDocument.ts b/server/packages/yaml-language-service/src/parser/yamlDocument.ts index 78dc7fe..26adc7c 100644 --- a/server/packages/yaml-language-service/src/parser/yamlDocument.ts +++ b/server/packages/yaml-language-service/src/parser/yamlDocument.ts @@ -111,6 +111,7 @@ export class YAMLDocument implements ParsedDocument { if (indentation === 0) return this.root; const parentIndentation = Math.max(0, indentation - this._indentation); const parentLine = this._textBuffer.findPreviousLineWithSameIndentation(offset, parentIndentation); + if (parentLine === undefined) return undefined; const parentOffset = this._textBuffer.getOffsetAt(Position.create(parentLine, parentIndentation)); const rootNode = this.root as ObjectASTNodeImpl; diff --git a/server/packages/yaml-language-service/src/utils/textBuffer.ts b/server/packages/yaml-language-service/src/utils/textBuffer.ts index b29896b..f3ad19f 100644 --- a/server/packages/yaml-language-service/src/utils/textBuffer.ts +++ b/server/packages/yaml-language-service/src/utils/textBuffer.ts @@ -97,7 +97,7 @@ export class TextBuffer { return indentation; } - public findPreviousLineWithSameIndentation(offset: number, indentation: number): number { + public findPreviousLineWithSameIndentation(offset: number, indentation: number): number | undefined { const position = this.getPosition(offset); const indentationSpaces = " ".repeat(indentation); let currentLine = position.line - 1; @@ -111,6 +111,9 @@ export class TextBuffer { currentLine--; } } + if (!found) { + return undefined; + } return currentLine; } @@ -122,4 +125,8 @@ export class TextBuffer { } return tokenIndex < position.character; } + + public isEmpty(): boolean { + return this.doc.getText().trim().length === 0; + } }