@singapore-editor/tree-sitter 0.1.1

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 (40) hide show
  1. package/README.md +32 -0
  2. package/dist/assets/__vite-browser-external-CMrW8369.js +9 -0
  3. package/dist/assets/__vite-browser-external-CMrW8369.js.map +1 -0
  4. package/dist/assets/treeSitter.worker-D1ozCaGZ.js +5698 -0
  5. package/dist/assets/treeSitter.worker-D1ozCaGZ.js.map +1 -0
  6. package/dist/index.d.ts +34 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +143 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/session.d.ts +89 -0
  11. package/dist/session.d.ts.map +1 -0
  12. package/dist/session.js +437 -0
  13. package/dist/session.js.map +1 -0
  14. package/dist/structuralSelection.d.ts +37 -0
  15. package/dist/structuralSelection.d.ts.map +1 -0
  16. package/dist/structuralSelection.js +139 -0
  17. package/dist/structuralSelection.js.map +1 -0
  18. package/dist/treeSitter/markdown.d.ts +12 -0
  19. package/dist/treeSitter/markdown.d.ts.map +1 -0
  20. package/dist/treeSitter/registry.d.ts +56 -0
  21. package/dist/treeSitter/registry.d.ts.map +1 -0
  22. package/dist/treeSitter/registry.js +144 -0
  23. package/dist/treeSitter/registry.js.map +1 -0
  24. package/dist/treeSitter/source.d.ts +42 -0
  25. package/dist/treeSitter/source.d.ts.map +1 -0
  26. package/dist/treeSitter/source.js +175 -0
  27. package/dist/treeSitter/source.js.map +1 -0
  28. package/dist/treeSitter/sourceChunkRetention.d.ts +30 -0
  29. package/dist/treeSitter/sourceChunkRetention.d.ts.map +1 -0
  30. package/dist/treeSitter/sourceChunkRetention.js +76 -0
  31. package/dist/treeSitter/sourceChunkRetention.js.map +1 -0
  32. package/dist/treeSitter/treeSitter.worker.d.ts +64 -0
  33. package/dist/treeSitter/treeSitter.worker.d.ts.map +1 -0
  34. package/dist/treeSitter/types.d.ts +198 -0
  35. package/dist/treeSitter/types.d.ts.map +1 -0
  36. package/dist/treeSitter/workerClient.d.ts +133 -0
  37. package/dist/treeSitter/workerClient.d.ts.map +1 -0
  38. package/dist/treeSitter/workerClient.js +420 -0
  39. package/dist/treeSitter/workerClient.js.map +1 -0
  40. package/package.json +50 -0
@@ -0,0 +1,437 @@
1
+ import { resolveTreeSitterLanguageClosure, withInjectedLanguages } from "./treeSitter/registry.js";
2
+ import { createTreeSitterWorkerBackend } from "./treeSitter/workerClient.js";
3
+ import { applyBatchToPieceTable, diffPieceTableSnapshots, documentSessionChangeTextSnapshot, offsetToPoint, pieceTableSnapshotsHaveSameText } from "@singapore-editor/core/document";
4
+ import { EditorTokenStore, createEditorRuntimeSessionId, createEmptySyntaxResult, treeSitterCapturesToEditorTokens } from "@singapore-editor/core/syntax";
5
+ //#region src/session.ts
6
+ var TreeSitterSyntaxSession = class {
7
+ documentId;
8
+ runtimeSessionId;
9
+ languageId;
10
+ languageResolver;
11
+ includeHighlights;
12
+ includeCaptures;
13
+ syntaxMode;
14
+ backend;
15
+ snapshotVersion = 0;
16
+ parsedSnapshotVersion = 0;
17
+ textSnapshot;
18
+ snapshot;
19
+ result;
20
+ currentFoldingSupport;
21
+ languageRegistrationPromise = null;
22
+ pendingLanguages = /* @__PURE__ */ new Map();
23
+ disposed = false;
24
+ onFirstParse;
25
+ constructor(options) {
26
+ this.documentId = options.documentId;
27
+ this.runtimeSessionId = options.runtimeSessionId ?? createEditorRuntimeSessionId();
28
+ this.languageId = options.languageId;
29
+ this.languageResolver = options.languageResolver;
30
+ this.currentFoldingSupport = options.languageResolver ? "pending" : options.foldingSupport ?? "supported";
31
+ this.includeHighlights = options.includeHighlights ?? true;
32
+ this.includeCaptures = options.includeCaptures ?? true;
33
+ this.syntaxMode = options.syntaxMode ?? "full";
34
+ this.textSnapshot = options.textSnapshot;
35
+ this.snapshot = options.snapshot;
36
+ this.backend = options.backend ?? createTreeSitterWorkerBackend();
37
+ this.onFirstParse = options.onFirstParse;
38
+ this.result = this.createEmptyResult({
39
+ snapshot: options.snapshot,
40
+ snapshotVersion: 0
41
+ });
42
+ }
43
+ get foldingSupport() {
44
+ return this.currentFoldingSupport;
45
+ }
46
+ async refresh(textSnapshot) {
47
+ if (this.disposed) return this.result;
48
+ const snapshotVersion = ++this.snapshotVersion;
49
+ const snapshot = textSnapshot.snapshot;
50
+ if (!await this.ensureLanguageRegistered()) return this.updateFromUnavailableLanguage(textSnapshot, snapshot);
51
+ if (this.disposed || !this.isCurrentSnapshotVersion(snapshotVersion)) return this.result;
52
+ const parsePayload = {
53
+ documentId: this.documentId,
54
+ runtimeSessionId: this.runtimeSessionId,
55
+ snapshotVersion,
56
+ languageId: this.languageId,
57
+ includeHighlights: this.includeHighlights,
58
+ includeCaptures: this.includeCaptures,
59
+ snapshot
60
+ };
61
+ let result = await this.backend.parse(this.syntaxMode === "range" ? {
62
+ ...parsePayload,
63
+ resultMode: "parseOnly"
64
+ } : {
65
+ ...parsePayload,
66
+ resultMode: "full"
67
+ });
68
+ for (let depth = 0; depth < 8 && result?.missingLanguages?.length; depth += 1) {
69
+ if (!await this.registerMissingLanguages(result.missingLanguages, snapshotVersion)) break;
70
+ if (this.disposed || !this.isCurrentSnapshotVersion(snapshotVersion)) return this.result;
71
+ result = await this.backend.parse(this.syntaxMode === "range" ? {
72
+ ...parsePayload,
73
+ resultMode: "parseOnly"
74
+ } : {
75
+ ...parsePayload,
76
+ resultMode: "full"
77
+ });
78
+ }
79
+ const next = this.updateFromTreeSitterResult(result, snapshotVersion, textSnapshot, snapshot);
80
+ if (result && !this.disposed) this.notifyFirstParse();
81
+ return next;
82
+ }
83
+ notifyFirstParse() {
84
+ const onFirstParse = this.onFirstParse;
85
+ this.onFirstParse = void 0;
86
+ onFirstParse?.();
87
+ }
88
+ async applyChange(change) {
89
+ if (this.disposed) return this.result;
90
+ if (change.kind === "none" || change.kind === "selection") return this.result;
91
+ if (this.parsedSnapshotVersion === 0) return this.refresh(documentSessionChangeTextSnapshot(change));
92
+ if (!await this.ensureLanguageRegistered()) {
93
+ this.snapshotVersion += 1;
94
+ return this.updateFromUnavailableLanguage(documentSessionChangeTextSnapshot(change), change.snapshot);
95
+ }
96
+ if (this.disposed) return this.result;
97
+ const edits = createSyntaxTextEdits(this.textSnapshot, this.snapshot, change);
98
+ if (edits.length === 0) {
99
+ this.textSnapshot = documentSessionChangeTextSnapshot(change);
100
+ this.snapshot = change.snapshot;
101
+ return this.result;
102
+ }
103
+ const editPayloadOptions = {
104
+ documentId: this.documentId,
105
+ runtimeSessionId: this.runtimeSessionId,
106
+ languageId: this.languageId,
107
+ previousSnapshotVersion: this.parsedSnapshotVersion,
108
+ snapshotVersion: ++this.snapshotVersion,
109
+ previousSnapshot: this.snapshot,
110
+ nextSnapshot: change.snapshot,
111
+ edits,
112
+ includeHighlights: this.includeHighlights,
113
+ includeCaptures: this.includeCaptures
114
+ };
115
+ const payload = this.syntaxMode === "range" ? createTreeSitterEditPayload({
116
+ ...editPayloadOptions,
117
+ resultMode: "parseOnly"
118
+ }) : createTreeSitterEditPayload({
119
+ ...editPayloadOptions,
120
+ resultMode: "full"
121
+ });
122
+ if (!payload) return this.refresh(documentSessionChangeTextSnapshot(change));
123
+ return this.applyIncrementalEdit(payload, documentSessionChangeTextSnapshot(change));
124
+ }
125
+ async queryRange(range) {
126
+ if (this.disposed) return this.result;
127
+ if (!this.backend.queryRange) return this.createRangeUnavailableResult(range, "Tree-sitter range queries are unavailable");
128
+ if (!this.canQueryRange()) return this.createRangeUnavailableResult(range, "Tree-sitter document has not been parsed");
129
+ const result = await this.backend.queryRange({
130
+ documentId: this.documentId,
131
+ runtimeSessionId: this.runtimeSessionId,
132
+ snapshotVersion: this.parsedSnapshotVersion,
133
+ languageId: this.languageId,
134
+ includeHighlights: this.includeHighlights,
135
+ includeCaptures: this.includeCaptures,
136
+ range
137
+ });
138
+ return this.updateFromTreeSitterRangeResult(result, range);
139
+ }
140
+ canQueryRange() {
141
+ return this.parsedSnapshotVersion !== 0 && this.parsedSnapshotVersion === this.snapshotVersion;
142
+ }
143
+ getResult() {
144
+ return this.result;
145
+ }
146
+ getTokens() {
147
+ return this.result.tokens;
148
+ }
149
+ getSnapshotVersion() {
150
+ return this.snapshotVersion;
151
+ }
152
+ dispose() {
153
+ if (this.disposed) return;
154
+ this.disposed = true;
155
+ this.backend.disposeDocument(this.runtimeSessionId);
156
+ }
157
+ async applyIncrementalEdit(payload, nextTextSnapshot) {
158
+ try {
159
+ const result = await this.backend.edit(payload);
160
+ if (this.disposed) return this.result;
161
+ if (!this.isCurrentSnapshotVersion(payload.snapshotVersion)) return this.result;
162
+ if (!result) return this.reparseAfterIncrementalFailure(nextTextSnapshot);
163
+ if (result.snapshotVersion !== payload.snapshotVersion) return this.reparseAfterIncrementalFailure(nextTextSnapshot);
164
+ if (await this.registerMissingLanguages(result.missingLanguages ?? [], payload.snapshotVersion)) {
165
+ if (this.disposed || !this.isCurrentSnapshotVersion(payload.snapshotVersion)) return this.result;
166
+ return this.refresh(nextTextSnapshot);
167
+ }
168
+ return this.updateFromTreeSitterResult(result, payload.snapshotVersion, nextTextSnapshot, payload.snapshot);
169
+ } catch {
170
+ if (this.disposed) return this.result;
171
+ if (!this.isCurrentSnapshotVersion(payload.snapshotVersion)) return this.result;
172
+ return this.reparseAfterIncrementalFailure(nextTextSnapshot);
173
+ }
174
+ }
175
+ reparseAfterIncrementalFailure(textSnapshot) {
176
+ if (this.disposed) return Promise.resolve(this.result);
177
+ this.parsedSnapshotVersion = 0;
178
+ const disposedRuntimeSessionId = this.runtimeSessionId;
179
+ this.runtimeSessionId = createEditorRuntimeSessionId();
180
+ this.backend.disposeDocument(disposedRuntimeSessionId);
181
+ return this.refresh(textSnapshot);
182
+ }
183
+ isCurrentSnapshotVersion(snapshotVersion) {
184
+ return snapshotVersion === this.snapshotVersion;
185
+ }
186
+ ensureLanguageRegistered() {
187
+ if (!this.languageResolver) return Promise.resolve(true);
188
+ if (!this.languageRegistrationPromise) this.languageRegistrationPromise = this.registerResolvedLanguage();
189
+ return this.languageRegistrationPromise;
190
+ }
191
+ async registerResolvedLanguage() {
192
+ const descriptor = await this.languageResolver?.resolveTreeSitterLanguage(this.languageId);
193
+ if (!descriptor) {
194
+ this.currentFoldingSupport = "unsupported";
195
+ return false;
196
+ }
197
+ this.currentFoldingSupport = descriptor.foldQuerySource?.trim() ? "supported" : "unsupported";
198
+ const descriptors = await withInjectedLanguages(this.languageResolver, descriptor, () => this.disposed);
199
+ if (this.disposed) return false;
200
+ await this.backend.registerLanguages(descriptors);
201
+ return true;
202
+ }
203
+ async registerMissingLanguages(languageIds, version) {
204
+ let loaded = false;
205
+ for (const id of new Set(languageIds)) {
206
+ if (this.disposed || !this.isCurrentSnapshotVersion(version)) return false;
207
+ let pending = this.pendingLanguages.get(id);
208
+ if (!pending) {
209
+ pending = this.resolveLanguageDependencies(id);
210
+ this.pendingLanguages.set(id, pending);
211
+ }
212
+ const descriptors = await pending;
213
+ if (this.disposed || !this.isCurrentSnapshotVersion(version)) return false;
214
+ if (descriptors.length === 0) continue;
215
+ await this.backend.registerLanguages(descriptors);
216
+ loaded = true;
217
+ }
218
+ return loaded;
219
+ }
220
+ async resolveLanguageDependencies(id) {
221
+ if (!this.languageResolver) return [];
222
+ return resolveTreeSitterLanguageClosure(this.languageResolver, id, () => this.disposed);
223
+ }
224
+ updateFromUnavailableLanguage(textSnapshot, snapshot) {
225
+ if (this.disposed) return this.result;
226
+ this.textSnapshot = textSnapshot;
227
+ this.snapshot = snapshot;
228
+ this.result = this.createEmptyResult({
229
+ degraded: {
230
+ kind: "language-unavailable",
231
+ message: `Tree-sitter language "${this.languageId}" is unavailable`
232
+ },
233
+ snapshot,
234
+ snapshotVersion: this.snapshotVersion
235
+ });
236
+ return this.result;
237
+ }
238
+ updateFromTreeSitterResult(result, snapshotVersion, textSnapshot, snapshot) {
239
+ if (this.disposed) return this.result;
240
+ if (!result) return this.result;
241
+ if (result.snapshotVersion !== snapshotVersion) return this.result;
242
+ if (result.snapshotVersion !== this.snapshotVersion) return this.result;
243
+ this.textSnapshot = textSnapshot;
244
+ this.snapshot = snapshot;
245
+ this.parsedSnapshotVersion = result.snapshotVersion;
246
+ if (isTreeSitterParseAckResult(result)) {
247
+ this.result = this.createEmptyResult({
248
+ degraded: treeSitterDegradedStateToEditorSyntaxState(result.degraded),
249
+ snapshot,
250
+ snapshotVersion: result.snapshotVersion
251
+ });
252
+ return this.result;
253
+ }
254
+ this.result = treeSitterParseResultToEditorSyntaxResult(result, this.resultContext(snapshot, []));
255
+ return this.result;
256
+ }
257
+ updateFromTreeSitterRangeResult(result, range) {
258
+ if (this.disposed) return this.result;
259
+ if (!result) return this.result;
260
+ if (result.snapshotVersion !== this.snapshotVersion) return this.result;
261
+ if (result.snapshotVersion !== this.parsedSnapshotVersion) return this.result;
262
+ if (!sameSyntaxRange(result.range, range)) return this.result;
263
+ this.result = treeSitterParseResultToEditorSyntaxResult(result, this.resultContext(this.snapshot, [range]));
264
+ return this.result;
265
+ }
266
+ createRangeUnavailableResult(range, message) {
267
+ return this.createEmptyResult({
268
+ degraded: {
269
+ kind: "range-unavailable",
270
+ message
271
+ },
272
+ requestedRanges: [range],
273
+ snapshot: this.snapshot,
274
+ snapshotVersion: this.parsedSnapshotVersion
275
+ });
276
+ }
277
+ createEmptyResult(options) {
278
+ return createEmptySyntaxResult({
279
+ degraded: options.degraded,
280
+ language: this.languageConfiguration(),
281
+ requestedRanges: options.requestedRanges,
282
+ snapshot: this.snapshotTag(options.snapshot, options.snapshotVersion)
283
+ });
284
+ }
285
+ resultContext(snapshot, requestedRanges) {
286
+ return {
287
+ includeCaptures: this.includeCaptures,
288
+ includeHighlights: this.includeHighlights,
289
+ mode: this.syntaxMode,
290
+ requestedRanges,
291
+ snapshotLength: snapshot.length
292
+ };
293
+ }
294
+ languageConfiguration() {
295
+ return {
296
+ includeCaptures: this.includeCaptures,
297
+ includeHighlights: this.includeHighlights,
298
+ languageId: this.languageId,
299
+ mode: this.syntaxMode
300
+ };
301
+ }
302
+ snapshotTag(snapshot, snapshotVersion) {
303
+ return {
304
+ documentId: this.documentId,
305
+ length: snapshot.length,
306
+ version: snapshotVersion
307
+ };
308
+ }
309
+ };
310
+ function createTreeSitterEditPayload(options) {
311
+ if (options.edits.length === 0) return null;
312
+ return {
313
+ documentId: options.documentId,
314
+ runtimeSessionId: options.runtimeSessionId,
315
+ previousSnapshotVersion: options.previousSnapshotVersion,
316
+ snapshotVersion: options.snapshotVersion,
317
+ languageId: options.languageId,
318
+ includeHighlights: options.includeHighlights ?? true,
319
+ includeCaptures: options.includeCaptures,
320
+ resultMode: options.resultMode,
321
+ snapshot: options.nextSnapshot,
322
+ edits: options.edits,
323
+ inputEdits: createTreeSitterInputEdits(options.previousSnapshot, options.edits)
324
+ };
325
+ }
326
+ var createTextDiffEdit = (previousText, nextText) => {
327
+ if (previousText === nextText) return null;
328
+ let start = 0;
329
+ const maxPrefixLength = Math.min(previousText.length, nextText.length);
330
+ while (start < maxPrefixLength && previousText[start] === nextText[start]) start += 1;
331
+ let previousEnd = previousText.length;
332
+ let nextEnd = nextText.length;
333
+ while (previousEnd > start && nextEnd > start && previousText[previousEnd - 1] === nextText[nextEnd - 1]) {
334
+ previousEnd -= 1;
335
+ nextEnd -= 1;
336
+ }
337
+ return {
338
+ from: start,
339
+ to: previousEnd,
340
+ text: nextText.slice(start, nextEnd)
341
+ };
342
+ };
343
+ var createSyntaxTextEdits = (previousTextSnapshot, previousSnapshot, change) => {
344
+ if (changeEditsApplyToSnapshot(previousSnapshot, change)) return change.edits;
345
+ const edit = diffPieceTableSnapshots(previousTextSnapshot.snapshot, documentSessionChangeTextSnapshot(change).snapshot);
346
+ return edit ? [edit] : [];
347
+ };
348
+ var changeEditsApplyToSnapshot = (snapshot, change) => {
349
+ try {
350
+ return pieceTableSnapshotsHaveSameText(applyBatchToPieceTable(snapshot, change.edits), change.snapshot);
351
+ } catch {
352
+ return false;
353
+ }
354
+ };
355
+ var treeSitterParseResultToEditorSyntaxResult = (result, context) => {
356
+ recordParseResultPayload(result);
357
+ return treeSitterParseResultToEditorSyntaxResultInner(result, context);
358
+ };
359
+ var treeSitterParseResultToEditorSyntaxResultInner = (result, context) => ({
360
+ captures: result.captures,
361
+ records: result.records,
362
+ degraded: treeSitterDegradedStateToEditorSyntaxState(result.degraded),
363
+ folds: result.folds,
364
+ brackets: result.brackets,
365
+ errors: result.errors,
366
+ injections: result.injections,
367
+ projection: {
368
+ language: {
369
+ includeCaptures: context.includeCaptures,
370
+ includeHighlights: context.includeHighlights,
371
+ languageId: result.languageId,
372
+ mode: context.mode
373
+ },
374
+ requestedRanges: context.requestedRanges,
375
+ snapshot: {
376
+ documentId: result.documentId,
377
+ length: context.snapshotLength,
378
+ version: result.snapshotVersion
379
+ }
380
+ },
381
+ tokens: resultTokens(result)
382
+ });
383
+ function resultTokens(result) {
384
+ if (result.tokensPacked) return EditorTokenStore.fromPacked(result.tokensPacked);
385
+ return EditorTokenStore.fromTokens(result.tokens ?? treeSitterCapturesToEditorTokens(result.captures));
386
+ }
387
+ function recordParseResultPayload(result) {
388
+ const sink = globalThis.__EDITOR_PERFORMANCE_DIAGNOSTICS__;
389
+ if (!sink?.enabled) return;
390
+ sink.record({
391
+ name: "treeSitter.parseResult.payload",
392
+ detail: {
393
+ captures: result.captures.length,
394
+ tokens: result.tokens?.length ?? result.tokensPacked?.starts.length ?? -1,
395
+ folds: result.folds.length,
396
+ brackets: result.brackets.length,
397
+ errors: result.errors.length,
398
+ injections: result.injections.length
399
+ }
400
+ });
401
+ }
402
+ var treeSitterDegradedStateToEditorSyntaxState = (degraded) => {
403
+ const first = degraded?.[0];
404
+ if (!first) return null;
405
+ return {
406
+ kind: first.kind,
407
+ phase: first.phase,
408
+ message: degraded.length === 1 ? first.message : `${first.message} (${degraded.length} Tree-sitter phases degraded)`
409
+ };
410
+ };
411
+ var isTreeSitterParseAckResult = (result) => "status" in result && result.status === "parsed";
412
+ var sameSyntaxRange = (left, right) => left.startIndex === right.startIndex && left.endIndex === right.endIndex;
413
+ var createTreeSitterInputEdits = (snapshot, edits) => {
414
+ const sorted = edits.toSorted((left, right) => right.from - left.from || right.to - left.to);
415
+ const inputEdits = [];
416
+ let workingSnapshot = snapshot;
417
+ for (const edit of sorted) {
418
+ const startPosition = offsetToPoint(workingSnapshot, edit.from);
419
+ const oldEndPosition = offsetToPoint(workingSnapshot, edit.to);
420
+ const nextSnapshot = applyBatchToPieceTable(workingSnapshot, [edit]);
421
+ const newEndIndex = edit.from + edit.text.length;
422
+ inputEdits.push({
423
+ startIndex: edit.from,
424
+ oldEndIndex: edit.to,
425
+ newEndIndex,
426
+ startPosition,
427
+ oldEndPosition,
428
+ newEndPosition: offsetToPoint(nextSnapshot, newEndIndex)
429
+ });
430
+ workingSnapshot = nextSnapshot;
431
+ }
432
+ return inputEdits;
433
+ };
434
+ //#endregion
435
+ export { TreeSitterSyntaxSession, createTextDiffEdit, createTreeSitterEditPayload };
436
+
437
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","names":[],"sources":["../src/session.ts"],"sourcesContent":["import {\n applyBatchToPieceTable,\n diffPieceTableSnapshots,\n type DocumentSessionChange,\n type DocumentTextSnapshot,\n offsetToPoint,\n type PieceTableSnapshot,\n pieceTableSnapshotsHaveSameText,\n type TextEdit,\n} from '@singapore-editor/core/document'\nimport {\n createEmptySyntaxResult,\n createEditorRuntimeSessionId,\n type EditorSyntaxDegradedState,\n type EditorSyntaxRange,\n type EditorSyntaxResult,\n type EditorSyntaxSession,\n type EditorSyntaxFoldingSupport,\n treeSitterCapturesToEditorTokens,\n EditorTokenStore,\n} from '@singapore-editor/core/syntax'\nimport { documentSessionChangeTextSnapshot } from '@singapore-editor/core/document'\nimport type {\n TreeSitterDegradedState,\n TreeSitterInputEdit,\n TreeSitterLanguageId,\n TreeSitterParseAckResult,\n TreeSitterParseResult,\n TreeSitterRangeResult,\n} from './treeSitter/types'\nimport {\n resolveTreeSitterLanguageClosure,\n withInjectedLanguages,\n type TreeSitterLanguageDescriptor,\n type TreeSitterLanguageResolver,\n} from './treeSitter/registry'\nimport {\n createTreeSitterWorkerBackend,\n type TreeSitterBackend,\n type TreeSitterBackendEditPayload,\n type TreeSitterEditPayload,\n} from './treeSitter/workerClient'\n\nexport type TreeSitterSyntaxSessionOptions = {\n readonly documentId: string\n readonly runtimeSessionId?: string\n readonly languageId: TreeSitterLanguageId\n readonly languageResolver?: TreeSitterLanguageResolver\n readonly foldingSupport?: Exclude<EditorSyntaxFoldingSupport, 'pending'>\n readonly includeHighlights?: boolean\n readonly includeCaptures?: boolean\n readonly syntaxMode?: 'full' | 'range'\n readonly textSnapshot: DocumentTextSnapshot\n readonly snapshot: PieceTableSnapshot\n readonly backend?: TreeSitterBackend\n /** Called once, after the session's first parse answers. */\n readonly onFirstParse?: () => void\n}\n\nexport class TreeSitterSyntaxSession implements EditorSyntaxSession {\n private readonly documentId: string\n private runtimeSessionId: string\n private readonly languageId: TreeSitterLanguageId\n private readonly languageResolver: TreeSitterLanguageResolver | undefined\n private readonly includeHighlights: boolean\n private readonly includeCaptures: boolean\n private readonly syntaxMode: 'full' | 'range'\n private readonly backend: TreeSitterBackend\n private snapshotVersion = 0\n private parsedSnapshotVersion = 0\n private textSnapshot: DocumentTextSnapshot\n private snapshot: PieceTableSnapshot\n private result: EditorSyntaxResult\n private currentFoldingSupport: EditorSyntaxFoldingSupport\n private languageRegistrationPromise: Promise<boolean> | null = null\n private readonly pendingLanguages = new Map<\n string,\n Promise<readonly TreeSitterLanguageDescriptor[]>\n >()\n private disposed = false\n private onFirstParse: (() => void) | undefined\n\n public constructor(options: TreeSitterSyntaxSessionOptions) {\n this.documentId = options.documentId\n this.runtimeSessionId = options.runtimeSessionId ?? createEditorRuntimeSessionId()\n this.languageId = options.languageId\n this.languageResolver = options.languageResolver\n this.currentFoldingSupport = options.languageResolver\n ? 'pending'\n : (options.foldingSupport ?? 'supported')\n this.includeHighlights = options.includeHighlights ?? true\n this.includeCaptures = options.includeCaptures ?? true\n this.syntaxMode = options.syntaxMode ?? 'full'\n this.textSnapshot = options.textSnapshot\n this.snapshot = options.snapshot\n this.backend = options.backend ?? createTreeSitterWorkerBackend()\n this.onFirstParse = options.onFirstParse\n this.result = this.createEmptyResult({ snapshot: options.snapshot, snapshotVersion: 0 })\n }\n\n public get foldingSupport(): EditorSyntaxFoldingSupport {\n return this.currentFoldingSupport\n }\n\n public async refresh(textSnapshot: DocumentTextSnapshot): Promise<EditorSyntaxResult> {\n if (this.disposed) return this.result\n\n const snapshotVersion = ++this.snapshotVersion\n const snapshot = textSnapshot.snapshot\n\n if (!(await this.ensureLanguageRegistered())) {\n return this.updateFromUnavailableLanguage(textSnapshot, snapshot)\n }\n\n // Language registration takes seconds on cold start, and the session can\n // be disposed while it is awaited. Parsing then would register a worker\n // document nothing ever frees: dispose already ran, and its\n // disposeDocument silently no-ops while the worker does not exist yet.\n if (this.disposed || !this.isCurrentSnapshotVersion(snapshotVersion)) return this.result\n\n const parsePayload = {\n documentId: this.documentId,\n runtimeSessionId: this.runtimeSessionId,\n snapshotVersion,\n languageId: this.languageId,\n includeHighlights: this.includeHighlights,\n includeCaptures: this.includeCaptures,\n snapshot,\n }\n let result = await this.backend.parse(\n this.syntaxMode === 'range'\n ? { ...parsePayload, resultMode: 'parseOnly' }\n : { ...parsePayload, resultMode: 'full' },\n )\n\n for (let depth = 0; depth < 8 && result?.missingLanguages?.length; depth += 1) {\n if (!(await this.registerMissingLanguages(result.missingLanguages, snapshotVersion))) break\n if (this.disposed || !this.isCurrentSnapshotVersion(snapshotVersion)) return this.result\n result = await this.backend.parse(\n this.syntaxMode === 'range'\n ? { ...parsePayload, resultMode: 'parseOnly' }\n : { ...parsePayload, resultMode: 'full' },\n )\n }\n\n const next = this.updateFromTreeSitterResult(result, snapshotVersion, textSnapshot, snapshot)\n if (result && !this.disposed) this.notifyFirstParse()\n return next\n }\n\n private notifyFirstParse(): void {\n const onFirstParse = this.onFirstParse\n this.onFirstParse = undefined\n onFirstParse?.()\n }\n\n public async applyChange(change: DocumentSessionChange): Promise<EditorSyntaxResult> {\n if (this.disposed) return this.result\n if (change.kind === 'none' || change.kind === 'selection') {\n return this.result\n }\n\n if (this.parsedSnapshotVersion === 0) {\n return this.refresh(documentSessionChangeTextSnapshot(change))\n }\n\n if (!(await this.ensureLanguageRegistered())) {\n this.snapshotVersion += 1\n return this.updateFromUnavailableLanguage(\n documentSessionChangeTextSnapshot(change),\n change.snapshot,\n )\n }\n\n if (this.disposed) return this.result\n\n const edits = createSyntaxTextEdits(this.textSnapshot, this.snapshot, change)\n if (edits.length === 0) {\n this.textSnapshot = documentSessionChangeTextSnapshot(change)\n this.snapshot = change.snapshot\n return this.result\n }\n\n const editPayloadOptions = {\n documentId: this.documentId,\n runtimeSessionId: this.runtimeSessionId,\n languageId: this.languageId,\n previousSnapshotVersion: this.parsedSnapshotVersion,\n snapshotVersion: ++this.snapshotVersion,\n previousSnapshot: this.snapshot,\n nextSnapshot: change.snapshot,\n edits,\n includeHighlights: this.includeHighlights,\n includeCaptures: this.includeCaptures,\n }\n const payload =\n this.syntaxMode === 'range'\n ? createTreeSitterEditPayload({ ...editPayloadOptions, resultMode: 'parseOnly' })\n : createTreeSitterEditPayload({ ...editPayloadOptions, resultMode: 'full' })\n\n if (!payload) {\n return this.refresh(documentSessionChangeTextSnapshot(change))\n }\n\n return this.applyIncrementalEdit(payload, documentSessionChangeTextSnapshot(change))\n }\n\n public async queryRange(range: EditorSyntaxRange): Promise<EditorSyntaxResult> {\n if (this.disposed) return this.result\n if (!this.backend.queryRange) {\n return this.createRangeUnavailableResult(range, 'Tree-sitter range queries are unavailable')\n }\n if (!this.canQueryRange()) {\n return this.createRangeUnavailableResult(range, 'Tree-sitter document has not been parsed')\n }\n\n const result = await this.backend.queryRange({\n documentId: this.documentId,\n runtimeSessionId: this.runtimeSessionId,\n snapshotVersion: this.parsedSnapshotVersion,\n languageId: this.languageId,\n includeHighlights: this.includeHighlights,\n includeCaptures: this.includeCaptures,\n range,\n })\n\n return this.updateFromTreeSitterRangeResult(result, range)\n }\n\n public canQueryRange(): boolean {\n return this.parsedSnapshotVersion !== 0 && this.parsedSnapshotVersion === this.snapshotVersion\n }\n\n public getResult(): EditorSyntaxResult {\n return this.result\n }\n\n public getTokens(): EditorSyntaxResult['tokens'] {\n return this.result.tokens\n }\n\n public getSnapshotVersion(): number {\n return this.snapshotVersion\n }\n\n public dispose(): void {\n if (this.disposed) return\n\n this.disposed = true\n this.backend.disposeDocument(this.runtimeSessionId)\n }\n\n private async applyIncrementalEdit(\n payload: TreeSitterBackendEditPayload,\n nextTextSnapshot: DocumentTextSnapshot,\n ): Promise<EditorSyntaxResult> {\n try {\n const result = await this.backend.edit(payload)\n if (this.disposed) return this.result\n if (!this.isCurrentSnapshotVersion(payload.snapshotVersion)) {\n return this.result\n }\n\n if (!result) {\n return this.reparseAfterIncrementalFailure(nextTextSnapshot)\n }\n\n if (result.snapshotVersion !== payload.snapshotVersion) {\n return this.reparseAfterIncrementalFailure(nextTextSnapshot)\n }\n\n if (\n await this.registerMissingLanguages(result.missingLanguages ?? [], payload.snapshotVersion)\n ) {\n if (this.disposed || !this.isCurrentSnapshotVersion(payload.snapshotVersion))\n return this.result\n return this.refresh(nextTextSnapshot)\n }\n\n return this.updateFromTreeSitterResult(\n result,\n payload.snapshotVersion,\n nextTextSnapshot,\n payload.snapshot,\n )\n } catch {\n if (this.disposed) return this.result\n if (!this.isCurrentSnapshotVersion(payload.snapshotVersion)) {\n return this.result\n }\n\n return this.reparseAfterIncrementalFailure(nextTextSnapshot)\n }\n }\n\n private reparseAfterIncrementalFailure(\n textSnapshot: DocumentTextSnapshot,\n ): Promise<EditorSyntaxResult> {\n if (this.disposed) return Promise.resolve(this.result)\n\n this.parsedSnapshotVersion = 0\n const disposedRuntimeSessionId = this.runtimeSessionId\n this.runtimeSessionId = createEditorRuntimeSessionId()\n this.backend.disposeDocument(disposedRuntimeSessionId)\n return this.refresh(textSnapshot)\n }\n\n private isCurrentSnapshotVersion(snapshotVersion: number): boolean {\n return snapshotVersion === this.snapshotVersion\n }\n\n private ensureLanguageRegistered(): Promise<boolean> {\n if (!this.languageResolver) return Promise.resolve(true)\n if (!this.languageRegistrationPromise) {\n this.languageRegistrationPromise = this.registerResolvedLanguage()\n }\n\n return this.languageRegistrationPromise\n }\n\n private async registerResolvedLanguage(): Promise<boolean> {\n const descriptor = await this.languageResolver?.resolveTreeSitterLanguage(this.languageId)\n if (!descriptor) {\n this.currentFoldingSupport = 'unsupported'\n return false\n }\n this.currentFoldingSupport = descriptor.foldQuerySource?.trim() ? 'supported' : 'unsupported'\n\n const descriptors = await withInjectedLanguages(\n this.languageResolver,\n descriptor,\n () => this.disposed,\n )\n if (this.disposed) return false\n await this.backend.registerLanguages(descriptors)\n return true\n }\n\n private async registerMissingLanguages(\n languageIds: readonly string[],\n version: number,\n ): Promise<boolean> {\n let loaded = false\n for (const id of new Set(languageIds)) {\n if (this.disposed || !this.isCurrentSnapshotVersion(version)) return false\n let pending = this.pendingLanguages.get(id)\n if (!pending) {\n pending = this.resolveLanguageDependencies(id)\n this.pendingLanguages.set(id, pending)\n }\n const descriptors = await pending\n if (this.disposed || !this.isCurrentSnapshotVersion(version)) return false\n if (descriptors.length === 0) continue\n await this.backend.registerLanguages(descriptors)\n loaded = true\n }\n return loaded\n }\n\n private async resolveLanguageDependencies(\n id: string,\n ): Promise<readonly TreeSitterLanguageDescriptor[]> {\n if (!this.languageResolver) return []\n return resolveTreeSitterLanguageClosure(this.languageResolver, id, () => this.disposed)\n }\n\n private updateFromUnavailableLanguage(\n textSnapshot: DocumentTextSnapshot,\n snapshot: PieceTableSnapshot,\n ): EditorSyntaxResult {\n if (this.disposed) return this.result\n\n this.textSnapshot = textSnapshot\n this.snapshot = snapshot\n this.result = this.createEmptyResult({\n degraded: {\n kind: 'language-unavailable',\n message: `Tree-sitter language \"${this.languageId}\" is unavailable`,\n },\n snapshot,\n snapshotVersion: this.snapshotVersion,\n })\n return this.result\n }\n\n private updateFromTreeSitterResult(\n result: TreeSitterParseResult | TreeSitterParseAckResult | undefined,\n snapshotVersion: number,\n textSnapshot: DocumentTextSnapshot,\n snapshot: PieceTableSnapshot,\n ): EditorSyntaxResult {\n if (this.disposed) return this.result\n if (!result) return this.result\n if (result.snapshotVersion !== snapshotVersion) return this.result\n if (result.snapshotVersion !== this.snapshotVersion) return this.result\n\n this.textSnapshot = textSnapshot\n this.snapshot = snapshot\n this.parsedSnapshotVersion = result.snapshotVersion\n if (isTreeSitterParseAckResult(result)) {\n this.result = this.createEmptyResult({\n degraded: treeSitterDegradedStateToEditorSyntaxState(result.degraded),\n snapshot,\n snapshotVersion: result.snapshotVersion,\n })\n return this.result\n }\n\n this.result = treeSitterParseResultToEditorSyntaxResult(\n result,\n this.resultContext(snapshot, []),\n )\n return this.result\n }\n\n private updateFromTreeSitterRangeResult(\n result: TreeSitterRangeResult | undefined,\n range: EditorSyntaxRange,\n ): EditorSyntaxResult {\n if (this.disposed) return this.result\n if (!result) return this.result\n if (result.snapshotVersion !== this.snapshotVersion) return this.result\n if (result.snapshotVersion !== this.parsedSnapshotVersion) return this.result\n if (!sameSyntaxRange(result.range, range)) return this.result\n\n this.result = treeSitterParseResultToEditorSyntaxResult(\n result,\n this.resultContext(this.snapshot, [range]),\n )\n return this.result\n }\n\n private createRangeUnavailableResult(\n range: EditorSyntaxRange,\n message: string,\n ): EditorSyntaxResult {\n return this.createEmptyResult({\n degraded: { kind: 'range-unavailable', message },\n requestedRanges: [range],\n snapshot: this.snapshot,\n snapshotVersion: this.parsedSnapshotVersion,\n })\n }\n\n private createEmptyResult(options: {\n readonly degraded?: EditorSyntaxDegradedState | null\n readonly requestedRanges?: readonly EditorSyntaxRange[]\n readonly snapshot: PieceTableSnapshot\n readonly snapshotVersion: number\n }): EditorSyntaxResult {\n return createEmptySyntaxResult({\n degraded: options.degraded,\n language: this.languageConfiguration(),\n requestedRanges: options.requestedRanges,\n snapshot: this.snapshotTag(options.snapshot, options.snapshotVersion),\n })\n }\n\n private resultContext(\n snapshot: PieceTableSnapshot,\n requestedRanges: readonly EditorSyntaxRange[],\n ): TreeSitterSyntaxResultContext {\n return {\n includeCaptures: this.includeCaptures,\n includeHighlights: this.includeHighlights,\n mode: this.syntaxMode,\n requestedRanges,\n snapshotLength: snapshot.length,\n }\n }\n\n private languageConfiguration() {\n return {\n includeCaptures: this.includeCaptures,\n includeHighlights: this.includeHighlights,\n languageId: this.languageId,\n mode: this.syntaxMode,\n }\n }\n\n private snapshotTag(snapshot: PieceTableSnapshot, snapshotVersion: number) {\n return {\n documentId: this.documentId,\n length: snapshot.length,\n version: snapshotVersion,\n }\n }\n}\n\ntype TreeSitterBaseEditPayloadOptions = {\n readonly documentId: string\n readonly runtimeSessionId: string\n readonly languageId: TreeSitterLanguageId\n readonly previousSnapshotVersion: number\n readonly snapshotVersion: number\n readonly previousSnapshot: PieceTableSnapshot\n readonly nextSnapshot: PieceTableSnapshot\n readonly edits: readonly TextEdit[]\n readonly includeHighlights?: boolean\n readonly includeCaptures?: boolean\n}\n\ntype TreeSitterEditPayloadOptions = TreeSitterBaseEditPayloadOptions & {\n readonly resultMode?: 'full'\n}\n\ntype TreeSitterParseOnlyEditPayloadOptions = TreeSitterBaseEditPayloadOptions & {\n readonly resultMode: 'parseOnly'\n}\n\nexport function createTreeSitterEditPayload(\n options: TreeSitterParseOnlyEditPayloadOptions,\n): TreeSitterBackendEditPayload | null\nexport function createTreeSitterEditPayload(\n options: TreeSitterEditPayloadOptions,\n): TreeSitterEditPayload | null\nexport function createTreeSitterEditPayload(\n options: TreeSitterEditPayloadOptions | TreeSitterParseOnlyEditPayloadOptions,\n): TreeSitterBackendEditPayload | null {\n if (options.edits.length === 0) return null\n\n return {\n documentId: options.documentId,\n runtimeSessionId: options.runtimeSessionId,\n previousSnapshotVersion: options.previousSnapshotVersion,\n snapshotVersion: options.snapshotVersion,\n languageId: options.languageId,\n includeHighlights: options.includeHighlights ?? true,\n includeCaptures: options.includeCaptures,\n resultMode: options.resultMode,\n snapshot: options.nextSnapshot,\n edits: options.edits,\n inputEdits: createTreeSitterInputEdits(options.previousSnapshot, options.edits),\n }\n}\n\nexport const createTextDiffEdit = (previousText: string, nextText: string): TextEdit | null => {\n if (previousText === nextText) return null\n\n let start = 0\n const maxPrefixLength = Math.min(previousText.length, nextText.length)\n while (start < maxPrefixLength && previousText[start] === nextText[start]) start += 1\n\n let previousEnd = previousText.length\n let nextEnd = nextText.length\n while (\n previousEnd > start &&\n nextEnd > start &&\n previousText[previousEnd - 1] === nextText[nextEnd - 1]\n ) {\n previousEnd -= 1\n nextEnd -= 1\n }\n\n return {\n from: start,\n to: previousEnd,\n text: nextText.slice(start, nextEnd),\n }\n}\n\nconst createSyntaxTextEdits = (\n previousTextSnapshot: DocumentTextSnapshot,\n previousSnapshot: PieceTableSnapshot,\n change: DocumentSessionChange,\n): readonly TextEdit[] => {\n if (changeEditsApplyToSnapshot(previousSnapshot, change)) return change.edits\n\n const edit = diffPieceTableSnapshots(\n previousTextSnapshot.snapshot,\n documentSessionChangeTextSnapshot(change).snapshot,\n )\n return edit ? [edit] : []\n}\n\nconst changeEditsApplyToSnapshot = (\n snapshot: PieceTableSnapshot,\n change: DocumentSessionChange,\n): boolean => {\n try {\n return pieceTableSnapshotsHaveSameText(\n applyBatchToPieceTable(snapshot, change.edits),\n change.snapshot,\n )\n } catch {\n return false\n }\n}\n\ntype TreeSitterSyntaxResultContext = {\n readonly includeCaptures: boolean\n readonly includeHighlights: boolean\n readonly mode: 'full' | 'range'\n readonly requestedRanges: readonly EditorSyntaxRange[]\n readonly snapshotLength: number\n}\n\nconst treeSitterParseResultToEditorSyntaxResult: typeof treeSitterParseResultToEditorSyntaxResultInner =\n (result, context) => {\n recordParseResultPayload(result)\n return treeSitterParseResultToEditorSyntaxResultInner(result, context)\n }\n\nconst treeSitterParseResultToEditorSyntaxResultInner = (\n result: TreeSitterParseResult,\n context: TreeSitterSyntaxResultContext,\n): EditorSyntaxResult => ({\n captures: result.captures,\n ...{ records: result.records },\n degraded: treeSitterDegradedStateToEditorSyntaxState(result.degraded),\n folds: result.folds,\n brackets: result.brackets,\n errors: result.errors,\n injections: result.injections,\n projection: {\n language: {\n includeCaptures: context.includeCaptures,\n includeHighlights: context.includeHighlights,\n languageId: result.languageId,\n mode: context.mode,\n },\n requestedRanges: context.requestedRanges,\n snapshot: {\n documentId: result.documentId,\n length: context.snapshotLength,\n version: result.snapshotVersion,\n },\n },\n tokens: resultTokens(result),\n})\n\nfunction resultTokens(result: TreeSitterParseResult): EditorTokenStore {\n if (result.tokensPacked) return EditorTokenStore.fromPacked(result.tokensPacked)\n return EditorTokenStore.fromTokens(\n result.tokens ?? treeSitterCapturesToEditorTokens(result.captures),\n )\n}\n\nfunction recordParseResultPayload(result: TreeSitterParseResult): void {\n const sink = (\n globalThis as {\n __EDITOR_PERFORMANCE_DIAGNOSTICS__?: {\n enabled: boolean\n record(diagnostic: { name: string; detail?: Record<string, unknown> }): void\n } | null\n }\n ).__EDITOR_PERFORMANCE_DIAGNOSTICS__\n if (!sink?.enabled) return\n\n sink.record({\n name: 'treeSitter.parseResult.payload',\n detail: {\n captures: result.captures.length,\n tokens: result.tokens?.length ?? result.tokensPacked?.starts.length ?? -1,\n folds: result.folds.length,\n brackets: result.brackets.length,\n errors: result.errors.length,\n injections: result.injections.length,\n },\n })\n}\n\nconst treeSitterDegradedStateToEditorSyntaxState = (\n degraded: readonly TreeSitterDegradedState[] | undefined,\n): EditorSyntaxDegradedState | null => {\n const first = degraded?.[0]\n if (!first) return null\n\n return {\n kind: first.kind,\n phase: first.phase,\n message:\n degraded.length === 1\n ? first.message\n : `${first.message} (${degraded.length} Tree-sitter phases degraded)`,\n }\n}\n\nconst isTreeSitterParseAckResult = (\n result: TreeSitterParseResult | TreeSitterParseAckResult,\n): result is TreeSitterParseAckResult => 'status' in result && result.status === 'parsed'\n\nconst sameSyntaxRange = (left: EditorSyntaxRange, right: EditorSyntaxRange): boolean =>\n left.startIndex === right.startIndex && left.endIndex === right.endIndex\n\nconst createTreeSitterInputEdits = (\n snapshot: PieceTableSnapshot,\n edits: readonly TextEdit[],\n): TreeSitterInputEdit[] => {\n const sorted = edits.toSorted((left, right) => right.from - left.from || right.to - left.to)\n const inputEdits: TreeSitterInputEdit[] = []\n let workingSnapshot = snapshot\n\n for (const edit of sorted) {\n const startPosition = offsetToPoint(workingSnapshot, edit.from)\n const oldEndPosition = offsetToPoint(workingSnapshot, edit.to)\n const nextSnapshot = applyBatchToPieceTable(workingSnapshot, [edit])\n const newEndIndex = edit.from + edit.text.length\n\n inputEdits.push({\n startIndex: edit.from,\n oldEndIndex: edit.to,\n newEndIndex,\n startPosition,\n oldEndPosition,\n newEndPosition: offsetToPoint(nextSnapshot, newEndIndex),\n })\n workingSnapshot = nextSnapshot\n }\n\n return inputEdits\n}\n"],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { PieceTableSnapshot, TextOffsetRange } from '@singapore-editor/core/document';
2
+ import type { FoldRange } from '@singapore-editor/core/syntax';
3
+ import { type PieceTableAnchor, type SelectionSet } from '@singapore-editor/core/document';
4
+ import type { TreeSitterBackend } from './treeSitter/workerClient';
5
+ import type { TreeSitterLanguageId, TreeSitterSelectionRange } from './treeSitter/types';
6
+ export type TreeSitterSelectionExpansionState = {
7
+ readonly snapshotVersion: number;
8
+ readonly stacks: readonly (readonly TreeSitterSelectionRange[])[];
9
+ };
10
+ export type TreeSitterSelectionCommandOptions = {
11
+ readonly documentId: string;
12
+ readonly runtimeSessionId: string;
13
+ readonly languageId: TreeSitterLanguageId;
14
+ readonly snapshotVersion: number;
15
+ readonly snapshot: PieceTableSnapshot;
16
+ readonly selections: SelectionSet<PieceTableAnchor>;
17
+ readonly backend: Pick<TreeSitterBackend, 'select'>;
18
+ readonly state?: TreeSitterSelectionExpansionState;
19
+ };
20
+ export type TreeSitterSelectionCommandResult = {
21
+ readonly selections: SelectionSet<PieceTableAnchor>;
22
+ readonly state: TreeSitterSelectionExpansionState;
23
+ readonly status: 'ok' | 'stale';
24
+ };
25
+ /**
26
+ * The nesting the grammar found, as one unordered bucket for the editor's selection ladder to rank.
27
+ *
28
+ * Fold ranges are node ranges the parse has already published, so expand climbs exactly the nesting
29
+ * the gutter offers to collapse rather than a second, differently shaped idea of what encloses what.
30
+ * The fold query only reports nodes that span lines, so a construct written on one line is left to
31
+ * the word and line rungs.
32
+ */
33
+ export declare const treeSitterSelectionRanges: (folds: readonly FoldRange[]) => readonly TextOffsetRange[];
34
+ export declare const selectTreeSitterToken: (options: TreeSitterSelectionCommandOptions) => Promise<TreeSitterSelectionCommandResult>;
35
+ export declare const expandTreeSitterSelection: (options: TreeSitterSelectionCommandOptions) => Promise<TreeSitterSelectionCommandResult>;
36
+ export declare const shrinkTreeSitterSelection: (options: TreeSitterSelectionCommandOptions) => TreeSitterSelectionCommandResult;
37
+ //# sourceMappingURL=structuralSelection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structuralSelection.d.ts","sourceRoot":"","sources":["../src/structuralSelection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAA;AAC1F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAA;AAC9D,OAAO,EAGL,KAAK,gBAAgB,EAErB,KAAK,YAAY,EAClB,MAAM,iCAAiC,CAAA;AACxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAClE,OAAO,KAAK,EACV,oBAAoB,EACpB,wBAAwB,EAEzB,MAAM,oBAAoB,CAAA;AAE3B,MAAM,MAAM,iCAAiC,GAAG;IAC9C,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,wBAAwB,EAAE,CAAC,EAAE,CAAA;CAClE,CAAA;AAED,MAAM,MAAM,iCAAiC,GAAG;IAC9C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;IACjC,QAAQ,CAAC,UAAU,EAAE,oBAAoB,CAAA;IACzC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAA;IACrC,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAA;IACnD,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAA;IACnD,QAAQ,CAAC,KAAK,CAAC,EAAE,iCAAiC,CAAA;CACnD,CAAA;AAED,MAAM,MAAM,gCAAgC,GAAG;IAC7C,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAA;IACnD,QAAQ,CAAC,KAAK,EAAE,iCAAiC,CAAA;IACjD,QAAQ,CAAC,MAAM,EAAE,IAAI,GAAG,OAAO,CAAA;CAChC,CAAA;AAeD;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,GACpC,OAAO,SAAS,SAAS,EAAE,KAC1B,SAAS,eAAe,EAC4C,CAAA;AAEvE,eAAO,MAAM,qBAAqB,GAChC,SAAS,iCAAiC,KACzC,OAAO,CAAC,gCAAgC,CAI1C,CAAA;AAED,eAAO,MAAM,yBAAyB,GACpC,SAAS,iCAAiC,KACzC,OAAO,CAAC,gCAAgC,CAS1C,CAAA;AAED,eAAO,MAAM,yBAAyB,GACpC,SAAS,iCAAiC,KACzC,gCAgBF,CAAA"}