Files
languageservices/languageservice/src/inlay-hints.ts
T
eric scipleandGitHub d2ffb50a92 Add language service support for action.yml files (#275)
- Add validation, completion, hover, and document links for action.yml files
- Implement document type detection to route action.yml to action-specific handlers
- Add expression context for composite actions (inputs, steps, github, runner, etc.)
- Add schema validation for required fields, branding, and composite step requirements
- Support JavaScript (node20/node24), Docker, and composite action types
- Validate action references in composite action uses steps
- Add JSDoc comments to parser and template functions
- Refactor hover to use hoverToken consistently
- Fix lint errors and add return type annotations
2026-01-02 10:38:52 -06:00

63 lines
2.1 KiB
TypeScript

import {isString} from "@actions/workflow-parser";
import {getCronDescription} from "@actions/workflow-parser/model/converter/cron";
import {TemplateToken} from "@actions/workflow-parser/templates/tokens/template-token";
import {File} from "@actions/workflow-parser/workflows/file";
import {TextDocument} from "vscode-languageserver-textdocument";
import {InlayHint, InlayHintKind} from "vscode-languageserver-types";
import {isActionDocument} from "./utils/document-type.js";
import {getOrParseWorkflow} from "./utils/workflow-cache.js";
/**
* Returns inlay hints for a workflow document.
* Currently supports cron expressions, showing a human-readable description
* of the schedule inline after the cron value.
*
* @param document Text document to get inlay hints for
* @returns Array of inlay hints
*/
export function getInlayHints(document: TextDocument): InlayHint[] {
// Inlay hints are only supported for workflow files (cron expressions)
if (isActionDocument(document.uri)) {
return [];
}
const file: File = {
name: document.uri,
content: document.getText()
};
const result = getOrParseWorkflow(file, document.uri);
if (!result?.value) {
return [];
}
const hints: InlayHint[] = [];
// Traverse the workflow AST to find cron expressions
for (const [parent, token, key] of TemplateToken.traverse(result.value)) {
const validationToken = key || parent || token;
const validationDefinition = validationToken.definition;
// Check for cron-pattern tokens
if (isString(token) && token.range && validationDefinition?.key === "cron-pattern") {
const cronValue = token.value;
const description = getCronDescription(cronValue);
if (description) {
// Position the hint at the end of the cron value
hints.push({
position: {
line: token.range.end.line - 1, // Convert from 1-based to 0-based
character: token.range.end.column - 1 // Convert from 1-based to 0-based
},
label: `→ ${description}`,
kind: InlayHintKind.Parameter,
paddingLeft: true
});
}
}
}
return hints;
}