hledger-lsp 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 (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +632 -0
  3. package/out/extension.d.ts +1 -0
  4. package/out/extension.d.ts.map +1 -0
  5. package/out/extension.js +2 -0
  6. package/out/extension.js.map +1 -0
  7. package/out/features/codeActions.d.ts +73 -0
  8. package/out/features/codeActions.d.ts.map +1 -0
  9. package/out/features/codeActions.js +417 -0
  10. package/out/features/codeActions.js.map +1 -0
  11. package/out/features/completion.d.ts +94 -0
  12. package/out/features/completion.d.ts.map +1 -0
  13. package/out/features/completion.js +323 -0
  14. package/out/features/completion.js.map +1 -0
  15. package/out/features/definition.d.ts +12 -0
  16. package/out/features/definition.d.ts.map +1 -0
  17. package/out/features/definition.js +61 -0
  18. package/out/features/definition.js.map +1 -0
  19. package/out/features/documentLinks.d.ts +17 -0
  20. package/out/features/documentLinks.d.ts.map +1 -0
  21. package/out/features/documentLinks.js +68 -0
  22. package/out/features/documentLinks.js.map +1 -0
  23. package/out/features/findReferences.d.ts +33 -0
  24. package/out/features/findReferences.d.ts.map +1 -0
  25. package/out/features/findReferences.js +79 -0
  26. package/out/features/findReferences.js.map +1 -0
  27. package/out/features/foldingRanges.d.ts +27 -0
  28. package/out/features/foldingRanges.d.ts.map +1 -0
  29. package/out/features/foldingRanges.js +111 -0
  30. package/out/features/foldingRanges.js.map +1 -0
  31. package/out/features/formatter.d.ts +70 -0
  32. package/out/features/formatter.d.ts.map +1 -0
  33. package/out/features/formatter.js +373 -0
  34. package/out/features/formatter.js.map +1 -0
  35. package/out/features/hover.d.ts +66 -0
  36. package/out/features/hover.d.ts.map +1 -0
  37. package/out/features/hover.js +387 -0
  38. package/out/features/hover.js.map +1 -0
  39. package/out/features/inlayHints.d.ts +43 -0
  40. package/out/features/inlayHints.d.ts.map +1 -0
  41. package/out/features/inlayHints.js +221 -0
  42. package/out/features/inlayHints.js.map +1 -0
  43. package/out/features/selectionRange.d.ts +47 -0
  44. package/out/features/selectionRange.d.ts.map +1 -0
  45. package/out/features/selectionRange.js +273 -0
  46. package/out/features/selectionRange.js.map +1 -0
  47. package/out/features/semanticTokens.d.ts +83 -0
  48. package/out/features/semanticTokens.d.ts.map +1 -0
  49. package/out/features/semanticTokens.js +370 -0
  50. package/out/features/semanticTokens.js.map +1 -0
  51. package/out/features/symbols.d.ts +47 -0
  52. package/out/features/symbols.d.ts.map +1 -0
  53. package/out/features/symbols.js +249 -0
  54. package/out/features/symbols.js.map +1 -0
  55. package/out/features/transactionAnalyzer.d.ts +63 -0
  56. package/out/features/transactionAnalyzer.d.ts.map +1 -0
  57. package/out/features/transactionAnalyzer.js +127 -0
  58. package/out/features/transactionAnalyzer.js.map +1 -0
  59. package/out/features/validator.d.ts +142 -0
  60. package/out/features/validator.d.ts.map +1 -0
  61. package/out/features/validator.js +633 -0
  62. package/out/features/validator.js.map +1 -0
  63. package/out/parser/ast.d.ts +37 -0
  64. package/out/parser/ast.d.ts.map +1 -0
  65. package/out/parser/ast.js +606 -0
  66. package/out/parser/ast.js.map +1 -0
  67. package/out/parser/includes.d.ts +25 -0
  68. package/out/parser/includes.d.ts.map +1 -0
  69. package/out/parser/includes.js +106 -0
  70. package/out/parser/includes.js.map +1 -0
  71. package/out/parser/index.d.ts +54 -0
  72. package/out/parser/index.d.ts.map +1 -0
  73. package/out/parser/index.js +146 -0
  74. package/out/parser/index.js.map +1 -0
  75. package/out/server/deps.d.ts +19 -0
  76. package/out/server/deps.d.ts.map +1 -0
  77. package/out/server/deps.js +77 -0
  78. package/out/server/deps.js.map +1 -0
  79. package/out/server/settings.d.ts +60 -0
  80. package/out/server/settings.d.ts.map +1 -0
  81. package/out/server/settings.js +110 -0
  82. package/out/server/settings.js.map +1 -0
  83. package/out/server.d.ts +3 -0
  84. package/out/server.d.ts.map +1 -0
  85. package/out/server.js +420 -0
  86. package/out/server.js.map +1 -0
  87. package/out/types.d.ts +84 -0
  88. package/out/types.d.ts.map +1 -0
  89. package/out/types.js +6 -0
  90. package/out/types.js.map +1 -0
  91. package/out/utils/index.d.ts +38 -0
  92. package/out/utils/index.d.ts.map +1 -0
  93. package/out/utils/index.js +89 -0
  94. package/out/utils/index.js.map +1 -0
  95. package/out/utils/uri.d.ts +32 -0
  96. package/out/utils/uri.d.ts.map +1 -0
  97. package/out/utils/uri.js +215 -0
  98. package/out/utils/uri.js.map +1 -0
  99. package/package.json +58 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;GAEG"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Utility functions for the hledger language server
3
+ */
4
+ /**
5
+ * Check if a line is a transaction header
6
+ * Transaction headers start with a date in YYYY-MM-DD or YYYY/MM/DD format
7
+ */
8
+ export declare function isTransactionHeader(line: string): boolean;
9
+ /**
10
+ * Check if a line is a posting (indented account line)
11
+ */
12
+ export declare function isPosting(line: string): boolean;
13
+ /**
14
+ * Check if a line is a comment
15
+ */
16
+ export declare function isComment(line: string): boolean;
17
+ /**
18
+ * Check if a line is a directive
19
+ */
20
+ export declare function isDirective(line: string): boolean;
21
+ /**
22
+ * Extract account name from a posting line
23
+ */
24
+ export declare function extractAccountFromPosting(line: string): string | null;
25
+ /**
26
+ * Parse a tag from a comment
27
+ * Tags are in the format tag:value or just tag:
28
+ */
29
+ export declare function extractTags(comment: string): Record<string, string>;
30
+ /**
31
+ * Get the indentation level of a line
32
+ */
33
+ export declare function getIndentationLevel(line: string): number;
34
+ /**
35
+ * Normalize account name (collapse multiple spaces)
36
+ */
37
+ export declare function normalizeAccountName(account: string): string;
38
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOzD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAG/C;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAG/C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAUjD;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKrE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUnE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGxD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5D"}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ /**
3
+ * Utility functions for the hledger language server
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isTransactionHeader = isTransactionHeader;
7
+ exports.isPosting = isPosting;
8
+ exports.isComment = isComment;
9
+ exports.isDirective = isDirective;
10
+ exports.extractAccountFromPosting = extractAccountFromPosting;
11
+ exports.extractTags = extractTags;
12
+ exports.getIndentationLevel = getIndentationLevel;
13
+ exports.normalizeAccountName = normalizeAccountName;
14
+ /**
15
+ * Check if a line is a transaction header
16
+ * Transaction headers start with a date in YYYY-MM-DD or YYYY/MM/DD format
17
+ */
18
+ function isTransactionHeader(line) {
19
+ const trimmed = line.trim();
20
+ if (!trimmed)
21
+ return false;
22
+ // Simple regex for date patterns
23
+ const datePattern = /^\d{4}[-/]\d{2}[-/]\d{2}/;
24
+ return datePattern.test(trimmed);
25
+ }
26
+ /**
27
+ * Check if a line is a posting (indented account line)
28
+ */
29
+ function isPosting(line) {
30
+ // Postings must be indented with at least one space or tab
31
+ return /^[ \t]+\S/.test(line);
32
+ }
33
+ /**
34
+ * Check if a line is a comment
35
+ */
36
+ function isComment(line) {
37
+ const trimmed = line.trim();
38
+ return trimmed.startsWith(';') || trimmed.startsWith('#');
39
+ }
40
+ /**
41
+ * Check if a line is a directive
42
+ */
43
+ function isDirective(line) {
44
+ const trimmed = line.trim();
45
+ const directives = ['account', 'commodity', 'payee', 'tag', 'include', 'alias', 'end'];
46
+ return directives.some(d => {
47
+ if (d === 'end') {
48
+ // 'end' can be standalone or followed by a space
49
+ return trimmed === d || trimmed.startsWith(d + ' ');
50
+ }
51
+ return trimmed.startsWith(d + ' ');
52
+ });
53
+ }
54
+ /**
55
+ * Extract account name from a posting line
56
+ */
57
+ function extractAccountFromPosting(line) {
58
+ const trimmed = line.trim();
59
+ // Account name is the first token after indentation
60
+ const match = trimmed.match(/^([^;\s]+(?:\s+[^;\s]+)*?)(?:\s{2,}|\s+\$|\s+[0-9-]|$)/);
61
+ return match ? match[1].trim() : null;
62
+ }
63
+ /**
64
+ * Parse a tag from a comment
65
+ * Tags are in the format tag:value or just tag:
66
+ */
67
+ function extractTags(comment) {
68
+ const tags = {};
69
+ const tagPattern = /(\w+):([^,\s]*)/g;
70
+ let match;
71
+ while ((match = tagPattern.exec(comment)) !== null) {
72
+ tags[match[1]] = match[2] || '';
73
+ }
74
+ return tags;
75
+ }
76
+ /**
77
+ * Get the indentation level of a line
78
+ */
79
+ function getIndentationLevel(line) {
80
+ const match = line.match(/^([ \t]+)/);
81
+ return match ? match[1].length : 0;
82
+ }
83
+ /**
84
+ * Normalize account name (collapse multiple spaces)
85
+ */
86
+ function normalizeAccountName(account) {
87
+ return account.replace(/\s+/g, ' ').trim();
88
+ }
89
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAMH,kDAOC;AAKD,8BAGC;AAKD,8BAGC;AAKD,kCAUC;AAKD,8DAKC;AAMD,kCAUC;AAKD,kDAGC;AAKD,oDAEC;AAnFD;;;GAGG;AACH,SAAgB,mBAAmB,CAAC,IAAY;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAE3B,iCAAiC;IACjC,MAAM,WAAW,GAAG,0BAA0B,CAAC;IAC/C,OAAO,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS,CAAC,IAAY;IACpC,2DAA2D;IAC3D,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS,CAAC,IAAY;IACpC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,OAAO,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAC5D,CAAC;AAED;;GAEG;AACH,SAAgB,WAAW,CAAC,IAAY;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,MAAM,UAAU,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IACvF,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;QACzB,IAAI,CAAC,KAAK,KAAK,EAAE,CAAC;YAChB,iDAAiD;YACjD,OAAO,OAAO,KAAK,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAgB,yBAAyB,CAAC,IAAY;IACpD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,oDAAoD;IACpD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;IACtF,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,SAAgB,WAAW,CAAC,OAAe;IACzC,MAAM,IAAI,GAA2B,EAAE,CAAC;IACxC,MAAM,UAAU,GAAG,kBAAkB,CAAC;IACtC,IAAI,KAAK,CAAC;IAEV,OAAO,CAAC,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACnD,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAClC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CAAC,IAAY;IAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACtC,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAAC,OAAe;IAClD,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { TextDocument } from 'vscode-languageserver-textdocument';
2
+ /**
3
+ * Convert a file:// URI to a filesystem path
4
+ * Properly decodes URI-encoded characters (e.g., %20 → space)
5
+ */
6
+ export declare function toFilePath(uri: string): string;
7
+ /**
8
+ * Ensure a path is represented as a file:// URI
9
+ * Properly encodes special characters (e.g., space → %20)
10
+ */
11
+ export declare function toFileUri(path: string): string;
12
+ /**
13
+ * Default fileReader implementation used by parser/server
14
+ */
15
+ export declare function defaultFileReader(uri: string): TextDocument | null;
16
+ /**
17
+ * Resolve include paths relative to a base URI.
18
+ * Behavior:
19
+ * - If includePath starts with 'file://': treat as absolute URI
20
+ * - If includePath starts with '/': treat as absolute filesystem path
21
+ * - If includePath starts with '~': expand tilde to home directory
22
+ * - Otherwise, treat as relative to the directory of baseUri
23
+ */
24
+ export declare function resolveIncludePath(includePath: string, baseUri: string): string;
25
+ /**
26
+ * Resolve include paths into one or more file:// URIs using fast-glob.
27
+ * This delegates glob expansion to fast-glob, configured to exclude dotfiles
28
+ * and to return absolute file paths. The pattern is interpreted relative to
29
+ * the including file's directory when not absolute.
30
+ */
31
+ export declare function resolveIncludePaths(includePath: string, baseUri: string): string[];
32
+ //# sourceMappingURL=uri.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uri.d.ts","sourceRoot":"","sources":["../../src/utils/uri.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAElE;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAgB9C;AA2BD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO9C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAWlE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAoC/E;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAyClF"}
@@ -0,0 +1,215 @@
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.toFilePath = toFilePath;
40
+ exports.toFileUri = toFileUri;
41
+ exports.defaultFileReader = defaultFileReader;
42
+ exports.resolveIncludePath = resolveIncludePath;
43
+ exports.resolveIncludePaths = resolveIncludePaths;
44
+ const fs = __importStar(require("fs"));
45
+ const path = __importStar(require("path"));
46
+ const os = __importStar(require("os"));
47
+ const fast_glob_1 = __importDefault(require("fast-glob"));
48
+ const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
49
+ /**
50
+ * Convert a file:// URI to a filesystem path
51
+ * Properly decodes URI-encoded characters (e.g., %20 → space)
52
+ */
53
+ function toFilePath(uri) {
54
+ if (uri.startsWith('file://')) {
55
+ const encodedPath = uri.substring(7);
56
+ // Decode each path component separately to handle encoded characters
57
+ const parts = encodedPath.split('/');
58
+ const decoded = parts.map(part => {
59
+ try {
60
+ return decodeURIComponent(part);
61
+ }
62
+ catch {
63
+ // If decoding fails, return the part as-is
64
+ return part;
65
+ }
66
+ }).join('/');
67
+ return decoded;
68
+ }
69
+ return uri;
70
+ }
71
+ /**
72
+ * Encode a path component for use in a file:// URI
73
+ * Encodes characters that are not allowed in URI paths according to RFC 3986
74
+ * Allowed unencoded: unreserved (A-Za-z0-9-._~) + sub-delims (!$&'()*+,;=) + : @
75
+ */
76
+ function encodePathComponent(component) {
77
+ // Characters that should NOT be encoded in file URI paths (per RFC 3986)
78
+ // unreserved: A-Z a-z 0-9 - . _ ~
79
+ // sub-delims: ! $ & ' ( ) * + , ; =
80
+ // also allowed in paths: : @
81
+ const allowedChars = /[A-Za-z0-9\-._~!$&'()*+,;=:@]/;
82
+ let result = '';
83
+ for (let i = 0; i < component.length; i++) {
84
+ const char = component[i];
85
+ if (allowedChars.test(char)) {
86
+ result += char;
87
+ }
88
+ else {
89
+ // Encode this character
90
+ result += '%' + char.charCodeAt(0).toString(16).toUpperCase().padStart(2, '0');
91
+ }
92
+ }
93
+ return result;
94
+ }
95
+ /**
96
+ * Ensure a path is represented as a file:// URI
97
+ * Properly encodes special characters (e.g., space → %20)
98
+ */
99
+ function toFileUri(path) {
100
+ if (path.startsWith('file://'))
101
+ return path;
102
+ // Encode each path component separately to preserve slashes
103
+ const parts = path.split('/');
104
+ const encoded = parts.map(part => encodePathComponent(part)).join('/');
105
+ return `file://${encoded}`;
106
+ }
107
+ /**
108
+ * Default fileReader implementation used by parser/server
109
+ */
110
+ function defaultFileReader(uri) {
111
+ try {
112
+ const filePath = toFilePath(uri);
113
+ if (fs.existsSync(filePath)) {
114
+ const content = fs.readFileSync(filePath, 'utf-8');
115
+ return vscode_languageserver_textdocument_1.TextDocument.create(uri, 'hledger', 1, content);
116
+ }
117
+ return null;
118
+ }
119
+ catch (error) {
120
+ return null;
121
+ }
122
+ }
123
+ /**
124
+ * Resolve include paths relative to a base URI.
125
+ * Behavior:
126
+ * - If includePath starts with 'file://': treat as absolute URI
127
+ * - If includePath starts with '/': treat as absolute filesystem path
128
+ * - If includePath starts with '~': expand tilde to home directory
129
+ * - Otherwise, treat as relative to the directory of baseUri
130
+ */
131
+ function resolveIncludePath(includePath, baseUri) {
132
+ // Handle file:// URI (e.g. file:///home/user/main.journal)
133
+ if (includePath.startsWith('file://')) {
134
+ // Already a file URI, return as-is
135
+ return includePath;
136
+ }
137
+ // Expand tilde to home directory (e.g. ~/main.journal)
138
+ if (includePath.startsWith('~')) {
139
+ const home = os.homedir();
140
+ // support both '~' and '~/...'
141
+ let rest = '';
142
+ if (includePath === '~') {
143
+ rest = '';
144
+ }
145
+ else if (includePath.startsWith('~/')) {
146
+ // remove the leading '~/'
147
+ rest = includePath.slice(2);
148
+ }
149
+ else {
150
+ // something like '~user/foo' - leave as-is for now (resolve will handle)
151
+ rest = includePath.slice(1);
152
+ }
153
+ const resolved = path.resolve(home, rest);
154
+ return toFileUri(resolved);
155
+ }
156
+ // If includePath starts with '/', treat it as an absolute filesystem path
157
+ // (matching hledger behaviour: leading slash means system-root absolute path)
158
+ if (includePath.startsWith('/')) {
159
+ const resolved = path.resolve(includePath);
160
+ return toFileUri(resolved);
161
+ }
162
+ // Relative to the including file
163
+ const basePath = toFilePath(baseUri);
164
+ const baseDir = path.dirname(basePath);
165
+ const resolved = path.join(baseDir, includePath);
166
+ return toFileUri(resolved);
167
+ }
168
+ /**
169
+ * Resolve include paths into one or more file:// URIs using fast-glob.
170
+ * This delegates glob expansion to fast-glob, configured to exclude dotfiles
171
+ * and to return absolute file paths. The pattern is interpreted relative to
172
+ * the including file's directory when not absolute.
173
+ */
174
+ function resolveIncludePaths(includePath, baseUri) {
175
+ // If not a glob, reuse resolveIncludePath for single-path cases
176
+ if (!/[*?\[\]{}]/.test(includePath)) {
177
+ return [resolveIncludePath(includePath, baseUri)];
178
+ }
179
+ // Determine cwd and pattern for fast-glob
180
+ let cwd;
181
+ let pattern = includePath;
182
+ if (includePath.startsWith('/')) {
183
+ // absolute pattern: remove leading slash and search from filesystem root
184
+ cwd = '/';
185
+ pattern = includePath.slice(1);
186
+ }
187
+ else if (includePath.startsWith('~')) {
188
+ const home = os.homedir();
189
+ if (includePath === '~') {
190
+ cwd = home;
191
+ pattern = '';
192
+ }
193
+ else if (includePath.startsWith('~/')) {
194
+ cwd = home;
195
+ pattern = includePath.slice(2);
196
+ }
197
+ else {
198
+ cwd = os.homedir();
199
+ pattern = includePath.slice(1);
200
+ }
201
+ }
202
+ else {
203
+ const basePath = toFilePath(baseUri);
204
+ cwd = path.dirname(basePath);
205
+ pattern = includePath;
206
+ }
207
+ // fast-glob options: only files, absolute paths, ignore dotfiles/directories
208
+ const entries = fast_glob_1.default.sync(pattern, { cwd, onlyFiles: true, absolute: true, dot: false });
209
+ // Exclude the including file itself if present
210
+ const includingFile = toFilePath(baseUri);
211
+ const filtered = entries.filter(p => p !== includingFile).map(p => toFileUri(p));
212
+ filtered.sort();
213
+ return filtered;
214
+ }
215
+ //# sourceMappingURL=uri.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uri.js","sourceRoot":"","sources":["../../src/utils/uri.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "hledger-lsp",
3
+ "version": "0.1.0",
4
+ "description": "Language Server Protocol implementation for hledger plain text accounting",
5
+ "main": "./out/server.js",
6
+ "bin": {
7
+ "hledger-lsp": "./out/server.js"
8
+ },
9
+ "files": [
10
+ "out/**/*",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc -p .",
16
+ "watch": "tsc -watch -p .",
17
+ "lint": "eslint src --ext ts",
18
+ "test": "jest",
19
+ "test:watch": "jest --watch",
20
+ "test:coverage": "jest --coverage",
21
+ "test:verbose": "jest --verbose",
22
+ "prepare": "npm run build"
23
+ },
24
+ "keywords": [
25
+ "hledger",
26
+ "lsp",
27
+ "language-server",
28
+ "accounting"
29
+ ],
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/ptimoney/hledger-lsp.git"
33
+ },
34
+ "bugs": {
35
+ "url": "https://github.com/ptimoney/hledger-lsp/issues"
36
+ },
37
+ "homepage": "https://github.com/ptimoney/hledger-lsp#readme",
38
+ "author": "Patrick Timoney",
39
+ "license": "MIT",
40
+ "engines": {
41
+ "node": ">=16.0.0"
42
+ },
43
+ "dependencies": {
44
+ "vscode-languageserver": "^9.0.1",
45
+ "fast-glob": "^3.2.12",
46
+ "vscode-languageserver-textdocument": "^1.0.12"
47
+ },
48
+ "devDependencies": {
49
+ "@types/jest": "^30.0.0",
50
+ "@types/node": "^24.10.0",
51
+ "@typescript-eslint/eslint-plugin": "^8.46.3",
52
+ "@typescript-eslint/parser": "^8.46.3",
53
+ "eslint": "^9.39.1",
54
+ "jest": "^30.2.0",
55
+ "ts-jest": "^29.4.5",
56
+ "typescript": "^5.9.3"
57
+ }
58
+ }