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,221 @@
1
+ "use strict";
2
+ /**
3
+ * Inlay hints provider for hledger language server
4
+ *
5
+ * Provides inline, non-intrusive information:
6
+ * - Inferred amounts on postings without explicit amounts
7
+ * - Running balances after each posting
8
+ * - Cost conversions when costs are involved
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.inlayHintsProvider = exports.InlayHintsProvider = void 0;
12
+ const vscode_languageserver_1 = require("vscode-languageserver");
13
+ const DEFAULT_SETTINGS = {
14
+ showInferredAmounts: true,
15
+ showRunningBalances: false, // Can be noisy, off by default
16
+ showCostConversions: true
17
+ };
18
+ class InlayHintsProvider {
19
+ /**
20
+ * Format an amount with proper commodity placement
21
+ */
22
+ formatAmount(quantity, commodity, parsed) {
23
+ // Find commodity format if available
24
+ const commodityInfo = parsed.commodities.find(c => c.name === commodity);
25
+ // Determine commodity placement
26
+ let commodityBefore = '';
27
+ let commodityAfter = '';
28
+ if (commodityInfo?.format) {
29
+ if (commodityInfo.format.symbolOnLeft) {
30
+ commodityBefore = commodityInfo.format.symbol || commodity;
31
+ }
32
+ else {
33
+ commodityAfter = commodityInfo.format.symbol || commodity;
34
+ }
35
+ }
36
+ else if (commodity) {
37
+ // Default heuristic: common currencies go on left
38
+ const leftSymbols = ['$', '€', '£', '¥'];
39
+ if (leftSymbols.includes(commodity)) {
40
+ commodityBefore = commodity;
41
+ }
42
+ else {
43
+ commodityAfter = ' ' + commodity;
44
+ }
45
+ }
46
+ // Format the number
47
+ const formattedNumber = quantity.toFixed(2);
48
+ // Build the formatted amount
49
+ return commodityBefore + formattedNumber + commodityAfter;
50
+ }
51
+ /**
52
+ * Provide inlay hints for a document
53
+ */
54
+ provideInlayHints(document, range, parsed, settings) {
55
+ const config = { ...DEFAULT_SETTINGS, ...settings };
56
+ const hints = [];
57
+ // Only process transactions within the requested range
58
+ for (const transaction of parsed.transactions) {
59
+ const txLine = transaction.line ?? 0;
60
+ // Skip transactions outside the range
61
+ if (txLine < range.start.line || txLine > range.end.line) {
62
+ continue;
63
+ }
64
+ // Inferred amount hints
65
+ if (config.showInferredAmounts) {
66
+ hints.push(...this.getInferredAmountHints(document, transaction, parsed));
67
+ }
68
+ // Running balance hints
69
+ if (config.showRunningBalances) {
70
+ hints.push(...this.getRunningBalanceHints(document, transaction, parsed));
71
+ }
72
+ // Cost conversion hints
73
+ if (config.showCostConversions) {
74
+ hints.push(...this.getCostConversionHints(document, transaction, parsed));
75
+ }
76
+ }
77
+ return hints;
78
+ }
79
+ /**
80
+ * Get hints for inferred amounts (postings without explicit amounts)
81
+ */
82
+ getInferredAmountHints(document, transaction, parsed) {
83
+ const hints = [];
84
+ // Calculate which posting(s) have inferred amounts
85
+ const postingsWithAmounts = transaction.postings.filter(p => p.amount);
86
+ // If all postings have amounts, nothing to infer
87
+ if (postingsWithAmounts.length === transaction.postings.length) {
88
+ return hints;
89
+ }
90
+ // Calculate the inferred amount(s)
91
+ // Group by commodity
92
+ const balances = new Map();
93
+ for (const posting of transaction.postings) {
94
+ if (posting.amount) {
95
+ // Use cost commodity if cost is present
96
+ if (posting.cost) {
97
+ const costCommodity = posting.cost.amount.commodity || '';
98
+ let costValue;
99
+ if (posting.cost.type === 'unit') {
100
+ costValue = posting.amount.quantity * posting.cost.amount.quantity;
101
+ }
102
+ else {
103
+ costValue = posting.cost.amount.quantity;
104
+ }
105
+ const current = balances.get(costCommodity) || 0;
106
+ balances.set(costCommodity, current + costValue);
107
+ }
108
+ else {
109
+ const commodity = posting.amount.commodity || '';
110
+ const current = balances.get(commodity) || 0;
111
+ balances.set(commodity, current + posting.amount.quantity);
112
+ }
113
+ }
114
+ }
115
+ // The inferred amount is the negation of the sum
116
+ const inferredAmounts = [];
117
+ for (const [commodity, balance] of balances.entries()) {
118
+ const amount = -balance;
119
+ inferredAmounts.push(this.formatAmount(amount, commodity, parsed));
120
+ }
121
+ // Find posting(s) without amounts and add hints
122
+ const txLine = transaction.line ?? 0;
123
+ let postingIndex = 0;
124
+ for (const posting of transaction.postings) {
125
+ if (!posting.amount) {
126
+ const lineNum = txLine + 1 + postingIndex; // +1 for header, then posting index
127
+ const line = document.getText({
128
+ start: { line: lineNum, character: 0 },
129
+ end: { line: lineNum, character: Number.MAX_SAFE_INTEGER }
130
+ });
131
+ // Find end of account name
132
+ const accountEnd = line.indexOf(posting.account) + posting.account.length;
133
+ hints.push({
134
+ position: vscode_languageserver_1.Position.create(lineNum, accountEnd),
135
+ label: ` ${inferredAmounts.join(', ')}`,
136
+ kind: vscode_languageserver_1.InlayHintKind.Parameter,
137
+ paddingLeft: true
138
+ });
139
+ }
140
+ postingIndex++;
141
+ }
142
+ return hints;
143
+ }
144
+ /**
145
+ * Get hints for running balances after each posting
146
+ */
147
+ getRunningBalanceHints(document, transaction, parsed) {
148
+ const hints = [];
149
+ // Track running balances across all transactions
150
+ // This would need to process ALL transactions up to this point
151
+ // For now, we'll just show transaction-local balance changes
152
+ const txLine = transaction.line ?? 0;
153
+ let postingIndex = 0;
154
+ for (const posting of transaction.postings) {
155
+ if (posting.amount) {
156
+ const lineNum = txLine + 1 + postingIndex;
157
+ const line = document.getText({
158
+ start: { line: lineNum, character: 0 },
159
+ end: { line: lineNum, character: Number.MAX_SAFE_INTEGER }
160
+ });
161
+ // Find end of line (before comment if any)
162
+ let endPos = line.length;
163
+ const commentPos = line.search(/[;#]/);
164
+ if (commentPos >= 0) {
165
+ endPos = commentPos;
166
+ }
167
+ const formattedAmount = this.formatAmount(posting.amount.quantity, posting.amount.commodity || '', parsed);
168
+ const balanceHint = `balance: ${formattedAmount}`;
169
+ hints.push({
170
+ position: vscode_languageserver_1.Position.create(lineNum, endPos),
171
+ label: ` (${balanceHint})`,
172
+ kind: vscode_languageserver_1.InlayHintKind.Type,
173
+ paddingLeft: true
174
+ });
175
+ }
176
+ postingIndex++;
177
+ }
178
+ return hints;
179
+ }
180
+ /**
181
+ * Get hints for cost conversions
182
+ */
183
+ getCostConversionHints(document, transaction, parsed) {
184
+ const hints = [];
185
+ const txLine = transaction.line ?? 0;
186
+ let postingIndex = 0;
187
+ for (const posting of transaction.postings) {
188
+ if (posting.amount && posting.cost) {
189
+ let totalCost;
190
+ if (posting.cost.type === 'unit') {
191
+ totalCost = posting.amount.quantity * posting.cost.amount.quantity;
192
+ }
193
+ else {
194
+ totalCost = posting.cost.amount.quantity;
195
+ }
196
+ const lineNum = txLine + 1 + postingIndex;
197
+ const line = document.getText({
198
+ start: { line: lineNum, character: 0 },
199
+ end: { line: lineNum, character: Number.MAX_SAFE_INTEGER }
200
+ });
201
+ // Find position after cost notation
202
+ const costMatch = line.match(/@@?[^;#]*/);
203
+ if (costMatch) {
204
+ const costEnd = line.indexOf(costMatch[0]) + costMatch[0].length;
205
+ const formattedCost = this.formatAmount(totalCost, posting.cost.amount.commodity || '', parsed);
206
+ hints.push({
207
+ position: vscode_languageserver_1.Position.create(lineNum, costEnd),
208
+ label: ` = ${formattedCost}`,
209
+ kind: vscode_languageserver_1.InlayHintKind.Type,
210
+ paddingLeft: true
211
+ });
212
+ }
213
+ }
214
+ postingIndex++;
215
+ }
216
+ return hints;
217
+ }
218
+ }
219
+ exports.InlayHintsProvider = InlayHintsProvider;
220
+ exports.inlayHintsProvider = new InlayHintsProvider();
221
+ //# sourceMappingURL=inlayHints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inlayHints.js","sourceRoot":"","sources":["../../src/features/inlayHints.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Selection range provider for hledger journal files
3
+ *
4
+ * Provides smart text selection expansion:
5
+ * - Account name -> Posting -> Transaction
6
+ * - Amount -> Posting -> Transaction
7
+ * - Description -> Transaction header -> Transaction
8
+ */
9
+ import { SelectionRange, Position } from 'vscode-languageserver/node';
10
+ import { TextDocument } from 'vscode-languageserver-textdocument';
11
+ import { ParsedDocument } from '../types';
12
+ export declare class SelectionRangeProvider {
13
+ /**
14
+ * Provide selection ranges for a position
15
+ */
16
+ provideSelectionRanges(document: TextDocument, positions: Position[], parsedDoc: ParsedDocument): SelectionRange[] | null;
17
+ /**
18
+ * Get selection range hierarchy at a specific position
19
+ */
20
+ private getSelectionRangeAtPosition;
21
+ /**
22
+ * Get selection range hierarchy for a transaction header
23
+ */
24
+ private getTransactionHeaderSelectionRange;
25
+ /**
26
+ * Get selection range hierarchy for a posting
27
+ */
28
+ private getPostingSelectionRange;
29
+ /**
30
+ * Get the range of the word at a specific character position
31
+ */
32
+ private getWordRangeAtPosition;
33
+ /**
34
+ * Get the range of the account name in a posting line
35
+ */
36
+ private getAccountRangeInPosting;
37
+ /**
38
+ * Find the range of a transaction starting from its header line
39
+ */
40
+ private findTransactionRange;
41
+ /**
42
+ * Find the range of a transaction starting from one of its posting lines
43
+ */
44
+ private findTransactionRangeFromPosting;
45
+ }
46
+ export declare const selectionRangeProvider: SelectionRangeProvider;
47
+ //# sourceMappingURL=selectionRange.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectionRange.d.ts","sourceRoot":"","sources":["../../src/features/selectionRange.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG1C,qBAAa,sBAAsB;IACjC;;OAEG;IACH,sBAAsB,CAAC,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,cAAc,GAAG,cAAc,EAAE,GAAG,IAAI;IAiBzH;;OAEG;IACH,OAAO,CAAC,2BAA2B;IA8BnC;;OAEG;IACH,OAAO,CAAC,kCAAkC;IA4C1C;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA8EhC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA6B9B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAyChC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAyB5B;;OAEG;IACH,OAAO,CAAC,+BAA+B;CAqBxC;AAED,eAAO,MAAM,sBAAsB,wBAA+B,CAAC"}
@@ -0,0 +1,273 @@
1
+ "use strict";
2
+ /**
3
+ * Selection range provider for hledger journal files
4
+ *
5
+ * Provides smart text selection expansion:
6
+ * - Account name -> Posting -> Transaction
7
+ * - Amount -> Posting -> Transaction
8
+ * - Description -> Transaction header -> Transaction
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.selectionRangeProvider = exports.SelectionRangeProvider = void 0;
12
+ const index_1 = require("../utils/index");
13
+ class SelectionRangeProvider {
14
+ /**
15
+ * Provide selection ranges for a position
16
+ */
17
+ provideSelectionRanges(document, positions, parsedDoc) {
18
+ if (positions.length === 0) {
19
+ return null;
20
+ }
21
+ const selectionRanges = [];
22
+ for (const position of positions) {
23
+ const range = this.getSelectionRangeAtPosition(document, position, parsedDoc);
24
+ if (range) {
25
+ selectionRanges.push(range);
26
+ }
27
+ }
28
+ return selectionRanges.length > 0 ? selectionRanges : null;
29
+ }
30
+ /**
31
+ * Get selection range hierarchy at a specific position
32
+ */
33
+ getSelectionRangeAtPosition(document, position, parsedDoc) {
34
+ const lines = document.getText().split('\n');
35
+ const currentLine = lines[position.line];
36
+ if (!currentLine)
37
+ return null;
38
+ const trimmed = currentLine.trim();
39
+ // Check if we're on a transaction header
40
+ if ((0, index_1.isTransactionHeader)(trimmed)) {
41
+ return this.getTransactionHeaderSelectionRange(currentLine, position, lines, position.line, parsedDoc);
42
+ }
43
+ // Check if we're on a posting
44
+ if ((0, index_1.isPosting)(currentLine)) {
45
+ return this.getPostingSelectionRange(currentLine, position, lines, position.line, parsedDoc);
46
+ }
47
+ // For other lines (comments, directives), just select the whole line
48
+ return {
49
+ range: {
50
+ start: { line: position.line, character: 0 },
51
+ end: { line: position.line, character: currentLine.length }
52
+ }
53
+ };
54
+ }
55
+ /**
56
+ * Get selection range hierarchy for a transaction header
57
+ */
58
+ getTransactionHeaderSelectionRange(line, position, lines, lineIndex, parsedDoc) {
59
+ // Find the word/token at the cursor position
60
+ const wordRange = this.getWordRangeAtPosition(line, position.character);
61
+ if (!wordRange)
62
+ return null;
63
+ // Level 1: Current word (date, status, description part, etc.)
64
+ const wordSelection = {
65
+ range: {
66
+ start: { line: position.line, character: wordRange.start },
67
+ end: { line: position.line, character: wordRange.end }
68
+ }
69
+ };
70
+ // Level 2: Entire transaction header line
71
+ const headerSelection = {
72
+ range: {
73
+ start: { line: position.line, character: 0 },
74
+ end: { line: position.line, character: line.length }
75
+ },
76
+ parent: undefined
77
+ };
78
+ wordSelection.parent = headerSelection;
79
+ // Level 3: Entire transaction (including postings)
80
+ const transactionRange = this.findTransactionRange(lineIndex, lines);
81
+ if (transactionRange) {
82
+ const transactionSelection = {
83
+ range: {
84
+ start: { line: transactionRange.start, character: 0 },
85
+ end: { line: transactionRange.end, character: lines[transactionRange.end]?.length || 0 }
86
+ }
87
+ };
88
+ headerSelection.parent = transactionSelection;
89
+ }
90
+ return wordSelection;
91
+ }
92
+ /**
93
+ * Get selection range hierarchy for a posting
94
+ */
95
+ getPostingSelectionRange(line, position, lines, lineIndex, parsedDoc) {
96
+ // Find the word/token at the cursor position
97
+ const wordRange = this.getWordRangeAtPosition(line, position.character);
98
+ if (!wordRange)
99
+ return null;
100
+ // Level 1: Current word (account name part, amount, commodity, etc.)
101
+ const wordSelection = {
102
+ range: {
103
+ start: { line: position.line, character: wordRange.start },
104
+ end: { line: position.line, character: wordRange.end }
105
+ }
106
+ };
107
+ // Level 2: Full account name if cursor is in account
108
+ const accountRange = this.getAccountRangeInPosting(line);
109
+ if (accountRange && position.character >= accountRange.start && position.character <= accountRange.end) {
110
+ const accountSelection = {
111
+ range: {
112
+ start: { line: position.line, character: accountRange.start },
113
+ end: { line: position.line, character: accountRange.end }
114
+ },
115
+ parent: undefined
116
+ };
117
+ wordSelection.parent = accountSelection;
118
+ // Level 3: Entire posting line
119
+ const postingSelection = {
120
+ range: {
121
+ start: { line: position.line, character: 0 },
122
+ end: { line: position.line, character: line.length }
123
+ }
124
+ };
125
+ accountSelection.parent = postingSelection;
126
+ // Level 4: Entire transaction
127
+ const transactionRange = this.findTransactionRangeFromPosting(lineIndex, lines);
128
+ if (transactionRange) {
129
+ const transactionSelection = {
130
+ range: {
131
+ start: { line: transactionRange.start, character: 0 },
132
+ end: { line: transactionRange.end, character: lines[transactionRange.end]?.length || 0 }
133
+ }
134
+ };
135
+ postingSelection.parent = transactionSelection;
136
+ }
137
+ return wordSelection;
138
+ }
139
+ // If not in account, just do word -> posting line -> transaction
140
+ const postingSelection = {
141
+ range: {
142
+ start: { line: position.line, character: 0 },
143
+ end: { line: position.line, character: line.length }
144
+ }
145
+ };
146
+ wordSelection.parent = postingSelection;
147
+ const transactionRange = this.findTransactionRangeFromPosting(lineIndex, lines);
148
+ if (transactionRange) {
149
+ const transactionSelection = {
150
+ range: {
151
+ start: { line: transactionRange.start, character: 0 },
152
+ end: { line: transactionRange.end, character: lines[transactionRange.end]?.length || 0 }
153
+ }
154
+ };
155
+ postingSelection.parent = transactionSelection;
156
+ }
157
+ return wordSelection;
158
+ }
159
+ /**
160
+ * Get the range of the word at a specific character position
161
+ */
162
+ getWordRangeAtPosition(line, character) {
163
+ if (character < 0 || character > line.length)
164
+ return null;
165
+ // If at whitespace, find next non-whitespace
166
+ while (character < line.length && /\s/.test(line[character])) {
167
+ character++;
168
+ }
169
+ if (character >= line.length)
170
+ return null;
171
+ // Find word boundaries
172
+ let start = character;
173
+ let end = character;
174
+ // Move start backwards to find word start
175
+ while (start > 0 && /[^\s:;#]/.test(line[start - 1])) {
176
+ start--;
177
+ }
178
+ // Move end forwards to find word end
179
+ while (end < line.length && /[^\s:;#]/.test(line[end])) {
180
+ end++;
181
+ }
182
+ if (start === end)
183
+ return null;
184
+ return { start, end };
185
+ }
186
+ /**
187
+ * Get the range of the account name in a posting line
188
+ */
189
+ getAccountRangeInPosting(line) {
190
+ // Find first non-whitespace (start of account)
191
+ let start = 0;
192
+ while (start < line.length && /\s/.test(line[start])) {
193
+ start++;
194
+ }
195
+ // Find end of account (two or more spaces, tab, or amount/comment)
196
+ let end = start;
197
+ let consecutiveSpaces = 0;
198
+ while (end < line.length) {
199
+ const char = line[end];
200
+ if (char === ' ') {
201
+ consecutiveSpaces++;
202
+ // Two consecutive spaces mark end of account
203
+ if (consecutiveSpaces >= 2) {
204
+ end -= consecutiveSpaces; // Back up to before the spaces
205
+ break;
206
+ }
207
+ }
208
+ else if (char === '\t' || char === ';' || char === '#') {
209
+ // Tab or comment marks end of account
210
+ break;
211
+ }
212
+ else {
213
+ consecutiveSpaces = 0;
214
+ }
215
+ end++;
216
+ }
217
+ // Trim trailing single space if any
218
+ while (end > start && line[end - 1] === ' ') {
219
+ end--;
220
+ }
221
+ if (start === end)
222
+ return null;
223
+ return { start, end };
224
+ }
225
+ /**
226
+ * Find the range of a transaction starting from its header line
227
+ */
228
+ findTransactionRange(startLine, lines) {
229
+ let endLine = startLine;
230
+ // Find where the transaction ends
231
+ for (let i = startLine + 1; i < lines.length; i++) {
232
+ const line = lines[i];
233
+ const trimmed = line.trim();
234
+ // Empty line marks end of transaction
235
+ if (!trimmed) {
236
+ break;
237
+ }
238
+ // If it's a posting or comment, extend the range
239
+ if ((0, index_1.isPosting)(line) || trimmed.startsWith(';') || trimmed.startsWith('#')) {
240
+ endLine = i;
241
+ }
242
+ else if ((0, index_1.isTransactionHeader)(trimmed)) {
243
+ // Hit the next transaction, stop here
244
+ break;
245
+ }
246
+ }
247
+ return { start: startLine, end: endLine };
248
+ }
249
+ /**
250
+ * Find the range of a transaction starting from one of its posting lines
251
+ */
252
+ findTransactionRangeFromPosting(postingLine, lines) {
253
+ // Find the transaction header by going backwards
254
+ let headerLine = postingLine;
255
+ for (let i = postingLine - 1; i >= 0; i--) {
256
+ const line = lines[i];
257
+ const trimmed = line.trim();
258
+ if (!trimmed) {
259
+ // Hit empty line before finding header
260
+ break;
261
+ }
262
+ if ((0, index_1.isTransactionHeader)(trimmed)) {
263
+ headerLine = i;
264
+ break;
265
+ }
266
+ }
267
+ // Now find the end from the header
268
+ return this.findTransactionRange(headerLine, lines);
269
+ }
270
+ }
271
+ exports.SelectionRangeProvider = SelectionRangeProvider;
272
+ exports.selectionRangeProvider = new SelectionRangeProvider();
273
+ //# sourceMappingURL=selectionRange.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectionRange.js","sourceRoot":"","sources":["../../src/features/selectionRange.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAKH,0CAAgE;AAEhE,MAAa,sBAAsB;IACjC;;OAEG;IACH,sBAAsB,CAAC,QAAsB,EAAE,SAAqB,EAAE,SAAyB;QAC7F,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,eAAe,GAAqB,EAAE,CAAC;QAE7C,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,IAAI,CAAC,2BAA2B,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;YAC9E,IAAI,KAAK,EAAE,CAAC;gBACV,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QAED,OAAO,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7D,CAAC;IAED;;OAEG;IACK,2BAA2B,CACjC,QAAsB,EACtB,QAAkB,EAClB,SAAyB;QAEzB,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAC;QAE9B,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;QAEnC,yCAAyC;QACzC,IAAI,IAAA,2BAAmB,EAAC,OAAO,CAAC,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC,kCAAkC,CAAC,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACzG,CAAC;QAED,8BAA8B;QAC9B,IAAI,IAAA,iBAAS,EAAC,WAAW,CAAC,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC,wBAAwB,CAAC,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC/F,CAAC;QAED,qEAAqE;QACrE,OAAO;YACL,KAAK,EAAE;gBACL,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE;gBAC5C,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE;aAC5D;SACF,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,kCAAkC,CACxC,IAAY,EACZ,QAAkB,EAClB,KAAe,EACf,SAAiB,EACjB,SAAyB;QAEzB,6CAA6C;QAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;QACxE,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAE5B,+DAA+D;QAC/D,MAAM,aAAa,GAAmB;YACpC,KAAK,EAAE;gBACL,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,KAAK,EAAE;gBAC1D,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,GAAG,EAAE;aACvD;SACF,CAAC;QAEF,0CAA0C;QAC1C,MAAM,eAAe,GAAmB;YACtC,KAAK,EAAE;gBACL,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE;gBAC5C,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE;aACrD;YACD,MAAM,EAAE,SAAS;SAClB,CAAC;QACF,aAAa,CAAC,MAAM,GAAG,eAAe,CAAC;QAEvC,mDAAmD;QACnD,MAAM,gBAAgB,GAAG,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACrE,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,oBAAoB,GAAmB;gBAC3C,KAAK,EAAE;oBACL,KAAK,EAAE,EAAE,IAAI,EAAE,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE;oBACrD,GAAG,EAAE,EAAE,IAAI,EAAE,gBAAgB,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC,EAAE;iBACzF;aACF,CAAC;YACF,eAAe,CAAC,MAAM,GAAG,oBAAoB,CAAC;QAChD,CAAC;QAED,OAAO,aAAa,CAAC;IACvB,CAAC;IAED;;OAEG;IACK,wBAAwB,CAC9B,IAAY,EACZ,QAAkB,EAClB,KAAe,EACf,SAAiB,EACjB,SAAyB;QAEzB,6CAA6C;QAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;QACxE,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAE5B,qEAAqE;QACrE,MAAM,aAAa,GAAmB;YACpC,KAAK,EAAE;gBACL,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,KAAK,EAAE;gBAC1D,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,GAAG,EAAE;aACvD;SACF,CAAC;QAEF,qDAAqD;QACrD,MAAM,YAAY,GAAG,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC;QACzD,IAAI,YAAY,IAAI,QAAQ,CAAC,SAAS,IAAI,YAAY,CAAC,KAAK,IAAI,QAAQ,CAAC,SAAS,IAAI,YAAY,CAAC,GAAG,EAAE,CAAC;YACvG,MAAM,gBAAgB,GAAmB;gBACvC,KAAK,EAAE;oBACL,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,CAAC,KAAK,EAAE;oBAC7D,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,CAAC,GAAG,EAAE;iBAC1D;gBACD,MAAM,EAAE,SAAS;aAClB,CAAC;YACF,aAAa,CAAC,MAAM,GAAG,gBAAgB,CAAC;YAExC,+BAA+B;YAC/B,MAAM,gBAAgB,GAAmB;gBACvC,KAAK,EAAE;oBACL,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE;oBAC5C,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE;iBACrD;aACF,CAAC;YACF,gBAAgB,CAAC,MAAM,GAAG,gBAAgB,CAAC;YAE3C,8BAA8B;YAC9B,MAAM,gBAAgB,GAAG,IAAI,CAAC,+BAA+B,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YAChF,IAAI,gBAAgB,EAAE,CAAC;gBACrB,MAAM,oBAAoB,GAAmB;oBAC3C,KAAK,EAAE;wBACL,KAAK,EAAE,EAAE,IAAI,EAAE,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE;wBACrD,GAAG,EAAE,EAAE,IAAI,EAAE,gBAAgB,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC,EAAE;qBACzF;iBACF,CAAC;gBACF,gBAAgB,CAAC,MAAM,GAAG,oBAAoB,CAAC;YACjD,CAAC;YAED,OAAO,aAAa,CAAC;QACvB,CAAC;QAED,iEAAiE;QACjE,MAAM,gBAAgB,GAAmB;YACvC,KAAK,EAAE;gBACL,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE;gBAC5C,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE;aACrD;SACF,CAAC;QACF,aAAa,CAAC,MAAM,GAAG,gBAAgB,CAAC;QAExC,MAAM,gBAAgB,GAAG,IAAI,CAAC,+BAA+B,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAChF,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,oBAAoB,GAAmB;gBAC3C,KAAK,EAAE;oBACL,KAAK,EAAE,EAAE,IAAI,EAAE,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE;oBACrD,GAAG,EAAE,EAAE,IAAI,EAAE,gBAAgB,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC,EAAE;iBACzF;aACF,CAAC;YACF,gBAAgB,CAAC,MAAM,GAAG,oBAAoB,CAAC;QACjD,CAAC;QAED,OAAO,aAAa,CAAC;IACvB,CAAC;IAED;;OAEG;IACK,sBAAsB,CAAC,IAAY,EAAE,SAAiB;QAC5D,IAAI,SAAS,GAAG,CAAC,IAAI,SAAS,GAAG,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAE1D,6CAA6C;QAC7C,OAAO,SAAS,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;YAC7D,SAAS,EAAE,CAAC;QACd,CAAC;QAED,IAAI,SAAS,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAE1C,uBAAuB;QACvB,IAAI,KAAK,GAAG,SAAS,CAAC;QACtB,IAAI,GAAG,GAAG,SAAS,CAAC;QAEpB,0CAA0C;QAC1C,OAAO,KAAK,GAAG,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,KAAK,EAAE,CAAC;QACV,CAAC;QAED,qCAAqC;QACrC,OAAO,GAAG,GAAG,IAAI,CAAC,MAAM,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACvD,GAAG,EAAE,CAAC;QACR,CAAC;QAED,IAAI,KAAK,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAE/B,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IACxB,CAAC;IAED;;OAEG;IACK,wBAAwB,CAAC,IAAY;QAC3C,+CAA+C;QAC/C,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,OAAO,KAAK,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACrD,KAAK,EAAE,CAAC;QACV,CAAC;QAED,mEAAmE;QACnE,IAAI,GAAG,GAAG,KAAK,CAAC;QAChB,IAAI,iBAAiB,GAAG,CAAC,CAAC;QAE1B,OAAO,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;YAEvB,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACjB,iBAAiB,EAAE,CAAC;gBACpB,6CAA6C;gBAC7C,IAAI,iBAAiB,IAAI,CAAC,EAAE,CAAC;oBAC3B,GAAG,IAAI,iBAAiB,CAAC,CAAC,+BAA+B;oBACzD,MAAM;gBACR,CAAC;YACH,CAAC;iBAAM,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACzD,sCAAsC;gBACtC,MAAM;YACR,CAAC;iBAAM,CAAC;gBACN,iBAAiB,GAAG,CAAC,CAAC;YACxB,CAAC;YAED,GAAG,EAAE,CAAC;QACR,CAAC;QAED,oCAAoC;QACpC,OAAO,GAAG,GAAG,KAAK,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YAC5C,GAAG,EAAE,CAAC;QACR,CAAC;QAED,IAAI,KAAK,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAE/B,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IACxB,CAAC;IAED;;OAEG;IACK,oBAAoB,CAAC,SAAiB,EAAE,KAAe;QAC7D,IAAI,OAAO,GAAG,SAAS,CAAC;QAExB,kCAAkC;QAClC,KAAK,IAAI,CAAC,GAAG,SAAS,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAClD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAE5B,sCAAsC;YACtC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM;YACR,CAAC;YAED,iDAAiD;YACjD,IAAI,IAAA,iBAAS,EAAC,IAAI,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1E,OAAO,GAAG,CAAC,CAAC;YACd,CAAC;iBAAM,IAAI,IAAA,2BAAmB,EAAC,OAAO,CAAC,EAAE,CAAC;gBACxC,sCAAsC;gBACtC,MAAM;YACR,CAAC;QACH,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;IAC5C,CAAC;IAED;;OAEG;IACK,+BAA+B,CAAC,WAAmB,EAAE,KAAe;QAC1E,iDAAiD;QACjD,IAAI,UAAU,GAAG,WAAW,CAAC;QAC7B,KAAK,IAAI,CAAC,GAAG,WAAW,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAE5B,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,uCAAuC;gBACvC,MAAM;YACR,CAAC;YAED,IAAI,IAAA,2BAAmB,EAAC,OAAO,CAAC,EAAE,CAAC;gBACjC,UAAU,GAAG,CAAC,CAAC;gBACf,MAAM;YACR,CAAC;QACH,CAAC;QAED,mCAAmC;QACnC,OAAO,IAAI,CAAC,oBAAoB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IACtD,CAAC;CACF;AAtTD,wDAsTC;AAEY,QAAA,sBAAsB,GAAG,IAAI,sBAAsB,EAAE,CAAC"}
@@ -0,0 +1,83 @@
1
+ import { TextDocument } from 'vscode-languageserver-textdocument';
2
+ import { ParsedDocument } from '../types';
3
+ /**
4
+ * Semantic token types for hledger syntax.
5
+ * These map to standard LSP semantic token types where possible.
6
+ */
7
+ export declare enum TokenType {
8
+ namespace = 0,// Account names (hierarchical)
9
+ type = 1,// Dates
10
+ class = 2,// Payees
11
+ enum = 3,// Commodities/currencies
12
+ property = 4,// Tags
13
+ keyword = 5,// Directives (account, commodity, payee, etc.)
14
+ number = 6,// Amounts
15
+ string = 7,// Transaction codes
16
+ comment = 8,// Comments
17
+ operator = 9
18
+ }
19
+ /**
20
+ * Semantic token modifiers for hledger syntax.
21
+ */
22
+ export declare enum TokenModifier {
23
+ declaration = 0,// Item is being declared (directive)
24
+ readonly = 1,// Item is immutable (dates, amounts)
25
+ deprecated = 2
26
+ }
27
+ /**
28
+ * Token type names in the order they appear in the enum.
29
+ * This array is sent to the client during initialization.
30
+ */
31
+ export declare const tokenTypes: string[];
32
+ /**
33
+ * Token modifier names in the order they appear in the enum.
34
+ * This array is sent to the client during initialization.
35
+ */
36
+ export declare const tokenModifiers: string[];
37
+ /**
38
+ * Provides semantic tokens for hledger journal files.
39
+ */
40
+ export declare class SemanticTokensProvider {
41
+ /**
42
+ * Provide semantic tokens for the entire document.
43
+ */
44
+ provideSemanticTokens(document: TextDocument, parsedDoc: ParsedDocument): number[];
45
+ /**
46
+ * Tokenize a single line.
47
+ */
48
+ private tokenizeLine;
49
+ /**
50
+ * Tokenize a comment line.
51
+ * @param line The line or substring containing the comment
52
+ * @param lineIndex The line number in the document
53
+ * @param builder The semantic tokens builder
54
+ * @param offset The character offset to add to all positions (used when line is a substring)
55
+ */
56
+ private tokenizeComment;
57
+ /**
58
+ * Tokenize a directive line.
59
+ * Returns true if the line was a directive.
60
+ */
61
+ private tokenizeDirective;
62
+ /**
63
+ * Tokenize a transaction header line.
64
+ * Returns true if the line was a transaction header.
65
+ */
66
+ private tokenizeTransactionHeader;
67
+ /**
68
+ * Tokenize a posting line.
69
+ * Returns true if the line was a posting.
70
+ */
71
+ private tokenizePosting;
72
+ /**
73
+ * Tokenize an amount (number + commodity), potentially with cost and assertion.
74
+ * Format: [COMMODITY] NUMBER [COMMODITY] [@ COST | @@ COST] [= ASSERTION]
75
+ */
76
+ private tokenizeAmount;
77
+ /**
78
+ * Tokenize a single amount (number + commodity) without cost or assertion.
79
+ */
80
+ private tokenizeSingleAmount;
81
+ }
82
+ export declare const semanticTokensProvider: SemanticTokensProvider;
83
+ //# sourceMappingURL=semanticTokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semanticTokens.d.ts","sourceRoot":"","sources":["../../src/features/semanticTokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAElE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C;;;GAGG;AACH,oBAAY,SAAS;IACnB,SAAS,IAAI,CAAK,+BAA+B;IACjD,IAAI,IAAI,CAAU,QAAQ;IAC1B,KAAK,IAAI,CAAS,SAAS;IAC3B,IAAI,IAAI,CAAU,yBAAyB;IAC3C,QAAQ,IAAI,CAAM,OAAO;IACzB,OAAO,IAAI,CAAO,+CAA+C;IACjE,MAAM,IAAI,CAAQ,UAAU;IAC5B,MAAM,IAAI,CAAQ,oBAAoB;IACtC,OAAO,IAAI,CAAO,WAAW;IAC7B,QAAQ,IAAI;CACb;AAED;;GAEG;AACH,oBAAY,aAAa;IACvB,WAAW,IAAI,CAAG,qCAAqC;IACvD,QAAQ,IAAI,CAAM,qCAAqC;IACvD,UAAU,IAAI;CACf;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,MAAM,EAW9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,EAIlC,CAAC;AAaF;;GAEG;AACH,qBAAa,sBAAsB;IACjC;;OAEG;IACH,qBAAqB,CACnB,QAAQ,EAAE,YAAY,EACtB,SAAS,EAAE,cAAc,GACxB,MAAM,EAAE;IAYX;;OAEG;IACH,OAAO,CAAC,YAAY;IAiCpB;;;;;;OAMG;IACH,OAAO,CAAC,eAAe;IA8DvB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAmFzB;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IA2EjC;;;OAGG;IACH,OAAO,CAAC,eAAe;IAiDvB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAyDtB;;OAEG;IACH,OAAO,CAAC,oBAAoB;CA8D7B;AAGD,eAAO,MAAM,sBAAsB,wBAA+B,CAAC"}