Complete multi-segment expressions

This commit is contained in:
Beth Brennan
2023-02-07 17:04:47 -05:00
parent 6e236514d5
commit b432867548
7 changed files with 39 additions and 15 deletions
@@ -262,6 +262,13 @@ jobs:
expect(result.map(x => x.label)).toEqual(["event"]);
});
it("auto-complete complex partial", async () => {
const input = 'run-name: "run ${{ github.ev| }} run"';
const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig);
expect(result.map(x => x.label)).toEqual(["event"]);
});
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";
+4 -6
View File
@@ -205,20 +205,18 @@ function getExpressionCompletionItems(
context: DescriptionDictionary,
pos: Position
): CompletionItem[] {
let expressionInput = "";
let currentInput = "";
let relCharPos: number = 0;
if (isBasicExpression(token)) {
expressionInput = currentInput = token.expression;
relCharPos = getRelCharPos(token.range!, expressionInput, pos);
currentInput = token.source || token.expression;
} else {
const stringToken = token.assertString("Expected string token for expression completion");
currentInput = stringToken.source || stringToken.value;
relCharPos = getRelCharPos(stringToken.range!, currentInput, pos);
expressionInput = (getExpressionInput(currentInput, relCharPos) || "").trim();
}
const relCharPos = getRelCharPos(token.range!, currentInput, pos);
const expressionInput = (getExpressionInput(currentInput, relCharPos) || "").trim();
try {
return completeExpression(expressionInput, context, [], validatorFunctions).map(item =>
mapExpressionCompletionItem(item, currentInput[relCharPos])
@@ -45,7 +45,7 @@ function stringToToken(value: string) {
}
function expressionToToken(expr: string) {
return new BasicExpressionToken(undefined, undefined, expr, undefined, undefined);
return new BasicExpressionToken(undefined, undefined, expr, undefined, undefined, expr);
}
function contextFromStrategy(strategy?: TemplateToken) {
@@ -111,7 +111,7 @@ function convertJob(context: TemplateContext, jobKey: StringToken, token: Mappin
id: jobKey,
name: undefined,
needs: undefined,
if: new BasicExpressionToken(undefined, undefined, "success()", undefined, undefined),
if: new BasicExpressionToken(undefined, undefined, "success()", undefined, undefined, "success()"),
env: undefined,
concurrency: undefined,
environment: undefined,
@@ -52,7 +52,7 @@ function convertStep(context: TemplateContext, idBuilder: IdBuilder, step: Templ
let uses: StringToken | undefined;
let continueOnError: boolean | undefined;
let env: MappingToken | undefined;
const ifCondition = new BasicExpressionToken(undefined, undefined, "success()", undefined, undefined);
const ifCondition = new BasicExpressionToken(undefined, undefined, "success()", undefined, undefined, "success()");
for (const item of mapping) {
const key = item.key.assertString("steps item key");
switch (key.value) {
@@ -606,8 +606,9 @@ class TemplateReader {
this._fileId,
token.range,
`format('${format.join("")}'${args.join("")})`,
token.definitionInfo,
expressionTokens
definitionInfo,
expressionTokens,
raw
);
}
@@ -667,7 +668,7 @@ class TemplateReader {
// Return the expression
return <ParseExpressionResult>{
expression: new BasicExpressionToken(this._fileId, range, trimmed, definitionInfo, undefined),
expression: new BasicExpressionToken(this._fileId, range, trimmed, definitionInfo, undefined, value),
error: undefined
};
}
@@ -13,6 +13,8 @@ export class BasicExpressionToken extends ExpressionToken {
public readonly originalExpressions: BasicExpressionToken[] | undefined;
public readonly source: string;
/**
* @param originalExpressions If the basic expression was transformed from individual expressions, these will be the original ones
*/
@@ -21,11 +23,13 @@ export class BasicExpressionToken extends ExpressionToken {
range: TokenRange | undefined,
expression: string,
definitionInfo: DefinitionInfo | undefined,
originalExpressions: BasicExpressionToken[] | undefined
originalExpressions: BasicExpressionToken[] | undefined,
source: string
) {
super(TokenType.BasicExpression, file, range, undefined, definitionInfo);
this.expr = expression;
this.originalExpressions = originalExpressions;
this.source = source;
}
public get expression(): string {
@@ -34,8 +38,22 @@ export class BasicExpressionToken extends ExpressionToken {
public override clone(omitSource?: boolean): TemplateToken {
return omitSource
? new BasicExpressionToken(undefined, undefined, this.expr, this.definitionInfo, this.originalExpressions)
: new BasicExpressionToken(this.file, this.range, this.expr, this.definitionInfo, this.originalExpressions);
? new BasicExpressionToken(
undefined,
undefined,
this.expr,
this.definitionInfo,
this.originalExpressions,
this.source
)
: new BasicExpressionToken(
this.file,
this.range,
this.expr,
this.definitionInfo,
this.originalExpressions,
this.source
);
}
public override toString(): string {