@opentui/core 0.1.27 → 0.1.29

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/index.js CHANGED
@@ -30,7 +30,6 @@ import {
30
30
  RootRenderable,
31
31
  Selection,
32
32
  StyledText,
33
- SyntaxStyle,
34
33
  TerminalConsole,
35
34
  TextAttributes,
36
35
  TextBuffer,
@@ -61,7 +60,6 @@ import {
61
60
  capture,
62
61
  clearEnvCache,
63
62
  convertGlobalToLocalSelection,
64
- convertThemeToStyles,
65
63
  coordinateToCharacterIndex,
66
64
  createCliRenderer,
67
65
  createTextAttributes,
@@ -133,7 +131,658 @@ import {
133
131
  white,
134
132
  wrapWithDelegates,
135
133
  yellow
136
- } from "./index-zx1dwm33.js";
134
+ } from "./index-bztetjc3.js";
135
+ // src/text-buffer-view.ts
136
+ class TextBufferView {
137
+ lib;
138
+ viewPtr;
139
+ textBuffer;
140
+ _destroyed = false;
141
+ constructor(lib, ptr, textBuffer) {
142
+ this.lib = lib;
143
+ this.viewPtr = ptr;
144
+ this.textBuffer = textBuffer;
145
+ }
146
+ static create(textBuffer) {
147
+ const lib = resolveRenderLib();
148
+ const viewPtr = lib.createTextBufferView(textBuffer.ptr);
149
+ return new TextBufferView(lib, viewPtr, textBuffer);
150
+ }
151
+ guard() {
152
+ if (this._destroyed)
153
+ throw new Error("TextBufferView is destroyed");
154
+ }
155
+ get ptr() {
156
+ this.guard();
157
+ return this.viewPtr;
158
+ }
159
+ setSelection(start, end, bgColor, fgColor) {
160
+ this.guard();
161
+ this.lib.textBufferViewSetSelection(this.viewPtr, start, end, bgColor || null, fgColor || null);
162
+ }
163
+ resetSelection() {
164
+ this.guard();
165
+ this.lib.textBufferViewResetSelection(this.viewPtr);
166
+ }
167
+ getSelection() {
168
+ this.guard();
169
+ return this.lib.textBufferViewGetSelection(this.viewPtr);
170
+ }
171
+ hasSelection() {
172
+ this.guard();
173
+ return this.getSelection() !== null;
174
+ }
175
+ setLocalSelection(anchorX, anchorY, focusX, focusY, bgColor, fgColor) {
176
+ this.guard();
177
+ return this.lib.textBufferViewSetLocalSelection(this.viewPtr, anchorX, anchorY, focusX, focusY, bgColor || null, fgColor || null);
178
+ }
179
+ resetLocalSelection() {
180
+ this.guard();
181
+ this.lib.textBufferViewResetLocalSelection(this.viewPtr);
182
+ }
183
+ setWrapWidth(width) {
184
+ this.guard();
185
+ this.lib.textBufferViewSetWrapWidth(this.viewPtr, width ?? 0);
186
+ }
187
+ setWrapMode(mode) {
188
+ this.guard();
189
+ this.lib.textBufferViewSetWrapMode(this.viewPtr, mode);
190
+ }
191
+ setViewportSize(width, height) {
192
+ this.guard();
193
+ this.lib.textBufferViewSetViewportSize(this.viewPtr, width, height);
194
+ }
195
+ get lineInfo() {
196
+ this.guard();
197
+ return this.lib.textBufferViewGetLineInfo(this.viewPtr);
198
+ }
199
+ get logicalLineInfo() {
200
+ this.guard();
201
+ return this.lib.textBufferViewGetLogicalLineInfo(this.viewPtr);
202
+ }
203
+ getSelectedText() {
204
+ this.guard();
205
+ const byteSize = this.textBuffer.byteSize;
206
+ if (byteSize === 0)
207
+ return "";
208
+ const selectedBytes = this.lib.textBufferViewGetSelectedTextBytes(this.viewPtr, byteSize);
209
+ if (!selectedBytes)
210
+ return "";
211
+ return this.lib.decoder.decode(selectedBytes);
212
+ }
213
+ getPlainText() {
214
+ this.guard();
215
+ const byteSize = this.textBuffer.byteSize;
216
+ if (byteSize === 0)
217
+ return "";
218
+ const plainBytes = this.lib.textBufferViewGetPlainTextBytes(this.viewPtr, byteSize);
219
+ if (!plainBytes)
220
+ return "";
221
+ return this.lib.decoder.decode(plainBytes);
222
+ }
223
+ destroy() {
224
+ if (this._destroyed)
225
+ return;
226
+ this._destroyed = true;
227
+ this.lib.destroyTextBufferView(this.viewPtr);
228
+ }
229
+ }
230
+ // src/edit-buffer.ts
231
+ import { EventEmitter } from "events";
232
+
233
+ class EditBuffer extends EventEmitter {
234
+ static registry = new Map;
235
+ static nativeEventsSubscribed = false;
236
+ lib;
237
+ bufferPtr;
238
+ textBufferPtr;
239
+ id;
240
+ _destroyed = false;
241
+ _textBytes = [];
242
+ _singleTextBytes = null;
243
+ _singleTextMemId = null;
244
+ _syntaxStyle;
245
+ constructor(lib, ptr) {
246
+ super();
247
+ this.lib = lib;
248
+ this.bufferPtr = ptr;
249
+ this.textBufferPtr = lib.editBufferGetTextBuffer(ptr);
250
+ this.id = lib.editBufferGetId(ptr);
251
+ EditBuffer.registry.set(this.id, this);
252
+ EditBuffer.subscribeToNativeEvents(lib);
253
+ }
254
+ static create(widthMethod) {
255
+ const lib = resolveRenderLib();
256
+ const ptr = lib.createEditBuffer(widthMethod);
257
+ return new EditBuffer(lib, ptr);
258
+ }
259
+ static subscribeToNativeEvents(lib) {
260
+ if (EditBuffer.nativeEventsSubscribed)
261
+ return;
262
+ EditBuffer.nativeEventsSubscribed = true;
263
+ lib.onAnyNativeEvent((name, data) => {
264
+ const buffer = new Uint16Array(data);
265
+ if (name.startsWith("eb_") && buffer.length >= 1) {
266
+ const id = buffer[0];
267
+ const instance = EditBuffer.registry.get(id);
268
+ if (instance) {
269
+ const eventName = name.slice(3);
270
+ const eventData = data.slice(2);
271
+ instance.emit(eventName, eventData);
272
+ }
273
+ }
274
+ });
275
+ }
276
+ guard() {
277
+ if (this._destroyed)
278
+ throw new Error("EditBuffer is destroyed");
279
+ }
280
+ get ptr() {
281
+ this.guard();
282
+ return this.bufferPtr;
283
+ }
284
+ setText(text, opts) {
285
+ this.guard();
286
+ const history = opts?.history ?? true;
287
+ const textBytes = this.lib.encoder.encode(text);
288
+ if (history) {
289
+ this._textBytes.push(textBytes);
290
+ const memId = this.lib.textBufferRegisterMemBuffer(this.textBufferPtr, textBytes, false);
291
+ this.lib.editBufferSetTextFromMem(this.bufferPtr, memId, true);
292
+ } else {
293
+ if (this._singleTextMemId !== null) {
294
+ this.lib.textBufferReplaceMemBuffer(this.textBufferPtr, this._singleTextMemId, textBytes, false);
295
+ } else {
296
+ this._singleTextMemId = this.lib.textBufferRegisterMemBuffer(this.textBufferPtr, textBytes, false);
297
+ }
298
+ this._singleTextBytes = textBytes;
299
+ this.lib.editBufferSetTextFromMem(this.bufferPtr, this._singleTextMemId, false);
300
+ }
301
+ }
302
+ setTextOwned(text, opts) {
303
+ this.guard();
304
+ const history = opts?.history ?? true;
305
+ const textBytes = this.lib.encoder.encode(text);
306
+ this.lib.editBufferSetText(this.bufferPtr, textBytes, history);
307
+ }
308
+ getText() {
309
+ this.guard();
310
+ const maxSize = 1024 * 1024;
311
+ const textBytes = this.lib.editBufferGetText(this.bufferPtr, maxSize);
312
+ if (!textBytes)
313
+ return "";
314
+ return this.lib.decoder.decode(textBytes);
315
+ }
316
+ insertChar(char) {
317
+ this.guard();
318
+ this.lib.editBufferInsertChar(this.bufferPtr, char);
319
+ }
320
+ insertText(text) {
321
+ this.guard();
322
+ this.lib.editBufferInsertText(this.bufferPtr, text);
323
+ }
324
+ deleteChar() {
325
+ this.guard();
326
+ this.lib.editBufferDeleteChar(this.bufferPtr);
327
+ }
328
+ deleteCharBackward() {
329
+ this.guard();
330
+ this.lib.editBufferDeleteCharBackward(this.bufferPtr);
331
+ }
332
+ newLine() {
333
+ this.guard();
334
+ this.lib.editBufferNewLine(this.bufferPtr);
335
+ }
336
+ deleteLine() {
337
+ this.guard();
338
+ this.lib.editBufferDeleteLine(this.bufferPtr);
339
+ }
340
+ moveCursorLeft() {
341
+ this.guard();
342
+ this.lib.editBufferMoveCursorLeft(this.bufferPtr);
343
+ }
344
+ moveCursorRight() {
345
+ this.guard();
346
+ this.lib.editBufferMoveCursorRight(this.bufferPtr);
347
+ }
348
+ moveCursorUp() {
349
+ this.guard();
350
+ this.lib.editBufferMoveCursorUp(this.bufferPtr);
351
+ }
352
+ moveCursorDown() {
353
+ this.guard();
354
+ this.lib.editBufferMoveCursorDown(this.bufferPtr);
355
+ }
356
+ gotoLine(line) {
357
+ this.guard();
358
+ this.lib.editBufferGotoLine(this.bufferPtr, line);
359
+ }
360
+ setCursor(line, col) {
361
+ this.guard();
362
+ this.lib.editBufferSetCursor(this.bufferPtr, line, col);
363
+ }
364
+ setCursorToLineCol(line, col) {
365
+ this.guard();
366
+ this.lib.editBufferSetCursorToLineCol(this.bufferPtr, line, col);
367
+ }
368
+ setCursorByOffset(offset) {
369
+ this.guard();
370
+ this.lib.editBufferSetCursorByOffset(this.bufferPtr, offset);
371
+ }
372
+ getCursorPosition() {
373
+ this.guard();
374
+ return this.lib.editBufferGetCursorPosition(this.bufferPtr);
375
+ }
376
+ debugLogRope() {
377
+ this.guard();
378
+ this.lib.editBufferDebugLogRope(this.bufferPtr);
379
+ }
380
+ undo() {
381
+ this.guard();
382
+ const maxSize = 256;
383
+ const metaBytes = this.lib.editBufferUndo(this.bufferPtr, maxSize);
384
+ if (!metaBytes)
385
+ return null;
386
+ return this.lib.decoder.decode(metaBytes);
387
+ }
388
+ redo() {
389
+ this.guard();
390
+ const maxSize = 256;
391
+ const metaBytes = this.lib.editBufferRedo(this.bufferPtr, maxSize);
392
+ if (!metaBytes)
393
+ return null;
394
+ return this.lib.decoder.decode(metaBytes);
395
+ }
396
+ canUndo() {
397
+ this.guard();
398
+ return this.lib.editBufferCanUndo(this.bufferPtr);
399
+ }
400
+ canRedo() {
401
+ this.guard();
402
+ return this.lib.editBufferCanRedo(this.bufferPtr);
403
+ }
404
+ clearHistory() {
405
+ this.guard();
406
+ this.lib.editBufferClearHistory(this.bufferPtr);
407
+ }
408
+ setDefaultFg(fg2) {
409
+ this.guard();
410
+ this.lib.textBufferSetDefaultFg(this.textBufferPtr, fg2);
411
+ }
412
+ setDefaultBg(bg2) {
413
+ this.guard();
414
+ this.lib.textBufferSetDefaultBg(this.textBufferPtr, bg2);
415
+ }
416
+ setDefaultAttributes(attributes) {
417
+ this.guard();
418
+ this.lib.textBufferSetDefaultAttributes(this.textBufferPtr, attributes);
419
+ }
420
+ resetDefaults() {
421
+ this.guard();
422
+ this.lib.textBufferResetDefaults(this.textBufferPtr);
423
+ }
424
+ setPlaceholder(text) {
425
+ this.guard();
426
+ this.lib.editBufferSetPlaceholder(this.bufferPtr, text);
427
+ }
428
+ setPlaceholderColor(color) {
429
+ this.guard();
430
+ this.lib.editBufferSetPlaceholderColor(this.bufferPtr, color);
431
+ }
432
+ setSyntaxStyle(style) {
433
+ this.guard();
434
+ this._syntaxStyle = style ?? undefined;
435
+ this.lib.textBufferSetSyntaxStyle(this.textBufferPtr, style?.ptr ?? null);
436
+ }
437
+ getSyntaxStyle() {
438
+ this.guard();
439
+ return this._syntaxStyle ?? null;
440
+ }
441
+ addHighlight(lineIdx, highlight) {
442
+ this.guard();
443
+ this.lib.textBufferAddHighlight(this.textBufferPtr, lineIdx, highlight);
444
+ }
445
+ addHighlightByCharRange(highlight) {
446
+ this.guard();
447
+ this.lib.textBufferAddHighlightByCharRange(this.textBufferPtr, highlight);
448
+ }
449
+ removeHighlightsByRef(hlRef) {
450
+ this.guard();
451
+ this.lib.textBufferRemoveHighlightsByRef(this.textBufferPtr, hlRef);
452
+ }
453
+ clearLineHighlights(lineIdx) {
454
+ this.guard();
455
+ this.lib.textBufferClearLineHighlights(this.textBufferPtr, lineIdx);
456
+ }
457
+ clearAllHighlights() {
458
+ this.guard();
459
+ this.lib.textBufferClearAllHighlights(this.textBufferPtr);
460
+ }
461
+ getLineHighlights(lineIdx) {
462
+ this.guard();
463
+ return this.lib.textBufferGetLineHighlights(this.textBufferPtr, lineIdx);
464
+ }
465
+ destroy() {
466
+ if (this._destroyed)
467
+ return;
468
+ this._destroyed = true;
469
+ EditBuffer.registry.delete(this.id);
470
+ this.lib.destroyEditBuffer(this.bufferPtr);
471
+ }
472
+ }
473
+ // src/editor-view.ts
474
+ class EditorView {
475
+ lib;
476
+ viewPtr;
477
+ editBuffer;
478
+ _destroyed = false;
479
+ constructor(lib, ptr, editBuffer) {
480
+ this.lib = lib;
481
+ this.viewPtr = ptr;
482
+ this.editBuffer = editBuffer;
483
+ }
484
+ static create(editBuffer, viewportWidth, viewportHeight) {
485
+ const lib = resolveRenderLib();
486
+ const viewPtr = lib.createEditorView(editBuffer.ptr, viewportWidth, viewportHeight);
487
+ return new EditorView(lib, viewPtr, editBuffer);
488
+ }
489
+ guard() {
490
+ if (this._destroyed)
491
+ throw new Error("EditorView is destroyed");
492
+ }
493
+ get ptr() {
494
+ this.guard();
495
+ return this.viewPtr;
496
+ }
497
+ setViewportSize(width, height) {
498
+ this.guard();
499
+ this.lib.editorViewSetViewportSize(this.viewPtr, width, height);
500
+ }
501
+ getViewport() {
502
+ this.guard();
503
+ return this.lib.editorViewGetViewport(this.viewPtr);
504
+ }
505
+ setScrollMargin(margin) {
506
+ this.guard();
507
+ this.lib.editorViewSetScrollMargin(this.viewPtr, margin);
508
+ }
509
+ setWrapMode(mode) {
510
+ this.guard();
511
+ this.lib.editorViewSetWrapMode(this.viewPtr, mode);
512
+ }
513
+ getVirtualLineCount() {
514
+ this.guard();
515
+ return this.lib.editorViewGetVirtualLineCount(this.viewPtr);
516
+ }
517
+ getTotalVirtualLineCount() {
518
+ this.guard();
519
+ return this.lib.editorViewGetTotalVirtualLineCount(this.viewPtr);
520
+ }
521
+ setSelection(start, end, bgColor, fgColor) {
522
+ this.guard();
523
+ this.lib.editorViewSetSelection(this.viewPtr, start, end, bgColor || null, fgColor || null);
524
+ }
525
+ resetSelection() {
526
+ this.guard();
527
+ this.lib.editorViewResetSelection(this.viewPtr);
528
+ }
529
+ getSelection() {
530
+ this.guard();
531
+ return this.lib.editorViewGetSelection(this.viewPtr);
532
+ }
533
+ hasSelection() {
534
+ this.guard();
535
+ return this.getSelection() !== null;
536
+ }
537
+ setLocalSelection(anchorX, anchorY, focusX, focusY, bgColor, fgColor) {
538
+ this.guard();
539
+ return this.lib.editorViewSetLocalSelection(this.viewPtr, anchorX, anchorY, focusX, focusY, bgColor || null, fgColor || null);
540
+ }
541
+ resetLocalSelection() {
542
+ this.guard();
543
+ this.lib.editorViewResetLocalSelection(this.viewPtr);
544
+ }
545
+ getSelectedText() {
546
+ this.guard();
547
+ const maxLength = 1024 * 1024;
548
+ const selectedBytes = this.lib.editorViewGetSelectedTextBytes(this.viewPtr, maxLength);
549
+ if (!selectedBytes)
550
+ return "";
551
+ return this.lib.decoder.decode(selectedBytes);
552
+ }
553
+ getCursor() {
554
+ this.guard();
555
+ return this.lib.editorViewGetCursor(this.viewPtr);
556
+ }
557
+ getText() {
558
+ this.guard();
559
+ const maxLength = 1024 * 1024;
560
+ const textBytes = this.lib.editorViewGetText(this.viewPtr, maxLength);
561
+ if (!textBytes)
562
+ return "";
563
+ return this.lib.decoder.decode(textBytes);
564
+ }
565
+ getVisualCursor() {
566
+ this.guard();
567
+ return this.lib.editorViewGetVisualCursor(this.viewPtr);
568
+ }
569
+ moveUpVisual() {
570
+ this.guard();
571
+ this.lib.editorViewMoveUpVisual(this.viewPtr);
572
+ }
573
+ moveDownVisual() {
574
+ this.guard();
575
+ this.lib.editorViewMoveDownVisual(this.viewPtr);
576
+ }
577
+ deleteSelectedText() {
578
+ this.guard();
579
+ this.lib.editorViewDeleteSelectedText(this.viewPtr);
580
+ }
581
+ setCursorByOffset(offset) {
582
+ this.guard();
583
+ this.lib.editorViewSetCursorByOffset(this.viewPtr, offset);
584
+ }
585
+ getLineInfo() {
586
+ this.guard();
587
+ const textBufferViewPtr = this.lib.editorViewGetTextBufferView(this.viewPtr);
588
+ return this.lib.textBufferViewGetLineInfo(textBufferViewPtr);
589
+ }
590
+ getLogicalLineInfo() {
591
+ this.guard();
592
+ const textBufferViewPtr = this.lib.editorViewGetTextBufferView(this.viewPtr);
593
+ return this.lib.textBufferViewGetLogicalLineInfo(textBufferViewPtr);
594
+ }
595
+ destroy() {
596
+ if (this._destroyed)
597
+ return;
598
+ this._destroyed = true;
599
+ this.lib.destroyEditorView(this.viewPtr);
600
+ }
601
+ }
602
+ // src/syntax-style.ts
603
+ function convertThemeToStyles(theme) {
604
+ const flatStyles = {};
605
+ for (const tokenStyle of theme) {
606
+ const styleDefinition = {};
607
+ if (tokenStyle.style.foreground) {
608
+ styleDefinition.fg = parseColor(tokenStyle.style.foreground);
609
+ }
610
+ if (tokenStyle.style.background) {
611
+ styleDefinition.bg = parseColor(tokenStyle.style.background);
612
+ }
613
+ if (tokenStyle.style.bold !== undefined) {
614
+ styleDefinition.bold = tokenStyle.style.bold;
615
+ }
616
+ if (tokenStyle.style.italic !== undefined) {
617
+ styleDefinition.italic = tokenStyle.style.italic;
618
+ }
619
+ if (tokenStyle.style.underline !== undefined) {
620
+ styleDefinition.underline = tokenStyle.style.underline;
621
+ }
622
+ if (tokenStyle.style.dim !== undefined) {
623
+ styleDefinition.dim = tokenStyle.style.dim;
624
+ }
625
+ for (const scope of tokenStyle.scope) {
626
+ flatStyles[scope] = styleDefinition;
627
+ }
628
+ }
629
+ return flatStyles;
630
+ }
631
+
632
+ class SyntaxStyle {
633
+ lib;
634
+ stylePtr;
635
+ _destroyed = false;
636
+ nameCache = new Map;
637
+ styleDefs = new Map;
638
+ mergedCache = new Map;
639
+ constructor(lib, ptr) {
640
+ this.lib = lib;
641
+ this.stylePtr = ptr;
642
+ }
643
+ static create() {
644
+ const lib = resolveRenderLib();
645
+ const ptr = lib.createSyntaxStyle();
646
+ return new SyntaxStyle(lib, ptr);
647
+ }
648
+ static fromTheme(theme) {
649
+ const style = SyntaxStyle.create();
650
+ const flatStyles = convertThemeToStyles(theme);
651
+ for (const [name, styleDef] of Object.entries(flatStyles)) {
652
+ style.registerStyle(name, styleDef);
653
+ }
654
+ return style;
655
+ }
656
+ static fromStyles(styles) {
657
+ const style = SyntaxStyle.create();
658
+ for (const [name, styleDef] of Object.entries(styles)) {
659
+ style.registerStyle(name, styleDef);
660
+ }
661
+ return style;
662
+ }
663
+ guard() {
664
+ if (this._destroyed)
665
+ throw new Error("NativeSyntaxStyle is destroyed");
666
+ }
667
+ registerStyle(name, style) {
668
+ this.guard();
669
+ const attributes = createTextAttributes({
670
+ bold: style.bold,
671
+ italic: style.italic,
672
+ underline: style.underline,
673
+ dim: style.dim
674
+ });
675
+ const id = this.lib.syntaxStyleRegister(this.stylePtr, name, style.fg || null, style.bg || null, attributes);
676
+ this.nameCache.set(name, id);
677
+ this.styleDefs.set(name, style);
678
+ return id;
679
+ }
680
+ resolveStyleId(name) {
681
+ this.guard();
682
+ const cached = this.nameCache.get(name);
683
+ if (cached !== undefined)
684
+ return cached;
685
+ const id = this.lib.syntaxStyleResolveByName(this.stylePtr, name);
686
+ if (id !== null) {
687
+ this.nameCache.set(name, id);
688
+ }
689
+ return id;
690
+ }
691
+ getStyleId(name) {
692
+ this.guard();
693
+ const id = this.resolveStyleId(name);
694
+ if (id !== null)
695
+ return id;
696
+ if (name.includes(".")) {
697
+ const baseName = name.split(".")[0];
698
+ return this.resolveStyleId(baseName);
699
+ }
700
+ return null;
701
+ }
702
+ get ptr() {
703
+ this.guard();
704
+ return this.stylePtr;
705
+ }
706
+ getStyleCount() {
707
+ this.guard();
708
+ return this.lib.syntaxStyleGetStyleCount(this.stylePtr);
709
+ }
710
+ clearNameCache() {
711
+ this.nameCache.clear();
712
+ }
713
+ getStyle(name) {
714
+ this.guard();
715
+ if (Object.prototype.hasOwnProperty.call(this.styleDefs, name)) {
716
+ return;
717
+ }
718
+ const style = this.styleDefs.get(name);
719
+ if (style)
720
+ return style;
721
+ if (name.includes(".")) {
722
+ const baseName = name.split(".")[0];
723
+ if (Object.prototype.hasOwnProperty.call(this.styleDefs, baseName)) {
724
+ return;
725
+ }
726
+ return this.styleDefs.get(baseName);
727
+ }
728
+ return;
729
+ }
730
+ mergeStyles(...styleNames) {
731
+ this.guard();
732
+ const cacheKey = styleNames.join(":");
733
+ const cached = this.mergedCache.get(cacheKey);
734
+ if (cached)
735
+ return cached;
736
+ const styleDefinition = {};
737
+ for (const name of styleNames) {
738
+ const style = this.getStyle(name);
739
+ if (!style)
740
+ continue;
741
+ if (style.fg)
742
+ styleDefinition.fg = style.fg;
743
+ if (style.bg)
744
+ styleDefinition.bg = style.bg;
745
+ if (style.bold !== undefined)
746
+ styleDefinition.bold = style.bold;
747
+ if (style.italic !== undefined)
748
+ styleDefinition.italic = style.italic;
749
+ if (style.underline !== undefined)
750
+ styleDefinition.underline = style.underline;
751
+ if (style.dim !== undefined)
752
+ styleDefinition.dim = style.dim;
753
+ }
754
+ const attributes = createTextAttributes({
755
+ bold: styleDefinition.bold,
756
+ italic: styleDefinition.italic,
757
+ underline: styleDefinition.underline,
758
+ dim: styleDefinition.dim
759
+ });
760
+ const merged = {
761
+ fg: styleDefinition.fg,
762
+ bg: styleDefinition.bg,
763
+ attributes
764
+ };
765
+ this.mergedCache.set(cacheKey, merged);
766
+ return merged;
767
+ }
768
+ clearCache() {
769
+ this.guard();
770
+ this.mergedCache.clear();
771
+ }
772
+ getCacheSize() {
773
+ this.guard();
774
+ return this.mergedCache.size;
775
+ }
776
+ destroy() {
777
+ if (this._destroyed)
778
+ return;
779
+ this._destroyed = true;
780
+ this.nameCache.clear();
781
+ this.styleDefs.clear();
782
+ this.mergedCache.clear();
783
+ this.lib.destroySyntaxStyle(this.stylePtr);
784
+ }
785
+ }
137
786
  // src/post/filters.ts
138
787
  function applyScanlines(buffer, strength = 0.8, step = 2) {
139
788
  const width = buffer.width;
@@ -1618,10 +2267,10 @@ class TextBufferRenderable extends Renderable {
1618
2267
  _defaultAttributes;
1619
2268
  _selectionBg;
1620
2269
  _selectionFg;
1621
- _wrap = false;
1622
2270
  _wrapMode = "word";
1623
2271
  lastLocalSelection = null;
1624
2272
  textBuffer;
2273
+ textBufferView;
1625
2274
  _lineInfo = { lineStarts: [], lineWidths: [], maxLineWidth: 0 };
1626
2275
  _defaultOptions = {
1627
2276
  fg: RGBA.fromValues(1, 1, 1, 1),
@@ -1630,7 +2279,6 @@ class TextBufferRenderable extends Renderable {
1630
2279
  selectionFg: undefined,
1631
2280
  selectable: true,
1632
2281
  attributes: 0,
1633
- wrap: true,
1634
2282
  wrapMode: "word"
1635
2283
  };
1636
2284
  constructor(ctx, options) {
@@ -1641,15 +2289,17 @@ class TextBufferRenderable extends Renderable {
1641
2289
  this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : this._defaultOptions.selectionBg;
1642
2290
  this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : this._defaultOptions.selectionFg;
1643
2291
  this.selectable = options.selectable ?? this._defaultOptions.selectable;
1644
- this._wrap = options.wrap ?? this._defaultOptions.wrap;
1645
2292
  this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode;
1646
2293
  this.textBuffer = TextBuffer.create(this._ctx.widthMethod);
1647
- this.textBuffer.setWrapMode(this._wrapMode);
2294
+ this.textBufferView = TextBufferView.create(this.textBuffer);
2295
+ const style = SyntaxStyle.create();
2296
+ this.textBuffer.setSyntaxStyle(style);
2297
+ this.textBufferView.setWrapMode(this._wrapMode);
1648
2298
  this.setupMeasureFunc();
1649
2299
  this.textBuffer.setDefaultFg(this._defaultFg);
1650
2300
  this.textBuffer.setDefaultBg(this._defaultBg);
1651
2301
  this.textBuffer.setDefaultAttributes(this._defaultAttributes);
1652
- if (this._wrap && this.width > 0) {
2302
+ if (this._wrapMode !== "none" && this.width > 0) {
1653
2303
  this.updateWrapWidth(this.width);
1654
2304
  }
1655
2305
  this.updateTextInfo();
@@ -1721,27 +2371,22 @@ class TextBufferRenderable extends Renderable {
1721
2371
  this.requestRender();
1722
2372
  }
1723
2373
  }
1724
- get wrap() {
1725
- return this._wrap;
1726
- }
1727
- set wrap(value) {
1728
- if (this._wrap !== value) {
1729
- this._wrap = value;
1730
- this.textBuffer.setWrapWidth(this._wrap ? this.width : null);
1731
- this.requestRender();
1732
- }
1733
- }
1734
2374
  get wrapMode() {
1735
2375
  return this._wrapMode;
1736
2376
  }
1737
2377
  set wrapMode(value) {
1738
2378
  if (this._wrapMode !== value) {
1739
2379
  this._wrapMode = value;
1740
- this.textBuffer.setWrapMode(this._wrapMode);
2380
+ this.textBufferView.setWrapMode(this._wrapMode);
2381
+ if (value !== "none" && this.width > 0) {
2382
+ this.updateWrapWidth(this.width);
2383
+ }
2384
+ this.yogaNode.markDirty();
1741
2385
  this.requestRender();
1742
2386
  }
1743
2387
  }
1744
2388
  onResize(width, height) {
2389
+ this.textBufferView.setViewportSize(width, height);
1745
2390
  if (this.lastLocalSelection) {
1746
2391
  const changed = this.updateLocalSelection(this.lastLocalSelection);
1747
2392
  if (changed) {
@@ -1757,10 +2402,10 @@ class TextBufferRenderable extends Renderable {
1757
2402
  }
1758
2403
  updateLocalSelection(localSelection) {
1759
2404
  if (!localSelection?.isActive) {
1760
- this.textBuffer.resetLocalSelection();
2405
+ this.textBufferView.resetLocalSelection();
1761
2406
  return true;
1762
2407
  }
1763
- return this.textBuffer.setLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg);
2408
+ return this.textBufferView.setLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg);
1764
2409
  }
1765
2410
  updateTextInfo() {
1766
2411
  if (this.lastLocalSelection) {
@@ -1773,18 +2418,18 @@ class TextBufferRenderable extends Renderable {
1773
2418
  this.requestRender();
1774
2419
  }
1775
2420
  updateLineInfo() {
1776
- const lineInfo = this.textBuffer.lineInfo;
2421
+ const lineInfo = this.textBufferView.logicalLineInfo;
1777
2422
  this._lineInfo.lineStarts = lineInfo.lineStarts;
1778
2423
  this._lineInfo.lineWidths = lineInfo.lineWidths;
1779
2424
  this._lineInfo.maxLineWidth = lineInfo.maxLineWidth;
1780
2425
  }
1781
2426
  updateWrapWidth(width) {
1782
- this.textBuffer.setWrapWidth(width);
2427
+ this.textBufferView.setWrapWidth(width);
1783
2428
  this.updateLineInfo();
1784
2429
  }
1785
2430
  setupMeasureFunc() {
1786
2431
  const measureFunc = (width, widthMode, height, heightMode) => {
1787
- if (this._wrap && this.width !== width) {
2432
+ if (this._wrapMode !== "none" && this.width !== width) {
1788
2433
  this.updateWrapWidth(width);
1789
2434
  } else {
1790
2435
  this.updateLineInfo();
@@ -1798,18 +2443,6 @@ class TextBufferRenderable extends Renderable {
1798
2443
  };
1799
2444
  this.yogaNode.setMeasureFunc(measureFunc);
1800
2445
  }
1801
- insertChunk(chunk, index) {
1802
- this.textBuffer.insertChunkGroup(index ?? this.textBuffer.chunkGroupCount, chunk.text, chunk.fg, chunk.bg, chunk.attributes);
1803
- this.updateTextInfo();
1804
- }
1805
- removeChunk(index) {
1806
- this.textBuffer.removeChunkGroup(index);
1807
- this.updateTextInfo();
1808
- }
1809
- replaceChunk(index, chunk) {
1810
- this.textBuffer.replaceChunkGroup(index, chunk.text, chunk.fg, chunk.bg, chunk.attributes);
1811
- this.updateTextInfo();
1812
- }
1813
2446
  shouldStartSelection(x, y) {
1814
2447
  if (!this.selectable)
1815
2448
  return false;
@@ -1827,13 +2460,13 @@ class TextBufferRenderable extends Renderable {
1827
2460
  return this.hasSelection();
1828
2461
  }
1829
2462
  getSelectedText() {
1830
- return this.textBuffer.getSelectedText();
2463
+ return this.textBufferView.getSelectedText();
1831
2464
  }
1832
2465
  hasSelection() {
1833
- return this.textBuffer.hasSelection();
2466
+ return this.textBufferView.hasSelection();
1834
2467
  }
1835
2468
  getSelection() {
1836
- return this.textBuffer.getSelection();
2469
+ return this.textBufferView.getSelection();
1837
2470
  }
1838
2471
  render(buffer, deltaTime) {
1839
2472
  if (!this.visible)
@@ -1844,16 +2477,11 @@ class TextBufferRenderable extends Renderable {
1844
2477
  }
1845
2478
  renderSelf(buffer) {
1846
2479
  if (this.textBuffer.ptr) {
1847
- const clipRect = {
1848
- x: this.x,
1849
- y: this.y,
1850
- width: this.width,
1851
- height: this.height
1852
- };
1853
- buffer.drawTextBuffer(this.textBuffer, this.x, this.y, clipRect);
2480
+ buffer.drawTextBuffer(this.textBufferView, this.x, this.y);
1854
2481
  }
1855
2482
  }
1856
2483
  destroy() {
2484
+ this.textBufferView.destroy();
1857
2485
  this.textBuffer.destroy();
1858
2486
  super.destroy();
1859
2487
  }
@@ -4264,24 +4892,6 @@ class TextRenderable extends TextBufferRenderable {
4264
4892
  this.updateTextInfo();
4265
4893
  }
4266
4894
  }
4267
- insertChunk(chunk, index) {
4268
- super.insertChunk(chunk, index);
4269
- this.clearChunks(this._text);
4270
- }
4271
- removeChunkByObject(chunk) {
4272
- const index = this._text.chunks.indexOf(chunk);
4273
- if (index === -1)
4274
- return;
4275
- super.removeChunk(index);
4276
- this.clearChunks(this._text);
4277
- }
4278
- replaceChunkByObject(chunk, oldChunk) {
4279
- const index = this._text.chunks.indexOf(oldChunk);
4280
- if (index === -1)
4281
- return;
4282
- super.replaceChunk(index, chunk);
4283
- this.clearChunks(this._text);
4284
- }
4285
4895
  updateTextFromNodes() {
4286
4896
  if (this.rootTextNode.isDirty && !this._hasManualStyledText) {
4287
4897
  const chunks = this.rootTextNode.gatherWithInheritedStyle({
@@ -4332,6 +4942,661 @@ class TextRenderable extends TextBufferRenderable {
4332
4942
  super.destroy();
4333
4943
  }
4334
4944
  }
4945
+ // src/renderables/EditBufferRenderable.ts
4946
+ class EditBufferRenderable extends Renderable {
4947
+ _focusable = true;
4948
+ selectable = true;
4949
+ _textColor;
4950
+ _backgroundColor;
4951
+ _defaultAttributes;
4952
+ _selectionBg;
4953
+ _selectionFg;
4954
+ _wrapMode = "word";
4955
+ _scrollMargin = 0.2;
4956
+ _showCursor = true;
4957
+ _cursorColor;
4958
+ lastLocalSelection = null;
4959
+ _cursorChangeListener = undefined;
4960
+ _contentChangeListener = undefined;
4961
+ editBuffer;
4962
+ editorView;
4963
+ _defaultOptions = {
4964
+ textColor: RGBA.fromValues(1, 1, 1, 1),
4965
+ backgroundColor: "transparent",
4966
+ selectionBg: undefined,
4967
+ selectionFg: undefined,
4968
+ selectable: true,
4969
+ attributes: 0,
4970
+ wrapMode: "word",
4971
+ scrollMargin: 0.2,
4972
+ showCursor: true,
4973
+ cursorColor: RGBA.fromValues(1, 1, 1, 1)
4974
+ };
4975
+ constructor(ctx, options) {
4976
+ super(ctx, options);
4977
+ this._textColor = parseColor(options.textColor ?? this._defaultOptions.textColor);
4978
+ this._backgroundColor = parseColor(options.backgroundColor ?? this._defaultOptions.backgroundColor);
4979
+ this._defaultAttributes = options.attributes ?? this._defaultOptions.attributes;
4980
+ this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : this._defaultOptions.selectionBg;
4981
+ this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : this._defaultOptions.selectionFg;
4982
+ this.selectable = options.selectable ?? this._defaultOptions.selectable;
4983
+ this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode;
4984
+ this._scrollMargin = options.scrollMargin ?? this._defaultOptions.scrollMargin;
4985
+ this._showCursor = options.showCursor ?? this._defaultOptions.showCursor;
4986
+ this._cursorColor = parseColor(options.cursorColor ?? this._defaultOptions.cursorColor);
4987
+ this.editBuffer = EditBuffer.create(this._ctx.widthMethod);
4988
+ this.editorView = EditorView.create(this.editBuffer, this.width || 80, this.height || 24);
4989
+ this.editorView.setWrapMode(this._wrapMode);
4990
+ this.editorView.setScrollMargin(this._scrollMargin);
4991
+ this.editBuffer.setDefaultFg(this._textColor);
4992
+ this.editBuffer.setDefaultBg(this._backgroundColor);
4993
+ this.editBuffer.setDefaultAttributes(this._defaultAttributes);
4994
+ if (options.syntaxStyle) {
4995
+ this.editBuffer.setSyntaxStyle(options.syntaxStyle);
4996
+ }
4997
+ this.setupMeasureFunc();
4998
+ this.setupEventListeners(options);
4999
+ }
5000
+ setupEventListeners(options) {
5001
+ this._cursorChangeListener = options.onCursorChange;
5002
+ this._contentChangeListener = options.onContentChange;
5003
+ this.editBuffer.on("cursor-changed", () => {
5004
+ if (this._cursorChangeListener) {
5005
+ const cursor = this.editBuffer.getCursorPosition();
5006
+ this._cursorChangeListener({
5007
+ line: cursor.line,
5008
+ visualColumn: cursor.visualColumn
5009
+ });
5010
+ }
5011
+ });
5012
+ this.editBuffer.on("content-changed", () => {
5013
+ this.yogaNode.markDirty();
5014
+ this.requestRender();
5015
+ if (this._contentChangeListener) {
5016
+ this._contentChangeListener({});
5017
+ }
5018
+ });
5019
+ }
5020
+ get plainText() {
5021
+ return this.editBuffer.getText();
5022
+ }
5023
+ get cursor() {
5024
+ return this.editBuffer.getCursorPosition();
5025
+ }
5026
+ get visualCursor() {
5027
+ return this.editorView.getVisualCursor();
5028
+ }
5029
+ set cursorOffset(offset) {
5030
+ this.editorView.setCursorByOffset(offset);
5031
+ }
5032
+ get textColor() {
5033
+ return this._textColor;
5034
+ }
5035
+ set textColor(value) {
5036
+ const newColor = parseColor(value ?? this._defaultOptions.textColor);
5037
+ if (this._textColor !== newColor) {
5038
+ this._textColor = newColor;
5039
+ this.editBuffer.setDefaultFg(newColor);
5040
+ this.requestRender();
5041
+ }
5042
+ }
5043
+ get selectionBg() {
5044
+ return this._selectionBg;
5045
+ }
5046
+ set selectionBg(value) {
5047
+ const newColor = value ? parseColor(value) : this._defaultOptions.selectionBg;
5048
+ if (this._selectionBg !== newColor) {
5049
+ this._selectionBg = newColor;
5050
+ if (this.lastLocalSelection) {
5051
+ this.updateLocalSelection(this.lastLocalSelection);
5052
+ }
5053
+ this.requestRender();
5054
+ }
5055
+ }
5056
+ get selectionFg() {
5057
+ return this._selectionFg;
5058
+ }
5059
+ set selectionFg(value) {
5060
+ const newColor = value ? parseColor(value) : this._defaultOptions.selectionFg;
5061
+ if (this._selectionFg !== newColor) {
5062
+ this._selectionFg = newColor;
5063
+ if (this.lastLocalSelection) {
5064
+ this.updateLocalSelection(this.lastLocalSelection);
5065
+ }
5066
+ this.requestRender();
5067
+ }
5068
+ }
5069
+ get backgroundColor() {
5070
+ return this._backgroundColor;
5071
+ }
5072
+ set backgroundColor(value) {
5073
+ const newColor = parseColor(value ?? this._defaultOptions.backgroundColor);
5074
+ if (this._backgroundColor !== newColor) {
5075
+ this._backgroundColor = newColor;
5076
+ this.editBuffer.setDefaultBg(newColor);
5077
+ this.requestRender();
5078
+ }
5079
+ }
5080
+ get attributes() {
5081
+ return this._defaultAttributes;
5082
+ }
5083
+ set attributes(value) {
5084
+ if (this._defaultAttributes !== value) {
5085
+ this._defaultAttributes = value;
5086
+ this.editBuffer.setDefaultAttributes(value);
5087
+ this.requestRender();
5088
+ }
5089
+ }
5090
+ get wrapMode() {
5091
+ return this._wrapMode;
5092
+ }
5093
+ set wrapMode(value) {
5094
+ if (this._wrapMode !== value) {
5095
+ this._wrapMode = value;
5096
+ this.editorView.setWrapMode(value);
5097
+ this.yogaNode.markDirty();
5098
+ this.requestRender();
5099
+ }
5100
+ }
5101
+ get showCursor() {
5102
+ return this._showCursor;
5103
+ }
5104
+ set showCursor(value) {
5105
+ if (this._showCursor !== value) {
5106
+ this._showCursor = value;
5107
+ this.requestRender();
5108
+ }
5109
+ }
5110
+ get cursorColor() {
5111
+ return this._cursorColor;
5112
+ }
5113
+ set cursorColor(value) {
5114
+ const newColor = parseColor(value);
5115
+ if (this._cursorColor !== newColor) {
5116
+ this._cursorColor = newColor;
5117
+ this.requestRender();
5118
+ }
5119
+ }
5120
+ onResize(width, height) {
5121
+ this.editorView.setViewportSize(width, height);
5122
+ if (this.lastLocalSelection) {
5123
+ const changed = this.updateLocalSelection(this.lastLocalSelection);
5124
+ if (changed) {
5125
+ this.requestRender();
5126
+ }
5127
+ }
5128
+ }
5129
+ refreshLocalSelection() {
5130
+ if (this.lastLocalSelection) {
5131
+ return this.updateLocalSelection(this.lastLocalSelection);
5132
+ }
5133
+ return false;
5134
+ }
5135
+ updateLocalSelection(localSelection) {
5136
+ if (!localSelection?.isActive) {
5137
+ this.editorView.resetLocalSelection();
5138
+ return true;
5139
+ }
5140
+ return this.editorView.setLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg);
5141
+ }
5142
+ shouldStartSelection(x, y) {
5143
+ if (!this.selectable)
5144
+ return false;
5145
+ const localX = x - this.x;
5146
+ const localY = y - this.y;
5147
+ return localX >= 0 && localX < this.width && localY >= 0 && localY < this.height;
5148
+ }
5149
+ onSelectionChanged(selection) {
5150
+ const localSelection = convertGlobalToLocalSelection(selection, this.x, this.y);
5151
+ this.lastLocalSelection = localSelection;
5152
+ const changed = this.updateLocalSelection(localSelection);
5153
+ if (changed) {
5154
+ this.requestRender();
5155
+ }
5156
+ return this.hasSelection();
5157
+ }
5158
+ getSelectedText() {
5159
+ return this.editorView.getSelectedText();
5160
+ }
5161
+ hasSelection() {
5162
+ return this.editorView.hasSelection();
5163
+ }
5164
+ getSelection() {
5165
+ return this.editorView.getSelection();
5166
+ }
5167
+ setupMeasureFunc() {
5168
+ const measureFunc = (width, widthMode, height, heightMode) => {
5169
+ if (this._wrapMode !== "none" && this.width !== width) {
5170
+ this.editorView.setViewportSize(width, height);
5171
+ } else {
5172
+ this.editorView.setViewportSize(width, height);
5173
+ }
5174
+ const lineInfo = this.editorView.getLogicalLineInfo();
5175
+ const measuredWidth = lineInfo.maxLineWidth;
5176
+ const measuredHeight = lineInfo.lineStarts.length;
5177
+ return {
5178
+ width: Math.max(1, measuredWidth),
5179
+ height: Math.max(1, measuredHeight)
5180
+ };
5181
+ };
5182
+ this.yogaNode.setMeasureFunc(measureFunc);
5183
+ }
5184
+ render(buffer, deltaTime) {
5185
+ if (!this.visible)
5186
+ return;
5187
+ if (this.isDestroyed)
5188
+ return;
5189
+ this.markClean();
5190
+ this._ctx.addToHitGrid(this.x, this.y, this.width, this.height, this.num);
5191
+ this.renderSelf(buffer);
5192
+ this.renderCursor(buffer);
5193
+ }
5194
+ renderSelf(buffer) {
5195
+ buffer.drawEditorView(this.editorView, this.x, this.y);
5196
+ }
5197
+ renderCursor(buffer) {
5198
+ if (!this._showCursor || !this._focused)
5199
+ return;
5200
+ const visualCursor = this.editorView.getVisualCursor();
5201
+ const cursorX = this.x + visualCursor.visualCol + 1;
5202
+ const cursorY = this.y + visualCursor.visualRow + 1;
5203
+ this._ctx.setCursorPosition(cursorX, cursorY, true);
5204
+ this._ctx.setCursorColor(this._cursorColor);
5205
+ this._ctx.setCursorStyle("block", true);
5206
+ }
5207
+ focus() {
5208
+ super.focus();
5209
+ this._ctx.setCursorStyle("block", true);
5210
+ this._ctx.setCursorColor(this._cursorColor);
5211
+ this.requestRender();
5212
+ }
5213
+ blur() {
5214
+ super.blur();
5215
+ this._ctx.setCursorPosition(0, 0, false);
5216
+ this.requestRender();
5217
+ }
5218
+ onRemove() {
5219
+ if (this._focused) {
5220
+ this._ctx.setCursorPosition(0, 0, false);
5221
+ }
5222
+ }
5223
+ destroy() {
5224
+ if (this._focused) {
5225
+ this._ctx.setCursorPosition(0, 0, false);
5226
+ }
5227
+ super.destroy();
5228
+ this.editorView.destroy();
5229
+ this.editBuffer.destroy();
5230
+ }
5231
+ set onCursorChange(handler) {
5232
+ this._cursorChangeListener = handler;
5233
+ }
5234
+ get onCursorChange() {
5235
+ return this._cursorChangeListener;
5236
+ }
5237
+ set onContentChange(handler) {
5238
+ this._contentChangeListener = handler;
5239
+ }
5240
+ get onContentChange() {
5241
+ return this._contentChangeListener;
5242
+ }
5243
+ get syntaxStyle() {
5244
+ return this.editBuffer.getSyntaxStyle();
5245
+ }
5246
+ set syntaxStyle(style) {
5247
+ this.editBuffer.setSyntaxStyle(style);
5248
+ this.requestRender();
5249
+ }
5250
+ }
5251
+
5252
+ // src/renderables/Textarea.ts
5253
+ class TextareaRenderable extends EditBufferRenderable {
5254
+ _placeholder;
5255
+ _unfocusedBackgroundColor;
5256
+ _unfocusedTextColor;
5257
+ _focusedBackgroundColor;
5258
+ _focusedTextColor;
5259
+ _placeholderColor;
5260
+ static defaults = {
5261
+ value: "",
5262
+ backgroundColor: "transparent",
5263
+ textColor: "#FFFFFF",
5264
+ focusedBackgroundColor: "transparent",
5265
+ focusedTextColor: "#FFFFFF",
5266
+ placeholder: null,
5267
+ placeholderColor: "#666666"
5268
+ };
5269
+ constructor(ctx, options) {
5270
+ const defaults = TextareaRenderable.defaults;
5271
+ const baseOptions = {
5272
+ ...options,
5273
+ backgroundColor: options.backgroundColor || defaults.backgroundColor,
5274
+ textColor: options.textColor || defaults.textColor
5275
+ };
5276
+ super(ctx, baseOptions);
5277
+ this._unfocusedBackgroundColor = parseColor(options.backgroundColor || defaults.backgroundColor);
5278
+ this._unfocusedTextColor = parseColor(options.textColor || defaults.textColor);
5279
+ this._focusedBackgroundColor = parseColor(options.focusedBackgroundColor || options.backgroundColor || defaults.focusedBackgroundColor);
5280
+ this._focusedTextColor = parseColor(options.focusedTextColor || options.textColor || defaults.focusedTextColor);
5281
+ this._placeholder = options.placeholder ?? defaults.placeholder;
5282
+ this._placeholderColor = parseColor(options.placeholderColor || defaults.placeholderColor);
5283
+ this.updateValue(options.value ?? defaults.value);
5284
+ this.updateColors();
5285
+ this.editBuffer.setPlaceholder(this._placeholder);
5286
+ this.editBuffer.setPlaceholderColor(this._placeholderColor);
5287
+ }
5288
+ handlePaste(text) {
5289
+ this.insertText(text);
5290
+ }
5291
+ handleKeyPress(key) {
5292
+ const keyName = typeof key === "string" ? key : key.name;
5293
+ const keySequence = typeof key === "string" ? key : key.sequence;
5294
+ const keyCtrl = typeof key === "string" ? false : key.ctrl;
5295
+ const keyShift = typeof key === "string" ? false : key.shift;
5296
+ const keyMeta = typeof key === "string" ? false : key.meta;
5297
+ if (keyCtrl && keyName === "z" && !keyShift) {
5298
+ this.undo();
5299
+ return true;
5300
+ } else if (keyCtrl && keyName === "y" || keyCtrl && keyShift && keyName === "z") {
5301
+ this.redo();
5302
+ return true;
5303
+ } else if (keyName === "left") {
5304
+ this.handleShiftSelection(keyShift, true);
5305
+ this.moveCursorLeft();
5306
+ this.handleShiftSelection(keyShift, false);
5307
+ return true;
5308
+ } else if (keyName === "right") {
5309
+ this.handleShiftSelection(keyShift, true);
5310
+ this.moveCursorRight();
5311
+ this.handleShiftSelection(keyShift, false);
5312
+ return true;
5313
+ } else if (keyName === "up") {
5314
+ this.handleShiftSelection(keyShift, true);
5315
+ this.moveCursorUp();
5316
+ this.handleShiftSelection(keyShift, false);
5317
+ return true;
5318
+ } else if (keyName === "down") {
5319
+ this.handleShiftSelection(keyShift, true);
5320
+ this.moveCursorDown();
5321
+ this.handleShiftSelection(keyShift, false);
5322
+ return true;
5323
+ } else if (keyName === "home") {
5324
+ this.handleShiftSelection(keyShift, true);
5325
+ const cursor = this.editorView.getCursor();
5326
+ this.editBuffer.setCursor(cursor.row, 0);
5327
+ this.handleShiftSelection(keyShift, false);
5328
+ return true;
5329
+ } else if (keyName === "end") {
5330
+ this.handleShiftSelection(keyShift, true);
5331
+ this.gotoLineEnd();
5332
+ this.handleShiftSelection(keyShift, false);
5333
+ return true;
5334
+ } else if (keyCtrl && keyName === "a") {
5335
+ this.editBuffer.setCursor(0, 0);
5336
+ return true;
5337
+ } else if (keyCtrl && keyName === "e") {
5338
+ this.gotoBufferEnd();
5339
+ return true;
5340
+ } else if (keyCtrl && keyName === "d") {
5341
+ this.deleteLine();
5342
+ return true;
5343
+ } else if (keyCtrl && keyName === "k") {
5344
+ this.deleteToLineEnd();
5345
+ return true;
5346
+ } else if (keyName === "backspace") {
5347
+ this.deleteCharBackward();
5348
+ return true;
5349
+ } else if (keyName === "delete") {
5350
+ this.deleteChar();
5351
+ return true;
5352
+ } else if (keyName === "return" || keyName === "enter") {
5353
+ this.newLine();
5354
+ return true;
5355
+ } else if (keySequence && !keyCtrl && !keyMeta) {
5356
+ const firstCharCode = keySequence.charCodeAt(0);
5357
+ if (firstCharCode < 32) {
5358
+ return false;
5359
+ }
5360
+ if (firstCharCode === 127) {
5361
+ return false;
5362
+ }
5363
+ this.insertText(keySequence);
5364
+ return true;
5365
+ }
5366
+ return false;
5367
+ }
5368
+ get value() {
5369
+ return this.editBuffer.getText();
5370
+ }
5371
+ set value(value) {
5372
+ this.updateValue(value);
5373
+ }
5374
+ updateValue(value) {
5375
+ this.editBuffer.setText(value, { history: false });
5376
+ this.yogaNode.markDirty();
5377
+ this.requestRender();
5378
+ }
5379
+ updateColors() {
5380
+ const effectiveBg = this._focused ? this._focusedBackgroundColor : this._unfocusedBackgroundColor;
5381
+ const effectiveFg = this._focused ? this._focusedTextColor : this._unfocusedTextColor;
5382
+ super.backgroundColor = effectiveBg;
5383
+ super.textColor = effectiveFg;
5384
+ }
5385
+ insertChar(char) {
5386
+ if (this.hasSelection()) {
5387
+ this.deleteSelectedText();
5388
+ }
5389
+ this.editBuffer.insertChar(char);
5390
+ this.requestRender();
5391
+ }
5392
+ insertText(text) {
5393
+ if (this.hasSelection()) {
5394
+ this.deleteSelectedText();
5395
+ }
5396
+ this.editBuffer.insertText(text);
5397
+ this.requestRender();
5398
+ }
5399
+ deleteChar() {
5400
+ if (this.hasSelection()) {
5401
+ this.deleteSelectedText();
5402
+ return;
5403
+ }
5404
+ this._ctx.clearSelection();
5405
+ this.editBuffer.deleteChar();
5406
+ this.requestRender();
5407
+ }
5408
+ deleteCharBackward() {
5409
+ if (this.hasSelection()) {
5410
+ this.deleteSelectedText();
5411
+ return;
5412
+ }
5413
+ this._ctx.clearSelection();
5414
+ this.editBuffer.deleteCharBackward();
5415
+ this.requestRender();
5416
+ }
5417
+ deleteSelectedText() {
5418
+ this.editorView.deleteSelectedText();
5419
+ this._ctx.clearSelection();
5420
+ this.requestRender();
5421
+ }
5422
+ newLine() {
5423
+ this._ctx.clearSelection();
5424
+ this.editBuffer.newLine();
5425
+ this.requestRender();
5426
+ }
5427
+ deleteLine() {
5428
+ this._ctx.clearSelection();
5429
+ this.editBuffer.deleteLine();
5430
+ this.requestRender();
5431
+ }
5432
+ moveCursorLeft() {
5433
+ this.editBuffer.moveCursorLeft();
5434
+ this.requestRender();
5435
+ }
5436
+ moveCursorRight() {
5437
+ this.editBuffer.moveCursorRight();
5438
+ this.requestRender();
5439
+ }
5440
+ moveCursorUp() {
5441
+ this.editorView.moveUpVisual();
5442
+ this.requestRender();
5443
+ }
5444
+ moveCursorDown() {
5445
+ this.editorView.moveDownVisual();
5446
+ this.requestRender();
5447
+ }
5448
+ gotoLine(line) {
5449
+ this.editBuffer.gotoLine(line);
5450
+ this.requestRender();
5451
+ }
5452
+ gotoLineEnd() {
5453
+ const cursor = this.editorView.getCursor();
5454
+ this.editBuffer.gotoLine(9999);
5455
+ const afterCursor = this.editorView.getCursor();
5456
+ if (afterCursor.row !== cursor.row) {
5457
+ this.editBuffer.setCursor(cursor.row, 9999);
5458
+ }
5459
+ this.requestRender();
5460
+ }
5461
+ gotoBufferEnd() {
5462
+ this.editBuffer.gotoLine(999999);
5463
+ this.requestRender();
5464
+ }
5465
+ deleteToLineEnd() {
5466
+ const cursor = this.editorView.getCursor();
5467
+ const startCol = cursor.col;
5468
+ const tempCursor = this.editorView.getCursor();
5469
+ this.editBuffer.setCursor(tempCursor.row, 9999);
5470
+ const endCursor = this.editorView.getCursor();
5471
+ const endCol = endCursor.col;
5472
+ this.editBuffer.setCursor(cursor.row, startCol);
5473
+ if (endCol > startCol) {
5474
+ for (let i = 0;i < endCol - startCol; i++) {
5475
+ this.deleteChar();
5476
+ }
5477
+ }
5478
+ this.requestRender();
5479
+ }
5480
+ undo() {
5481
+ this._ctx.clearSelection();
5482
+ this.editBuffer.undo();
5483
+ this.requestRender();
5484
+ }
5485
+ redo() {
5486
+ this._ctx.clearSelection();
5487
+ this.editBuffer.redo();
5488
+ this.requestRender();
5489
+ }
5490
+ handleShiftSelection(shiftPressed, isBeforeMovement) {
5491
+ if (!this.selectable)
5492
+ return;
5493
+ if (!shiftPressed) {
5494
+ this._ctx.clearSelection();
5495
+ return;
5496
+ }
5497
+ const visualCursor = this.editorView.getVisualCursor();
5498
+ const viewport = this.editorView.getViewport();
5499
+ const cursorX = this.x + visualCursor.visualCol;
5500
+ const cursorY = this.y + (visualCursor.visualRow - viewport.offsetY);
5501
+ if (isBeforeMovement) {
5502
+ if (!this._ctx.hasSelection) {
5503
+ this._ctx.startSelection(this, cursorX, cursorY);
5504
+ }
5505
+ } else {
5506
+ this._ctx.updateSelection(this, cursorX, cursorY);
5507
+ }
5508
+ }
5509
+ focus() {
5510
+ super.focus();
5511
+ this.updateColors();
5512
+ }
5513
+ blur() {
5514
+ super.blur();
5515
+ this.updateColors();
5516
+ }
5517
+ get placeholder() {
5518
+ return this._placeholder;
5519
+ }
5520
+ set placeholder(value) {
5521
+ if (this._placeholder !== value) {
5522
+ this._placeholder = value;
5523
+ this.editBuffer.setPlaceholder(value);
5524
+ this.requestRender();
5525
+ }
5526
+ }
5527
+ get backgroundColor() {
5528
+ return this._unfocusedBackgroundColor;
5529
+ }
5530
+ set backgroundColor(value) {
5531
+ const newColor = parseColor(value ?? TextareaRenderable.defaults.backgroundColor);
5532
+ if (this._unfocusedBackgroundColor !== newColor) {
5533
+ this._unfocusedBackgroundColor = newColor;
5534
+ this.updateColors();
5535
+ }
5536
+ }
5537
+ get textColor() {
5538
+ return this._unfocusedTextColor;
5539
+ }
5540
+ set textColor(value) {
5541
+ const newColor = parseColor(value ?? TextareaRenderable.defaults.textColor);
5542
+ if (this._unfocusedTextColor !== newColor) {
5543
+ this._unfocusedTextColor = newColor;
5544
+ this.updateColors();
5545
+ }
5546
+ }
5547
+ set focusedBackgroundColor(value) {
5548
+ const newColor = parseColor(value ?? TextareaRenderable.defaults.focusedBackgroundColor);
5549
+ if (this._focusedBackgroundColor !== newColor) {
5550
+ this._focusedBackgroundColor = newColor;
5551
+ this.updateColors();
5552
+ }
5553
+ }
5554
+ set focusedTextColor(value) {
5555
+ const newColor = parseColor(value ?? TextareaRenderable.defaults.focusedTextColor);
5556
+ if (this._focusedTextColor !== newColor) {
5557
+ this._focusedTextColor = newColor;
5558
+ this.updateColors();
5559
+ }
5560
+ }
5561
+ set placeholderColor(value) {
5562
+ const newColor = parseColor(value ?? TextareaRenderable.defaults.placeholderColor);
5563
+ if (this._placeholderColor !== newColor) {
5564
+ this._placeholderColor = newColor;
5565
+ this.editBuffer.setPlaceholderColor(newColor);
5566
+ this.requestRender();
5567
+ }
5568
+ }
5569
+ get cursorOffset() {
5570
+ return this.editorView.getVisualCursor().offset;
5571
+ }
5572
+ set cursorOffset(offset) {
5573
+ this.editorView.setCursorByOffset(offset);
5574
+ this.requestRender();
5575
+ }
5576
+ addHighlight(lineIdx, highlight) {
5577
+ this.editBuffer.addHighlight(lineIdx, highlight);
5578
+ this.requestRender();
5579
+ }
5580
+ addHighlightByCharRange(highlight) {
5581
+ this.editBuffer.addHighlightByCharRange(highlight);
5582
+ this.requestRender();
5583
+ }
5584
+ removeHighlightsByRef(hlRef) {
5585
+ this.editBuffer.removeHighlightsByRef(hlRef);
5586
+ this.requestRender();
5587
+ }
5588
+ clearLineHighlights(lineIdx) {
5589
+ this.editBuffer.clearLineHighlights(lineIdx);
5590
+ this.requestRender();
5591
+ }
5592
+ clearAllHighlights() {
5593
+ this.editBuffer.clearAllHighlights();
5594
+ this.requestRender();
5595
+ }
5596
+ getLineHighlights(lineIdx) {
5597
+ return this.editBuffer.getLineHighlights(lineIdx);
5598
+ }
5599
+ }
4335
5600
  export {
4336
5601
  yellow,
4337
5602
  wrapWithDelegates,
@@ -4444,8 +5709,10 @@ export {
4444
5709
  VRenderable,
4445
5710
  TreeSitterClient,
4446
5711
  Timeline,
5712
+ TextareaRenderable,
4447
5713
  TextRenderable,
4448
5714
  TextNodeRenderable,
5715
+ TextBufferView,
4449
5716
  TextBufferRenderable,
4450
5717
  TextBuffer,
4451
5718
  TextAttributes,
@@ -4487,6 +5754,8 @@ export {
4487
5754
  Generic,
4488
5755
  FrameBufferRenderable,
4489
5756
  FrameBuffer,
5757
+ EditorView,
5758
+ EditBuffer,
4490
5759
  DistortionEffect,
4491
5760
  DebugOverlayCorner,
4492
5761
  DataPathsManager,
@@ -4508,5 +5777,5 @@ export {
4508
5777
  ASCIIFont
4509
5778
  };
4510
5779
 
4511
- //# debugId=6F0864CECE58138064756E2164756E21
5780
+ //# debugId=B4995BB40805F64B64756E2164756E21
4512
5781
  //# sourceMappingURL=index.js.map