Merge pull request #59 from github/joshmgross/improve-expression-completion

Improve auto-completion for expression functions
This commit is contained in:
Josh Gross
2022-12-15 10:59:00 -05:00
committed by GitHub
4 changed files with 79 additions and 9 deletions
+2 -1
View File
@@ -39,6 +39,7 @@
},
"dependencies": {
"@github/actions-workflow-parser": "*",
"@github/actions-expressions": "*",
"vscode-languageserver-textdocument": "^1.0.7",
"vscode-languageserver-types": "^3.17.2",
"yaml": "^2.1.1"
@@ -58,4 +59,4 @@
"ts-jest": "^29.0.3",
"typescript": "^4.8.4"
}
}
}
@@ -1,4 +1,5 @@
import {data} from "@github/actions-expressions";
import {CompletionItemKind} from "vscode-languageserver-types";
import {complete, getExpressionInput} from "./complete";
import {ContextProviderConfig} from "./context-providers/config";
import {registerLogger} from "./log";
@@ -672,4 +673,53 @@ jobs:
expect(result.map(x => x.label)).toEqual(["color"]);
});
});
it("context completion items include kind and insert text", async () => {
const input = `
on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: echo \${{ | }}.txt
`;
const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig);
// Built-in function
const toJSON = result.find(x => x.label === "toJson");
expect(toJSON).toBeDefined();
expect(toJSON!.kind).toBe(CompletionItemKind.Function);
expect(toJSON!.insertText).toBe("toJson()");
// Function from context
const hashFiles = result.find(x => x.label === "hashFiles");
expect(hashFiles).toBeDefined();
expect(hashFiles!.kind).toBe(CompletionItemKind.Function);
expect(hashFiles!.insertText).toBe("hashFiles()");
// Not a function
const github = result.find(x => x.label === "github");
expect(github).toBeDefined();
expect(github!.kind).toBe(CompletionItemKind.Variable);
expect(github!.insertText).toBeUndefined();
});
it("function parentheses are not inserted when parentheses already exist", async () => {
const input = `
on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: echo \${{ toJS|(github.event) }}
`;
const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig);
expect(result.find(x => x.label === "toJson")!.insertText).toBe("toJson");
});
});
+19 -2
View File
@@ -1,4 +1,5 @@
import {complete as completeExpression} from "@github/actions-expressions";
import {CompletionItem as ExpressionCompletionItem} from "@github/actions-expressions/completion";
import {convertWorkflowTemplate, isSequence, isString, parseWorkflow} from "@github/actions-workflow-parser";
import {ErrorPolicy} from "@github/actions-workflow-parser/model/convert";
import {DefinitionType} from "@github/actions-workflow-parser/templates/schema/definition-type";
@@ -9,7 +10,7 @@ import {MappingToken} from "@github/actions-workflow-parser/templates/tokens/map
import {TokenType} from "@github/actions-workflow-parser/templates/tokens/types";
import {File} from "@github/actions-workflow-parser/workflows/file";
import {Position, TextDocument} from "vscode-languageserver-textdocument";
import {CompletionItem, CompletionItemTag, Range, TextEdit} from "vscode-languageserver-types";
import {CompletionItem, CompletionItemKind, CompletionItemTag, Range, TextEdit} from "vscode-languageserver-types";
import {ContextProviderConfig} from "./context-providers/config";
import {getContext, Mode} from "./context-providers/default";
import {getWorkflowContext, WorkflowContext} from "./context/workflow-context";
@@ -87,7 +88,9 @@ export async function complete(
const allowedContext = token.definitionInfo?.allowedContext || [];
const context = await getContext(allowedContext, contextProviderConfig, workflowContext, Mode.Completion);
return completeExpression(expressionInput, context, []);
return completeExpression(expressionInput, context, []).map(item =>
mapExpressionCompletionItem(item, currentInput[relCharPos])
);
}
}
@@ -192,3 +195,17 @@ function filterAndSortCompletionOptions(options: Value[], existingValues?: Set<s
options.sort((a, b) => a.label.localeCompare(b.label));
return options;
}
function mapExpressionCompletionItem(item: ExpressionCompletionItem, charAfterPos: string): CompletionItem {
let insertText: string | undefined;
// Insert parentheses if the cursor is after a function
// and the function does not have any parantheses already
if (item.function) {
insertText = charAfterPos === "(" ? item.label : item.label + "()";
}
return {
label: item.label,
insertText: insertText,
kind: item.function ? CompletionItemKind.Function : CompletionItemKind.Variable
};
}
+8 -6
View File
@@ -43,6 +43,7 @@
"version": "0.1.57",
"license": "MIT",
"dependencies": {
"@github/actions-expressions": "*",
"@github/actions-workflow-parser": "*",
"vscode-languageserver-textdocument": "^1.0.7",
"vscode-languageserver-types": "^3.17.2",
@@ -683,9 +684,9 @@
"dev": true
},
"node_modules/@github/actions-expressions": {
"version": "0.0.7",
"resolved": "https://npm.pkg.github.com/download/@github/actions-expressions/0.0.7/deed2be11b9f74791730303b6e33f9aca701d6a7",
"integrity": "sha512-PG8dQUafOckk/ny5O1wcUcfml5IZM8REoi7WBBY1HfpnRR7mL7gqTczQEmQWNTpoHb9f1VQK47y2hBZTOg9Y7g==",
"version": "0.0.8",
"resolved": "https://npm.pkg.github.com/download/@github/actions-expressions/0.0.8/055f455fcb0ed907f52c349b9385728aeed38f9a",
"integrity": "sha512-SPuGfnjgKAbMzJNCk4sZPAK2bxHlRXDJCk6vrwIi9VJL16Eh1YyiyM4fU9kV5EXEE5AV9aPFlZAPXu6t0mmBNw==",
"license": "MIT",
"engines": {
"node": ">= 16"
@@ -13500,9 +13501,9 @@
"dev": true
},
"@github/actions-expressions": {
"version": "0.0.7",
"resolved": "https://npm.pkg.github.com/download/@github/actions-expressions/0.0.7/deed2be11b9f74791730303b6e33f9aca701d6a7",
"integrity": "sha512-PG8dQUafOckk/ny5O1wcUcfml5IZM8REoi7WBBY1HfpnRR7mL7gqTczQEmQWNTpoHb9f1VQK47y2hBZTOg9Y7g=="
"version": "0.0.8",
"resolved": "https://npm.pkg.github.com/download/@github/actions-expressions/0.0.8/055f455fcb0ed907f52c349b9385728aeed38f9a",
"integrity": "sha512-SPuGfnjgKAbMzJNCk4sZPAK2bxHlRXDJCk6vrwIi9VJL16Eh1YyiyM4fU9kV5EXEE5AV9aPFlZAPXu6t0mmBNw=="
},
"@github/actions-languageserver": {
"version": "file:actions-languageserver",
@@ -13524,6 +13525,7 @@
"@github/actions-languageservice": {
"version": "file:actions-languageservice",
"requires": {
"@github/actions-expressions": "*",
"@github/actions-workflow-parser": "*",
"@types/jest": "^29.0.3",
"jest": "^29.0.3",