@px-lsp/server 0.1.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 (163) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +334 -0
  3. package/THIRD-PARTY-NOTICES.md +83 -0
  4. package/data/ck3/dataTypes.json +2195 -0
  5. package/data/ck3/data_types/data_types_common.txt +2040 -0
  6. package/data/ck3/data_types/data_types_gui.txt +5264 -0
  7. package/data/ck3/data_types/data_types_internalclausewitzgui.txt +14843 -0
  8. package/data/ck3/data_types/data_types_script.txt +4251 -0
  9. package/data/ck3/data_types/data_types_uncategorized.txt +109984 -0
  10. package/data/ck3/freqs.json +1 -0
  11. package/data/ck3/guiSchema.json +6344 -0
  12. package/data/ck3/script_docs/effects.log +16059 -0
  13. package/data/ck3/script_docs/event_targets.log +2098 -0
  14. package/data/ck3/script_docs/modifiers.log +2228 -0
  15. package/data/ck3/script_docs/on_actions.log +5275 -0
  16. package/data/ck3/script_docs/triggers.log +11991 -0
  17. package/data/ck3/structures.json +9743 -0
  18. package/data/ck3/wikidocs/ATTRIBUTION.md +18 -0
  19. package/data/ck3/wikidocs/Data_types.md +2568 -0
  20. package/data/ck3/wikidocs/Effects_list.md +1176 -0
  21. package/data/ck3/wikidocs/Scopes_list.md +341 -0
  22. package/data/ck3/wikidocs/Triggers_list.md +1097 -0
  23. package/data/eu5/data_types/data_types_common.txt +2087 -0
  24. package/data/eu5/data_types/data_types_gui.txt +6732 -0
  25. package/data/eu5/data_types/data_types_internalclausewitzgui.txt +19276 -0
  26. package/data/eu5/data_types/data_types_script.txt +5688 -0
  27. package/data/eu5/data_types/data_types_uncategorized.txt +135569 -0
  28. package/data/vic3/data_types/data_types_common.txt +2021 -0
  29. package/data/vic3/data_types/data_types_gui.txt +5592 -0
  30. package/data/vic3/data_types/data_types_internalclausewitzgui.txt +17304 -0
  31. package/data/vic3/data_types/data_types_script.txt +2817 -0
  32. package/data/vic3/data_types/data_types_uncategorized.txt +84354 -0
  33. package/data/vic3/freqs.json +1 -0
  34. package/data/vic3/guiSchema.json +5578 -0
  35. package/data/vic3/script_docs/effects.log +38135 -0
  36. package/data/vic3/script_docs/event_targets.log +2028 -0
  37. package/data/vic3/script_docs/modifiers.log +18954 -0
  38. package/data/vic3/script_docs/on_actions.log +1561 -0
  39. package/data/vic3/script_docs/triggers.log +15738 -0
  40. package/data/vic3/structures.json +10189 -0
  41. package/dist/server.js +63668 -0
  42. package/media/px-lsp.svg +12 -0
  43. package/package.json +50 -0
  44. package/src/clientMode.ts +60 -0
  45. package/src/coa/coa.ts +184 -0
  46. package/src/coa/coaParse.ts +267 -0
  47. package/src/context.ts +78 -0
  48. package/src/contextKeywords.ts +224 -0
  49. package/src/data/dataBindingMacros.ts +82 -0
  50. package/src/data/dataFnDocs.ts +152 -0
  51. package/src/data/dataFnUsage.ts +431 -0
  52. package/src/data/dataTypes.ts +279 -0
  53. package/src/data/defines.ts +123 -0
  54. package/src/data/docsParser.ts +453 -0
  55. package/src/data/keywordDocs.ts +98 -0
  56. package/src/data/modifierTemplates.ts +143 -0
  57. package/src/data/textFormatting.ts +165 -0
  58. package/src/data/wikiDocs.ts +187 -0
  59. package/src/dds/decoder.ts +1007 -0
  60. package/src/dds/encode.ts +235 -0
  61. package/src/dds/index.ts +58 -0
  62. package/src/dds/png.ts +96 -0
  63. package/src/dds/tga.ts +62 -0
  64. package/src/documents.ts +35 -0
  65. package/src/features/assetPaths.ts +169 -0
  66. package/src/features/codeActions.ts +148 -0
  67. package/src/features/colors.ts +244 -0
  68. package/src/features/completion.ts +961 -0
  69. package/src/features/datafunction.ts +729 -0
  70. package/src/features/definition.ts +84 -0
  71. package/src/features/diagnostics.ts +244 -0
  72. package/src/features/folding.ts +106 -0
  73. package/src/features/formatting.ts +60 -0
  74. package/src/features/guiLanguage.ts +366 -0
  75. package/src/features/guiNavigation.ts +140 -0
  76. package/src/features/guiTree.ts +97 -0
  77. package/src/features/hover.ts +817 -0
  78. package/src/features/hoverRender.ts +222 -0
  79. package/src/features/inlayHints.ts +147 -0
  80. package/src/features/locFormatting.ts +127 -0
  81. package/src/features/references.ts +70 -0
  82. package/src/features/rename.ts +135 -0
  83. package/src/features/scopeAt.ts +65 -0
  84. package/src/features/semanticTokens.ts +188 -0
  85. package/src/features/signatureHelp.ts +72 -0
  86. package/src/features/symbols.ts +241 -0
  87. package/src/features/textureHover.ts +143 -0
  88. package/src/features/workspaceSymbols.ts +69 -0
  89. package/src/games/active.ts +19 -0
  90. package/src/games/ck3/ambientScopes.ts +273 -0
  91. package/src/games/ck3/index.ts +38 -0
  92. package/src/games/ck3/meta.ts +28 -0
  93. package/src/games/ck3/modifierPlaceholders.ts +61 -0
  94. package/src/games/ck3/saveSchema.ts +134 -0
  95. package/src/games/ck3/scaffolds.ts +197 -0
  96. package/src/games/ck3/schema.ts +422 -0
  97. package/src/games/ck3/structures.ts +887 -0
  98. package/src/games/eu5/index.ts +75 -0
  99. package/src/games/eu5/meta.ts +44 -0
  100. package/src/games/eu5/scaffolds.ts +49 -0
  101. package/src/games/eu5/schema.generated.ts +1043 -0
  102. package/src/games/jomini/variables.ts +134 -0
  103. package/src/games/profile.ts +205 -0
  104. package/src/games/registry.ts +27 -0
  105. package/src/games/vic3/index.ts +52 -0
  106. package/src/games/vic3/meta.ts +55 -0
  107. package/src/games/vic3/saveSchema.ts +77 -0
  108. package/src/games/vic3/scaffolds.ts +135 -0
  109. package/src/games/vic3/schema.ts +650 -0
  110. package/src/games/vic3/structures.ts +33 -0
  111. package/src/gui/anchorSpec.ts +66 -0
  112. package/src/gui/declMarkers.ts +30 -0
  113. package/src/gui/fillGeometry.ts +101 -0
  114. package/src/gui/guiDefs.ts +386 -0
  115. package/src/gui/guiDependencies.ts +352 -0
  116. package/src/gui/guiLinks.ts +64 -0
  117. package/src/gui/layoutEngine.ts +1998 -0
  118. package/src/gui/layoutService.ts +221 -0
  119. package/src/gui/measuredMetrics.ts +21 -0
  120. package/src/gui/previewService.ts +89 -0
  121. package/src/gui/saveSchema.ts +220 -0
  122. package/src/gui/saveValues.ts +399 -0
  123. package/src/gui/saveZip.ts +60 -0
  124. package/src/gui/sourceEdit.ts +535 -0
  125. package/src/gui/sourceEditService.ts +439 -0
  126. package/src/gui/sourceModel.ts +603 -0
  127. package/src/gui/textResolve.ts +145 -0
  128. package/src/gui/textureInfo.ts +106 -0
  129. package/src/gui/vocabulary.ts +149 -0
  130. package/src/gui/widgetEdit.ts +52 -0
  131. package/src/gui/widgetInfo.ts +245 -0
  132. package/src/index/docComments.ts +103 -0
  133. package/src/index/extract.ts +252 -0
  134. package/src/index/indexer.ts +369 -0
  135. package/src/index/intern.ts +101 -0
  136. package/src/index/lazyRefs.ts +145 -0
  137. package/src/index/modOrigin.ts +69 -0
  138. package/src/index/references.ts +534 -0
  139. package/src/overview/dependencies.ts +240 -0
  140. package/src/overview/eventBanner.ts +95 -0
  141. package/src/overview/eventDetail.ts +482 -0
  142. package/src/overview/eventGraph.ts +617 -0
  143. package/src/overview/eventVocabulary.ts +214 -0
  144. package/src/overview/locCoverage.ts +138 -0
  145. package/src/overview/modOverview.ts +29 -0
  146. package/src/overview/overrides.ts +89 -0
  147. package/src/parseCache.ts +81 -0
  148. package/src/parser/cst.ts +257 -0
  149. package/src/parser/encoding.ts +106 -0
  150. package/src/parser/index.ts +7 -0
  151. package/src/parser/lexer.ts +245 -0
  152. package/src/parser/locParser.ts +276 -0
  153. package/src/parser/parser.ts +360 -0
  154. package/src/schema/freqs.ts +70 -0
  155. package/src/schema/loader.ts +113 -0
  156. package/src/schema/types.ts +142 -0
  157. package/src/scopes/inference.ts +478 -0
  158. package/src/scopes/model.ts +148 -0
  159. package/src/scopes/varTypes.ts +290 -0
  160. package/src/server.ts +1894 -0
  161. package/src/serverData.ts +98 -0
  162. package/src/structure.ts +56 -0
  163. package/src/wordAt.ts +49 -0
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Shared mutable state for the language server: parsed script_docs tokens and
3
+ * the definition index, plus a plain change-listener list so features can
4
+ * invalidate caches. The vscode EventEmitter of the old in-process design is
5
+ * replaced by a minimal callback registry (no vscode imports server-side).
6
+ */
7
+ import type { TokenData } from "@px-lsp/protocol/types";
8
+ import { compileModifierTemplates, type ModifierTemplate } from "./data/modifierTemplates";
9
+ import { emptyDataTypes, type DataTypesData } from "./data/dataTypes";
10
+ import { emptyUsage, type DataFnUsage } from "./data/dataFnUsage";
11
+ import { DefinesIndex } from "./data/defines";
12
+ import { TextFormattingIndex } from "./data/textFormatting";
13
+ import { DefinitionIndex } from "./index/indexer";
14
+ import { ReferenceIndex } from "./index/references";
15
+ import { ScopeModel } from "./scopes/model";
16
+
17
+ export class ServerData {
18
+ tokens: TokenData[] = [];
19
+ /** name -> all tokens with that name (a name can be both trigger and effect). */
20
+ tokenMap = new Map<string, TokenData[]>();
21
+ /** Templated modifier tags ($CULTURE$_opinion), compiled for lazy expansion. */
22
+ modifierTemplates: ModifierTemplate[] = [];
23
+ /** [ ... ] datafunction tables (bundled wiki baseline / user's DumpDataTypes output). */
24
+ dataTypes: DataTypesData = emptyDataTypes();
25
+ /** Vanilla [ ... ] usage harvest: counts, literals, examples (dataFnUsage.ts). */
26
+ dataFnUsage: DataFnUsage = emptyUsage();
27
+ /** `define:NS|CONST` constants harvested from engine/game/mod defines. */
28
+ defines = new DefinesIndex();
29
+ /** `#tag` loc text-formatting definitions harvested from gui textformatting blocks. */
30
+ textFormatting = new TextFormattingIndex();
31
+ index = new DefinitionIndex();
32
+ /** Usage sites, mod files only (vanilla references are computed on demand). */
33
+ refIndex = new ReferenceIndex();
34
+ /** Event namespaces declared by mod files (for conservative unknown-event checks). */
35
+ modNamespaces = new Set<string>();
36
+ /** Definition kinds that appear in completion lists (from the schema). */
37
+ completableKinds = new Set<string>();
38
+ /** Scope link table derived from the token data (AD-5); rebuilt with tokens. */
39
+ scopeModel = new ScopeModel([]);
40
+ /** on_action name → expected root scope, parsed from the user's on_actions.log. */
41
+ onActionScopes = new Map<string, string>();
42
+ /** Schema root scopes for an absolute file path (set by the host; used for
43
+ * static variable-type resolution — see scopes/varTypes.ts). */
44
+ rootScopesForFile: (file: string) => Set<string> | null = () => null;
45
+ /** Origin label for a definition: the owning mod's descriptor name instead of
46
+ * the generic "mod"/"parent" (set by the host from the configured roots —
47
+ * see index/modOrigin.ts). Default: the raw source tag. */
48
+ originLabel: (def: { file: string; source: string }) => string = (def) => def.source;
49
+ /** The mod root a file lives under (set by the host; used to scope the
50
+ * overview views to one workspace mod). Default: unknown. */
51
+ modRootOf: (file: string) => string | null = () => null;
52
+
53
+ private listeners: Array<() => void> = [];
54
+
55
+ onDidChange(listener: () => void): void {
56
+ this.listeners.push(listener);
57
+ }
58
+
59
+ setTokens(tokens: TokenData[]): void {
60
+ this.tokens = tokens;
61
+ this.tokenMap.clear();
62
+ for (const t of tokens) {
63
+ const list = this.tokenMap.get(t.name);
64
+ if (list) list.push(t);
65
+ else this.tokenMap.set(t.name, [t]);
66
+ }
67
+ this.scopeModel = new ScopeModel(tokens);
68
+ this.applyScriptedLists();
69
+ this.fire();
70
+ }
71
+
72
+ setModifierTemplates(raw: TokenData[]): void {
73
+ this.modifierTemplates = compileModifierTemplates(raw);
74
+ this.fire();
75
+ }
76
+
77
+ notifyIndexChanged(): void {
78
+ this.applyScriptedLists();
79
+ this.fire();
80
+ }
81
+
82
+ /** Feed scripted-list definitions (name + base) into the scope model so their
83
+ * generated every_/any_/random_/ordered_ iterators resolve target scopes. */
84
+ private applyScriptedLists(): void {
85
+ const lists: Array<{ name: string; base?: string }> = [];
86
+ // index.scriptedLists() is the incremental form of
87
+ // entries(d => d.kind === "scripted_list") — same result, without the
88
+ // full-name walk this used to pay on every index change (§B2).
89
+ for (const d of this.index.scriptedLists()) {
90
+ lists.push({ name: d.name, base: d.value });
91
+ }
92
+ this.scopeModel.setScriptedLists(lists);
93
+ }
94
+
95
+ private fire(): void {
96
+ for (const l of this.listeners) l();
97
+ }
98
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Block-schema structure context (update plan v1.1 §B2): which named sub-block
3
+ * of a definition kind the cursor sits in, and the KeySpecs valid there.
4
+ *
5
+ * Pairs the file's schema kind (from classifyFile) with the CST block stack:
6
+ * the innermost stack keyword that names a structure sub-block wins; otherwise
7
+ * the cursor is at the definition's top level. Transparent wrappers (first_valid,
8
+ * random_list, if…) are simply not named blocks, so the walk skips past them.
9
+ *
10
+ * No `vscode` imports: unit-tested in plain Node.
11
+ */
12
+ import type { KeySpec } from "./schema/types";
13
+ import type { StructureIndex } from "./schema/loader";
14
+ import { blockStackFromParse } from "./context";
15
+ import type { ParseResult } from "./parser";
16
+
17
+ export interface StructureContext {
18
+ /** Schema kind of the file, e.g. "character_interaction". */
19
+ kind: string;
20
+ /** Named sub-block the cursor is in, or "" for the definition's top level. */
21
+ block: string;
22
+ /** KeySpecs valid at this position (empty if the kind/block is unknown). */
23
+ keys: Map<string, KeySpec>;
24
+ }
25
+
26
+ /**
27
+ * Resolve the structure context at `offset`. Returns null when the file's kind
28
+ * has no `structure` layer (most kinds) — callers then skip structure work.
29
+ */
30
+ export function structureContextAt(
31
+ parse: ParseResult,
32
+ offset: number,
33
+ kind: string,
34
+ structures: StructureIndex
35
+ ): StructureContext | null {
36
+ const byBlock = structures.keysByKindBlock.get(kind);
37
+ if (!byBlock) return null;
38
+
39
+ const stack = blockStackFromParse(parse, offset);
40
+ // The outermost named frame is the definition body; its top-level keys apply
41
+ // only when the cursor sits DIRECTLY in it. A recognized sub-block (option,
42
+ // send_option…) supplies its own keys. Any other named block between the
43
+ // definition body and the cursor (immediate, trigger, limit, a scope change…)
44
+ // is a trigger/effect/transparent block, not a structural level — return null so
45
+ // completion offers tokens there instead of leaking top-level structure keys.
46
+ const named = stack.filter((s) => s !== "<anon>");
47
+ if (named.length === 0) return null; // above/outside any definition body
48
+ const innermost = named[named.length - 1].toLowerCase();
49
+ if (named.length === 1) {
50
+ // Directly in the definition body → top-level keys.
51
+ return { kind, block: "", keys: byBlock.get("") ?? new Map<string, KeySpec>() };
52
+ }
53
+ const sub = byBlock.get(innermost);
54
+ if (sub) return { kind, block: innermost, keys: sub };
55
+ return null;
56
+ }
package/src/wordAt.ts ADDED
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Word extraction matching the language-configuration wordPattern
3
+ * (`[A-Za-z0-9_][A-Za-z0-9_.\-]*`), so server-side lookups see the same words
4
+ * the editor selects. No `vscode` imports.
5
+ */
6
+
7
+ const WORD = /[A-Za-z0-9_][A-Za-z0-9_.-]*/g;
8
+
9
+ export interface WordRange {
10
+ word: string;
11
+ /** Character offsets on the line. */
12
+ start: number;
13
+ end: number;
14
+ }
15
+
16
+ /** The word at `character` on `lineText`, VS Code-style (position may touch either edge). */
17
+ export function wordRangeAt(lineText: string, character: number): WordRange | null {
18
+ WORD.lastIndex = 0;
19
+ let m: RegExpExecArray | null;
20
+ while ((m = WORD.exec(lineText)) !== null) {
21
+ const start = m.index;
22
+ const end = start + m[0].length;
23
+ if (character >= start && character <= end) return { word: m[0], start, end };
24
+ if (start > character) break;
25
+ }
26
+ return null;
27
+ }
28
+
29
+ /** Prefixes that make the following word a saved-scope / variable reference. */
30
+ const SCOPE_PREFIXES = ["scope", "var", "local_var", "global_var"];
31
+
32
+ /**
33
+ * If the word at `range` is immediately preceded by a `scope:` / `var:` (etc.)
34
+ * prefix on the line, return that prefix; otherwise null. The wordPattern splits
35
+ * at `:`, so hover would otherwise look up the bare name and lose the prefix
36
+ * (update plan v1.1 §B3 hover work).
37
+ */
38
+ export function scopePrefixBefore(lineText: string, range: WordRange): string | null {
39
+ if (range.start === 0 || lineText[range.start - 1] !== ":") return null;
40
+ const before = lineText.slice(0, range.start - 1);
41
+ for (const p of SCOPE_PREFIXES) {
42
+ if (before.endsWith(p)) {
43
+ // Make sure the prefix is a whole token (not the tail of a longer word).
44
+ const at = before.length - p.length;
45
+ if (at === 0 || !/[A-Za-z0-9_.-]/.test(before[at - 1])) return p;
46
+ }
47
+ }
48
+ return null;
49
+ }