Skip to content

Commit 1116f79

Browse files
committed
Address PR review: rename files, move position calculation to quickfix
- Rename index.ts files to follow repo patterns: - code-actions/index.ts → code-actions/code-actions.ts - code-actions/quickfix/index.ts → quickfix/quickfix-providers.ts - Move position calculation from validation to quickfix: - MissingInputsDiagnosticData now passes raw token ranges - Quickfix computes insertion position and indentation at code action time - detectIndentSize moved from validate.ts to validate-action-reference.ts
1 parent 1ba0f24 commit 1116f79

8 files changed

Lines changed: 197 additions & 123 deletions

File tree

languageservice/src/code-actions/index.ts renamed to languageservice/src/code-actions/code-actions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {FeatureFlags} from "@actions/expressions";
22
import {CodeAction, CodeActionKind, Diagnostic} from "vscode-languageserver-types";
33
import {CodeActionContext, CodeActionProvider} from "./types.js";
4-
import {getQuickfixProviders} from "./quickfix/index.js";
4+
import {getQuickfixProviders} from "./quickfix/quickfix-providers.js";
55

66
export interface CodeActionParams {
77
uri: string;
Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {CodeAction, TextEdit} from "vscode-languageserver-types";
1+
import {CodeAction, Position, TextEdit} from "vscode-languageserver-types";
22
import {CodeActionProvider} from "../types.js";
33
import {DiagnosticCode, MissingInputsDiagnosticData} from "../../validate-action-reference.js";
44

@@ -12,7 +12,7 @@ export const addMissingInputsProvider: CodeActionProvider = {
1212
}
1313

1414
const edits = createInputEdits(data);
15-
if (!edits) {
15+
if (!edits || edits.length === 0) {
1616
return undefined;
1717
}
1818

@@ -29,37 +29,77 @@ export const addMissingInputsProvider: CodeActionProvider = {
2929
}
3030
};
3131

32+
/**
33+
* Calculate insert position and indentation, then generate edits for missing inputs.
34+
* Position calculation is done here in the quickfix rather than during validation.
35+
*/
3236
function createInputEdits(data: MissingInputsDiagnosticData): TextEdit[] {
33-
const edits: TextEdit[] = [];
34-
3537
const formatInputLines = (indent: string) =>
3638
data.missingInputs.map(input => {
3739
const value = input.default ?? '""';
3840
return `${indent}${input.name}: ${value}`;
3941
});
4042

41-
if (data.hasWithKey && data.withIndent !== undefined) {
42-
// `with:` exists - use its indentation + 2 for inputs
43-
const inputIndent = " ".repeat(data.withIndent + data.indentSize);
43+
if (data.withInfo) {
44+
// `with:` exists - calculate indentation from existing structure
45+
const withIndent = data.withInfo.keyRange.start.column - 1; // 0-indexed
46+
const indentSize = data.withInfo.firstChildColumn
47+
? data.withInfo.firstChildColumn - data.withInfo.keyRange.start.column
48+
: data.indentSize;
49+
50+
const inputIndent = " ".repeat(withIndent + indentSize);
4451
const inputLines = formatInputLines(inputIndent);
4552

46-
edits.push({
47-
range: {start: data.insertPosition, end: data.insertPosition},
48-
newText: inputLines.map(line => line + "\n").join("")
49-
});
53+
// Calculate insert position
54+
const insertPosition = calculateWithInsertPosition(data.withInfo);
55+
56+
return [
57+
{
58+
range: {start: insertPosition, end: insertPosition},
59+
newText: inputLines.map(line => line + "\n").join("")
60+
}
61+
];
5062
} else {
51-
// No `with:` key - `with:` at step indentation, inputs at step indentation + 2
52-
const withIndent = " ".repeat(data.stepIndent);
53-
const inputIndent = " ".repeat(data.stepIndent + data.indentSize);
63+
// No `with:` key - add `with:` at the same level as other step keys (e.g., "uses")
64+
const firstKeyColumn = data.firstStepKeyColumn ?? data.stepRange.start.column;
65+
const withKeyIndent = firstKeyColumn - 1; // 0-indexed (columns are 1-based)
66+
67+
const withIndent = " ".repeat(withKeyIndent);
68+
const inputIndent = " ".repeat(withKeyIndent + data.indentSize);
5469
const inputLines = formatInputLines(inputIndent);
5570

5671
const newText = `${withIndent}with:\n` + inputLines.map(line => `${line}\n`).join("");
5772

58-
edits.push({
59-
range: {start: data.insertPosition, end: data.insertPosition},
60-
newText
61-
});
73+
// Insert at end of step (before the line after the step ends)
74+
const insertPosition: Position = {
75+
line: data.stepRange.end.line - 1,
76+
character: 0
77+
};
78+
79+
return [
80+
{
81+
range: {start: insertPosition, end: insertPosition},
82+
newText
83+
}
84+
];
6285
}
86+
}
6387

64-
return edits;
88+
/**
89+
* Calculate where to insert new inputs when `with:` already exists.
90+
*/
91+
function calculateWithInsertPosition(withInfo: NonNullable<MissingInputsDiagnosticData["withInfo"]>): Position {
92+
if (withInfo.hasChildren) {
93+
// Insert after the last child (at end of with: block)
94+
return {
95+
line: withInfo.valueRange.end.line - 1,
96+
character: 0
97+
};
98+
} else {
99+
// Empty with: block - insert on the next line after with:
100+
return {
101+
line: withInfo.keyRange.end.line,
102+
character: 0
103+
};
104+
}
65105
}

languageservice/src/code-actions/quickfix/index.ts renamed to languageservice/src/code-actions/quickfix/quickfix-providers.ts

File renamed without changes.

languageservice/src/code-actions/tests/runner.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {TextEdit} from "vscode-languageserver-types";
44
import {TextDocument} from "vscode-languageserver-textdocument";
55
import {FeatureFlags} from "@actions/expressions";
66
import {validate, ValidationConfig} from "../../validate.js";
7-
import {getCodeActions, CodeActionParams} from "../index.js";
7+
import {getCodeActions, CodeActionParams} from "../code-actions.js";
88

99
// Marker pattern: # want "diagnostic message" fix="code-action-name"
1010
const MARKER_PATTERN = /#\s*want\s+"([^"]+)"(?:\s+fix="([^"]+)")?/;

languageservice/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ export {getInlayHints} from "./inlay-hints.js";
66
export {Logger, LogLevel, registerLogger, setLogLevel} from "./log.js";
77
export {validate, ValidationConfig, ActionsMetadataProvider} from "./validate.js";
88
export {ValueProviderConfig, ValueProviderKind} from "./value-providers/config.js";
9-
export {getCodeActions, CodeActionParams} from "./code-actions/index.js";
9+
export {getCodeActions, CodeActionParams} from "./code-actions/code-actions.js";

languageservice/src/validate-action-reference.test.ts

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -257,20 +257,30 @@ jobs:
257257
owner: "actions",
258258
ref: "v1"
259259
},
260-
hasWithKey: true,
261-
indentSize: 2,
262-
insertPosition: {
263-
character: 0,
264-
line: 9
265-
},
266260
missingInputs: [
267261
{
268262
default: undefined,
269263
name: "path"
270264
}
271265
],
272-
stepIndent: 6,
273-
withIndent: 6
266+
stepRange: {
267+
start: {line: 7, column: 7},
268+
end: {line: 10, column: 1}
269+
},
270+
firstStepKeyColumn: 7,
271+
indentSize: 2,
272+
withInfo: {
273+
keyRange: {
274+
start: {line: 8, column: 7},
275+
end: {line: 8, column: 11}
276+
},
277+
valueRange: {
278+
start: {line: 9, column: 9},
279+
end: {line: 10, column: 1}
280+
},
281+
hasChildren: true,
282+
firstChildColumn: 9
283+
}
274284
}
275285
}
276286
]);
@@ -324,12 +334,6 @@ jobs:
324334
owner: "actions",
325335
ref: "v1"
326336
},
327-
hasWithKey: true,
328-
indentSize: 2,
329-
insertPosition: {
330-
character: 0,
331-
line: 9
332-
},
333337
missingInputs: [
334338
{
335339
default: undefined,
@@ -340,8 +344,24 @@ jobs:
340344
name: "key"
341345
}
342346
],
343-
stepIndent: 6,
344-
withIndent: 6
347+
stepRange: {
348+
start: {line: 7, column: 7},
349+
end: {line: 10, column: 1}
350+
},
351+
firstStepKeyColumn: 7,
352+
indentSize: 2,
353+
withInfo: {
354+
keyRange: {
355+
start: {line: 8, column: 7},
356+
end: {line: 8, column: 11}
357+
},
358+
valueRange: {
359+
start: {line: 9, column: 9},
360+
end: {line: 10, column: 1}
361+
},
362+
hasChildren: true,
363+
firstChildColumn: 9
364+
}
345365
}
346366
}
347367
]);
@@ -379,12 +399,6 @@ jobs:
379399
owner: "actions",
380400
ref: "v1"
381401
},
382-
hasWithKey: false,
383-
indentSize: 2,
384-
insertPosition: {
385-
character: 0,
386-
line: 7
387-
},
388402
missingInputs: [
389403
{
390404
default: undefined,
@@ -395,8 +409,12 @@ jobs:
395409
name: "key"
396410
}
397411
],
398-
stepIndent: 6,
399-
withIndent: undefined
412+
stepRange: {
413+
start: {line: 7, column: 7},
414+
end: {line: 8, column: 1}
415+
},
416+
firstStepKeyColumn: 7,
417+
indentSize: 2
400418
}
401419
}
402420
]);

0 commit comments

Comments
 (0)