@opentui/core 0.1.24 → 0.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/3d.js +1 -1
  2. package/README.md +5 -1
  3. package/Renderable.d.ts +18 -8
  4. package/animation/Timeline.d.ts +2 -1
  5. package/ansi.d.ts +2 -17
  6. package/assets/javascript/highlights.scm +205 -0
  7. package/assets/javascript/tree-sitter-javascript.wasm +0 -0
  8. package/assets/typescript/highlights.scm +604 -0
  9. package/assets/typescript/tree-sitter-typescript.wasm +0 -0
  10. package/{index-0yx9rnxg.js → index-pxa2sv92.js} +1798 -258
  11. package/index-pxa2sv92.js.map +52 -0
  12. package/index.js +449 -246
  13. package/index.js.map +15 -13
  14. package/lib/KeyHandler.d.ts +51 -9
  15. package/lib/data-paths.d.ts +26 -0
  16. package/lib/debounce.d.ts +42 -0
  17. package/lib/env.d.ts +42 -0
  18. package/lib/hast-styled-text.d.ts +3 -23
  19. package/lib/index.d.ts +6 -0
  20. package/lib/parse.keypress.d.ts +2 -2
  21. package/lib/queue.d.ts +15 -0
  22. package/lib/scroll-acceleration.d.ts +43 -0
  23. package/{singleton.d.ts → lib/singleton.d.ts} +2 -0
  24. package/lib/styled-text.d.ts +0 -15
  25. package/lib/syntax-style.d.ts +36 -0
  26. package/lib/tree-sitter/assets/update.d.ts +11 -0
  27. package/lib/tree-sitter/client.d.ts +46 -0
  28. package/lib/tree-sitter/default-parsers.d.ts +2 -0
  29. package/lib/tree-sitter/download-utils.d.ts +21 -0
  30. package/lib/tree-sitter/index.d.ts +10 -0
  31. package/lib/tree-sitter/parser.worker.d.ts +1 -0
  32. package/lib/tree-sitter/resolve-ft.d.ts +2 -0
  33. package/lib/tree-sitter/types.d.ts +64 -0
  34. package/lib/tree-sitter-styled-text.d.ts +7 -0
  35. package/lib/validate-dir-name.d.ts +1 -0
  36. package/package.json +21 -8
  37. package/parser.worker.js +640 -0
  38. package/parser.worker.js.map +11 -0
  39. package/renderables/ASCIIFont.d.ts +1 -1
  40. package/renderables/Code.d.ts +31 -0
  41. package/renderables/Input.d.ts +4 -4
  42. package/renderables/ScrollBar.d.ts +2 -2
  43. package/renderables/ScrollBox.d.ts +7 -3
  44. package/renderables/Select.d.ts +2 -2
  45. package/renderables/TabSelect.d.ts +2 -2
  46. package/renderables/Text.d.ts +11 -65
  47. package/renderables/TextBufferRenderable.d.ts +81 -0
  48. package/renderables/TextNode.d.ts +1 -0
  49. package/renderables/index.d.ts +2 -0
  50. package/renderer.d.ts +5 -3
  51. package/testing/mock-keys.d.ts +1 -0
  52. package/testing/spy.d.ts +7 -0
  53. package/testing/test-renderer.d.ts +1 -0
  54. package/testing.d.ts +1 -0
  55. package/testing.js +31 -6
  56. package/testing.js.map +6 -5
  57. package/types.d.ts +2 -1
  58. package/zig.d.ts +1 -0
  59. package/index-0yx9rnxg.js.map +0 -38
package/index.js CHANGED
@@ -7,16 +7,22 @@ import {
7
7
  CliRenderEvents,
8
8
  CliRenderer,
9
9
  ConsolePosition,
10
+ DataPathsManager,
10
11
  DebugOverlayCorner,
11
12
  Edge,
12
13
  Gutter,
14
+ InternalKeyHandler,
15
+ KeyEvent,
13
16
  KeyHandler,
14
17
  LayoutEvents,
18
+ LinearScrollAccel,
15
19
  LogLevel,
20
+ MacOSScrollAccel,
16
21
  MouseButton,
17
22
  MouseEvent,
18
23
  MouseParser,
19
24
  OptimizedBuffer,
25
+ PasteEvent,
20
26
  RGBA,
21
27
  Renderable,
22
28
  RenderableEvents,
@@ -27,6 +33,8 @@ import {
27
33
  TerminalConsole,
28
34
  TextAttributes,
29
35
  TextBuffer,
36
+ TreeSitterClient,
37
+ addDefaultParsers,
30
38
  bg,
31
39
  bgBlack,
32
40
  bgBlue,
@@ -50,21 +58,29 @@ import {
50
58
  brightWhite,
51
59
  brightYellow,
52
60
  capture,
61
+ clearEnvCache,
53
62
  convertGlobalToLocalSelection,
63
+ convertThemeToStyles,
54
64
  coordinateToCharacterIndex,
55
65
  createCliRenderer,
56
66
  createTextAttributes,
57
67
  cyan,
58
68
  delegate,
59
69
  dim,
70
+ env,
71
+ envRegistry,
60
72
  exports_src,
73
+ extToFiletype,
61
74
  fg,
62
75
  fonts,
76
+ generateEnvColored,
77
+ generateEnvMarkdown,
63
78
  getBorderFromSides,
64
79
  getBorderSides,
65
80
  getCharacterPositions,
66
- getKeyHandler,
81
+ getDataPaths,
67
82
  getObjectsInViewport,
83
+ getTreeSitterClient,
68
84
  green,
69
85
  h,
70
86
  hastToStyledText,
@@ -77,6 +93,7 @@ import {
77
93
  isValidPercentage,
78
94
  italic,
79
95
  magenta,
96
+ main,
80
97
  maybeMakeRenderable,
81
98
  measureText,
82
99
  nonAlphanumericKeys,
@@ -97,7 +114,9 @@ import {
97
114
  parsePositionType,
98
115
  parseUnit,
99
116
  parseWrap,
117
+ pathToFiletype,
100
118
  red,
119
+ registerEnvVar,
101
120
  renderFontToFrameBuffer,
102
121
  resolveRenderLib,
103
122
  reverse,
@@ -106,12 +125,14 @@ import {
106
125
  strikethrough,
107
126
  stringToStyledText,
108
127
  t,
128
+ treeSitterToStyledText,
129
+ treeSitterToTextChunks,
109
130
  underline,
110
131
  visualizeRenderableTree,
111
132
  white,
112
133
  wrapWithDelegates,
113
134
  yellow
114
- } from "./index-0yx9rnxg.js";
135
+ } from "./index-pxa2sv92.js";
115
136
  // src/post/filters.ts
116
137
  function applyScanlines(buffer, strength = 0.8, step = 2) {
117
138
  const width = buffer.width;
@@ -1407,6 +1428,354 @@ class BoxRenderable extends Renderable {
1407
1428
  }
1408
1429
  }
1409
1430
  }
1431
+ // src/renderables/TextBufferRenderable.ts
1432
+ class TextBufferRenderable extends Renderable {
1433
+ selectable = true;
1434
+ _defaultFg;
1435
+ _defaultBg;
1436
+ _defaultAttributes;
1437
+ _selectionBg;
1438
+ _selectionFg;
1439
+ _wrap = false;
1440
+ _wrapMode = "word";
1441
+ lastLocalSelection = null;
1442
+ textBuffer;
1443
+ _lineInfo = { lineStarts: [], lineWidths: [], maxLineWidth: 0 };
1444
+ _defaultOptions = {
1445
+ fg: RGBA.fromValues(1, 1, 1, 1),
1446
+ bg: RGBA.fromValues(0, 0, 0, 0),
1447
+ selectionBg: undefined,
1448
+ selectionFg: undefined,
1449
+ selectable: true,
1450
+ attributes: 0,
1451
+ wrap: true,
1452
+ wrapMode: "word"
1453
+ };
1454
+ constructor(ctx, options) {
1455
+ super(ctx, options);
1456
+ this._defaultFg = parseColor(options.fg ?? this._defaultOptions.fg);
1457
+ this._defaultBg = parseColor(options.bg ?? this._defaultOptions.bg);
1458
+ this._defaultAttributes = options.attributes ?? this._defaultOptions.attributes;
1459
+ this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : this._defaultOptions.selectionBg;
1460
+ this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : this._defaultOptions.selectionFg;
1461
+ this.selectable = options.selectable ?? this._defaultOptions.selectable;
1462
+ this._wrap = options.wrap ?? this._defaultOptions.wrap;
1463
+ this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode;
1464
+ this.textBuffer = TextBuffer.create(this._ctx.widthMethod);
1465
+ this.textBuffer.setWrapMode(this._wrapMode);
1466
+ this.setupMeasureFunc();
1467
+ this.textBuffer.setDefaultFg(this._defaultFg);
1468
+ this.textBuffer.setDefaultBg(this._defaultBg);
1469
+ this.textBuffer.setDefaultAttributes(this._defaultAttributes);
1470
+ if (this._wrap && this.width > 0) {
1471
+ this.updateWrapWidth(this.width);
1472
+ }
1473
+ this.updateTextInfo();
1474
+ }
1475
+ get plainText() {
1476
+ return this.textBuffer.getPlainText();
1477
+ }
1478
+ get textLength() {
1479
+ return this.textBuffer.length;
1480
+ }
1481
+ get fg() {
1482
+ return this._defaultFg;
1483
+ }
1484
+ set fg(value) {
1485
+ const newColor = parseColor(value ?? this._defaultOptions.fg);
1486
+ if (this._defaultFg !== newColor) {
1487
+ this._defaultFg = newColor;
1488
+ this.textBuffer.setDefaultFg(this._defaultFg);
1489
+ this.onFgChanged(newColor);
1490
+ this.requestRender();
1491
+ }
1492
+ }
1493
+ get selectionBg() {
1494
+ return this._selectionBg;
1495
+ }
1496
+ set selectionBg(value) {
1497
+ const newColor = value ? parseColor(value) : this._defaultOptions.selectionBg;
1498
+ if (this._selectionBg !== newColor) {
1499
+ this._selectionBg = newColor;
1500
+ if (this.lastLocalSelection) {
1501
+ this.updateLocalSelection(this.lastLocalSelection);
1502
+ }
1503
+ this.requestRender();
1504
+ }
1505
+ }
1506
+ get selectionFg() {
1507
+ return this._selectionFg;
1508
+ }
1509
+ set selectionFg(value) {
1510
+ const newColor = value ? parseColor(value) : this._defaultOptions.selectionFg;
1511
+ if (this._selectionFg !== newColor) {
1512
+ this._selectionFg = newColor;
1513
+ if (this.lastLocalSelection) {
1514
+ this.updateLocalSelection(this.lastLocalSelection);
1515
+ }
1516
+ this.requestRender();
1517
+ }
1518
+ }
1519
+ get bg() {
1520
+ return this._defaultBg;
1521
+ }
1522
+ set bg(value) {
1523
+ const newColor = parseColor(value ?? this._defaultOptions.bg);
1524
+ if (this._defaultBg !== newColor) {
1525
+ this._defaultBg = newColor;
1526
+ this.textBuffer.setDefaultBg(this._defaultBg);
1527
+ this.onBgChanged(newColor);
1528
+ this.requestRender();
1529
+ }
1530
+ }
1531
+ get attributes() {
1532
+ return this._defaultAttributes;
1533
+ }
1534
+ set attributes(value) {
1535
+ if (this._defaultAttributes !== value) {
1536
+ this._defaultAttributes = value;
1537
+ this.textBuffer.setDefaultAttributes(this._defaultAttributes);
1538
+ this.onAttributesChanged(value);
1539
+ this.requestRender();
1540
+ }
1541
+ }
1542
+ get wrap() {
1543
+ return this._wrap;
1544
+ }
1545
+ set wrap(value) {
1546
+ if (this._wrap !== value) {
1547
+ this._wrap = value;
1548
+ this.textBuffer.setWrapWidth(this._wrap ? this.width : null);
1549
+ this.requestRender();
1550
+ }
1551
+ }
1552
+ get wrapMode() {
1553
+ return this._wrapMode;
1554
+ }
1555
+ set wrapMode(value) {
1556
+ if (this._wrapMode !== value) {
1557
+ this._wrapMode = value;
1558
+ this.textBuffer.setWrapMode(this._wrapMode);
1559
+ this.requestRender();
1560
+ }
1561
+ }
1562
+ onResize(width, height) {
1563
+ if (this.lastLocalSelection) {
1564
+ const changed = this.updateLocalSelection(this.lastLocalSelection);
1565
+ if (changed) {
1566
+ this.requestRender();
1567
+ }
1568
+ }
1569
+ }
1570
+ refreshLocalSelection() {
1571
+ if (this.lastLocalSelection) {
1572
+ return this.updateLocalSelection(this.lastLocalSelection);
1573
+ }
1574
+ return false;
1575
+ }
1576
+ updateLocalSelection(localSelection) {
1577
+ if (!localSelection?.isActive) {
1578
+ this.textBuffer.resetLocalSelection();
1579
+ return true;
1580
+ }
1581
+ return this.textBuffer.setLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg);
1582
+ }
1583
+ updateTextInfo() {
1584
+ if (this.lastLocalSelection) {
1585
+ const changed = this.updateLocalSelection(this.lastLocalSelection);
1586
+ if (changed) {
1587
+ this.requestRender();
1588
+ }
1589
+ }
1590
+ this.yogaNode.markDirty();
1591
+ this.requestRender();
1592
+ }
1593
+ updateLineInfo() {
1594
+ const lineInfo = this.textBuffer.lineInfo;
1595
+ this._lineInfo.lineStarts = lineInfo.lineStarts;
1596
+ this._lineInfo.lineWidths = lineInfo.lineWidths;
1597
+ this._lineInfo.maxLineWidth = lineInfo.maxLineWidth;
1598
+ }
1599
+ updateWrapWidth(width) {
1600
+ this.textBuffer.setWrapWidth(width);
1601
+ this.updateLineInfo();
1602
+ }
1603
+ setupMeasureFunc() {
1604
+ const measureFunc = (width, widthMode, height, heightMode) => {
1605
+ if (this._wrap && this.width !== width) {
1606
+ this.updateWrapWidth(width);
1607
+ } else {
1608
+ this.updateLineInfo();
1609
+ }
1610
+ const measuredWidth = this._lineInfo.maxLineWidth;
1611
+ const measuredHeight = this._lineInfo.lineStarts.length;
1612
+ return {
1613
+ width: Math.max(1, measuredWidth),
1614
+ height: Math.max(1, measuredHeight)
1615
+ };
1616
+ };
1617
+ this.yogaNode.setMeasureFunc(measureFunc);
1618
+ }
1619
+ insertChunk(chunk, index) {
1620
+ this.textBuffer.insertChunkGroup(index ?? this.textBuffer.chunkGroupCount, chunk.text, chunk.fg, chunk.bg, chunk.attributes);
1621
+ this.updateTextInfo();
1622
+ }
1623
+ removeChunk(index) {
1624
+ this.textBuffer.removeChunkGroup(index);
1625
+ this.updateTextInfo();
1626
+ }
1627
+ replaceChunk(index, chunk) {
1628
+ this.textBuffer.replaceChunkGroup(index, chunk.text, chunk.fg, chunk.bg, chunk.attributes);
1629
+ this.updateTextInfo();
1630
+ }
1631
+ shouldStartSelection(x, y) {
1632
+ if (!this.selectable)
1633
+ return false;
1634
+ const localX = x - this.x;
1635
+ const localY = y - this.y;
1636
+ return localX >= 0 && localX < this.width && localY >= 0 && localY < this.height;
1637
+ }
1638
+ onSelectionChanged(selection) {
1639
+ const localSelection = convertGlobalToLocalSelection(selection, this.x, this.y);
1640
+ this.lastLocalSelection = localSelection;
1641
+ const changed = this.updateLocalSelection(localSelection);
1642
+ if (changed) {
1643
+ this.requestRender();
1644
+ }
1645
+ return this.hasSelection();
1646
+ }
1647
+ getSelectedText() {
1648
+ return this.textBuffer.getSelectedText();
1649
+ }
1650
+ hasSelection() {
1651
+ return this.textBuffer.hasSelection();
1652
+ }
1653
+ getSelection() {
1654
+ return this.textBuffer.getSelection();
1655
+ }
1656
+ render(buffer, deltaTime) {
1657
+ if (!this.visible)
1658
+ return;
1659
+ this.markClean();
1660
+ this._ctx.addToHitGrid(this.x, this.y, this.width, this.height, this.num);
1661
+ this.renderSelf(buffer);
1662
+ }
1663
+ renderSelf(buffer) {
1664
+ if (this.textBuffer.ptr) {
1665
+ const clipRect = {
1666
+ x: this.x,
1667
+ y: this.y,
1668
+ width: this.width,
1669
+ height: this.height
1670
+ };
1671
+ buffer.drawTextBuffer(this.textBuffer, this.x, this.y, clipRect);
1672
+ }
1673
+ }
1674
+ destroy() {
1675
+ this.textBuffer.destroy();
1676
+ super.destroy();
1677
+ }
1678
+ onFgChanged(newColor) {}
1679
+ onBgChanged(newColor) {}
1680
+ onAttributesChanged(newAttributes) {}
1681
+ }
1682
+
1683
+ // src/renderables/Code.ts
1684
+ class CodeRenderable extends TextBufferRenderable {
1685
+ _content;
1686
+ _filetype;
1687
+ _syntaxStyle;
1688
+ _isHighlighting = false;
1689
+ _treeSitterClient;
1690
+ _pendingRehighlight = false;
1691
+ _contentDefaultOptions = {
1692
+ content: ""
1693
+ };
1694
+ constructor(ctx, options) {
1695
+ super(ctx, options);
1696
+ this._content = options.content ?? this._contentDefaultOptions.content;
1697
+ this._filetype = options.filetype;
1698
+ this._syntaxStyle = options.syntaxStyle;
1699
+ this._treeSitterClient = options.treeSitterClient ?? getTreeSitterClient();
1700
+ this.updateContent(this._content);
1701
+ }
1702
+ get content() {
1703
+ return this._content;
1704
+ }
1705
+ set content(value) {
1706
+ if (this._content !== value) {
1707
+ this._content = value;
1708
+ this.updateContent(value);
1709
+ }
1710
+ }
1711
+ get filetype() {
1712
+ return this._filetype;
1713
+ }
1714
+ set filetype(value) {
1715
+ if (this._filetype !== value) {
1716
+ this._filetype = value;
1717
+ this.updateContent(this._content);
1718
+ }
1719
+ }
1720
+ get syntaxStyle() {
1721
+ return this._syntaxStyle;
1722
+ }
1723
+ set syntaxStyle(value) {
1724
+ if (this._syntaxStyle !== value) {
1725
+ this._syntaxStyle = value;
1726
+ this.updateContent(this._content);
1727
+ }
1728
+ }
1729
+ async updateContent(content) {
1730
+ if (content.length === 0)
1731
+ return;
1732
+ if (this._isHighlighting) {
1733
+ this._pendingRehighlight = true;
1734
+ return;
1735
+ }
1736
+ if (!this._filetype) {
1737
+ this.fallback(content);
1738
+ return;
1739
+ }
1740
+ this.fallback(content);
1741
+ this._isHighlighting = true;
1742
+ try {
1743
+ const styledText = await treeSitterToStyledText(content, this._filetype, this._syntaxStyle, this._treeSitterClient);
1744
+ if (this.isDestroyed)
1745
+ return;
1746
+ this.textBuffer.setStyledText(styledText);
1747
+ this.updateTextInfo();
1748
+ } catch (error) {
1749
+ console.warn("Code highlighting failed, falling back to plain text:", error);
1750
+ this.fallback(content);
1751
+ } finally {
1752
+ this._isHighlighting = false;
1753
+ if (this._pendingRehighlight) {
1754
+ this._pendingRehighlight = false;
1755
+ process.nextTick(() => this.updateContent(this._content));
1756
+ }
1757
+ }
1758
+ }
1759
+ fallback(content) {
1760
+ const fallbackStyledText = this.createFallbackStyledText(content);
1761
+ if (this.isDestroyed)
1762
+ return;
1763
+ this.textBuffer.setStyledText(fallbackStyledText);
1764
+ this.updateTextInfo();
1765
+ }
1766
+ createFallbackStyledText(content) {
1767
+ const chunks = [
1768
+ {
1769
+ __isChunk: true,
1770
+ text: content,
1771
+ fg: this._defaultFg,
1772
+ bg: this._defaultBg,
1773
+ attributes: this._defaultAttributes
1774
+ }
1775
+ ];
1776
+ return new StyledText(chunks);
1777
+ }
1778
+ }
1410
1779
  // src/renderables/FrameBuffer.ts
1411
1780
  class FrameBufferRenderable extends Renderable {
1412
1781
  frameBuffer;
@@ -1647,6 +2016,9 @@ class TextNodeRenderable extends BaseRenderable {
1647
2016
  get attributes() {
1648
2017
  return this._attributes;
1649
2018
  }
2019
+ findDescendantById(id) {
2020
+ return;
2021
+ }
1650
2022
  }
1651
2023
 
1652
2024
  class RootTextNodeRenderable extends TextNodeRenderable {
@@ -1664,53 +2036,19 @@ class RootTextNodeRenderable extends TextNodeRenderable {
1664
2036
  }
1665
2037
 
1666
2038
  // src/renderables/Text.ts
1667
- class TextRenderable extends Renderable {
1668
- selectable = true;
2039
+ class TextRenderable extends TextBufferRenderable {
1669
2040
  _text;
1670
- _defaultFg;
1671
- _defaultBg;
1672
- _defaultAttributes;
1673
- _selectionBg;
1674
- _selectionFg;
1675
- _wrap = false;
1676
- _wrapMode = "word";
1677
- lastLocalSelection = null;
1678
- textBuffer;
1679
- _lineInfo = { lineStarts: [], lineWidths: [], maxLineWidth: 0 };
2041
+ _hasManualStyledText = false;
1680
2042
  rootTextNode;
1681
- _defaultOptions = {
1682
- content: "",
1683
- fg: RGBA.fromValues(1, 1, 1, 1),
1684
- bg: RGBA.fromValues(0, 0, 0, 0),
1685
- selectionBg: undefined,
1686
- selectionFg: undefined,
1687
- selectable: true,
1688
- attributes: 0,
1689
- wrap: true,
1690
- wrapMode: "word"
2043
+ _contentDefaultOptions = {
2044
+ content: ""
1691
2045
  };
1692
2046
  constructor(ctx, options) {
1693
2047
  super(ctx, options);
1694
- const content = options.content ?? this._defaultOptions.content;
2048
+ const content = options.content ?? this._contentDefaultOptions.content;
1695
2049
  const styledText = typeof content === "string" ? stringToStyledText(content) : content;
1696
2050
  this._text = styledText;
1697
- this._defaultFg = parseColor(options.fg ?? this._defaultOptions.fg);
1698
- this._defaultBg = parseColor(options.bg ?? this._defaultOptions.bg);
1699
- this._defaultAttributes = options.attributes ?? this._defaultOptions.attributes;
1700
- this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : this._defaultOptions.selectionBg;
1701
- this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : this._defaultOptions.selectionFg;
1702
- this.selectable = options.selectable ?? this._defaultOptions.selectable;
1703
- this._wrap = options.wrap ?? this._defaultOptions.wrap;
1704
- this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode;
1705
- this.textBuffer = TextBuffer.create(this._ctx.widthMethod);
1706
- this.textBuffer.setWrapMode(this._wrapMode);
1707
- if (this._wrap) {
1708
- this.textBuffer.setWrapWidth(this.width > 0 ? this.width : 40);
1709
- }
1710
- this.textBuffer.setDefaultFg(this._defaultFg);
1711
- this.textBuffer.setDefaultBg(this._defaultBg);
1712
- this.textBuffer.setDefaultAttributes(this._defaultAttributes);
1713
- this.setupMeasureFunc();
2051
+ this._hasManualStyledText = options.content !== undefined && content !== "";
1714
2052
  this.rootTextNode = new RootTextNodeRenderable(ctx, {
1715
2053
  id: `${this.id}-root`,
1716
2054
  fg: this._defaultFg,
@@ -1718,8 +2056,6 @@ class TextRenderable extends Renderable {
1718
2056
  attributes: this._defaultAttributes
1719
2057
  }, this);
1720
2058
  this.updateTextBuffer(styledText);
1721
- this._text.mount(this);
1722
- this.updateTextInfo();
1723
2059
  }
1724
2060
  updateTextBuffer(styledText) {
1725
2061
  this.textBuffer.setStyledText(styledText);
@@ -1729,12 +2065,6 @@ class TextRenderable extends Renderable {
1729
2065
  get content() {
1730
2066
  return this._text;
1731
2067
  }
1732
- get plainText() {
1733
- return this.textBuffer.getPlainText();
1734
- }
1735
- get textLength() {
1736
- return this.textBuffer.length;
1737
- }
1738
2068
  get chunks() {
1739
2069
  return this._text.chunks;
1740
2070
  }
@@ -1742,172 +2072,42 @@ class TextRenderable extends Renderable {
1742
2072
  return this.rootTextNode;
1743
2073
  }
1744
2074
  set content(value) {
2075
+ this._hasManualStyledText = true;
1745
2076
  const styledText = typeof value === "string" ? stringToStyledText(value) : value;
1746
2077
  if (this._text !== styledText) {
1747
2078
  this._text = styledText;
1748
- styledText.mount(this);
1749
2079
  this.updateTextBuffer(styledText);
1750
2080
  this.updateTextInfo();
1751
2081
  }
1752
2082
  }
1753
- get fg() {
1754
- return this._defaultFg;
1755
- }
1756
- set fg(value) {
1757
- const newColor = parseColor(value ?? this._defaultOptions.fg);
1758
- this.rootTextNode.fg = newColor;
1759
- if (this._defaultFg !== newColor) {
1760
- this._defaultFg = newColor;
1761
- this.textBuffer.setDefaultFg(this._defaultFg);
1762
- this.rootTextNode.fg = newColor;
1763
- this.requestRender();
1764
- }
1765
- }
1766
- get selectionBg() {
1767
- return this._selectionBg;
1768
- }
1769
- set selectionBg(value) {
1770
- const newColor = value ? parseColor(value) : this._defaultOptions.selectionBg;
1771
- if (this._selectionBg !== newColor) {
1772
- this._selectionBg = newColor;
1773
- if (this.lastLocalSelection) {
1774
- this.updateLocalSelection(this.lastLocalSelection);
1775
- }
1776
- this.requestRender();
1777
- }
1778
- }
1779
- get selectionFg() {
1780
- return this._selectionFg;
1781
- }
1782
- set selectionFg(value) {
1783
- const newColor = value ? parseColor(value) : this._defaultOptions.selectionFg;
1784
- if (this._selectionFg !== newColor) {
1785
- this._selectionFg = newColor;
1786
- if (this.lastLocalSelection) {
1787
- this.updateLocalSelection(this.lastLocalSelection);
1788
- }
1789
- this.requestRender();
1790
- }
1791
- }
1792
- get bg() {
1793
- return this._defaultBg;
1794
- }
1795
- set bg(value) {
1796
- const newColor = parseColor(value ?? this._defaultOptions.bg);
1797
- this.rootTextNode.bg = newColor;
1798
- if (this._defaultBg !== newColor) {
1799
- this._defaultBg = newColor;
1800
- this.textBuffer.setDefaultBg(this._defaultBg);
1801
- this.rootTextNode.bg = newColor;
1802
- this.requestRender();
1803
- }
1804
- }
1805
- get attributes() {
1806
- return this._defaultAttributes;
1807
- }
1808
- set attributes(value) {
1809
- if (this._defaultAttributes !== value) {
1810
- this._defaultAttributes = value;
1811
- this.textBuffer.setDefaultAttributes(this._defaultAttributes);
1812
- this.rootTextNode.attributes = value;
1813
- this.requestRender();
1814
- }
1815
- }
1816
- get wrap() {
1817
- return this._wrap;
1818
- }
1819
- set wrap(value) {
1820
- if (this._wrap !== value) {
1821
- this._wrap = value;
1822
- this.textBuffer.setWrapWidth(this._wrap ? this.width : null);
1823
- this.requestRender();
1824
- }
1825
- }
1826
- get wrapMode() {
1827
- return this._wrapMode;
1828
- }
1829
- set wrapMode(value) {
1830
- if (this._wrapMode !== value) {
1831
- this._wrapMode = value;
1832
- this.textBuffer.setWrapMode(this._wrapMode);
1833
- this.requestRender();
1834
- }
1835
- }
1836
- onResize(width, height) {
1837
- if (this._wrap) {
1838
- this.textBuffer.setWrapWidth(width);
1839
- this.updateTextInfo();
1840
- } else if (this.lastLocalSelection) {
1841
- const changed = this.updateLocalSelection(this.lastLocalSelection);
1842
- if (changed) {
1843
- this.requestRender();
1844
- }
1845
- }
1846
- }
1847
- updateLocalSelection(localSelection) {
1848
- if (!localSelection?.isActive) {
1849
- this.textBuffer.resetLocalSelection();
1850
- return true;
1851
- }
1852
- return this.textBuffer.setLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg);
1853
- }
1854
- updateTextInfo() {
1855
- const lineInfo = this.textBuffer.lineInfo;
1856
- this._lineInfo.lineStarts = lineInfo.lineStarts;
1857
- this._lineInfo.lineWidths = lineInfo.lineWidths;
1858
- this._lineInfo.maxLineWidth = lineInfo.maxLineWidth;
1859
- if (this.lastLocalSelection) {
1860
- const changed = this.updateLocalSelection(this.lastLocalSelection);
1861
- if (changed) {
1862
- this.requestRender();
1863
- }
1864
- }
1865
- this.yogaNode.markDirty();
1866
- this.requestRender();
1867
- }
1868
- setupMeasureFunc() {
1869
- const measureFunc = (width, widthMode, height, heightMode) => {
1870
- const maxLineWidth = this._lineInfo.maxLineWidth;
1871
- const numLines = this._lineInfo.lineStarts.length;
1872
- let measuredWidth = maxLineWidth;
1873
- let measuredHeight = numLines;
1874
- return {
1875
- width: Math.max(1, measuredWidth),
1876
- height: Math.max(1, measuredHeight)
1877
- };
1878
- };
1879
- this.yogaNode.setMeasureFunc(measureFunc);
1880
- }
1881
2083
  insertChunk(chunk, index) {
1882
- this.textBuffer.insertChunkGroup(index ?? this.textBuffer.chunkGroupCount, chunk.text, chunk.fg, chunk.bg, chunk.attributes);
1883
- this.updateTextInfo();
2084
+ super.insertChunk(chunk, index);
1884
2085
  this.clearChunks(this._text);
1885
2086
  }
1886
- removeChunk(chunk) {
2087
+ removeChunkByObject(chunk) {
1887
2088
  const index = this._text.chunks.indexOf(chunk);
1888
2089
  if (index === -1)
1889
2090
  return;
1890
- this.textBuffer.removeChunkGroup(index);
1891
- this.updateTextInfo();
2091
+ super.removeChunk(index);
1892
2092
  this.clearChunks(this._text);
1893
2093
  }
1894
- replaceChunk(chunk, oldChunk) {
2094
+ replaceChunkByObject(chunk, oldChunk) {
1895
2095
  const index = this._text.chunks.indexOf(oldChunk);
1896
2096
  if (index === -1)
1897
2097
  return;
1898
- this.textBuffer.replaceChunkGroup(index, chunk.text, chunk.fg, chunk.bg, chunk.attributes);
1899
- this.updateTextInfo();
2098
+ super.replaceChunk(index, chunk);
1900
2099
  this.clearChunks(this._text);
1901
2100
  }
1902
2101
  updateTextFromNodes() {
1903
- if (this.rootTextNode.isDirty) {
2102
+ if (this.rootTextNode.isDirty && !this._hasManualStyledText) {
1904
2103
  const chunks = this.rootTextNode.gatherWithInheritedStyle({
1905
2104
  fg: this._defaultFg,
1906
2105
  bg: this._defaultBg,
1907
2106
  attributes: this._defaultAttributes
1908
2107
  });
1909
2108
  this.textBuffer.setStyledText(new StyledText(chunks));
1910
- this.updateTextInfo();
2109
+ this.refreshLocalSelection();
2110
+ this.yogaNode.markDirty();
1911
2111
  }
1912
2112
  }
1913
2113
  add(obj, index) {
@@ -1930,59 +2130,23 @@ class TextRenderable extends Renderable {
1930
2130
  this.rootTextNode.clear();
1931
2131
  const emptyStyledText = stringToStyledText("");
1932
2132
  this._text = emptyStyledText;
1933
- emptyStyledText.mount(this);
1934
2133
  this.updateTextBuffer(emptyStyledText);
1935
2134
  this.updateTextInfo();
1936
2135
  this.requestRender();
1937
2136
  }
1938
- shouldStartSelection(x, y) {
1939
- if (!this.selectable)
1940
- return false;
1941
- const localX = x - this.x;
1942
- const localY = y - this.y;
1943
- return localX >= 0 && localX < this.width && localY >= 0 && localY < this.height;
1944
- }
1945
- onSelectionChanged(selection) {
1946
- const localSelection = convertGlobalToLocalSelection(selection, this.x, this.y);
1947
- this.lastLocalSelection = localSelection;
1948
- const changed = this.updateLocalSelection(localSelection);
1949
- if (changed) {
1950
- this.requestRender();
1951
- }
1952
- return this.hasSelection();
1953
- }
1954
- getSelectedText() {
1955
- return this.textBuffer.getSelectedText();
1956
- }
1957
- hasSelection() {
1958
- return this.textBuffer.hasSelection();
1959
- }
1960
- getSelection() {
1961
- return this.textBuffer.getSelection();
1962
- }
1963
2137
  onLifecyclePass = () => {
1964
2138
  this.updateTextFromNodes();
1965
2139
  };
1966
- render(buffer, deltaTime) {
1967
- if (!this.visible)
1968
- return;
1969
- this.markClean();
1970
- this._ctx.addToHitGrid(this.x, this.y, this.width, this.height, this.num);
1971
- this.renderSelf(buffer);
2140
+ onFgChanged(newColor) {
2141
+ this.rootTextNode.fg = newColor;
1972
2142
  }
1973
- renderSelf(buffer) {
1974
- if (this.textBuffer.ptr) {
1975
- const clipRect = {
1976
- x: this.x,
1977
- y: this.y,
1978
- width: this.width,
1979
- height: this.height
1980
- };
1981
- buffer.drawTextBuffer(this.textBuffer, this.x, this.y, clipRect);
1982
- }
2143
+ onBgChanged(newColor) {
2144
+ this.rootTextNode.bg = newColor;
2145
+ }
2146
+ onAttributesChanged(newAttributes) {
2147
+ this.rootTextNode.attributes = newAttributes;
1983
2148
  }
1984
2149
  destroy() {
1985
- this.textBuffer.destroy();
1986
2150
  this.rootTextNode.children.length = 0;
1987
2151
  super.destroy();
1988
2152
  }
@@ -2003,6 +2167,7 @@ class ASCIIFontRenderable extends FrameBufferRenderable {
2003
2167
  const text = options.text || "";
2004
2168
  const measurements = measureText({ text, font });
2005
2169
  super(ctx, {
2170
+ flexShrink: 0,
2006
2171
  ...options,
2007
2172
  width: measurements.width || 1,
2008
2173
  height: measurements.height || 1,
@@ -3052,7 +3217,7 @@ class SliderRenderable extends Renderable {
3052
3217
  _foregroundColor;
3053
3218
  _onChange;
3054
3219
  constructor(ctx, options) {
3055
- super(ctx, options);
3220
+ super(ctx, { flexShrink: 0, ...options });
3056
3221
  this.orientation = options.orientation;
3057
3222
  this._min = options.min ?? 0;
3058
3223
  this._max = options.max ?? 100;
@@ -3661,6 +3826,7 @@ class ScrollBoxRenderable extends BoxRenderable {
3661
3826
  _stickyScrollRight = false;
3662
3827
  _stickyStart;
3663
3828
  _hasManualScroll = false;
3829
+ scrollAccel;
3664
3830
  get stickyScroll() {
3665
3831
  return this._stickyScroll;
3666
3832
  }
@@ -3759,10 +3925,10 @@ class ScrollBoxRenderable extends BoxRenderable {
3759
3925
  stickyStart,
3760
3926
  scrollX = false,
3761
3927
  scrollY = true,
3928
+ scrollAcceleration,
3762
3929
  ...options
3763
3930
  }) {
3764
3931
  super(ctx, {
3765
- flexShrink: 1,
3766
3932
  flexDirection: "row",
3767
3933
  alignItems: "stretch",
3768
3934
  ...options,
@@ -3771,10 +3937,15 @@ class ScrollBoxRenderable extends BoxRenderable {
3771
3937
  this.internalId = ScrollBoxRenderable.idCounter++;
3772
3938
  this._stickyScroll = stickyScroll;
3773
3939
  this._stickyStart = stickyStart;
3940
+ if (scrollAcceleration) {
3941
+ this.scrollAccel = scrollAcceleration;
3942
+ } else if (process.platform === "darwin") {
3943
+ this.scrollAccel = new MacOSScrollAccel;
3944
+ }
3945
+ this.scrollAccel ??= new LinearScrollAccel;
3774
3946
  this.wrapper = new BoxRenderable(ctx, {
3775
3947
  flexDirection: "column",
3776
3948
  flexGrow: 1,
3777
- flexShrink: 1,
3778
3949
  ...wrapperOptions,
3779
3950
  id: `scroll-box-wrapper-${this.internalId}`
3780
3951
  });
@@ -3782,7 +3953,6 @@ class ScrollBoxRenderable extends BoxRenderable {
3782
3953
  this.viewport = new BoxRenderable(ctx, {
3783
3954
  flexDirection: "column",
3784
3955
  flexGrow: 1,
3785
- flexShrink: 1,
3786
3956
  overflow: "hidden",
3787
3957
  onSizeChange: () => {
3788
3958
  this.recalculateBarProps();
@@ -3793,6 +3963,7 @@ class ScrollBoxRenderable extends BoxRenderable {
3793
3963
  this.wrapper.add(this.viewport);
3794
3964
  this.content = new ContentRenderable(ctx, this.viewport, {
3795
3965
  alignSelf: "flex-start",
3966
+ flexShrink: 0,
3796
3967
  ...scrollX ? { minWidth: "100%" } : { minWidth: "100%", maxWidth: "100%" },
3797
3968
  ...scrollY ? { minHeight: "100%" } : { minHeight: "100%", maxHeight: "100%" },
3798
3969
  onSizeChange: () => {
@@ -3869,6 +4040,9 @@ class ScrollBoxRenderable extends BoxRenderable {
3869
4040
  add(obj, index) {
3870
4041
  return this.content.add(obj, index);
3871
4042
  }
4043
+ insertBefore(obj, anchor) {
4044
+ return this.content.insertBefore(obj, anchor);
4045
+ }
3872
4046
  remove(id) {
3873
4047
  this.content.remove(id);
3874
4048
  }
@@ -3880,14 +4054,18 @@ class ScrollBoxRenderable extends BoxRenderable {
3880
4054
  let dir = event.scroll?.direction;
3881
4055
  if (event.modifiers.shift)
3882
4056
  dir = dir === "up" ? "left" : dir === "down" ? "right" : dir === "right" ? "down" : "up";
3883
- if (dir === "up")
3884
- this.scrollTop -= event.scroll?.delta ?? 0;
3885
- else if (dir === "down")
3886
- this.scrollTop += event.scroll?.delta ?? 0;
3887
- else if (dir === "left")
3888
- this.scrollLeft -= event.scroll?.delta ?? 0;
3889
- else if (dir === "right")
3890
- this.scrollLeft += event.scroll?.delta ?? 0;
4057
+ const baseDelta = event.scroll?.delta ?? 0;
4058
+ const now = Date.now();
4059
+ const multiplier = this.scrollAccel.tick(now);
4060
+ if (dir === "up") {
4061
+ this.scrollTop -= baseDelta * multiplier;
4062
+ } else if (dir === "down") {
4063
+ this.scrollTop += baseDelta * multiplier;
4064
+ } else if (dir === "left") {
4065
+ this.scrollLeft -= baseDelta * multiplier;
4066
+ } else if (dir === "right") {
4067
+ this.scrollLeft += baseDelta * multiplier;
4068
+ }
3891
4069
  this._hasManualScroll = true;
3892
4070
  }
3893
4071
  if (event.type === "drag" && event.isSelecting) {
@@ -3899,10 +4077,12 @@ class ScrollBoxRenderable extends BoxRenderable {
3899
4077
  handleKeyPress(key) {
3900
4078
  if (this.verticalScrollBar.handleKeyPress(key)) {
3901
4079
  this._hasManualScroll = true;
4080
+ this.scrollAccel.reset();
3902
4081
  return true;
3903
4082
  }
3904
4083
  if (this.horizontalScrollBar.handleKeyPress(key)) {
3905
4084
  this._hasManualScroll = true;
4085
+ this.scrollAccel.reset();
3906
4086
  return true;
3907
4087
  }
3908
4088
  return false;
@@ -4152,7 +4332,10 @@ export {
4152
4332
  white,
4153
4333
  vstyles,
4154
4334
  visualizeRenderableTree,
4335
+ main as updateAssets,
4155
4336
  underline,
4337
+ treeSitterToTextChunks,
4338
+ treeSitterToStyledText,
4156
4339
  t,
4157
4340
  stringToStyledText,
4158
4341
  strikethrough,
@@ -4161,7 +4344,9 @@ export {
4161
4344
  reverse,
4162
4345
  resolveRenderLib,
4163
4346
  renderFontToFrameBuffer,
4347
+ registerEnvVar,
4164
4348
  red,
4349
+ pathToFiletype,
4165
4350
  parseWrap,
4166
4351
  parseUnit,
4167
4352
  parsePositionType,
@@ -4194,12 +4379,18 @@ export {
4194
4379
  hastToStyledText,
4195
4380
  h,
4196
4381
  green,
4197
- getKeyHandler,
4382
+ getTreeSitterClient,
4383
+ getDataPaths,
4198
4384
  getCharacterPositions,
4199
4385
  getBorderSides,
4200
4386
  getBorderFromSides,
4387
+ generateEnvMarkdown,
4388
+ generateEnvColored,
4201
4389
  fonts,
4202
4390
  fg,
4391
+ extToFiletype,
4392
+ envRegistry,
4393
+ env,
4203
4394
  engine,
4204
4395
  dim,
4205
4396
  delegate,
@@ -4208,7 +4399,9 @@ export {
4208
4399
  createTextAttributes,
4209
4400
  createCliRenderer,
4210
4401
  coordinateToCharacterIndex,
4402
+ convertThemeToStyles,
4211
4403
  convertGlobalToLocalSelection,
4404
+ clearEnvCache,
4212
4405
  capture,
4213
4406
  brightYellow,
4214
4407
  brightWhite,
@@ -4239,12 +4432,15 @@ export {
4239
4432
  applyGrayscale,
4240
4433
  applyChromaticAberration,
4241
4434
  applyAsciiArt,
4435
+ addDefaultParsers,
4242
4436
  exports_src as Yoga,
4243
4437
  VignetteEffect,
4244
4438
  VRenderable,
4439
+ TreeSitterClient,
4245
4440
  Timeline,
4246
4441
  TextRenderable,
4247
4442
  TextNodeRenderable,
4443
+ TextBufferRenderable,
4248
4444
  TextBuffer,
4249
4445
  TextAttributes,
4250
4446
  Text,
@@ -4265,13 +4461,18 @@ export {
4265
4461
  RenderableEvents,
4266
4462
  Renderable,
4267
4463
  RGBA,
4464
+ PasteEvent,
4268
4465
  OptimizedBuffer,
4269
4466
  MouseParser,
4270
4467
  MouseEvent,
4271
4468
  MouseButton,
4469
+ MacOSScrollAccel,
4272
4470
  LogLevel,
4471
+ LinearScrollAccel,
4273
4472
  LayoutEvents,
4274
4473
  KeyHandler,
4474
+ KeyEvent,
4475
+ InternalKeyHandler,
4275
4476
  InputRenderableEvents,
4276
4477
  InputRenderable,
4277
4478
  Input,
@@ -4280,7 +4481,9 @@ export {
4280
4481
  FrameBuffer,
4281
4482
  DistortionEffect,
4282
4483
  DebugOverlayCorner,
4484
+ DataPathsManager,
4283
4485
  ConsolePosition,
4486
+ CodeRenderable,
4284
4487
  CliRenderer,
4285
4488
  CliRenderEvents,
4286
4489
  BrightnessEffect,
@@ -4297,5 +4500,5 @@ export {
4297
4500
  ASCIIFont
4298
4501
  };
4299
4502
 
4300
- //# debugId=5FB73C20BB0792E864756E2164756E21
4503
+ //# debugId=F1FAFC796A264ABA64756E2164756E21
4301
4504
  //# sourceMappingURL=index.js.map