@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.
Files changed (53) hide show
  1. package/dist/completions/build.d.ts +2 -2
  2. package/dist/completions/build.d.ts.map +1 -1
  3. package/dist/completions/build.js +39 -64
  4. package/dist/completions/detect-context.d.ts +16 -43
  5. package/dist/completions/detect-context.d.ts.map +1 -1
  6. package/dist/completions/detect-context.js +63 -262
  7. package/dist/completions/import-source.d.ts +5 -5
  8. package/dist/completions/import-source.d.ts.map +1 -1
  9. package/dist/completions/import-source.js +15 -15
  10. package/dist/completions/resolve-node.d.ts +50 -0
  11. package/dist/completions/resolve-node.d.ts.map +1 -0
  12. package/dist/completions/resolve-node.js +269 -0
  13. package/dist/completions/valid-capabilities.d.ts +3 -0
  14. package/dist/completions/valid-capabilities.d.ts.map +1 -1
  15. package/dist/completions/valid-capabilities.js +10 -0
  16. package/dist/definition/build-definition.d.ts +13 -0
  17. package/dist/definition/build-definition.d.ts.map +1 -0
  18. package/dist/definition/build-definition.js +98 -0
  19. package/dist/definition/index.d.ts +2 -0
  20. package/dist/definition/index.d.ts.map +1 -0
  21. package/dist/definition/index.js +1 -0
  22. package/dist/hover/build-hover.d.ts +4 -0
  23. package/dist/hover/build-hover.d.ts.map +1 -0
  24. package/dist/hover/build-hover.js +125 -0
  25. package/dist/hover/index.d.ts +2 -0
  26. package/dist/hover/index.d.ts.map +1 -0
  27. package/dist/hover/index.js +1 -0
  28. package/dist/index.d.ts +3 -0
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +3 -0
  31. package/dist/semantic-tokens/build-semantic-tokens.d.ts +12 -0
  32. package/dist/semantic-tokens/build-semantic-tokens.d.ts.map +1 -0
  33. package/dist/semantic-tokens/build-semantic-tokens.js +55 -0
  34. package/dist/semantic-tokens/index.d.ts +2 -0
  35. package/dist/semantic-tokens/index.d.ts.map +1 -0
  36. package/dist/semantic-tokens/index.js +1 -0
  37. package/dist/types.d.ts +45 -6
  38. package/dist/types.d.ts.map +1 -1
  39. package/dist/types.js +3 -0
  40. package/package.json +2 -2
  41. package/src/completions/build.ts +40 -72
  42. package/src/completions/detect-context.ts +74 -291
  43. package/src/completions/import-source.ts +16 -16
  44. package/src/completions/resolve-node.ts +405 -0
  45. package/src/completions/valid-capabilities.ts +11 -0
  46. package/src/definition/build-definition.ts +123 -0
  47. package/src/definition/index.ts +1 -0
  48. package/src/hover/build-hover.ts +149 -0
  49. package/src/hover/index.ts +1 -0
  50. package/src/index.ts +3 -0
  51. package/src/semantic-tokens/build-semantic-tokens.ts +64 -0
  52. package/src/semantic-tokens/index.ts +1 -0
  53. package/src/types.ts +57 -6
@@ -0,0 +1 @@
1
+ export { buildHover } from "./build-hover.js";
package/src/index.ts CHANGED
@@ -1,3 +1,6 @@
1
1
  export * from "./types.js";
2
2
  export * from "./completions/index.js";
3
3
  export * from "./diagnostics/index.js";
4
+ export * from "./hover/index.js";
5
+ export * from "./semantic-tokens/index.js";
6
+ export * from "./definition/index.js";
@@ -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 { AnalysisRegistry, DiagnosticSeverity, PositionIndex, Range } from "@telorun/analyzer";
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 should replace text from this 0-based column on the
28
- * cursor's line up to the cursor. Required when the completion value
29
- * contains non-word characters (`/`, `@`, `.`) that the host's default
30
- * word boundary would not include in the replaced range. */
31
- replaceFromColumn?: number;
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.