@coze-editor/extensions 0.1.0-alpha.09ffeb

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.
package/dist/index.js ADDED
@@ -0,0 +1,1418 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/index.ts
20
+ var index_exports = {};
21
+ __export(index_exports, {
22
+ FocusableWidget: () => FocusableWidget,
23
+ SelectionSide: () => SelectionSide,
24
+ astDebugger: () => astDebugger,
25
+ astDecorator: () => astDecorator,
26
+ autoSelectRanges: () => rangesFacet,
27
+ autoSelectUserEvent: () => selectUserEvent,
28
+ backgroundDecorations: () => backgroundDecorations,
29
+ colorizationBrackets: () => colorizationBrackets,
30
+ deletionEnlarger: () => deletionEnlarger,
31
+ elementAtPosition: () => elementAtPosition,
32
+ focusableKeymap: () => focusableKeymap,
33
+ frozenRanges: () => frozenRanges,
34
+ indentGuides: () => indentGuides,
35
+ inputRules: () => inputRules,
36
+ matchingBrackets: () => matchingBrackets,
37
+ mergeableMarkers: () => mergeableMarkers,
38
+ mixLanguages: () => mixLanguages,
39
+ positionElementLayer: () => positionElementLayer,
40
+ scrollBeyondLastLine: () => scrollBeyondLastLine,
41
+ selectionEnlarger: () => selectionEnlarger,
42
+ updateWholeDecorations: () => updateWholeDecorations
43
+ });
44
+ module.exports = __toCommonJS(index_exports);
45
+
46
+ // src/ast-decorator/whole.ts
47
+ var import_es_toolkit = require("es-toolkit");
48
+ var import_utils = require("@coze-editor/utils");
49
+ var import_view2 = require("@codemirror/view");
50
+ var import_state2 = require("@codemirror/state");
51
+ var import_language = require("@codemirror/language");
52
+
53
+ // src/background-decorations/index.ts
54
+ var import_view = require("@codemirror/view");
55
+ var import_state = require("@codemirror/state");
56
+
57
+ // src/background-decorations/squash.ts
58
+ function squash(decorations) {
59
+ const result = [];
60
+ const grouped = groupDecorationsByClassName(decorations);
61
+ grouped.forEach((decos, className) => {
62
+ const merged = mergeIntervals(decos);
63
+ result.push(
64
+ ...merged.map((m) => ({
65
+ from: m.start,
66
+ to: m.end,
67
+ className
68
+ }))
69
+ );
70
+ });
71
+ return result;
72
+ }
73
+ function groupDecorationsByClassName(decorations) {
74
+ const map = /* @__PURE__ */ new Map();
75
+ decorations.forEach((deco) => {
76
+ if (!map.has(deco.className)) {
77
+ map.set(deco.className, []);
78
+ }
79
+ map.get(deco.className).push(deco);
80
+ });
81
+ return map;
82
+ }
83
+ function mergeIntervals(decorations) {
84
+ const merged = [];
85
+ const cloned = decorations.map((deco) => ({
86
+ start: deco.from,
87
+ end: deco.to
88
+ }));
89
+ cloned.sort((a, b) => a.start - b.start);
90
+ let current = cloned[0];
91
+ for (let i = 1; i < cloned.length; i++) {
92
+ const next = cloned[i];
93
+ if (next.start <= current.end) {
94
+ current.end = Math.max(current.end, next.end);
95
+ } else {
96
+ merged.push(current);
97
+ current = next;
98
+ }
99
+ }
100
+ merged.push(current);
101
+ return merged;
102
+ }
103
+
104
+ // src/background-decorations/cut.ts
105
+ function cutAtLineBreak(decorations, state) {
106
+ const cuts = [];
107
+ decorations.forEach((deco) => {
108
+ const startLine = state.doc.lineAt(deco.from);
109
+ const endLine = state.doc.lineAt(deco.to);
110
+ if (startLine.number !== endLine.number) {
111
+ const slices = [];
112
+ let pos = deco.from;
113
+ for (let i = startLine.number; i < endLine.number; i++) {
114
+ const line = state.doc.line(i);
115
+ slices.push({
116
+ from: pos,
117
+ to: line.to,
118
+ className: deco.className
119
+ });
120
+ pos = line.to + 1;
121
+ }
122
+ slices.push({
123
+ from: pos,
124
+ to: deco.to,
125
+ className: deco.className
126
+ });
127
+ cuts.push(...slices);
128
+ } else {
129
+ cuts.push(deco);
130
+ }
131
+ });
132
+ return cuts;
133
+ }
134
+
135
+ // src/background-decorations/index.ts
136
+ function configChanged(update) {
137
+ return update.startState.facet(backgroundDecorations) !== update.state.facet(backgroundDecorations);
138
+ }
139
+ var backgroundDecoratorLayer = (0, import_view.layer)({
140
+ above: false,
141
+ markers(view) {
142
+ const decorations = view.state.facet(backgroundDecorations).reduce((memo, current) => [...memo, ...current(view)], []);
143
+ return cutAtLineBreak(squash(decorations), view.state).map(
144
+ (deco) => import_view.RectangleMarker.forRange(
145
+ view,
146
+ deco.className,
147
+ import_state.EditorSelection.range(deco.from, deco.to)
148
+ )
149
+ ).reduce((memo, current) => [...memo, ...current], []);
150
+ },
151
+ update(update) {
152
+ return update.focusChanged || update.docChanged || update.selectionSet || update.viewportChanged || configChanged(update);
153
+ },
154
+ class: "cm-backgroundDecoratorLayer"
155
+ });
156
+ var backgroundDecorations = import_state.Facet.define({
157
+ enables: [backgroundDecoratorLayer]
158
+ });
159
+
160
+ // src/ast-decorator/whole.ts
161
+ var updateWholeDecorationsEffect = import_state2.StateEffect.define();
162
+ function updateWholeDecorations(view) {
163
+ view.dispatch({
164
+ effects: updateWholeDecorationsEffect.of(null)
165
+ });
166
+ }
167
+ var classNameDecorationCache = /* @__PURE__ */ new Map();
168
+ function getClassDecoration(className) {
169
+ if (!classNameDecorationCache.has(className)) {
170
+ classNameDecorationCache.set(
171
+ className,
172
+ import_view2.Decoration.mark({
173
+ class: className
174
+ })
175
+ );
176
+ }
177
+ return classNameDecorationCache.get(className);
178
+ }
179
+ function buildDecorations(state, tree) {
180
+ const decorates = state.facet(wholeASTDecoratorFacet) ?? [];
181
+ const treeCursor = tree.cursor();
182
+ const decorations = {
183
+ highest: import_view2.Decoration.none,
184
+ high: import_view2.Decoration.none,
185
+ default: import_view2.Decoration.none,
186
+ low: import_view2.Decoration.none,
187
+ lowest: import_view2.Decoration.none
188
+ };
189
+ let atomicRanges = import_state2.RangeSet.empty;
190
+ let backgroundDecorations2 = [];
191
+ const from = 0;
192
+ const to = state.doc.length;
193
+ (0, import_utils.traverseAST)(treeCursor, from, to, (cursor) => {
194
+ decorates.forEach((decorate) => {
195
+ const decorationSpec = decorate(cursor, state);
196
+ let specs = [];
197
+ if (Array.isArray(decorationSpec)) {
198
+ specs = decorationSpec;
199
+ } else if (decorationSpec) {
200
+ specs = [decorationSpec];
201
+ }
202
+ specs.forEach((spec) => {
203
+ const result = updateDecorationSpec(cursor, spec, {
204
+ decorations,
205
+ backgroundDecorations: backgroundDecorations2,
206
+ atomicRanges
207
+ });
208
+ if (!result) {
209
+ return;
210
+ }
211
+ backgroundDecorations2 = result.backgroundDecorations;
212
+ atomicRanges = result.atomicRanges;
213
+ });
214
+ });
215
+ });
216
+ return {
217
+ decorations,
218
+ atomicRanges,
219
+ backgroundDecorations: backgroundDecorations2
220
+ };
221
+ }
222
+ function updateDecorationSpec(cursor, decorationSpec, {
223
+ decorations,
224
+ backgroundDecorations: backgroundDecorations2,
225
+ atomicRanges
226
+ }) {
227
+ if (!decorationSpec) {
228
+ return;
229
+ }
230
+ const from = decorationSpec.from ?? cursor.from;
231
+ const to = decorationSpec.to ?? cursor.to;
232
+ const omitKeys = ["type", "from", "to", "atomicRange"];
233
+ let decorationRange = null;
234
+ switch (decorationSpec.type) {
235
+ case "className":
236
+ decorationRange = from === to ? null : getClassDecoration(decorationSpec.className).range(from, to);
237
+ break;
238
+ case "replace":
239
+ decorationRange = import_view2.Decoration.replace(
240
+ (0, import_es_toolkit.omit)(decorationSpec, omitKeys)
241
+ ).range(from, to);
242
+ break;
243
+ case "widget":
244
+ decorationRange = import_view2.Decoration.widget((0, import_es_toolkit.omit)(decorationSpec, omitKeys)).range(
245
+ from
246
+ );
247
+ break;
248
+ case "background":
249
+ backgroundDecorations2.push({
250
+ from: decorationSpec.from ?? cursor.from,
251
+ to: decorationSpec.to ?? cursor.to,
252
+ className: decorationSpec.className
253
+ });
254
+ break;
255
+ }
256
+ if (decorationRange) {
257
+ const prec = decorationSpec.type === "className" ? decorationSpec.prec ?? "default" : "default";
258
+ if (decorations[prec]) {
259
+ decorations[prec] = decorations[prec].update({
260
+ add: [decorationRange],
261
+ sort: true
262
+ });
263
+ }
264
+ }
265
+ if (decorationSpec.type !== "background" && decorationRange && decorationSpec.atomicRange === true) {
266
+ atomicRanges = atomicRanges.update({
267
+ add: [decorationRange],
268
+ sort: true
269
+ });
270
+ }
271
+ return {
272
+ decorations,
273
+ backgroundDecorations: backgroundDecorations2,
274
+ atomicRanges
275
+ };
276
+ }
277
+ var decorateField = import_state2.StateField.define({
278
+ create(state) {
279
+ return buildDecorations(state, (0, import_language.syntaxTree)(state));
280
+ },
281
+ update(value, tr) {
282
+ const tree = (0, import_language.syntaxTree)(tr.state);
283
+ const hasUpdateEffect = tr.effects.some(
284
+ (effect) => effect.is(updateWholeDecorationsEffect)
285
+ );
286
+ const syntaxTreeChanged = (0, import_language.syntaxTree)(tr.startState) !== tree;
287
+ if (syntaxTreeChanged || hasUpdateEffect) {
288
+ value = buildDecorations(tr.state, tree);
289
+ }
290
+ return value;
291
+ },
292
+ provide(field) {
293
+ return [
294
+ import_state2.Prec.highest(
295
+ import_view2.EditorView.decorations.compute(
296
+ [field],
297
+ (state) => state.field(field).decorations.highest
298
+ )
299
+ ),
300
+ import_state2.Prec.high(
301
+ import_view2.EditorView.decorations.compute(
302
+ [field],
303
+ (state) => state.field(field).decorations.high
304
+ )
305
+ ),
306
+ import_state2.Prec.default(
307
+ import_view2.EditorView.decorations.compute(
308
+ [field],
309
+ (state) => state.field(field).decorations.default
310
+ )
311
+ ),
312
+ import_state2.Prec.low(
313
+ import_view2.EditorView.decorations.compute(
314
+ [field],
315
+ (state) => state.field(field).decorations.low
316
+ )
317
+ ),
318
+ import_state2.Prec.lowest(
319
+ import_view2.EditorView.decorations.compute(
320
+ [field],
321
+ (state) => state.field(field).decorations.lowest
322
+ )
323
+ ),
324
+ import_view2.EditorView.atomicRanges.of((view) => view.state.field(field).atomicRanges),
325
+ backgroundDecorations.of(
326
+ (view) => view.state.field(field).backgroundDecorations
327
+ )
328
+ ];
329
+ }
330
+ });
331
+ var wholeASTDecoratorFacet = import_state2.Facet.define({
332
+ enables: [decorateField, backgroundDecoratorLayer]
333
+ });
334
+
335
+ // src/ast-decorator/cursor.ts
336
+ var import_view3 = require("@codemirror/view");
337
+ var import_state3 = require("@codemirror/state");
338
+ var import_language2 = require("@codemirror/language");
339
+ var CursorASTView = class {
340
+ constructor(view) {
341
+ this.view = view;
342
+ }
343
+ classNameDecorationCache = /* @__PURE__ */ new Map();
344
+ decorations = import_view3.Decoration.none;
345
+ backgroundDecorations = [];
346
+ getClassDecoration(className) {
347
+ if (!this.classNameDecorationCache.has(className)) {
348
+ this.classNameDecorationCache.set(
349
+ className,
350
+ import_view3.Decoration.mark({
351
+ class: className
352
+ })
353
+ );
354
+ }
355
+ return this.classNameDecorationCache.get(className);
356
+ }
357
+ update(update) {
358
+ if (update.focusChanged && update.view.hasFocus || !update.startState.selection.eq(update.state.selection)) {
359
+ const tree = (0, import_language2.syntaxTree)(update.state);
360
+ const pos = update.state.selection.main.head;
361
+ const decorators = update.state.facet(cursorASTDecoratorFacet);
362
+ const cursor = tree.cursorAt(pos, 0);
363
+ const builder = new import_state3.RangeSetBuilder();
364
+ const bgDecorations = [];
365
+ do {
366
+ decorators.forEach((decorator) => {
367
+ const decorationSpec = decorator(cursor, update.state);
368
+ if (!decorationSpec) {
369
+ return;
370
+ }
371
+ let decoration;
372
+ switch (decorationSpec.type) {
373
+ case "className":
374
+ decoration = this.getClassDecoration(decorationSpec.className);
375
+ break;
376
+ case "background":
377
+ bgDecorations.push({
378
+ from: decorationSpec.from ?? cursor.from,
379
+ to: decorationSpec.to ?? cursor.to,
380
+ className: decorationSpec.className
381
+ });
382
+ break;
383
+ }
384
+ if (decoration) {
385
+ builder.add(
386
+ decorationSpec.from ?? cursor.from,
387
+ decorationSpec.to ?? cursor.to,
388
+ decoration
389
+ );
390
+ }
391
+ });
392
+ } while (cursor.parent());
393
+ this.decorations = builder.finish();
394
+ this.backgroundDecorations = bgDecorations;
395
+ }
396
+ if (update.focusChanged && !update.view.hasFocus) {
397
+ this.decorations = import_view3.Decoration.none;
398
+ this.backgroundDecorations = [];
399
+ }
400
+ }
401
+ };
402
+ var cursorASTDecoratorFacet = import_state3.Facet.define({
403
+ enables: [
404
+ import_view3.ViewPlugin.fromClass(CursorASTView, {
405
+ decorations: (v) => v.decorations,
406
+ provide(plugin) {
407
+ return [
408
+ backgroundDecorations.of(
409
+ (view) => {
410
+ var _a;
411
+ return ((_a = view.plugin(plugin)) == null ? void 0 : _a.backgroundDecorations) ?? [];
412
+ }
413
+ )
414
+ ];
415
+ }
416
+ })
417
+ ]
418
+ });
419
+
420
+ // src/ast-decorator/index.ts
421
+ var astDecorator = {
422
+ whole: wholeASTDecoratorFacet,
423
+ fromCursor: cursorASTDecoratorFacet
424
+ };
425
+
426
+ // src/ast-debugger/index.ts
427
+ var import_utils2 = require("@coze-editor/utils");
428
+ var import_view4 = require("@codemirror/view");
429
+ var import_language3 = require("@codemirror/language");
430
+ var astDebugger = import_view4.ViewPlugin.fromClass(
431
+ class {
432
+ constructor(view) {
433
+ printTreeFromState(view.state);
434
+ }
435
+ update(update) {
436
+ if (update.docChanged) {
437
+ printTreeFromState(update.state);
438
+ }
439
+ }
440
+ }
441
+ );
442
+ function printTreeFromState(state) {
443
+ const tree = (0, import_language3.syntaxTree)(state);
444
+ console.groupCollapsed("Syntax Tree");
445
+ const cursor = tree.cursor();
446
+ (0, import_utils2.traverseAST)(cursor, 0, tree.length, (cursor2) => {
447
+ console.group(
448
+ `%c${cursor2.name}(${cursor2.from}:${cursor2.to})`,
449
+ "color: purple;"
450
+ );
451
+ console.log(state.sliceDoc(cursor2.from, cursor2.to));
452
+ console.groupEnd();
453
+ });
454
+ console.groupEnd();
455
+ }
456
+
457
+ // src/focusable/focusable.ts
458
+ var import_view5 = require("@codemirror/view");
459
+ var focusableKeymap = import_view5.keymap.of([
460
+ {
461
+ key: "ArrowLeft",
462
+ run(view) {
463
+ const mainSelection = view.state.selection.main;
464
+ if (!mainSelection.empty) {
465
+ return false;
466
+ }
467
+ let handled = false;
468
+ const pos = mainSelection.from;
469
+ for (const line of view.docView.children) {
470
+ for (const child of line.children) {
471
+ if (child.isWidget && child.widget instanceof FocusableWidget && child.posAtEnd === pos) {
472
+ child.widget.focus(1);
473
+ handled = true;
474
+ }
475
+ }
476
+ if (handled) {
477
+ break;
478
+ }
479
+ }
480
+ return handled;
481
+ }
482
+ },
483
+ {
484
+ key: "ArrowRight",
485
+ run(view) {
486
+ const mainSelection = view.state.selection.main;
487
+ if (!mainSelection.empty) {
488
+ return false;
489
+ }
490
+ let handled = false;
491
+ const pos = mainSelection.from;
492
+ for (const line of view.docView.children) {
493
+ for (const child of line.children) {
494
+ if (child.isWidget && child.widget instanceof FocusableWidget && child.posAtStart === pos) {
495
+ child.widget.focus(-1);
496
+ handled = true;
497
+ break;
498
+ }
499
+ }
500
+ if (handled) {
501
+ break;
502
+ }
503
+ }
504
+ return handled;
505
+ }
506
+ }
507
+ ]);
508
+ var FocusableWidget = class extends import_view5.WidgetType {
509
+ };
510
+
511
+ // src/auto-select-ranges/extension.ts
512
+ var import_utils3 = require("@coze-editor/utils");
513
+ var import_view6 = require("@codemirror/view");
514
+ var import_state4 = require("@codemirror/state");
515
+
516
+ // src/auto-select-ranges/utils.ts
517
+ function mergeIntervals2(ranges) {
518
+ if (ranges.length === 0) {
519
+ return [];
520
+ }
521
+ const merged = [];
522
+ const cloned = ranges.map((range2) => ({
523
+ from: range2.from,
524
+ to: range2.to
525
+ }));
526
+ cloned.sort((a, b) => a.from - b.from);
527
+ let current = cloned[0];
528
+ for (let i = 1; i < cloned.length; i++) {
529
+ const next = cloned[i];
530
+ if (next.from <= current.to) {
531
+ current.to = Math.max(current.to, next.to);
532
+ } else {
533
+ merged.push(current);
534
+ current = next;
535
+ }
536
+ }
537
+ if (current) {
538
+ merged.push(current);
539
+ }
540
+ return merged;
541
+ }
542
+ function findContainingRange(ranges, pos) {
543
+ for (const range2 of ranges) {
544
+ if (pos >= range2.from && pos <= range2.to) {
545
+ return range2;
546
+ }
547
+ }
548
+ }
549
+
550
+ // src/auto-select-ranges/extension.ts
551
+ var extension = import_view6.ViewPlugin.fromClass(
552
+ class {
553
+ lastFocus = false;
554
+ constructor(view) {
555
+ this.lastFocus = view.hasFocus;
556
+ }
557
+ update(update) {
558
+ const userEvent = update.state.facet(selectUserEvent) ?? "select";
559
+ const hasSelectUserEvent = update.transactions.some(
560
+ (tr) => tr.isUserEvent(userEvent)
561
+ );
562
+ if (hasSelectUserEvent) {
563
+ const lastHasFocus = this.lastFocus;
564
+ const startSelection = update.startState.selection;
565
+ const { selection } = update.state;
566
+ const rangesProviders = update.state.facet(rangesFacet);
567
+ const ranges = mergeIntervals2(
568
+ (0, import_utils3.flatten)(
569
+ rangesProviders.map((provider) => provider(update.view.state))
570
+ ).filter(Boolean)
571
+ );
572
+ const currentRange = findContainingRange(ranges, selection.main.from);
573
+ if (selection.main.empty && currentRange && (!lastHasFocus || // 上一次的选区 from 或 to 在当前选区外(“首次进入”当前选区)
574
+ findContainingRange(ranges, startSelection.main.from) !== currentRange || findContainingRange(ranges, startSelection.main.to) !== currentRange)) {
575
+ queueMicrotask(() => {
576
+ update.view.dispatch({
577
+ selection: selection.replaceRange(
578
+ import_state4.EditorSelection.range(currentRange.from, currentRange.to)
579
+ )
580
+ });
581
+ });
582
+ }
583
+ }
584
+ if (this.lastFocus !== update.view.hasFocus) {
585
+ this.lastFocus = update.view.hasFocus;
586
+ }
587
+ }
588
+ }
589
+ );
590
+ var rangesFacet = import_state4.Facet.define({
591
+ enables: extension
592
+ });
593
+ var selectUserEvent = import_state4.Facet.define({
594
+ combine: import_utils3.FacetCombineStrategy.Last
595
+ });
596
+
597
+ // src/selection-enlarger/extension.ts
598
+ var import_utils5 = require("@coze-editor/utils");
599
+ var import_state5 = require("@codemirror/state");
600
+ var extension2 = import_state5.EditorState.transactionFilter.of((tr) => {
601
+ if (tr.docChanged || tr.newSelection.eq(tr.startState.selection)) {
602
+ return tr;
603
+ }
604
+ const providers = tr.startState.facet(selectionEnlarger);
605
+ const specs = (0, import_utils5.flatten)(providers.map((provider) => provider(tr.startState)));
606
+ let { newSelection } = tr;
607
+ newSelection.ranges.forEach((range2, index) => {
608
+ for (const spec of specs) {
609
+ if ((0, import_utils5.hasOverlap)(range2, spec.source)) {
610
+ const isReversed = range2.head < range2.anchor;
611
+ const from = Math.min(range2.from, spec.target.from);
612
+ const to = Math.max(range2.to, spec.target.to);
613
+ const newRange = isReversed ? import_state5.EditorSelection.range(
614
+ to,
615
+ from,
616
+ range2.goalColumn,
617
+ range2.bidiLevel ?? void 0
618
+ ) : import_state5.EditorSelection.range(
619
+ from,
620
+ to,
621
+ range2.goalColumn,
622
+ range2.bidiLevel ?? void 0
623
+ );
624
+ newSelection = newSelection.replaceRange(newRange, index);
625
+ }
626
+ }
627
+ });
628
+ return [
629
+ tr,
630
+ {
631
+ selection: newSelection
632
+ }
633
+ ];
634
+ });
635
+ var selectionEnlarger = import_state5.Facet.define({
636
+ enables: extension2
637
+ });
638
+
639
+ // src/deletion-enlarger/extension.ts
640
+ var import_utils6 = require("@coze-editor/utils");
641
+ var import_state6 = require("@codemirror/state");
642
+ var extension3 = import_state6.EditorState.transactionFilter.of((tr) => {
643
+ const providers = tr.startState.facet(deletionEnlarger);
644
+ const specs = (0, import_utils6.flatten)(providers.map((provider) => provider(tr.startState)));
645
+ const { length } = tr.startState.doc;
646
+ let changes = import_state6.ChangeSet.empty(length);
647
+ tr.changes.iterChanges((fromA, toA, fromB, toB) => {
648
+ const isDeletion = fromB === toB;
649
+ if (!isDeletion) {
650
+ return;
651
+ }
652
+ for (const spec of specs) {
653
+ if ((0, import_utils6.hasOverlap)(
654
+ {
655
+ from: fromA,
656
+ to: toA
657
+ },
658
+ spec.source
659
+ )) {
660
+ const change = import_state6.ChangeSet.of([{ ...spec.target, insert: "" }], length);
661
+ changes = changes.compose(change.map(changes));
662
+ }
663
+ }
664
+ });
665
+ const nextChanges = changes.map(tr.changes);
666
+ if (nextChanges.empty) {
667
+ return tr;
668
+ }
669
+ return [
670
+ tr,
671
+ {
672
+ changes: nextChanges,
673
+ sequential: true
674
+ }
675
+ ];
676
+ });
677
+ var deletionEnlarger = import_state6.Facet.define({
678
+ enables: extension3
679
+ });
680
+
681
+ // src/input-rules/index.ts
682
+ var import_view7 = require("@codemirror/view");
683
+ var import_state7 = require("@codemirror/state");
684
+ var android = typeof navigator === "object" && /Android\b/.test(navigator.userAgent);
685
+ var isExtension = (v) => Boolean(v);
686
+ var inputRules = (rules) => {
687
+ const ruleExtensions = (rules ?? []).map(({ type, triggerCharacter, handler }) => {
688
+ if (type === "character") {
689
+ return import_view7.EditorView.inputHandler.of((view, from, to, insert) => {
690
+ if ((android ? view.composing : view.compositionStarted) || view.state.readOnly) {
691
+ return false;
692
+ }
693
+ const sel = view.state.selection.main;
694
+ if (insert !== triggerCharacter || from !== sel.from || to !== sel.to) {
695
+ return false;
696
+ }
697
+ return handler({
698
+ view,
699
+ state: view.state,
700
+ from,
701
+ to
702
+ });
703
+ });
704
+ }
705
+ }).filter((v) => isExtension(v));
706
+ return import_state7.Prec.high(ruleExtensions);
707
+ };
708
+
709
+ // src/mix-languages/mix.ts
710
+ var import_common = require("@lezer/common");
711
+ var import_lezer_parser_template = require("@coze-editor/lezer-parser-template");
712
+ var import_language4 = require("@codemirror/language");
713
+ function mixLanguages({ name, outerLanguage, innerLanguage }) {
714
+ return import_language4.LRLanguage.define({
715
+ name,
716
+ parser: import_lezer_parser_template.parser.configure({
717
+ wrap: (0, import_common.parseMixed)((node) => {
718
+ if (outerLanguage && node.type.isTop) {
719
+ return {
720
+ parser: outerLanguage.parser,
721
+ overlay: (n) => n.type.name === "Text"
722
+ };
723
+ }
724
+ if (innerLanguage && node.name === "InterpolationContent") {
725
+ return {
726
+ parser: innerLanguage.parser
727
+ };
728
+ }
729
+ return null;
730
+ })
731
+ })
732
+ });
733
+ }
734
+
735
+ // src/indent-guides/index.ts
736
+ var import_es_toolkit2 = require("es-toolkit");
737
+ var import_view8 = require("@codemirror/view");
738
+ var import_state8 = require("@codemirror/state");
739
+
740
+ // src/indent-guides/utils.ts
741
+ var SPACES = /^\s*/;
742
+ var getCodeStart = (text) => text.match(SPACES)[0].length;
743
+ var fromPairs = (pairs2) => {
744
+ let index = -1;
745
+ const length = pairs2 == null ? 0 : pairs2.length;
746
+ const result = {};
747
+ while (++index < length) {
748
+ const pair = pairs2[index];
749
+ result[pair[0]] = pair[1];
750
+ }
751
+ return result;
752
+ };
753
+
754
+ // src/indent-guides/index.ts
755
+ var indentationMark = import_view8.Decoration.mark({ class: "cm-indentation-guide" });
756
+ var indentationLevelMarks = (0, import_es_toolkit2.range)(20).map(
757
+ (i) => import_view8.Decoration.line({ class: `cm-indentation-level-${i}` })
758
+ );
759
+ var IndentationWidget = class _IndentationWidget extends import_view8.WidgetType {
760
+ constructor(indents) {
761
+ super();
762
+ this.indents = indents;
763
+ }
764
+ static create(indents) {
765
+ return import_view8.Decoration.widget({
766
+ widget: new _IndentationWidget(indents),
767
+ side: 1
768
+ });
769
+ }
770
+ toDOM() {
771
+ const wrap = document.createElement("span");
772
+ wrap.className = "cm-indentation-widget";
773
+ for (const indent of this.indents) {
774
+ const marker = wrap.appendChild(document.createElement("span"));
775
+ marker.className = "cm-indentation-guide";
776
+ marker.textContent = " ";
777
+ wrap.append(" ".repeat(indent - 1));
778
+ }
779
+ return wrap;
780
+ }
781
+ };
782
+ function makeIndentationMark(from, to, indent, tabSize, builder) {
783
+ builder.add(from, from, indentationLevelMarks[indent / tabSize]);
784
+ for (let i = from; i < Math.min(from + indent, to); i += tabSize) {
785
+ builder.add(i, i + 1, indentationMark);
786
+ }
787
+ }
788
+ function makeIndentationWidget(from, to, tabSize, builder) {
789
+ const length = to - from;
790
+ if (length !== 0) {
791
+ return;
792
+ }
793
+ if (tabSize > 2) {
794
+ builder.add(to, to, IndentationWidget.create([tabSize]));
795
+ } else {
796
+ builder.add(to, to, IndentationWidget.create([2, tabSize * 2]));
797
+ }
798
+ }
799
+ function makeIndentationDecorators(view) {
800
+ const builder = new import_state8.RangeSetBuilder();
801
+ const tabSize = Number(view.state.tabSize);
802
+ const { doc } = view.state;
803
+ const spaceOnlyLines = [];
804
+ let currentIndent = 0;
805
+ for (const { from: visibleFrom, to: visibleTo } of view.visibleRanges) {
806
+ let to = visibleFrom - 1;
807
+ let pos, from, length, text;
808
+ while ((pos = to + 1) <= visibleTo) {
809
+ ({ from, to, length, text } = doc.lineAt(pos));
810
+ const codeStartsAt = getCodeStart(text);
811
+ const isAllSpaces = codeStartsAt === length;
812
+ const skipIndent = codeStartsAt === 0;
813
+ const isComment = text[codeStartsAt] === "/";
814
+ if (isAllSpaces) {
815
+ spaceOnlyLines.push({ from, to });
816
+ continue;
817
+ } else if (skipIndent) {
818
+ spaceOnlyLines.length = 0;
819
+ continue;
820
+ }
821
+ const indent = Math.ceil(codeStartsAt / tabSize) * tabSize;
822
+ if (!isComment) {
823
+ currentIndent = indent;
824
+ }
825
+ for (const { from: spaceFrom, to: spaceTo } of spaceOnlyLines) {
826
+ makeIndentationMark(
827
+ spaceFrom,
828
+ spaceTo,
829
+ currentIndent,
830
+ tabSize,
831
+ builder
832
+ );
833
+ makeIndentationWidget(spaceFrom, spaceTo, tabSize, builder);
834
+ }
835
+ spaceOnlyLines.length = 0;
836
+ makeIndentationMark(from, to, indent, tabSize, builder);
837
+ }
838
+ }
839
+ return builder.finish();
840
+ }
841
+ var showIndentations = import_view8.ViewPlugin.fromClass(
842
+ class {
843
+ decorations;
844
+ constructor(view) {
845
+ this.decorations = makeIndentationDecorators(view);
846
+ }
847
+ update(update) {
848
+ if (update.docChanged || update.viewportChanged) {
849
+ this.decorations = makeIndentationDecorators(update.view);
850
+ }
851
+ }
852
+ },
853
+ {
854
+ decorations: (v) => v.decorations
855
+ }
856
+ );
857
+ var indentationTheme = import_view8.EditorView.baseTheme({
858
+ ".cm-line": {
859
+ paddingLeft: 0,
860
+ marginLeft: "2px"
861
+ },
862
+ ".cm-indentation-guide": {
863
+ position: "relative"
864
+ },
865
+ ".cm-indentation-guide:after": {
866
+ position: "absolute",
867
+ content: "''",
868
+ right: "0.9ch",
869
+ height: "1.4em",
870
+ borderLeft: "1px solid rgba(28, 31, 35, .08)"
871
+ },
872
+ ...fromPairs(
873
+ indentationLevelMarks.map((_decoration, i) => [
874
+ `.cm-indentation-level-${i}`,
875
+ { textIndent: `-${i * 2}ch`, paddingLeft: `${i * 2}ch` }
876
+ ])
877
+ )
878
+ });
879
+ var indentGuides = () => [showIndentations, indentationTheme];
880
+
881
+ // src/scroll-beyond-last-line/index.ts
882
+ var import_view9 = require("@codemirror/view");
883
+
884
+ // src/scroll-beyond-last-line/empty-block.ts
885
+ var EmptyBlock = class {
886
+ constructor(lineNumber, contentHeight, scrollHeight) {
887
+ this.lineNumber = lineNumber;
888
+ this.contentHeight = contentHeight;
889
+ this.scrollHeight = scrollHeight;
890
+ }
891
+ draw() {
892
+ const elt = document.createElement("div");
893
+ elt.className = "cm-empty-scroll-block-maker";
894
+ this.adjust(elt);
895
+ return elt;
896
+ }
897
+ update(_, prev) {
898
+ return prev.lineNumber === this.lineNumber && prev.contentHeight === this.contentHeight && prev.scrollHeight === this.scrollHeight;
899
+ }
900
+ adjust(elt) {
901
+ elt.style.display = "block";
902
+ elt.style.width = "1px";
903
+ if (this.lineNumber > 1) {
904
+ elt.style.height = `calc(${typeof this.scrollHeight === "number" ? `${this.scrollHeight}px` : "100%"} + ${this.contentHeight}px)`;
905
+ } else {
906
+ elt.style.height = "0";
907
+ }
908
+ }
909
+ eq(p) {
910
+ return this.lineNumber === p.lineNumber && this.contentHeight === p.contentHeight && this.scrollHeight === p.scrollHeight;
911
+ }
912
+ };
913
+
914
+ // src/scroll-beyond-last-line/index.ts
915
+ var scrollBeyondLastLine = (scrollHeight) => [
916
+ (0, import_view9.layer)({
917
+ above: false,
918
+ updateOnDocViewUpdate: true,
919
+ class: "cm-empty-marker-layer",
920
+ update(update) {
921
+ return update.state.doc.lines !== update.startState.doc.lines;
922
+ },
923
+ markers(view) {
924
+ const maker = new EmptyBlock(
925
+ view.state.doc.lines,
926
+ view.contentHeight,
927
+ scrollHeight
928
+ );
929
+ return [maker];
930
+ }
931
+ }),
932
+ import_view9.EditorView.theme({
933
+ "& .cm-empty-marker-layer": {
934
+ height: "100%"
935
+ }
936
+ })
937
+ ];
938
+
939
+ // src/brackets/matching-brackets.ts
940
+ var import_view10 = require("@codemirror/view");
941
+ var import_state9 = require("@codemirror/state");
942
+ var pairs = {
943
+ "(": ")",
944
+ "{": "}",
945
+ "[": "]",
946
+ ")": "(",
947
+ "}": "{",
948
+ "]": "["
949
+ };
950
+ var findMatchingBracket = (state, cursorPos) => {
951
+ try {
952
+ const doc = state.doc.toString();
953
+ let stack = [];
954
+ let leftIndex = -1;
955
+ let rightIndex = -1;
956
+ for (let i = cursorPos - 1; i >= 0; i--) {
957
+ const char = doc[i];
958
+ if (pairs[char]) {
959
+ if ([")", "}", "]"].includes(char)) {
960
+ stack.push(char);
961
+ } else {
962
+ if (stack.length === 0) {
963
+ leftIndex = i;
964
+ break;
965
+ }
966
+ const lastBracket = stack.pop();
967
+ if (pairs[char] !== lastBracket) {
968
+ return null;
969
+ }
970
+ }
971
+ }
972
+ }
973
+ stack = [];
974
+ for (let i = cursorPos; i < doc.length; i++) {
975
+ const char = doc[i];
976
+ if (pairs[char]) {
977
+ if (["(", "{", "["].includes(char)) {
978
+ stack.push(char);
979
+ } else {
980
+ if (stack.length === 0) {
981
+ rightIndex = i;
982
+ break;
983
+ }
984
+ const lastBracket = stack.pop();
985
+ if (pairs[char] !== lastBracket) {
986
+ return null;
987
+ }
988
+ }
989
+ }
990
+ }
991
+ if (leftIndex !== -1 && rightIndex !== -1) {
992
+ return [leftIndex, rightIndex];
993
+ }
994
+ return null;
995
+ } catch (e) {
996
+ console.error("findMatchingBracket failed", e);
997
+ return null;
998
+ }
999
+ };
1000
+ var renderMatch = (match) => {
1001
+ const decorations = [];
1002
+ const mark = import_view10.Decoration.mark({ class: "cm-matchingBracket" });
1003
+ decorations.push(mark.range(match, match + 1));
1004
+ return decorations;
1005
+ };
1006
+ var bracketMatchingState = import_state9.StateField.define({
1007
+ create() {
1008
+ return import_view10.Decoration.none;
1009
+ },
1010
+ update(deco, tr) {
1011
+ if (!tr.docChanged && !tr.selection) {
1012
+ return deco;
1013
+ }
1014
+ let decorations = [];
1015
+ for (const range2 of tr.state.selection.ranges) {
1016
+ if (!range2.empty) {
1017
+ continue;
1018
+ }
1019
+ const match = findMatchingBracket(tr.state, range2.head);
1020
+ if (match) {
1021
+ decorations = decorations.concat(
1022
+ renderMatch(match[0]),
1023
+ renderMatch(match[1])
1024
+ );
1025
+ }
1026
+ }
1027
+ return import_view10.Decoration.set(decorations, true);
1028
+ },
1029
+ provide: (f) => import_view10.EditorView.decorations.from(f)
1030
+ });
1031
+ var matchingBrackets = [bracketMatchingState];
1032
+
1033
+ // src/brackets/colorization.ts
1034
+ var import_view11 = require("@codemirror/view");
1035
+ var import_language5 = require("@codemirror/language");
1036
+ var DEFAULT_COLORS = ["#ffd700", "#da70d6", "#179fff"];
1037
+ var ColorizationBracketsPlugin = import_view11.ViewPlugin.fromClass(
1038
+ class {
1039
+ decorations;
1040
+ constructor(view) {
1041
+ this.decorations = this.getBracketDecorations(view);
1042
+ }
1043
+ update(update) {
1044
+ if (update.docChanged || update.selectionSet || update.viewportChanged) {
1045
+ this.decorations = this.getBracketDecorations(update.view);
1046
+ }
1047
+ }
1048
+ getBracketDecorations(view) {
1049
+ const { doc } = view.state;
1050
+ const decorations = [];
1051
+ const stack = [];
1052
+ const limitNodeType = ["Comment", "String"];
1053
+ const tree = (0, import_language5.syntaxTree)(view.state);
1054
+ for (let pos = 0; pos < doc.length; pos += 1) {
1055
+ const char = doc.sliceString(pos, pos + 1);
1056
+ const node = tree.resolveInner(pos);
1057
+ if (limitNodeType.includes(node.type.name)) {
1058
+ continue;
1059
+ }
1060
+ if (char === "(" || char === "[" || char === "{") {
1061
+ stack.push({ type: char, from: pos });
1062
+ } else if (char === ")" || char === "]" || char === "}") {
1063
+ const open = stack.pop();
1064
+ if (open && open.type === this.getMatchingBracket(char)) {
1065
+ const index = stack.length % 3;
1066
+ decorations.push(
1067
+ import_view11.Decoration.mark({ class: `colorization-bracket-${index}` }).range(
1068
+ open.from,
1069
+ open.from + 1
1070
+ ),
1071
+ import_view11.Decoration.mark({ class: `colorization-bracket-${index}` }).range(
1072
+ pos,
1073
+ pos + 1
1074
+ )
1075
+ );
1076
+ }
1077
+ }
1078
+ }
1079
+ decorations.sort((a, b) => a.from - b.from || a.startSide - b.startSide);
1080
+ return import_view11.Decoration.set(decorations);
1081
+ }
1082
+ getMatchingBracket(closingBracket) {
1083
+ switch (closingBracket) {
1084
+ case ")":
1085
+ return "(";
1086
+ case "]":
1087
+ return "[";
1088
+ case "}":
1089
+ return "{";
1090
+ default:
1091
+ return null;
1092
+ }
1093
+ }
1094
+ },
1095
+ {
1096
+ decorations: (v) => v.decorations
1097
+ }
1098
+ );
1099
+ var colorizationBrackets = [
1100
+ ColorizationBracketsPlugin,
1101
+ import_view11.EditorView.baseTheme({
1102
+ ".colorization-bracket-0": { color: DEFAULT_COLORS[0] },
1103
+ ".colorization-bracket-0 > span": { color: DEFAULT_COLORS[0] },
1104
+ ".colorization-bracket-1": { color: DEFAULT_COLORS[1] },
1105
+ ".colorization-bracket-1 > span": { color: DEFAULT_COLORS[1] },
1106
+ ".colorization-bracket-2": { color: DEFAULT_COLORS[2] },
1107
+ ".colorization-bracket-2 > span": { color: DEFAULT_COLORS[2] }
1108
+ })
1109
+ ];
1110
+
1111
+ // src/position/index.ts
1112
+ var import_view12 = require("@codemirror/view");
1113
+ var import_state10 = require("@codemirror/state");
1114
+ var SelectionSide = /* @__PURE__ */ ((SelectionSide2) => {
1115
+ SelectionSide2["Head"] = "head";
1116
+ SelectionSide2["Anchor"] = "anchor";
1117
+ return SelectionSide2;
1118
+ })(SelectionSide || {});
1119
+ var elementAtPosition = import_state10.Facet.define();
1120
+ function configChanged2(update) {
1121
+ return update.startState.facet(elementAtPosition) !== update.state.facet(elementAtPosition);
1122
+ }
1123
+ var PositionMarker = class {
1124
+ constructor(dom, rect) {
1125
+ this.dom = dom;
1126
+ this.rect = rect;
1127
+ }
1128
+ eq(marker) {
1129
+ return Boolean(
1130
+ (!this.rect && !marker.rect || this.rect && marker.rect && this.rect.left === marker.rect.left && this.rect.top === marker.rect.top && this.rect.width === marker.rect.width && this.rect.height === marker.rect.height) && this.dom === marker.dom
1131
+ );
1132
+ }
1133
+ draw() {
1134
+ this.adjust(this.dom);
1135
+ return this.dom;
1136
+ }
1137
+ update() {
1138
+ this.adjust(this.dom);
1139
+ return true;
1140
+ }
1141
+ adjust(elt) {
1142
+ elt.style.pointerEvents = "none";
1143
+ if (!this.rect) {
1144
+ return;
1145
+ }
1146
+ elt.style.left = `${this.rect.left}px`;
1147
+ elt.style.top = `${this.rect.top}px`;
1148
+ elt.style.width = `${this.rect.width}px`;
1149
+ elt.style.height = `${this.rect.height}px`;
1150
+ }
1151
+ };
1152
+ function getBase(view) {
1153
+ const rect = view.scrollDOM.getBoundingClientRect();
1154
+ const left = view.textDirection === import_view12.Direction.LTR ? rect.left : rect.right - view.scrollDOM.clientWidth * view.scaleX;
1155
+ return {
1156
+ left: left - view.scrollDOM.scrollLeft * view.scaleX,
1157
+ top: rect.top - view.scrollDOM.scrollTop * view.scaleY
1158
+ };
1159
+ }
1160
+ var positionElementLayer = (0, import_view12.layer)({
1161
+ above: true,
1162
+ markers(view) {
1163
+ const elements = view.state.facet(elementAtPosition);
1164
+ if (!elements || elements.length === 0) {
1165
+ return [];
1166
+ }
1167
+ const base = getBase(view);
1168
+ const temp = [];
1169
+ const markers = [];
1170
+ for (const { dom, pos } of elements) {
1171
+ if (!dom) {
1172
+ continue;
1173
+ }
1174
+ let finalPos = -1;
1175
+ if (typeof pos === "function") {
1176
+ finalPos = pos(view);
1177
+ } else if (typeof pos === "number") {
1178
+ finalPos = pos;
1179
+ } else if (pos === "head" /* Head */) {
1180
+ finalPos = view.state.selection.main.head;
1181
+ } else if (pos === "anchor" /* Anchor */) {
1182
+ finalPos = view.state.selection.main.anchor;
1183
+ }
1184
+ const coords = view.coordsAtPos(finalPos);
1185
+ if (coords) {
1186
+ temp.push(coords);
1187
+ const width = 1;
1188
+ const left = coords.left - base.left - width / 2;
1189
+ const top = coords.top - base.top;
1190
+ const height = coords.bottom - coords.top;
1191
+ markers.push(new PositionMarker(dom, { left, top, width, height }));
1192
+ } else {
1193
+ markers.push(new PositionMarker(dom));
1194
+ }
1195
+ }
1196
+ return markers;
1197
+ },
1198
+ update(update) {
1199
+ return update.docChanged || update.selectionSet || update.viewportChanged || configChanged2(update);
1200
+ },
1201
+ class: "cm-positionReferenceLayer"
1202
+ });
1203
+
1204
+ // src/mergeable-markers/index.ts
1205
+ var import_view13 = require("@codemirror/view");
1206
+ var import_state11 = require("@codemirror/state");
1207
+
1208
+ // src/mergeable-markers/squash.ts
1209
+ function squash2(decorations) {
1210
+ const result = [];
1211
+ const grouped = groupDecorationsByClassName2(decorations);
1212
+ grouped.forEach((decos, className) => {
1213
+ const merged = mergeIntervals3(decos);
1214
+ result.push(
1215
+ ...merged.map((m) => ({
1216
+ from: m.start,
1217
+ to: m.end,
1218
+ className
1219
+ }))
1220
+ );
1221
+ });
1222
+ result.sort((a, b) => a.from - b.from);
1223
+ return result;
1224
+ }
1225
+ function groupDecorationsByClassName2(decorations) {
1226
+ const map = /* @__PURE__ */ new Map();
1227
+ decorations.forEach((deco) => {
1228
+ if (!map.has(deco.className)) {
1229
+ map.set(deco.className, []);
1230
+ }
1231
+ map.get(deco.className).push(deco);
1232
+ });
1233
+ return map;
1234
+ }
1235
+ function mergeIntervals3(decorations) {
1236
+ const merged = [];
1237
+ const cloned = decorations.map((deco) => ({
1238
+ start: deco.from,
1239
+ end: deco.to
1240
+ }));
1241
+ cloned.sort((a, b) => a.start - b.start);
1242
+ let current = cloned[0];
1243
+ for (let i = 1; i < cloned.length; i++) {
1244
+ const next = cloned[i];
1245
+ if (next.start <= current.end) {
1246
+ current.end = Math.max(current.end, next.end);
1247
+ } else {
1248
+ merged.push(current);
1249
+ current = next;
1250
+ }
1251
+ }
1252
+ merged.push(current);
1253
+ return merged;
1254
+ }
1255
+
1256
+ // src/mergeable-markers/index.ts
1257
+ var cache = /* @__PURE__ */ new Map();
1258
+ function getClassNameDecoration(className) {
1259
+ const cacheKey = className;
1260
+ if (!cache.has(cacheKey)) {
1261
+ const mark = import_view13.Decoration.mark({ class: className });
1262
+ cache.set(cacheKey, mark);
1263
+ }
1264
+ return cache.get(cacheKey);
1265
+ }
1266
+ var mergeableMarkers = import_state11.Facet.define({
1267
+ combine(specs) {
1268
+ const builder = new import_state11.RangeSetBuilder();
1269
+ const flattened = specs.reduce(
1270
+ (memo, current) => [...memo, ...current],
1271
+ []
1272
+ );
1273
+ for (const spec of squash2(flattened)) {
1274
+ const decoration = getClassNameDecoration(spec.className);
1275
+ builder.add(spec.from, spec.to, decoration);
1276
+ }
1277
+ return builder.finish();
1278
+ },
1279
+ enables(self) {
1280
+ return import_view13.EditorView.decorations.compute([self], (state) => state.facet(self));
1281
+ }
1282
+ });
1283
+
1284
+ // src/frozen-ranges/extension.ts
1285
+ var import_utils8 = require("@coze-editor/utils");
1286
+ var import_state12 = require("@codemirror/state");
1287
+ var extension4 = [
1288
+ // 禁止编辑
1289
+ import_state12.EditorState.changeFilter.of((tr) => {
1290
+ const providers = tr.startState.facet(frozenRanges);
1291
+ const specs = providers.reduce(
1292
+ (memo, provider) => [...memo, ...provider(tr.startState)],
1293
+ []
1294
+ );
1295
+ if (Array.isArray(specs)) {
1296
+ const flattened = specs.reduce(
1297
+ (memo, current) => [...memo, current.from, current.to],
1298
+ []
1299
+ );
1300
+ return flattened;
1301
+ }
1302
+ return true;
1303
+ }),
1304
+ // forbid cursor move into frozen ranges
1305
+ import_state12.EditorState.transactionFilter.of((tr) => {
1306
+ const len = tr.startState.doc.length;
1307
+ const providers = tr.startState.facet(frozenRanges);
1308
+ const specs = providers.reduce((memo, provider) => [...memo, ...provider(tr.state)], []).filter(
1309
+ (spec) => spec.from >= 0 && spec.from < len && spec.to >= 0 && spec.to < len
1310
+ );
1311
+ let { newSelection } = tr;
1312
+ newSelection.ranges.forEach((range2, index) => {
1313
+ for (const spec of specs) {
1314
+ if (range2.empty && range2.from > spec.from && range2.to < spec.to) {
1315
+ newSelection = newSelection.replaceRange(
1316
+ import_state12.EditorSelection.cursor(
1317
+ range2.assoc > 0 ? spec.from : spec.to,
1318
+ range2.assoc
1319
+ ),
1320
+ index
1321
+ );
1322
+ }
1323
+ if (!range2.empty && (0, import_utils8.hasOverlap)(range2, spec)) {
1324
+ const isReversed = range2.head < range2.anchor;
1325
+ if (
1326
+ // anchor at left
1327
+ range2.anchor < spec.from
1328
+ ) {
1329
+ newSelection = newSelection.replaceRange(
1330
+ import_state12.EditorSelection.range(
1331
+ range2.anchor,
1332
+ spec.from,
1333
+ range2.goalColumn,
1334
+ range2.bidiLevel ?? void 0
1335
+ ),
1336
+ index
1337
+ );
1338
+ } else if (
1339
+ // anchor at right
1340
+ range2.anchor > spec.to
1341
+ ) {
1342
+ newSelection = newSelection.replaceRange(
1343
+ import_state12.EditorSelection.range(
1344
+ range2.anchor,
1345
+ spec.to,
1346
+ range2.goalColumn,
1347
+ range2.bidiLevel ?? void 0
1348
+ ),
1349
+ index
1350
+ );
1351
+ } else if (
1352
+ // anchor inside
1353
+ range2.anchor >= spec.from && range2.anchor <= spec.to
1354
+ ) {
1355
+ if (isReversed) {
1356
+ newSelection = newSelection.replaceRange(
1357
+ import_state12.EditorSelection.range(
1358
+ spec.from,
1359
+ Math.min(range2.head, spec.from),
1360
+ range2.goalColumn,
1361
+ range2.bidiLevel ?? void 0
1362
+ ),
1363
+ index
1364
+ );
1365
+ } else {
1366
+ newSelection = newSelection.replaceRange(
1367
+ import_state12.EditorSelection.range(
1368
+ spec.to,
1369
+ Math.max(range2.head, spec.to),
1370
+ range2.goalColumn,
1371
+ range2.bidiLevel ?? void 0
1372
+ ),
1373
+ index
1374
+ );
1375
+ }
1376
+ }
1377
+ }
1378
+ }
1379
+ });
1380
+ if (newSelection.eq(tr.newSelection)) {
1381
+ return tr;
1382
+ }
1383
+ return [
1384
+ tr,
1385
+ {
1386
+ selection: newSelection
1387
+ }
1388
+ ];
1389
+ })
1390
+ ];
1391
+ var frozenRanges = import_state12.Facet.define({
1392
+ enables: () => extension4
1393
+ });
1394
+ // Annotate the CommonJS export names for ESM import in node:
1395
+ 0 && (module.exports = {
1396
+ FocusableWidget,
1397
+ SelectionSide,
1398
+ astDebugger,
1399
+ astDecorator,
1400
+ autoSelectRanges,
1401
+ autoSelectUserEvent,
1402
+ backgroundDecorations,
1403
+ colorizationBrackets,
1404
+ deletionEnlarger,
1405
+ elementAtPosition,
1406
+ focusableKeymap,
1407
+ frozenRanges,
1408
+ indentGuides,
1409
+ inputRules,
1410
+ matchingBrackets,
1411
+ mergeableMarkers,
1412
+ mixLanguages,
1413
+ positionElementLayer,
1414
+ scrollBeyondLastLine,
1415
+ selectionEnlarger,
1416
+ updateWholeDecorations
1417
+ });
1418
+ //# sourceMappingURL=index.js.map