@telorun/ide-support 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/completions/build.d.ts +2 -2
- package/dist/completions/build.d.ts.map +1 -1
- package/dist/completions/build.js +39 -64
- package/dist/completions/detect-context.d.ts +16 -43
- package/dist/completions/detect-context.d.ts.map +1 -1
- package/dist/completions/detect-context.js +63 -262
- package/dist/completions/import-source.d.ts +5 -5
- package/dist/completions/import-source.d.ts.map +1 -1
- package/dist/completions/import-source.js +15 -15
- package/dist/completions/resolve-node.d.ts +50 -0
- package/dist/completions/resolve-node.d.ts.map +1 -0
- package/dist/completions/resolve-node.js +269 -0
- package/dist/completions/valid-capabilities.d.ts +3 -0
- package/dist/completions/valid-capabilities.d.ts.map +1 -1
- package/dist/completions/valid-capabilities.js +10 -0
- package/dist/definition/build-definition.d.ts +13 -0
- package/dist/definition/build-definition.d.ts.map +1 -0
- package/dist/definition/build-definition.js +98 -0
- package/dist/definition/index.d.ts +2 -0
- package/dist/definition/index.d.ts.map +1 -0
- package/dist/definition/index.js +1 -0
- package/dist/hover/build-hover.d.ts +4 -0
- package/dist/hover/build-hover.d.ts.map +1 -0
- package/dist/hover/build-hover.js +125 -0
- package/dist/hover/index.d.ts +2 -0
- package/dist/hover/index.d.ts.map +1 -0
- package/dist/hover/index.js +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/semantic-tokens/build-semantic-tokens.d.ts +12 -0
- package/dist/semantic-tokens/build-semantic-tokens.d.ts.map +1 -0
- package/dist/semantic-tokens/build-semantic-tokens.js +55 -0
- package/dist/semantic-tokens/index.d.ts +2 -0
- package/dist/semantic-tokens/index.d.ts.map +1 -0
- package/dist/semantic-tokens/index.js +1 -0
- package/dist/types.d.ts +45 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -0
- package/package.json +2 -2
- package/src/completions/build.ts +40 -72
- package/src/completions/detect-context.ts +74 -291
- package/src/completions/import-source.ts +16 -16
- package/src/completions/resolve-node.ts +405 -0
- package/src/completions/valid-capabilities.ts +11 -0
- package/src/definition/build-definition.ts +123 -0
- package/src/definition/index.ts +1 -0
- package/src/hover/build-hover.ts +149 -0
- package/src/hover/index.ts +1 -0
- package/src/index.ts +3 -0
- package/src/semantic-tokens/build-semantic-tokens.ts +64 -0
- package/src/semantic-tokens/index.ts +1 -0
- package/src/types.ts +57 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { buildHover } from "./build-hover.js";
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildLineOffsets,
|
|
3
|
+
offsetToPosition,
|
|
4
|
+
parseToAst,
|
|
5
|
+
type AnalysisRegistry,
|
|
6
|
+
type AstDocument,
|
|
7
|
+
type AstNode,
|
|
8
|
+
} from "@telorun/analyzer";
|
|
9
|
+
import type { SemanticToken } from "../types.js";
|
|
10
|
+
import { scalarString } from "../completions/resolve-node.js";
|
|
11
|
+
import { CAPABILITY_VALUES } from "../completions/valid-capabilities.js";
|
|
12
|
+
|
|
13
|
+
const CAPABILITIES = new Set<string>(CAPABILITY_VALUES);
|
|
14
|
+
|
|
15
|
+
/** Registry-aware semantic tokens: a `kind:` value that resolves to a known
|
|
16
|
+
* definition is a `type`; a `capability:` value is an `interface`; a `!ref`
|
|
17
|
+
* target is a `variable`. Everything else (structure, CEL, tags) is left to the
|
|
18
|
+
* TextMate grammar. Ref targets are colored here rather than in the grammar
|
|
19
|
+
* because a `!ref` after a `key:` is tokenized by the bundled YAML grammar
|
|
20
|
+
* before a Telo pattern can claim it — the AST sees it unambiguously. An
|
|
21
|
+
* unresolved kind gets no token, so a typo stays uncolored — a quiet signal
|
|
22
|
+
* that pairs with the analyzer's `UNDEFINED_KIND` diagnostic. */
|
|
23
|
+
export function buildSemanticTokens(
|
|
24
|
+
text: string,
|
|
25
|
+
registry: AnalysisRegistry | undefined,
|
|
26
|
+
docs?: AstDocument[],
|
|
27
|
+
): SemanticToken[] {
|
|
28
|
+
const astDocs = docs ?? parseToAst(text);
|
|
29
|
+
const lineOffsets = buildLineOffsets(text);
|
|
30
|
+
|
|
31
|
+
const tokens: SemanticToken[] = [];
|
|
32
|
+
const emit = (node: AstNode | undefined, type: SemanticToken["type"]): void => {
|
|
33
|
+
if (!node) return;
|
|
34
|
+
const start = offsetToPosition(node.range[0], lineOffsets);
|
|
35
|
+
const end = offsetToPosition(node.range[1], lineOffsets);
|
|
36
|
+
// Kind / capability values never span lines; a clamped single-line token.
|
|
37
|
+
if (start.line !== end.line) return;
|
|
38
|
+
tokens.push({ line: start.line, character: start.character, length: end.character - start.character, type });
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const walk = (node: AstNode): void => {
|
|
42
|
+
if (node.kind === "map") {
|
|
43
|
+
for (const pair of node.entries) {
|
|
44
|
+
const key = scalarString(pair.key);
|
|
45
|
+
const value = scalarString(pair.value);
|
|
46
|
+
if (key === "kind" && value && registry?.resolveDefinition(value)) {
|
|
47
|
+
emit(pair.value, "type");
|
|
48
|
+
} else if (key === "capability" && value && CAPABILITIES.has(value)) {
|
|
49
|
+
emit(pair.value, "interface");
|
|
50
|
+
}
|
|
51
|
+
if (pair.value) walk(pair.value);
|
|
52
|
+
}
|
|
53
|
+
} else if (node.kind === "seq") {
|
|
54
|
+
for (const item of node.items) walk(item);
|
|
55
|
+
} else if (node.kind === "scalar" && node.tag === "!ref") {
|
|
56
|
+
emit(node, "variable");
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
for (const doc of astDocs) {
|
|
61
|
+
if (doc.root) walk(doc.root);
|
|
62
|
+
}
|
|
63
|
+
return tokens;
|
|
64
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { buildSemanticTokens } from "./build-semantic-tokens.js";
|
package/src/types.ts
CHANGED
|
@@ -10,10 +10,22 @@ export type {
|
|
|
10
10
|
PositionIndex,
|
|
11
11
|
} from "@telorun/analyzer";
|
|
12
12
|
|
|
13
|
-
import type {
|
|
13
|
+
import type {
|
|
14
|
+
AnalysisRegistry,
|
|
15
|
+
DiagnosticSeverity,
|
|
16
|
+
Position,
|
|
17
|
+
PositionIndex,
|
|
18
|
+
Range,
|
|
19
|
+
} from "@telorun/analyzer";
|
|
14
20
|
|
|
15
21
|
export type CompletionKind = "class" | "enumMember" | "property" | "folder" | "module" | "value";
|
|
16
22
|
|
|
23
|
+
/** A source span the host replaces wholesale when a completion is accepted. */
|
|
24
|
+
export interface ReplaceRange {
|
|
25
|
+
start: Position;
|
|
26
|
+
end: Position;
|
|
27
|
+
}
|
|
28
|
+
|
|
17
29
|
export interface CompletionResult {
|
|
18
30
|
label: string;
|
|
19
31
|
kind: CompletionKind;
|
|
@@ -24,11 +36,50 @@ export interface CompletionResult {
|
|
|
24
36
|
preselect?: boolean;
|
|
25
37
|
sortText?: string;
|
|
26
38
|
filterText?: string;
|
|
27
|
-
/** When set, the host
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
|
|
39
|
+
/** When set, the host replaces this whole source range with the accepted
|
|
40
|
+
* value — the full span of the existing node, not just the prefix up to the
|
|
41
|
+
* cursor. This overwrites any suffix after the cursor (`Sql.Co|nnection` +
|
|
42
|
+
* `Sql.Connection` → no leftover `nnection`) and cleanly replaces values
|
|
43
|
+
* containing non-word characters (`/`, `@`, `.`). A zero-width range is a
|
|
44
|
+
* pure insert. */
|
|
45
|
+
replaceRange?: ReplaceRange;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Rendered hover for the symbol under the cursor. `contents` is GitHub-flavored
|
|
49
|
+
* markdown; `range` (when present) is the source span the host underlines. */
|
|
50
|
+
export interface HoverResult {
|
|
51
|
+
contents: string;
|
|
52
|
+
range?: ReplaceRange;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Semantic token type names emitted by `buildSemanticTokens`. Kept to the
|
|
56
|
+
* standard VS Code / LSP set so hosts register them against a stock legend and
|
|
57
|
+
* every theme colors them without extra configuration. `type` marks a resolved
|
|
58
|
+
* resource kind; `interface` marks a capability value; `variable` marks a
|
|
59
|
+
* `!ref` target. */
|
|
60
|
+
export type SemanticTokenType = "type" | "interface" | "variable";
|
|
61
|
+
|
|
62
|
+
/** The legend a host registers before mapping `buildSemanticTokens` output. The
|
|
63
|
+
* numeric token-type of each `SemanticToken` is its index in this array. */
|
|
64
|
+
export const SEMANTIC_TOKEN_LEGEND: readonly SemanticTokenType[] = ["type", "interface", "variable"];
|
|
65
|
+
|
|
66
|
+
/** One absolute-positioned semantic token. Every Telo semantic token is
|
|
67
|
+
* single-line (kinds and capabilities never wrap), so a `{line, char, length}`
|
|
68
|
+
* triple is sufficient; the host encodes it into its own builder. */
|
|
69
|
+
export interface SemanticToken {
|
|
70
|
+
line: number;
|
|
71
|
+
character: number;
|
|
72
|
+
length: number;
|
|
73
|
+
type: SemanticTokenType;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Where a `!ref` target is defined — for go-to-definition. `uri` is the
|
|
77
|
+
* target file's canonical source (absolute path for local files, an http/oci
|
|
78
|
+
* URL for a registry import); `range` spans the target resource's
|
|
79
|
+
* `metadata.name` (falling back to its first line). */
|
|
80
|
+
export interface DefinitionResult {
|
|
81
|
+
uri: string;
|
|
82
|
+
range: Range;
|
|
32
83
|
}
|
|
33
84
|
|
|
34
85
|
/** A candidate module ref surfaced by the hub's `/refs` lexical autocomplete.
|