diff --git a/actions-expressions/src/completion.test.ts b/actions-expressions/src/completion.test.ts index 810cd44..64e9283 100644 --- a/actions-expressions/src/completion.test.ts +++ b/actions-expressions/src/completion.test.ts @@ -70,6 +70,12 @@ describe("auto-complete", () => { }); }); + describe("in multi-line expressions", () => { + it("includes built-in functions", () => { + expect(testComplete("1 == (\nto").map(x => x.label)).toContainEqual("toJson"); + }); + }); + describe("for contexts", () => { it("provides suggestions for env", () => { const expected = completionItems("BAR_TEST", "FOO"); diff --git a/actions-languageservice/src/utils/transform.test.ts b/actions-languageservice/src/utils/transform.test.ts index ba4d85d..db91c60 100644 --- a/actions-languageservice/src/utils/transform.test.ts +++ b/actions-languageservice/src/utils/transform.test.ts @@ -37,7 +37,7 @@ jobs: jobs: build: runs-on: - - dummy`); + - key`); expect(newPos.character).toEqual(9); }); @@ -53,7 +53,23 @@ jobs: jobs: build: runs-on: - dummy:`); + key:`); expect(newPos.character).toEqual(7); }); + + it("does not transform expression lines", () => { + const [doc, pos] = getPositionFromCursor(`on: push +jobs: + build: + runs-on: + \${{ github| }}`); + const [newDoc, newPos] = transform(doc, pos); + + expect(newDoc.getText()).toEqual(`on: push +jobs: + build: + runs-on: + \${{ github }}`); + expect(newPos.character).toEqual(16); + }); }); diff --git a/actions-languageservice/src/utils/transform.ts b/actions-languageservice/src/utils/transform.ts index 015f709..a71ef9e 100644 --- a/actions-languageservice/src/utils/transform.ts +++ b/actions-languageservice/src/utils/transform.ts @@ -1,7 +1,7 @@ import {Position, TextDocument} from "vscode-languageserver-textdocument"; import {Range} from "vscode-languageserver-types"; -const DUMMY_KEY = "dummy"; +const PLACEHOLDER_KEY = "key"; // Transform a document to work around YAML parsing issues // Based on `_transform` in https://github.com/cschleiden/github-actions-parser/blob/main/src/lib/parser/complete.ts#L311 @@ -27,29 +27,33 @@ export function transform(doc: TextDocument, pos: Position): [TextDocument, Posi // Special case for Actions, if this line contains an expression marker, do _not_ transform. This is // an ugly fix for auto-completion in multi-line YAML strings. At this point in the process, we cannot // determine if a line is in such a multi-line string. - if (line.indexOf("${{") === -1) { - const colon = line.indexOf(":"); - if (colon === -1) { - const trimmedLine = line.trim(); - if (trimmedLine === "" || trimmedLine === "-") { - // Node in sequence or empty line - let spacer = ""; - if (trimmedLine === "-" && !line.endsWith(" ")) { - spacer = " "; - offset++; - } + if (line.indexOf("${{") !== -1) { + return [doc, pos]; + } - line = - line.substring(0, linePos) + spacer + DUMMY_KEY + (trimmedLine === "-" ? "" : ":") + line.substring(linePos); - - // Adjust pos by one to prevent a sequence node being marked as active + const containsColon = line.indexOf(":") !== -1; + if (!containsColon) { + const trimmedLine = line.trim(); + if (trimmedLine === "" || trimmedLine === "-") { + // Pos in sequence or empty line + let spacer = ""; + if (trimmedLine === "-" && !line.endsWith(" ")) { + spacer = " "; offset++; - } else if (!trimmedLine.startsWith("-")) { - // Add `:` to end of line - line = line + ":"; } - } else { - offset = offset - 1; + + line = + line.substring(0, linePos) + + spacer + + PLACEHOLDER_KEY + + (trimmedLine === "-" ? "" : ":") + + line.substring(linePos); + + // Adjust pos by one to prevent a sequence node being marked as active + offset++; + } else if (!trimmedLine.startsWith("-")) { + // Add `:` to end of line + line = line + ":"; } }