From 2eb53df976a084fd81a1278a877ccc6ddf07a188 Mon Sep 17 00:00:00 2001 From: eric sciple Date: Mon, 22 Dec 2025 07:02:58 -0600 Subject: [PATCH] Fix one-of property completions to insert value on next line (#262) When completing a one-of typed property in key mode (e.g., 'check_run: ty|'), insert newline and indentation to produce valid YAML structure instead of inserting just the key name which creates invalid YAML. --- languageservice/src/complete.test.ts | 20 +++++++++++++++++-- .../src/value-providers/definition.ts | 6 +++--- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/languageservice/src/complete.test.ts b/languageservice/src/complete.test.ts index 5d56f03..bdd078d 100644 --- a/languageservice/src/complete.test.ts +++ b/languageservice/src/complete.test.ts @@ -510,11 +510,27 @@ jobs: expect(result.filter(x => x.label === "types").map(x => x.textEdit?.newText)).toEqual(["types: "]); }); - it("does not add : for one-of in key mode", async () => { + it("adds newline and indentation for one-of in key mode", async () => { const input = "on:\n check_run: ty|"; const result = await complete(...getPositionFromCursor(input)); - expect(result.filter(x => x.label === "types").map(x => x.textEdit?.newText)).toEqual(["types"]); + // When completing a one-of property in key mode (after colon on same line), + // insert newline + indentation + key + colon to create valid YAML structure + expect(result.filter(x => x.label === "types").map(x => x.textEdit?.newText)).toEqual(["\n types: "]); + }); + + it("handles mixed string and mapping completions for one-of in key mode", async () => { + const input = "on: push\npermissions: |"; + + const result = await complete(...getPositionFromCursor(input)); + + // String values (read-all, write-all) should insert directly without newline + expect(result.filter(x => x.label === "read-all").map(x => x.textEdit?.newText)).toEqual(["read-all"]); + expect(result.filter(x => x.label === "write-all").map(x => x.textEdit?.newText)).toEqual(["write-all"]); + + // Mapping keys with one-of types should insert with newline and indentation + expect(result.filter(x => x.label === "actions").map(x => x.textEdit?.newText)).toEqual(["\n actions: "]); + expect(result.filter(x => x.label === "contents").map(x => x.textEdit?.newText)).toEqual(["\n contents: "]); }); }); diff --git a/languageservice/src/value-providers/definition.ts b/languageservice/src/value-providers/definition.ts index 2b16f3e..99137a3 100644 --- a/languageservice/src/value-providers/definition.ts +++ b/languageservice/src/value-providers/definition.ts @@ -92,10 +92,10 @@ function mappingValues( break; case DefinitionType.OneOf: - if (mode == DefinitionValueMode.Parent) { - insertText = `${key}: `; + if (mode == DefinitionValueMode.Key) { + insertText = `\n${indentation}${key}: `; } else { - // No special insertText in this case + insertText = `${key}: `; } break;