From fc87fcb11fc8fce209bca01750b8a1eab1fca788 Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Tue, 7 Feb 2023 18:35:50 -0500 Subject: [PATCH] Add a `FileProvider` to auto-completion --- actions-languageserver/src/connection.ts | 1 + actions-languageserver/src/on-completion.ts | 17 +-- .../src/complete.expressions.test.ts | 118 +++++++++--------- actions-languageservice/src/complete.test.ts | 4 +- actions-languageservice/src/complete.ts | 24 +++- 5 files changed, 90 insertions(+), 74 deletions(-) diff --git a/actions-languageserver/src/connection.ts b/actions-languageserver/src/connection.ts index d061b4e..d3c8bf9 100644 --- a/actions-languageserver/src/connection.ts +++ b/actions-languageserver/src/connection.ts @@ -119,6 +119,7 @@ export function initConnection(connection: Connection) { connection.onCompletion(async ({position, textDocument}: TextDocumentPositionParams): Promise => { return await onCompletion( + connection, position, documents.get(textDocument.uri)!, client, diff --git a/actions-languageserver/src/on-completion.ts b/actions-languageserver/src/on-completion.ts index 8be0d3b..0d0ae4f 100644 --- a/actions-languageserver/src/on-completion.ts +++ b/actions-languageserver/src/on-completion.ts @@ -1,23 +1,26 @@ import {complete} from "@github/actions-languageservice/complete"; import {Octokit} from "@octokit/rest"; -import {CompletionItem, Position} from "vscode-languageserver"; +import {CompletionItem, Connection, Position} from "vscode-languageserver"; import {TextDocument} from "vscode-languageserver-textdocument"; import {contextProviders} from "./context-providers"; +import {getFileProvider} from "./file-provider"; import {RepositoryContext} from "./initializationOptions"; import {TTLCache} from "./utils/cache"; import {valueProviders} from "./value-providers"; export async function onCompletion( + connection: Connection, position: Position, document: TextDocument, client: Octokit | undefined, repoContext: RepositoryContext | undefined, cache: TTLCache ): Promise { - return await complete( - document, - position, - repoContext && valueProviders(client, repoContext, cache), - repoContext && contextProviders(client, repoContext, cache) - ); + return await complete(document, position, { + valueProviderConfig: repoContext && valueProviders(client, repoContext, cache), + contextProviderConfig: repoContext && contextProviders(client, repoContext, cache), + fileProvider: getFileProvider(client, cache, repoContext?.workspaceUri, async path => { + return await connection.sendRequest("actions/readFile", {path}); + }) + }); } diff --git a/actions-languageservice/src/complete.expressions.test.ts b/actions-languageservice/src/complete.expressions.test.ts index fb0e65b..e9a0acf 100644 --- a/actions-languageservice/src/complete.expressions.test.ts +++ b/actions-languageservice/src/complete.expressions.test.ts @@ -59,7 +59,7 @@ describe("expressions", () => { describe("top-level auto-complete", () => { it("single region", async () => { const input = "run-name: ${{ | }}"; - const result = await complete(...getPositionFromCursor(input), undefined, undefined); + const result = await complete(...getPositionFromCursor(input)); expect(result.map(x => x.label)).toEqual([ "github", @@ -76,18 +76,16 @@ describe("expressions", () => { }); it("within parentheses", async () => { - const result = await complete( - ...getPositionFromCursor("run-name: ${{ 1 == (github.|) }}"), - undefined, + const result = await complete(...getPositionFromCursor("run-name: ${{ 1 == (github.|) }}"), { contextProviderConfig - ); + }); expect(result.map(x => x.label)).toEqual(["event"]); }); it("contains description", async () => { const input = "run-name: ${{ github.| }}"; - const result = await complete(...getPositionFromCursor(input), undefined, undefined); + const result = await complete(...getPositionFromCursor(input)); expect(result).toContainEqual({ label: "api_url", @@ -101,7 +99,7 @@ describe("expressions", () => { it("single region with existing input", async () => { const input = "run-name: ${{ g| }}"; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual([ "github", @@ -119,7 +117,7 @@ describe("expressions", () => { it("single region with existing condition", async () => { const input = "run-name: ${{ g| == 'test' }}"; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual([ "github", @@ -137,7 +135,7 @@ describe("expressions", () => { it("multiple regions with partial function", async () => { const input = "run-name: Run a ${{ inputs.test }} one-line script ${{ from|('test') == inputs.name }}"; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual([ "github", @@ -155,7 +153,7 @@ describe("expressions", () => { it("multiple regions - first region", async () => { const input = "run-name: test-${{ git| == 1 }}-${{ github.event }}"; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual([ "github", @@ -173,7 +171,7 @@ describe("expressions", () => { it("multiple regions", async () => { const input = "run-name: test-${{ github }}-${{ | }}"; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual([ "github", @@ -199,7 +197,7 @@ jobs: first line test \${{ github.| }} test2`; - const result = await complete(...getPositionFromCursor(input, 1), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input, 1), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["event"]); }); @@ -213,7 +211,7 @@ jobs: first line test \${{ github.| }} test2`; - const result = await complete(...getPositionFromCursor(input, 1), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input, 1), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["event"]); }); @@ -227,7 +225,7 @@ jobs: first line test \${{ github.| }} test2`; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["event"]); }); @@ -241,7 +239,7 @@ jobs: first line test \${{ github.| }} test2`; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["event"]); }); @@ -261,21 +259,21 @@ jobs: foo: '{}' steps: - name: "\${{ fromJSON('test') == (inputs.|) }}"`; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["test"]); }); it("nested auto-complete", async () => { const input = "run-name: ${{ github.| }}"; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["event"]); }); it("auto-complete partial", async () => { const input = "run-name: ${{ github.ev| }}"; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["event"]); }); @@ -283,7 +281,7 @@ jobs: it("using default context provider", async () => { const input = "on: push\njobs:\n build:\n runs-on: ubuntu-latest\n environment:\n url: ${{ runner.| }}\n steps:\n - run: echo"; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["arch", "name", "os", "temp", "tool_cache"]); }); @@ -298,7 +296,7 @@ jobs: runs-on: ubuntu-latest steps: - run: echo`; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["event"]); }); @@ -311,7 +309,7 @@ jobs: runs-on: ubuntu-latest steps: - run: echo`; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["event"]); }); @@ -326,7 +324,7 @@ jobs: runs-on: ubuntu-latest steps: - run: echo`; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["event"]); }); @@ -339,7 +337,7 @@ jobs: runs-on: ubuntu-latest steps: - run: echo`; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["event"]); }); @@ -355,7 +353,7 @@ jobs: steps: - run: echo if: \${{ github.| }}`; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["event"]); }); @@ -368,7 +366,7 @@ jobs: steps: - run: echo if: github.|`; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["event"]); }); @@ -388,7 +386,7 @@ jobs: with: deploy-key: \${{ secrets.| `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["GITHUB_TOKEN"]); }); @@ -412,7 +410,7 @@ jobs: steps: - run: echo "hello \${{ needs.| `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["b"]); }); @@ -431,7 +429,7 @@ jobs: steps: - run: echo "hello \${{ needs.a.| `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["outputs", "result"]); }); @@ -452,7 +450,7 @@ jobs: steps: - run: echo "hello \${{ needs.a.outputs.| `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["build_id"]); }); @@ -481,7 +479,7 @@ jobs: env: envstepb: step_b_env `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["envjobb", "envstepb", "envwf"]); }); @@ -509,7 +507,7 @@ jobs: steps: - run: echo "hello \${{ inputs.| `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["another-name", "name", "third-name"]); }); @@ -524,7 +522,7 @@ jobs: steps: - run: echo "hello \${{ inputs.| `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result).toEqual([]); }); @@ -542,7 +540,7 @@ jobs: - run: echo \${{ github.| }} `; - const result = await complete(...getPositionFromCursor(input), undefined, undefined); + const result = await complete(...getPositionFromCursor(input)); expect(result.map(x => x.label)).toContain("actor"); }); @@ -570,7 +568,7 @@ jobs: steps: - run: echo "hello \${{ github.event.inputs.| `; - const result = await complete(...getPositionFromCursor(input), undefined, undefined); + const result = await complete(...getPositionFromCursor(input)); expect(result.map(x => x.label)).toEqual(["another-name", "name", "third-name"]); }); @@ -587,7 +585,7 @@ jobs: - run: echo \${{ github.event.| }} `; - const result = await complete(...getPositionFromCursor(input), undefined, undefined); + const result = await complete(...getPositionFromCursor(input)); expect(result.map(x => x.label)).not.toContain("inputs"); expect(result.map(x => x.label)).not.toContain("schedule"); @@ -607,7 +605,7 @@ jobs: - run: echo \${{ github.event.| }} `; - const result = await complete(...getPositionFromCursor(input), undefined, undefined); + const result = await complete(...getPositionFromCursor(input)); expect(result.map(x => x.label)).toEqual(["repository", "schedule", "workflow"]); }); @@ -623,7 +621,7 @@ jobs: - run: echo \${{ github.event.| }} `; - const result = await complete(...getPositionFromCursor(input), undefined, undefined); + const result = await complete(...getPositionFromCursor(input)); // forced is part of the push event payload expect(result.map(x => x.label)).toContain("forced"); @@ -642,7 +640,7 @@ jobs: - run: echo \${{ github.event.| }} `; - const result = await complete(...getPositionFromCursor(input), undefined, undefined); + const result = await complete(...getPositionFromCursor(input)); // We don't validate github.event for workflow_call, // but there should still be auto-completion suggestions @@ -665,7 +663,7 @@ jobs: - id: c run: echo "hello \${{ steps.| `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["a", "b"]); }); @@ -681,7 +679,7 @@ jobs: run: echo hello a - run: echo "hello \${{ steps.a.| `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["conclusion", "outcome", "outputs"]); }); @@ -700,7 +698,7 @@ jobs: - id: c run: echo hello c `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["a"]); }); @@ -717,7 +715,7 @@ jobs: run: echo hello b - run: echo "hello \${{ steps.| `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["b"]); }); @@ -736,7 +734,7 @@ jobs: - run: npm test > test-job-\${{ | }}.txt `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).not.toContain("strategy"); }); @@ -757,7 +755,7 @@ jobs: - run: npm test > test-job-\${{ | }}.txt `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toContain("strategy"); }); @@ -778,7 +776,7 @@ jobs: - run: npm test > test-job-\${{ strategy.| }}.txt `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["fail-fast", "job-index", "job-total", "max-parallel"]); }); @@ -797,7 +795,7 @@ jobs: - run: npm test > test-job-\${{ | }}.txt `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).not.toContain("strategy"); }); @@ -818,7 +816,7 @@ jobs: - run: npm test > test-job-\${{ | }}.txt `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toContain("strategy"); }); @@ -841,7 +839,7 @@ jobs: node-version: \${{ matrix.| }} `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["node", "os"]); }); @@ -873,7 +871,7 @@ jobs: node-version: \${{ matrix.| }} `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["animal", "color", "fruit", "shape"]); }); @@ -894,7 +892,7 @@ jobs: node-version: \${{ matrix.| }} `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual([]); }); @@ -918,7 +916,7 @@ jobs: node-version: \${{ matrix.| }} `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["animal", "fruit"]); }); @@ -940,7 +938,7 @@ jobs: node-version: \${{ matrix.| }} `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["color"]); }); @@ -963,7 +961,7 @@ jobs: - run: echo \${{ job.| }} `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["container", "services", "status"]); }); @@ -980,7 +978,7 @@ jobs: run: echo hi `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual([ "env", "github", @@ -1014,7 +1012,7 @@ jobs: run: echo hi `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["foo"]); }); @@ -1031,7 +1029,7 @@ jobs: - run: echo \${{ job.container.| }} `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["id", "network"]); }); @@ -1051,7 +1049,7 @@ jobs: - run: echo \${{ job.services.| }} `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["nginx", "redis"]); }); @@ -1072,7 +1070,7 @@ jobs: - run: echo \${{ job.services.nginx.| }} `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.map(x => x.label)).toEqual(["id", "network", "ports"]); }); }); @@ -1089,7 +1087,7 @@ jobs: - run: echo \${{ | }}.txt `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); // Built-in function const toJSON = result.find(x => x.label === "toJson"); @@ -1121,7 +1119,7 @@ jobs: - run: echo \${{ toJS|(github.event) }} `; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), {contextProviderConfig}); expect(result.find(x => x.label === "toJson")!.insertText).toBe("toJson"); }); diff --git a/actions-languageservice/src/complete.test.ts b/actions-languageservice/src/complete.test.ts index d7ab496..5dda48e 100644 --- a/actions-languageservice/src/complete.test.ts +++ b/actions-languageservice/src/complete.test.ts @@ -192,7 +192,7 @@ jobs: } } }; - const result = await complete(...getPositionFromCursor(input), config); + const result = await complete(...getPositionFromCursor(input), {valueProviderConfig: config}); expect(result).not.toBeUndefined(); expect(result.length).toEqual(1); @@ -210,7 +210,7 @@ jobs: } } }; - const result = await complete(...getPositionFromCursor(input), config); + const result = await complete(...getPositionFromCursor(input), {valueProviderConfig: config}); expect(result).not.toBeUndefined(); expect(result.length).toEqual(1); diff --git a/actions-languageservice/src/complete.ts b/actions-languageservice/src/complete.ts index 1b888b7..8fd5eb6 100644 --- a/actions-languageservice/src/complete.ts +++ b/actions-languageservice/src/complete.ts @@ -13,6 +13,7 @@ import {TemplateToken} from "@github/actions-workflow-parser/templates/tokens/in import {MappingToken} from "@github/actions-workflow-parser/templates/tokens/mapping-token"; import {TokenType} from "@github/actions-workflow-parser/templates/tokens/types"; import {File} from "@github/actions-workflow-parser/workflows/file"; +import {FileProvider} from "@github/actions-workflow-parser/workflows/file-provider"; import {Position, TextDocument} from "vscode-languageserver-textdocument"; import {CompletionItem, CompletionItemKind, CompletionItemTag, Range, TextEdit} from "vscode-languageserver-types"; import {ContextProviderConfig} from "./context-providers/config"; @@ -43,11 +44,16 @@ export function getExpressionInput(input: string, pos: number): string { return input.substring(startPos, pos); } +export type CompletionConfig = { + valueProviderConfig?: ValueProviderConfig; + contextProviderConfig?: ContextProviderConfig; + fileProvider?: FileProvider; +}; + export async function complete( textDocument: TextDocument, position: Position, - valueProviderConfig?: ValueProviderConfig, - contextProviderConfig?: ContextProviderConfig + config?: CompletionConfig ): Promise { // Edge case: when completing a key like `foo:|`, do not calculate auto-completions const charBeforePos = textDocument.getText({ @@ -71,7 +77,15 @@ export async function complete( } const {token, keyToken, parent, path} = findToken(newPos, result.value); - const template = await convertWorkflowTemplate(result.context, result.value, ErrorPolicy.TryConversion); + const template = await convertWorkflowTemplate( + result.context, + result.value, + ErrorPolicy.TryConversion, + config?.fileProvider, + { + fetchReusableWorkflowDepth: config?.fileProvider ? 1 : 0 + } + ); const workflowContext = getWorkflowContext(textDocument.uri, template, path); // If we are inside an expression, take a different code-path. The workflow parser does not correctly create @@ -79,7 +93,7 @@ export async function complete( if (token) { if (isBasicExpression(token) || isPotentiallyExpression(token)) { const allowedContext = token.definitionInfo?.allowedContext || []; - const context = await getContext(allowedContext, contextProviderConfig, workflowContext, Mode.Completion); + const context = await getContext(allowedContext, config?.contextProviderConfig, workflowContext, Mode.Completion); return getExpressionCompletionItems(token, context, newPos); } @@ -88,7 +102,7 @@ export async function complete( const indentation = guessIndentation(newDoc, 2, true); // Use 2 spaces as default and most common for YAML const indentString = " ".repeat(indentation.tabSize); - const values = await getValues(token, keyToken, parent, valueProviderConfig, workflowContext, indentString); + const values = await getValues(token, keyToken, parent, config?.valueProviderConfig, workflowContext, indentString); let replaceRange: Range | undefined; if (token?.range) {