Correctly indent completion options

This commit is contained in:
Christopher Schleiden
2023-08-04 11:19:42 -07:00
parent 4ddbbc9db7
commit 4f7d03ed0c
3 changed files with 42 additions and 12 deletions
+10 -2
View File
@@ -4,8 +4,8 @@ import {complete} from "./complete";
import {registerLogger} from "./log"; import {registerLogger} from "./log";
import {getPositionFromCursor} from "./test-utils/cursor-position"; import {getPositionFromCursor} from "./test-utils/cursor-position";
import {TestLogger} from "./test-utils/logger"; import {TestLogger} from "./test-utils/logger";
import {ValueProviderConfig, ValueProviderKind} from "./value-providers/config";
import {clearCache} from "./utils/workflow-cache"; import {clearCache} from "./utils/workflow-cache";
import {ValueProviderConfig, ValueProviderKind} from "./value-providers/config";
registerLogger(new TestLogger()); registerLogger(new TestLogger());
@@ -475,7 +475,7 @@ jobs:
}); });
}); });
it("adds a new line and indentation for mapping keys", async () => { it("adds a new line and indentation for mapping keys when the key is given", async () => {
const input = "concurrency: |"; const input = "concurrency: |";
const result = await complete(...getPositionFromCursor(input)); const result = await complete(...getPositionFromCursor(input));
@@ -485,4 +485,12 @@ jobs:
]); ]);
expect(result.filter(x => x.label === "group").map(x => x.textEdit?.newText)).toEqual(["\n group: "]); expect(result.filter(x => x.label === "group").map(x => x.textEdit?.newText)).toEqual(["\n group: "]);
}); });
it("does not add new line if no key in line", async () => {
const input = "run-n|";
const result = await complete(...getPositionFromCursor(input));
expect(result.filter(x => x.label === "run-name").map(x => x.textEdit?.newText)).toEqual(["run-name: "]);
});
}); });
+2 -2
View File
@@ -24,7 +24,7 @@ import {isPlaceholder, transform} from "./utils/transform";
import {fetchOrConvertWorkflowTemplate, fetchOrParseWorkflow} from "./utils/workflow-cache"; import {fetchOrConvertWorkflowTemplate, fetchOrParseWorkflow} from "./utils/workflow-cache";
import {Value, ValueProviderConfig} from "./value-providers/config"; import {Value, ValueProviderConfig} from "./value-providers/config";
import {defaultValueProviders} from "./value-providers/default"; import {defaultValueProviders} from "./value-providers/default";
import {definitionValues} from "./value-providers/definition"; import {DefinitionValueMode, definitionValues} from "./value-providers/definition";
export function getExpressionInput(input: string, pos: number): string { export function getExpressionInput(input: string, pos: number): string {
// Find start marker around the cursor position // Find start marker around the cursor position
@@ -180,7 +180,7 @@ async function getValues(
return []; return [];
} }
const values = definitionValues(def, indentation); const values = definitionValues(def, indentation, keyToken ? DefinitionValueMode.Key : DefinitionValueMode.Parent);
return filterAndSortCompletionOptions(values, existingValues); return filterAndSortCompletionOptions(values, existingValues);
} }
@@ -9,15 +9,30 @@ import {getWorkflowSchema} from "@actions/workflow-parser/workflows/workflow-sch
import {Value} from "./config"; import {Value} from "./config";
import {stringsToValues} from "./strings-to-values"; import {stringsToValues} from "./strings-to-values";
export function definitionValues(def: Definition, indentation: string): Value[] { export enum DefinitionValueMode {
/**
* We're getting completion options for a parent token
* foo:
* ba|
*/
Parent,
/**
* We're getting completion options for a key token. For example:
* foo: |
*/
Key
}
export function definitionValues(def: Definition, indentation: string, mode: DefinitionValueMode): Value[] {
const schema = getWorkflowSchema(); const schema = getWorkflowSchema();
if (def instanceof MappingDefinition) { if (def instanceof MappingDefinition) {
return mappingValues(def, schema.definitions, indentation); return mappingValues(def, schema.definitions, indentation, mode);
} }
if (def instanceof OneOfDefinition) { if (def instanceof OneOfDefinition) {
return oneOfValues(def, schema.definitions, indentation); return oneOfValues(def, schema.definitions, indentation, mode);
} }
if (def instanceof BooleanDefinition) { if (def instanceof BooleanDefinition) {
@@ -36,7 +51,7 @@ export function definitionValues(def: Definition, indentation: string): Value[]
if (def instanceof SequenceDefinition) { if (def instanceof SequenceDefinition) {
const itemDef = schema.getDefinition(def.itemType); const itemDef = schema.getDefinition(def.itemType);
if (itemDef) { if (itemDef) {
return definitionValues(itemDef, indentation); return definitionValues(itemDef, indentation, mode);
} }
} }
@@ -46,7 +61,8 @@ export function definitionValues(def: Definition, indentation: string): Value[]
function mappingValues( function mappingValues(
mappingDefinition: MappingDefinition, mappingDefinition: MappingDefinition,
definitions: {[key: string]: Definition}, definitions: {[key: string]: Definition},
indentation: string indentation: string,
mode: DefinitionValueMode
): Value[] { ): Value[] {
const properties: Value[] = []; const properties: Value[] = [];
for (const [key, value] of Object.entries(mappingDefinition.properties)) { for (const [key, value] of Object.entries(mappingDefinition.properties)) {
@@ -73,8 +89,13 @@ function mappingValues(
case DefinitionType.String: case DefinitionType.String:
case DefinitionType.Boolean: case DefinitionType.Boolean:
insertText = `\n${indentation}${key}: `; if (mode == DefinitionValueMode.Key) {
insertText = `\n${indentation}${key}: `;
} else {
insertText = `${key}: `;
}
break; break;
default: default:
insertText = `${key}: `; insertText = `${key}: `;
} }
@@ -93,11 +114,12 @@ function mappingValues(
function oneOfValues( function oneOfValues(
oneOfDefinition: OneOfDefinition, oneOfDefinition: OneOfDefinition,
definitions: {[key: string]: Definition}, definitions: {[key: string]: Definition},
indentation: string indentation: string,
mode: DefinitionValueMode
): Value[] { ): Value[] {
const values: Value[] = []; const values: Value[] = [];
for (const key of oneOfDefinition.oneOf) { for (const key of oneOfDefinition.oneOf) {
values.push(...definitionValues(definitions[key], indentation)); values.push(...definitionValues(definitions[key], indentation, mode));
} }
return distinctValues(values); return distinctValues(values);
} }