hledger-lsp 0.1.5 → 0.1.6

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 (73) hide show
  1. package/README.md +82 -167
  2. package/out/features/codeActions.d.ts +0 -4
  3. package/out/features/codeActions.d.ts.map +1 -1
  4. package/out/features/codeActions.js +7 -23
  5. package/out/features/codeActions.js.map +1 -1
  6. package/out/features/codeLens.d.ts +29 -0
  7. package/out/features/codeLens.d.ts.map +1 -0
  8. package/out/features/codeLens.js +102 -0
  9. package/out/features/codeLens.js.map +1 -0
  10. package/out/features/completion.d.ts.map +1 -1
  11. package/out/features/completion.js +19 -6
  12. package/out/features/completion.js.map +1 -1
  13. package/out/features/definition.d.ts.map +1 -1
  14. package/out/features/definition.js.map +1 -1
  15. package/out/features/foldingRanges.d.ts.map +1 -1
  16. package/out/features/foldingRanges.js +6 -2
  17. package/out/features/foldingRanges.js.map +1 -1
  18. package/out/features/formatter.d.ts.map +1 -1
  19. package/out/features/formatter.js.map +1 -1
  20. package/out/features/formattingUtils.d.ts +38 -0
  21. package/out/features/formattingUtils.d.ts.map +1 -0
  22. package/out/features/formattingUtils.js +107 -0
  23. package/out/features/formattingUtils.js.map +1 -0
  24. package/out/features/hover.d.ts +0 -4
  25. package/out/features/hover.d.ts.map +1 -1
  26. package/out/features/hover.js +7 -16
  27. package/out/features/hover.js.map +1 -1
  28. package/out/features/inlayHints.d.ts +5 -4
  29. package/out/features/inlayHints.d.ts.map +1 -1
  30. package/out/features/inlayHints.js +154 -84
  31. package/out/features/inlayHints.js.map +1 -1
  32. package/out/features/symbols.d.ts.map +1 -1
  33. package/out/features/symbols.js +4 -1
  34. package/out/features/symbols.js.map +1 -1
  35. package/out/features/validator.d.ts +0 -4
  36. package/out/features/validator.d.ts.map +1 -1
  37. package/out/features/validator.js +101 -93
  38. package/out/features/validator.js.map +1 -1
  39. package/out/parser/ast.d.ts +2 -2
  40. package/out/parser/ast.d.ts.map +1 -1
  41. package/out/parser/ast.js +8 -3
  42. package/out/parser/ast.js.map +1 -1
  43. package/out/parser/index.d.ts +8 -5
  44. package/out/parser/index.d.ts.map +1 -1
  45. package/out/parser/index.js +0 -7
  46. package/out/parser/index.js.map +1 -1
  47. package/out/server/configFile.d.ts +104 -0
  48. package/out/server/configFile.d.ts.map +1 -0
  49. package/out/server/configFile.js +231 -0
  50. package/out/server/configFile.js.map +1 -0
  51. package/out/server/settings.d.ts +8 -0
  52. package/out/server/settings.d.ts.map +1 -1
  53. package/out/server/settings.js +8 -0
  54. package/out/server/settings.js.map +1 -1
  55. package/out/server/workspace.d.ts +126 -0
  56. package/out/server/workspace.d.ts.map +1 -0
  57. package/out/server/workspace.js +599 -0
  58. package/out/server/workspace.js.map +1 -0
  59. package/out/server.js +431 -23
  60. package/out/server.js.map +1 -1
  61. package/out/types.d.ts +15 -4
  62. package/out/types.d.ts.map +1 -1
  63. package/out/types.js +11 -0
  64. package/out/types.js.map +1 -1
  65. package/out/utils/amountFormatter.d.ts +14 -0
  66. package/out/utils/amountFormatter.d.ts.map +1 -0
  67. package/out/utils/amountFormatter.js +55 -0
  68. package/out/utils/amountFormatter.js.map +1 -0
  69. package/out/utils/balanceCalculator.d.ts +32 -0
  70. package/out/utils/balanceCalculator.d.ts.map +1 -0
  71. package/out/utils/balanceCalculator.js +93 -0
  72. package/out/utils/balanceCalculator.js.map +1 -0
  73. package/package.json +1 -1
@@ -0,0 +1,599 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.WorkspaceManager = void 0;
40
+ const fast_glob_1 = __importDefault(require("fast-glob"));
41
+ const path = __importStar(require("path"));
42
+ const os = __importStar(require("os"));
43
+ const uri_1 = require("../utils/uri");
44
+ const configFile_1 = require("./configFile");
45
+ class WorkspaceManager {
46
+ constructor() {
47
+ // Core state
48
+ this.workspaceFolders = [];
49
+ this.journalFiles = new Set();
50
+ this.includeGraph = new Map(); // file → files it includes
51
+ this.reverseGraph = new Map(); // file → files that include it
52
+ this.rootFile = null;
53
+ this.workspaceCache = null; // single cached workspace state
54
+ // Configuration
55
+ this.config = null;
56
+ this.configPath = null;
57
+ // Performance metrics
58
+ this.metrics = {
59
+ cacheHits: 0,
60
+ cacheMisses: 0,
61
+ totalParseTime: 0, // milliseconds
62
+ parseCount: 0,
63
+ initializationTime: 0
64
+ };
65
+ }
66
+ /**
67
+ * Initialize the WorkspaceManager with workspace folders and dependencies.
68
+ * This discovers all journal files, builds the include graph, and identifies root files.
69
+ * Optionally loads configuration from .hledger-lsp.json if present.
70
+ */
71
+ async initialize(workspaceFolders, parser, fileReader, connection, runtimeConfig) {
72
+ const startTime = Date.now();
73
+ this.workspaceFolders = workspaceFolders;
74
+ this.parser = parser;
75
+ this.fileReader = fileReader;
76
+ this.connection = connection;
77
+ // Try to discover and load config file
78
+ await this.loadConfig(runtimeConfig);
79
+ // Discover all journal files in workspace
80
+ for (const folder of workspaceFolders) {
81
+ const files = await this.discoverJournalFiles(folder);
82
+ for (const file of files) {
83
+ this.journalFiles.add(file);
84
+ }
85
+ }
86
+ connection.console.log(`Discovered ${this.journalFiles.size} journal files in workspace`);
87
+ // Warn if workspace is very large
88
+ if (this.journalFiles.size > 100) {
89
+ connection.console.warn(`Large workspace detected (${this.journalFiles.size} files). ` +
90
+ `Consider using exclude patterns in .hledger-lsp.json to improve performance.`);
91
+ }
92
+ // Build include graph
93
+ await this.buildIncludeGraph();
94
+ // Identify root file (auto-detect + explicit from config)
95
+ this.identifyRootFile();
96
+ const endTime = Date.now();
97
+ this.metrics.initializationTime = endTime - startTime;
98
+ connection.console.info(`[WorkspaceManager] Root file: ${this.rootFile || 'none'} (initialized in ${this.metrics.initializationTime}ms)`);
99
+ // Warn if initialization was slow
100
+ if (this.metrics.initializationTime > 5000) {
101
+ connection.console.warn(`Workspace initialization took ${this.metrics.initializationTime}ms. ` +
102
+ `Consider optimizing your workspace structure or using exclude patterns.`);
103
+ }
104
+ }
105
+ /**
106
+ * Discover and load configuration from .hledger-lsp.json
107
+ */
108
+ async loadConfig(runtimeConfig) {
109
+ if (this.workspaceFolders.length === 0) {
110
+ return;
111
+ }
112
+ // Try to find config file starting from first workspace folder
113
+ const workspaceRoot = this.workspaceFolders[0];
114
+ this.configPath = (0, configFile_1.discoverConfigFile)(workspaceRoot, workspaceRoot);
115
+ if (this.configPath) {
116
+ try {
117
+ const loadResult = (0, configFile_1.loadConfigFile)(this.configPath);
118
+ // Log any warnings
119
+ if (loadResult.warnings.length > 0) {
120
+ this.connection.console.warn(`Warnings in ${this.configPath}:\n${loadResult.warnings.join('\n')}`);
121
+ }
122
+ // Merge with runtime config (runtime takes precedence)
123
+ this.config = (0, configFile_1.mergeConfig)(loadResult.config, runtimeConfig);
124
+ this.connection.console.log(`Loaded configuration from ${this.configPath}`);
125
+ }
126
+ catch (error) {
127
+ this.connection.console.error(`Failed to load config file ${this.configPath}: ${error}`);
128
+ // Continue without config
129
+ }
130
+ }
131
+ // If no config file, just use runtime config with defaults
132
+ if (!this.config) {
133
+ this.config = (0, configFile_1.mergeConfig)({}, runtimeConfig);
134
+ }
135
+ }
136
+ /**
137
+ * Discover all .journal and .hledger files in a workspace folder.
138
+ * Uses fast-glob to find files, using patterns from config.
139
+ */
140
+ async discoverJournalFiles(folder) {
141
+ const folderPath = (0, uri_1.toFilePath)(folder);
142
+ // Use patterns from config, or defaults
143
+ const patterns = this.config?.include ?? ['**/*.journal', '**/*.hledger'];
144
+ const ignore = this.config?.exclude ?? ['**/node_modules/**', '**/.git/**', '**/.*'];
145
+ try {
146
+ const entries = await (0, fast_glob_1.default)(patterns, {
147
+ cwd: folderPath,
148
+ onlyFiles: true,
149
+ absolute: true,
150
+ dot: false,
151
+ ignore
152
+ });
153
+ // Convert to file:// URIs
154
+ const uris = entries.map(p => (0, uri_1.toFileUri)(p));
155
+ uris.sort();
156
+ return uris;
157
+ }
158
+ catch (error) {
159
+ this.connection.console.error(`Error discovering journal files in ${folder}: ${error}`);
160
+ return [];
161
+ }
162
+ }
163
+ /**
164
+ * Build the include graph by parsing each discovered file for include directives.
165
+ * This creates both forward (file → includes) and reverse (file → included by) mappings.
166
+ *
167
+ * IMPORTANT: We parse WITHOUT following includes to get only DIRECT includes,
168
+ * not transitive ones. This ensures the graph accurately represents the include structure.
169
+ */
170
+ async buildIncludeGraph() {
171
+ for (const fileUri of this.journalFiles) {
172
+ const doc = this.fileReader(fileUri);
173
+ if (!doc)
174
+ continue;
175
+ // Parse WITHOUT following includes - we only want direct include directives from this file
176
+ const parsed = this.parser.parse(doc, {
177
+ baseUri: fileUri,
178
+ // Don't provide fileReader - this prevents following includes
179
+ fileReader: undefined
180
+ });
181
+ // Extract include directives from this file only
182
+ const includeDirectives = parsed.directives.filter((d) => d.type === 'include' && d.sourceUri === fileUri);
183
+ // Now resolve each include directive to get the actual file URIs
184
+ const includedFiles = new Set();
185
+ for (const directive of includeDirectives) {
186
+ // The parser's include manager already resolved these paths
187
+ // We can find which files were meant to be included by looking at
188
+ // include directives that have the resolved path
189
+ // Since we didn't follow includes, we need to resolve the paths ourselves
190
+ // Get the include manager's resolution logic
191
+ const includePath = directive.value;
192
+ // Try to resolve this include path to a file URI
193
+ // We'll check against our discovered journal files
194
+ const baseDir = path.dirname((0, uri_1.toFilePath)(fileUri));
195
+ // Handle different include path types
196
+ let resolvedPaths = [];
197
+ if (includePath.includes('*') || includePath.includes('?')) {
198
+ // Glob pattern - find matching files
199
+ const pattern = path.isAbsolute(includePath)
200
+ ? includePath
201
+ : path.join(baseDir, includePath);
202
+ try {
203
+ const matches = fast_glob_1.default.sync(pattern, {
204
+ cwd: baseDir,
205
+ absolute: true,
206
+ onlyFiles: true
207
+ });
208
+ resolvedPaths = matches.map(p => (0, uri_1.toFileUri)(p));
209
+ }
210
+ catch (err) {
211
+ this.connection.console.warn(`[WorkspaceManager] Failed to resolve glob pattern ${includePath}: ${err}`);
212
+ }
213
+ }
214
+ else {
215
+ // Regular file path
216
+ let resolvedPath;
217
+ if (path.isAbsolute(includePath)) {
218
+ resolvedPath = includePath;
219
+ }
220
+ else if (includePath.startsWith('~/')) {
221
+ resolvedPath = path.join(os.homedir(), includePath.slice(2));
222
+ }
223
+ else {
224
+ resolvedPath = path.join(baseDir, includePath);
225
+ }
226
+ const resolvedUri = (0, uri_1.toFileUri)(resolvedPath);
227
+ // Only add if it's in our discovered files
228
+ if (this.journalFiles.has(resolvedUri)) {
229
+ resolvedPaths = [resolvedUri];
230
+ }
231
+ }
232
+ // Add all resolved paths to included files
233
+ for (const resolvedUri of resolvedPaths) {
234
+ if (this.journalFiles.has(resolvedUri)) {
235
+ includedFiles.add(resolvedUri);
236
+ }
237
+ }
238
+ }
239
+ // Update include graph
240
+ this.includeGraph.set(fileUri, includedFiles);
241
+ if (includedFiles.size > 0) {
242
+ this.connection.console.log(`[WorkspaceManager] ${fileUri} directly includes ${includedFiles.size} file(s): ${Array.from(includedFiles).join(', ')}`);
243
+ }
244
+ // Update reverse graph
245
+ for (const includedFile of includedFiles) {
246
+ let parents = this.reverseGraph.get(includedFile);
247
+ if (!parents) {
248
+ parents = new Set();
249
+ this.reverseGraph.set(includedFile, parents);
250
+ }
251
+ parents.add(fileUri);
252
+ }
253
+ }
254
+ }
255
+ /**
256
+ * Identify the single root file using the following algorithm:
257
+ * 1. If explicitly configured in config, use that
258
+ * 2. If autoDetectRoot is enabled, use heuristics to find the best root:
259
+ * a. Prefer files with NO parents (not included by anyone)
260
+ * b. Among those, prefer the one that includes the most files
261
+ * c. If multiple candidates, prefer one with "main" or "all" in the name
262
+ * d. If still tied, use alphabetically first
263
+ * 3. If no suitable root found, return null (workspace features disabled)
264
+ */
265
+ identifyRootFile() {
266
+ this.rootFile = null;
267
+ // Step 1: Check for explicit root file from config
268
+ if (this.config && this.config.rootFile && this.configPath) {
269
+ const configDir = path.dirname(this.configPath);
270
+ const explicitRoot = (0, configFile_1.resolveRootFile)(this.config, configDir);
271
+ if (explicitRoot) {
272
+ // Verify the file exists and is in our discovered files
273
+ if (this.journalFiles.has(explicitRoot)) {
274
+ this.rootFile = explicitRoot;
275
+ this.connection.console.log(`[WorkspaceManager] Using explicit root from config: ${explicitRoot}`);
276
+ return;
277
+ }
278
+ else {
279
+ this.connection.console.warn(`[WorkspaceManager] Configured root file not found: ${explicitRoot}`);
280
+ }
281
+ }
282
+ }
283
+ // Step 2: Auto-detect root (if enabled)
284
+ const shouldAutoDetect = this.config?.workspace?.autoDetectRoot ?? true;
285
+ if (!shouldAutoDetect) {
286
+ this.connection.console.warn('[WorkspaceManager] Auto-detect disabled and no valid root configured, workspace features disabled');
287
+ return;
288
+ }
289
+ // Find all files with no parents (not included by anyone)
290
+ const candidateRoots = [];
291
+ for (const fileUri of this.journalFiles) {
292
+ const parents = this.reverseGraph.get(fileUri);
293
+ if (!parents || parents.size === 0) {
294
+ candidateRoots.push(fileUri);
295
+ this.connection.console.log(`[WorkspaceManager] Root candidate (no parents): ${fileUri}`);
296
+ }
297
+ }
298
+ if (candidateRoots.length === 0) {
299
+ this.connection.console.warn('[WorkspaceManager] No root candidates found (all files are included by others), workspace features disabled');
300
+ return;
301
+ }
302
+ if (candidateRoots.length === 1) {
303
+ this.rootFile = candidateRoots[0];
304
+ this.connection.console.log(`[WorkspaceManager] Auto-detected root: ${this.rootFile}`);
305
+ return;
306
+ }
307
+ // Multiple candidates - use heuristics to pick the best one
308
+ this.connection.console.log(`[WorkspaceManager] Multiple root candidates (${candidateRoots.length}), using heuristics to select best`);
309
+ // Score each candidate
310
+ const scores = candidateRoots.map(root => {
311
+ const includeCount = this.includeGraph.get(root)?.size || 0;
312
+ const basename = path.basename((0, uri_1.toFilePath)(root)).toLowerCase();
313
+ const hasMainInName = basename.includes('main') || basename.includes('all') || basename.includes('index');
314
+ return {
315
+ root,
316
+ includeCount,
317
+ hasMainInName,
318
+ basename
319
+ };
320
+ });
321
+ // Sort by: 1) include count (desc), 2) has "main" in name, 3) alphabetically
322
+ scores.sort((a, b) => {
323
+ if (a.includeCount !== b.includeCount) {
324
+ return b.includeCount - a.includeCount;
325
+ }
326
+ if (a.hasMainInName !== b.hasMainInName) {
327
+ return a.hasMainInName ? -1 : 1;
328
+ }
329
+ return a.basename.localeCompare(b.basename);
330
+ });
331
+ this.rootFile = scores[0].root;
332
+ this.connection.console.log(`[WorkspaceManager] Selected root: ${this.rootFile} (includes: ${scores[0].includeCount}, hasMain: ${scores[0].hasMainInName})`);
333
+ }
334
+ /**
335
+ * Get the root file for a given file URI.
336
+ * Returns the single root file if it transitively includes this file, or null otherwise.
337
+ *
338
+ * Algorithm:
339
+ * 1. If no root file identified, return null
340
+ * 2. If the root file transitively includes this file (or is the file itself), return the root
341
+ * 3. Otherwise return null (file is not part of the workspace's include graph)
342
+ */
343
+ getRootForFile(uri) {
344
+ // If workspace hasn't finished initializing yet, return null
345
+ if (!this.rootFile) {
346
+ return null;
347
+ }
348
+ // Check if the root file transitively includes this file
349
+ if (this.rootIncludesFile(this.rootFile, uri)) {
350
+ return this.rootFile;
351
+ }
352
+ // File is not part of the workspace's include graph
353
+ return null;
354
+ }
355
+ /**
356
+ * Check if a root file transitively includes a target file.
357
+ * Uses BFS to traverse the include graph.
358
+ */
359
+ rootIncludesFile(root, target) {
360
+ if (root === target)
361
+ return true;
362
+ const visited = new Set();
363
+ const queue = [root];
364
+ while (queue.length > 0) {
365
+ const current = queue.shift();
366
+ if (visited.has(current))
367
+ continue;
368
+ visited.add(current);
369
+ if (current === target)
370
+ return true;
371
+ const includes = this.includeGraph.get(current);
372
+ if (includes) {
373
+ for (const included of includes) {
374
+ if (!visited.has(included)) {
375
+ queue.push(included);
376
+ }
377
+ }
378
+ }
379
+ }
380
+ return false;
381
+ }
382
+ /**
383
+ * Get the workspace folder that contains the given URI.
384
+ * Returns null if the file is outside all workspace folders.
385
+ *
386
+ * Edge case handling: Files outside workspace folders will return null,
387
+ * which triggers a fallback to document-mode parsing. This is intentional
388
+ * and allows the LSP to work with files opened outside the workspace.
389
+ */
390
+ getWorkspaceFolder(uri) {
391
+ const filePath = (0, uri_1.toFilePath)(uri);
392
+ for (const folder of this.workspaceFolders) {
393
+ const folderPath = (0, uri_1.toFilePath)(folder);
394
+ if (filePath.startsWith(folderPath)) {
395
+ return folder;
396
+ }
397
+ }
398
+ // File is outside all workspace folders
399
+ this.connection.console.log(`[WorkspaceManager] File outside workspace folders: ${uri}`);
400
+ return null;
401
+ }
402
+ /**
403
+ * Parse the workspace from the root file.
404
+ * Returns a cached ParsedDocument if available, otherwise parses and caches.
405
+ */
406
+ parseWorkspace(force = false) {
407
+ if (!this.rootFile) {
408
+ this.connection.console.info('[WorkspaceManager] No root file - cannot parse workspace');
409
+ return null;
410
+ }
411
+ // Check cache unless force is true
412
+ if (!force && this.workspaceCache) {
413
+ this.metrics.cacheHits++;
414
+ this.connection.console.info(`[WorkspaceManager] Using cached workspace (root: ${path.basename((0, uri_1.toFilePath)(this.rootFile))})`);
415
+ return this.workspaceCache;
416
+ }
417
+ // Cache miss - need to parse
418
+ this.metrics.cacheMisses++;
419
+ const parseStartTime = Date.now();
420
+ this.connection.console.info(`[WorkspaceManager] Parsing workspace from root: ${this.rootFile}`);
421
+ // Parse from root
422
+ const rootDoc = this.fileReader(this.rootFile);
423
+ if (!rootDoc) {
424
+ throw new Error(`Root file not found: ${this.rootFile}`);
425
+ }
426
+ const parsed = this.parser.parse(rootDoc, {
427
+ baseUri: this.rootFile,
428
+ fileReader: this.fileReader
429
+ });
430
+ const parseEndTime = Date.now();
431
+ const parseTime = parseEndTime - parseStartTime;
432
+ this.metrics.totalParseTime += parseTime;
433
+ this.metrics.parseCount++;
434
+ // Log parse completion
435
+ this.connection.console.info(`[WorkspaceManager] Parsed workspace in ${parseTime}ms (${parsed.transactions.length} transactions, ${parsed.accounts.size} accounts)`);
436
+ // Log slow parses
437
+ if (parseTime > 1000) {
438
+ this.connection.console.warn(`[WorkspaceManager] Slow parse detected: ${this.rootFile} took ${parseTime}ms`);
439
+ }
440
+ // Cache the result
441
+ this.workspaceCache = parsed;
442
+ return parsed;
443
+ }
444
+ /**
445
+ * Invalidate the cache for a file.
446
+ * Clears the workspace cache if the root file transitively includes this file.
447
+ */
448
+ invalidateFile(uri) {
449
+ // If root file includes this file, clear the workspace cache
450
+ if (this.rootFile && this.rootIncludesFile(this.rootFile, uri)) {
451
+ this.connection.console.info(`[WorkspaceManager] Invalidating cache due to change in: ${uri}`);
452
+ this.workspaceCache = null;
453
+ }
454
+ else {
455
+ this.connection.console.info(`[WorkspaceManager] File change doesn't affect workspace cache: ${uri}`);
456
+ }
457
+ // Also clear the parser's include cache
458
+ this.parser.clearCache(uri);
459
+ }
460
+ /**
461
+ * Get diagnostic information about the workspace.
462
+ * Useful for troubleshooting and performance monitoring.
463
+ */
464
+ getDiagnosticInfo() {
465
+ const totalAccesses = this.metrics.cacheHits + this.metrics.cacheMisses;
466
+ const cacheHitRate = totalAccesses > 0
467
+ ? ((this.metrics.cacheHits / totalAccesses) * 100).toFixed(1) + '%'
468
+ : 'N/A';
469
+ const avgParseTime = this.metrics.parseCount > 0
470
+ ? Math.round(this.metrics.totalParseTime / this.metrics.parseCount)
471
+ : 0;
472
+ return {
473
+ totalFiles: this.journalFiles.size,
474
+ rootFile: this.rootFile,
475
+ cached: this.workspaceCache !== null,
476
+ configFile: this.configPath,
477
+ performance: {
478
+ initializationTime: this.metrics.initializationTime,
479
+ cacheHits: this.metrics.cacheHits,
480
+ cacheMisses: this.metrics.cacheMisses,
481
+ cacheHitRate,
482
+ averageParseTime: avgParseTime,
483
+ totalParseTime: this.metrics.totalParseTime,
484
+ parseCount: this.metrics.parseCount
485
+ }
486
+ };
487
+ }
488
+ /**
489
+ * Log diagnostic information to the console.
490
+ * Useful for debugging and performance analysis.
491
+ */
492
+ logDiagnostics() {
493
+ const info = this.getDiagnosticInfo();
494
+ this.connection.console.log('=== WorkspaceManager Diagnostics ===');
495
+ this.connection.console.log(`Files: ${info.totalFiles} total`);
496
+ this.connection.console.log(`Root: ${info.rootFile || 'none'}`);
497
+ this.connection.console.log(`Cache: ${info.cached ? 'populated' : 'empty'}`);
498
+ this.connection.console.log(`Config: ${info.configFile || 'none'}`);
499
+ this.connection.console.log('Performance:');
500
+ this.connection.console.log(` Initialization: ${info.performance.initializationTime}ms`);
501
+ this.connection.console.log(` Cache hits: ${info.performance.cacheHits}`);
502
+ this.connection.console.log(` Cache misses: ${info.performance.cacheMisses}`);
503
+ this.connection.console.log(` Cache hit rate: ${info.performance.cacheHitRate}`);
504
+ this.connection.console.log(` Parses: ${info.performance.parseCount} (avg ${info.performance.averageParseTime}ms)`);
505
+ this.connection.console.log(` Total parse time: ${info.performance.totalParseTime}ms`);
506
+ this.connection.console.log('===================================');
507
+ }
508
+ /**
509
+ * Generate a text-based tree representation of the workspace.
510
+ */
511
+ getWorkspaceTree() {
512
+ if (!this.rootFile) {
513
+ return 'No root file identified';
514
+ }
515
+ const lines = [];
516
+ lines.push(path.basename((0, uri_1.toFilePath)(this.rootFile)));
517
+ this.printTree(this.rootFile, '', lines, new Set([this.rootFile]));
518
+ return lines.join('\n');
519
+ }
520
+ /**
521
+ * Generate a structured representation of the workspace for better tooling integration.
522
+ * Returns an array of entries with display text and absolute file paths.
523
+ */
524
+ getWorkspaceTreeStructured() {
525
+ if (!this.rootFile) {
526
+ return [];
527
+ }
528
+ const entries = [];
529
+ const rootPath = (0, uri_1.toFilePath)(this.rootFile);
530
+ entries.push({
531
+ display: path.basename(rootPath),
532
+ path: rootPath,
533
+ uri: this.rootFile
534
+ });
535
+ this.collectTreeEntries(this.rootFile, '', entries, new Set([this.rootFile]));
536
+ return entries;
537
+ }
538
+ collectTreeEntries(uri, prefix, entries, visited) {
539
+ const includes = this.includeGraph.get(uri);
540
+ if (!includes || includes.size === 0)
541
+ return;
542
+ const children = Array.from(includes).sort();
543
+ const parentPath = (0, uri_1.toFilePath)(uri);
544
+ const parentDir = path.dirname(parentPath);
545
+ for (let i = 0; i < children.length; i++) {
546
+ const child = children[i];
547
+ const isLast = i === children.length - 1;
548
+ const marker = isLast ? '└── ' : '├── ';
549
+ const childPath = (0, uri_1.toFilePath)(child);
550
+ const displayPath = path.relative(parentDir, childPath);
551
+ entries.push({
552
+ display: `${prefix}${marker}${displayPath}`,
553
+ path: childPath,
554
+ uri: child
555
+ });
556
+ if (!visited.has(child)) {
557
+ const newPrefix = prefix + (isLast ? ' ' : '│ ');
558
+ this.collectTreeEntries(child, newPrefix, entries, new Set([...visited, child]));
559
+ }
560
+ else {
561
+ entries.push({
562
+ display: `${prefix}${isLast ? ' ' : '│ '}└── (cycle)`,
563
+ path: '',
564
+ uri: ''
565
+ });
566
+ }
567
+ }
568
+ }
569
+ printTree(uri, prefix, lines, visited) {
570
+ const includes = this.includeGraph.get(uri);
571
+ if (!includes || includes.size === 0)
572
+ return;
573
+ const children = Array.from(includes).sort();
574
+ const parentPath = (0, uri_1.toFilePath)(uri);
575
+ const parentDir = path.dirname(parentPath);
576
+ for (let i = 0; i < children.length; i++) {
577
+ const child = children[i];
578
+ const isLast = i === children.length - 1;
579
+ const marker = isLast ? '└── ' : '├── ';
580
+ const childPath = (0, uri_1.toFilePath)(child);
581
+ let displayPath = path.relative(parentDir, childPath);
582
+ // Ensure it looks like a file path
583
+ if (!displayPath.startsWith('.') && !displayPath.startsWith('/')) {
584
+ // It's in the same directory or a subdirectory, keep it as is
585
+ // (path.relative returns just filename for same dir)
586
+ }
587
+ lines.push(`${prefix}${marker}${displayPath}`);
588
+ if (!visited.has(child)) {
589
+ const newPrefix = prefix + (isLast ? ' ' : '│ ');
590
+ this.printTree(child, newPrefix, lines, new Set([...visited, child]));
591
+ }
592
+ else {
593
+ lines.push(`${prefix}${isLast ? ' ' : '│ '}└── (cycle)`);
594
+ }
595
+ }
596
+ }
597
+ }
598
+ exports.WorkspaceManager = WorkspaceManager;
599
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/server/workspace.ts"],"names":[],"mappings":"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"}