r2ui 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +64 -0
  3. data/README.md +79 -0
  4. data/lib/r2ui/app.rb +311 -34
  5. data/lib/r2ui/canvas.rb +135 -14
  6. data/lib/r2ui/cli/builder.rb +72 -0
  7. data/lib/r2ui/cli/context.rb +45 -0
  8. data/lib/r2ui/cli/definition.rb +174 -0
  9. data/lib/r2ui/cli/ext/ask.rb +133 -0
  10. data/lib/r2ui/cli/ext/box.rb +112 -0
  11. data/lib/r2ui/cli/ext/choose.rb +162 -0
  12. data/lib/r2ui/cli/ext/choose_many.rb +241 -0
  13. data/lib/r2ui/cli/ext/color_option.rb +64 -0
  14. data/lib/r2ui/cli/ext/completion.rb +520 -0
  15. data/lib/r2ui/cli/ext/config.rb +179 -0
  16. data/lib/r2ui/cli/ext/confirm.rb +110 -0
  17. data/lib/r2ui/cli/ext/dashboard.rb +105 -0
  18. data/lib/r2ui/cli/ext/diff.rb +195 -0
  19. data/lib/r2ui/cli/ext/editor.rb +94 -0
  20. data/lib/r2ui/cli/ext/env.rb +108 -0
  21. data/lib/r2ui/cli/ext/examples.rb +62 -0
  22. data/lib/r2ui/cli/ext/filter.rb +269 -0
  23. data/lib/r2ui/cli/ext/format.rb +104 -0
  24. data/lib/r2ui/cli/ext/list.rb +117 -0
  25. data/lib/r2ui/cli/ext/log.rb +89 -0
  26. data/lib/r2ui/cli/ext/pager.rb +97 -0
  27. data/lib/r2ui/cli/ext/pairs.rb +62 -0
  28. data/lib/r2ui/cli/ext/parallel.rb +274 -0
  29. data/lib/r2ui/cli/ext/password.rb +158 -0
  30. data/lib/r2ui/cli/ext/progress.rb +330 -0
  31. data/lib/r2ui/cli/ext/reference.rb +129 -0
  32. data/lib/r2ui/cli/ext/spinner.rb +165 -0
  33. data/lib/r2ui/cli/ext/summary.rb +63 -0
  34. data/lib/r2ui/cli/ext/table.rb +141 -0
  35. data/lib/r2ui/cli/ext/tasks.rb +216 -0
  36. data/lib/r2ui/cli/ext/trace.rb +64 -0
  37. data/lib/r2ui/cli/ext/tree.rb +114 -0
  38. data/lib/r2ui/cli/ext/version.rb +67 -0
  39. data/lib/r2ui/cli/extension.rb +129 -0
  40. data/lib/r2ui/cli/help.rb +115 -0
  41. data/lib/r2ui/cli/helpers.rb +20 -0
  42. data/lib/r2ui/cli/live.rb +150 -0
  43. data/lib/r2ui/cli/parser.rb +165 -0
  44. data/lib/r2ui/cli/prompt.rb +133 -0
  45. data/lib/r2ui/cli/runner.rb +86 -0
  46. data/lib/r2ui/cli/shell.rb +185 -0
  47. data/lib/r2ui/cli/testing.rb +49 -0
  48. data/lib/r2ui/cli.rb +129 -0
  49. data/lib/r2ui/compat/bubbletea/LICENSE-bubbletea.txt +21 -0
  50. data/lib/r2ui/compat/bubbletea/ansi.rb +424 -0
  51. data/lib/r2ui/compat/bubbletea/commands.rb +143 -0
  52. data/lib/r2ui/compat/bubbletea/input.rb +269 -0
  53. data/lib/r2ui/compat/bubbletea/input_reader.rb +66 -0
  54. data/lib/r2ui/compat/bubbletea/messages.rb +251 -0
  55. data/lib/r2ui/compat/bubbletea/model.rb +65 -0
  56. data/lib/r2ui/compat/bubbletea/native.rb +254 -0
  57. data/lib/r2ui/compat/bubbletea/renderer.rb +192 -0
  58. data/lib/r2ui/compat/bubbletea/runner.rb +425 -0
  59. data/lib/r2ui/compat/bubbletea/terminal.rb +230 -0
  60. data/lib/r2ui/compat/bubbletea/version.rb +8 -0
  61. data/lib/r2ui/compat/bubbletea/width_table.rb +228 -0
  62. data/lib/r2ui/compat/bubbletea.rb +16 -0
  63. data/lib/r2ui/compat/lipgloss/border.rb +17 -0
  64. data/lib/r2ui/compat/lipgloss/color.rb +78 -0
  65. data/lib/r2ui/compat/lipgloss/color_blend.rb +166 -0
  66. data/lib/r2ui/compat/lipgloss/colorful.rb +585 -0
  67. data/lib/r2ui/compat/lipgloss/layout.rb +461 -0
  68. data/lib/r2ui/compat/lipgloss/list.rb +85 -0
  69. data/lib/r2ui/compat/lipgloss/position.rb +30 -0
  70. data/lib/r2ui/compat/lipgloss/style/border.rb +134 -0
  71. data/lib/r2ui/compat/lipgloss/style.rb +1062 -0
  72. data/lib/r2ui/compat/lipgloss/table/render.rb +518 -0
  73. data/lib/r2ui/compat/lipgloss/table.rb +185 -0
  74. data/lib/r2ui/compat/lipgloss/termenv.rb +768 -0
  75. data/lib/r2ui/compat/lipgloss/text/unicode_tables.rb +428 -0
  76. data/lib/r2ui/compat/lipgloss/text.rb +1555 -0
  77. data/lib/r2ui/compat/lipgloss/tree/go_tree.rb +243 -0
  78. data/lib/r2ui/compat/lipgloss/tree.rb +105 -0
  79. data/lib/r2ui/compat/lipgloss/version.rb +15 -0
  80. data/lib/r2ui/compat/lipgloss.rb +64 -0
  81. data/lib/r2ui/compat/load_path/bubbletea.rb +4 -0
  82. data/lib/r2ui/compat/load_path/lipgloss.rb +4 -0
  83. data/lib/r2ui/component.rb +67 -0
  84. data/lib/r2ui/context.rb +87 -0
  85. data/lib/r2ui/drop_in.rb +16 -0
  86. data/lib/r2ui/dsl/column.rb +11 -3
  87. data/lib/r2ui/dsl/dashboard.rb +45 -9
  88. data/lib/r2ui/dsl/resource.rb +12 -0
  89. data/lib/r2ui/ext/after.rb +54 -0
  90. data/lib/r2ui/ext/async.rb +81 -0
  91. data/lib/r2ui/ext/batch_sequence.rb +54 -0
  92. data/lib/r2ui/ext/countdown.rb +52 -0
  93. data/lib/r2ui/ext/data_table.rb +71 -0
  94. data/lib/r2ui/ext/every.rb +66 -0
  95. data/lib/r2ui/ext/exec.rb +116 -0
  96. data/lib/r2ui/ext/file_picker.rb +78 -0
  97. data/lib/r2ui/ext/focus_report.rb +69 -0
  98. data/lib/r2ui/ext/help.rb +62 -0
  99. data/lib/r2ui/ext/keys.rb +64 -0
  100. data/lib/r2ui/ext/list.rb +145 -0
  101. data/lib/r2ui/ext/messages.rb +87 -0
  102. data/lib/r2ui/ext/mouse.rb +134 -0
  103. data/lib/r2ui/ext/paginator.rb +86 -0
  104. data/lib/r2ui/ext/paste.rb +86 -0
  105. data/lib/r2ui/ext/println.rb +21 -0
  106. data/lib/r2ui/ext/progress.rb +85 -0
  107. data/lib/r2ui/ext/refresh.rb +56 -0
  108. data/lib/r2ui/ext/resize.rb +62 -0
  109. data/lib/r2ui/ext/screen.rb +47 -0
  110. data/lib/r2ui/ext/screen_mode.rb +63 -0
  111. data/lib/r2ui/ext/spinner.rb +59 -0
  112. data/lib/r2ui/ext/state.rb +45 -0
  113. data/lib/r2ui/ext/stopwatch.rb +67 -0
  114. data/lib/r2ui/ext/suspend.rb +56 -0
  115. data/lib/r2ui/ext/text_area.rb +73 -0
  116. data/lib/r2ui/ext/text_input.rb +83 -0
  117. data/lib/r2ui/ext/theme.rb +112 -0
  118. data/lib/r2ui/ext/view.rb +37 -0
  119. data/lib/r2ui/ext/viewport.rb +92 -0
  120. data/lib/r2ui/ext/window_title.rb +51 -0
  121. data/lib/r2ui/extension.rb +199 -0
  122. data/lib/r2ui/history.rb +4 -1
  123. data/lib/r2ui/keys.rb +35 -8
  124. data/lib/r2ui/motion.rb +169 -0
  125. data/lib/r2ui/panel_state.rb +46 -2
  126. data/lib/r2ui/renderer.rb +87 -22
  127. data/lib/r2ui/version.rb +1 -1
  128. data/lib/r2ui/widgets/box.rb +6 -3
  129. data/lib/r2ui/widgets/glyphs.rb +149 -0
  130. data/lib/r2ui/widgets/table.rb +109 -25
  131. data/lib/r2ui.rb +12 -1
  132. metadata +119 -4
  133. data/lib/r2ui/terminal.rb +0 -53
@@ -0,0 +1,228 @@
1
+ # frozen_string_literal: true
2
+
3
+ module R2UI
4
+ module Compat
5
+ module Tea
6
+ # Per-codepoint cell widths as rivo/uniseg v0.4.7 (used by
7
+ # charmbracelet/x/ansi v0.8.0) computes them. Recorded from the real
8
+ # bubbletea 0.1.4 gem's `Program#string_width` for every codepoint.
9
+ module WidthTable
10
+ # [first, last, width] for every codepoint whose width is not 1.
11
+ WIDTHS = [
12
+ [0x00000, 0x0001F, 0], [0x0007F, 0x0009F, 0], [0x000AD, 0x000AD, 0],
13
+ [0x00300, 0x0036F, 0], [0x00483, 0x00489, 0], [0x00591, 0x005BD, 0],
14
+ [0x005BF, 0x005BF, 0], [0x005C1, 0x005C2, 0], [0x005C4, 0x005C5, 0],
15
+ [0x005C7, 0x005C7, 0], [0x00610, 0x0061A, 0], [0x0061C, 0x0061C, 0],
16
+ [0x0064B, 0x0065F, 0], [0x00670, 0x00670, 0], [0x006D6, 0x006DC, 0],
17
+ [0x006DF, 0x006E4, 0], [0x006E7, 0x006E8, 0], [0x006EA, 0x006ED, 0],
18
+ [0x00711, 0x00711, 0], [0x00730, 0x0074A, 0], [0x007A6, 0x007B0, 0],
19
+ [0x007EB, 0x007F3, 0], [0x007FD, 0x007FD, 0], [0x00816, 0x00819, 0],
20
+ [0x0081B, 0x00823, 0], [0x00825, 0x00827, 0], [0x00829, 0x0082D, 0],
21
+ [0x00859, 0x0085B, 0], [0x00898, 0x0089F, 0], [0x008CA, 0x008E1, 0],
22
+ [0x008E3, 0x00902, 0], [0x0093A, 0x0093A, 0], [0x0093C, 0x0093C, 0],
23
+ [0x00941, 0x00948, 0], [0x0094D, 0x0094D, 0], [0x00951, 0x00957, 0],
24
+ [0x00962, 0x00963, 0], [0x00981, 0x00981, 0], [0x009BC, 0x009BC, 0],
25
+ [0x009BE, 0x009BE, 0], [0x009C1, 0x009C4, 0], [0x009CD, 0x009CD, 0],
26
+ [0x009D7, 0x009D7, 0], [0x009E2, 0x009E3, 0], [0x009FE, 0x009FE, 0],
27
+ [0x00A01, 0x00A02, 0], [0x00A3C, 0x00A3C, 0], [0x00A41, 0x00A42, 0],
28
+ [0x00A47, 0x00A48, 0], [0x00A4B, 0x00A4D, 0], [0x00A51, 0x00A51, 0],
29
+ [0x00A70, 0x00A71, 0], [0x00A75, 0x00A75, 0], [0x00A81, 0x00A82, 0],
30
+ [0x00ABC, 0x00ABC, 0], [0x00AC1, 0x00AC5, 0], [0x00AC7, 0x00AC8, 0],
31
+ [0x00ACD, 0x00ACD, 0], [0x00AE2, 0x00AE3, 0], [0x00AFA, 0x00AFF, 0],
32
+ [0x00B01, 0x00B01, 0], [0x00B3C, 0x00B3C, 0], [0x00B3E, 0x00B3F, 0],
33
+ [0x00B41, 0x00B44, 0], [0x00B4D, 0x00B4D, 0], [0x00B55, 0x00B57, 0],
34
+ [0x00B62, 0x00B63, 0], [0x00B82, 0x00B82, 0], [0x00BBE, 0x00BBE, 0],
35
+ [0x00BC0, 0x00BC0, 0], [0x00BCD, 0x00BCD, 0], [0x00BD7, 0x00BD7, 0],
36
+ [0x00C00, 0x00C00, 0], [0x00C04, 0x00C04, 0], [0x00C3C, 0x00C3C, 0],
37
+ [0x00C3E, 0x00C40, 0], [0x00C46, 0x00C48, 0], [0x00C4A, 0x00C4D, 0],
38
+ [0x00C55, 0x00C56, 0], [0x00C62, 0x00C63, 0], [0x00C81, 0x00C81, 0],
39
+ [0x00CBC, 0x00CBC, 0], [0x00CBF, 0x00CBF, 0], [0x00CC2, 0x00CC2, 0],
40
+ [0x00CC6, 0x00CC6, 0], [0x00CCC, 0x00CCD, 0], [0x00CD5, 0x00CD6, 0],
41
+ [0x00CE2, 0x00CE3, 0], [0x00D00, 0x00D01, 0], [0x00D3B, 0x00D3C, 0],
42
+ [0x00D3E, 0x00D3E, 0], [0x00D41, 0x00D44, 0], [0x00D4D, 0x00D4D, 0],
43
+ [0x00D57, 0x00D57, 0], [0x00D62, 0x00D63, 0], [0x00D81, 0x00D81, 0],
44
+ [0x00DCA, 0x00DCA, 0], [0x00DCF, 0x00DCF, 0], [0x00DD2, 0x00DD4, 0],
45
+ [0x00DD6, 0x00DD6, 0], [0x00DDF, 0x00DDF, 0], [0x00E31, 0x00E31, 0],
46
+ [0x00E34, 0x00E3A, 0], [0x00E47, 0x00E4E, 0], [0x00EB1, 0x00EB1, 0],
47
+ [0x00EB4, 0x00EBC, 0], [0x00EC8, 0x00ECE, 0], [0x00F18, 0x00F19, 0],
48
+ [0x00F35, 0x00F35, 0], [0x00F37, 0x00F37, 0], [0x00F39, 0x00F39, 0],
49
+ [0x00F71, 0x00F7E, 0], [0x00F80, 0x00F84, 0], [0x00F86, 0x00F87, 0],
50
+ [0x00F8D, 0x00F97, 0], [0x00F99, 0x00FBC, 0], [0x00FC6, 0x00FC6, 0],
51
+ [0x0102D, 0x01030, 0], [0x01032, 0x01037, 0], [0x01039, 0x0103A, 0],
52
+ [0x0103D, 0x0103E, 0], [0x01058, 0x01059, 0], [0x0105E, 0x01060, 0],
53
+ [0x01071, 0x01074, 0], [0x01082, 0x01082, 0], [0x01085, 0x01086, 0],
54
+ [0x0108D, 0x0108D, 0], [0x0109D, 0x0109D, 0], [0x01100, 0x0115F, 2],
55
+ [0x0135D, 0x0135F, 0], [0x01712, 0x01714, 0], [0x01732, 0x01733, 0],
56
+ [0x01752, 0x01753, 0], [0x01772, 0x01773, 0], [0x017B4, 0x017B5, 0],
57
+ [0x017B7, 0x017BD, 0], [0x017C6, 0x017C6, 0], [0x017C9, 0x017D3, 0],
58
+ [0x017DD, 0x017DD, 0], [0x0180B, 0x0180F, 0], [0x01885, 0x01886, 0],
59
+ [0x018A9, 0x018A9, 0], [0x01920, 0x01922, 0], [0x01927, 0x01928, 0],
60
+ [0x01932, 0x01932, 0], [0x01939, 0x0193B, 0], [0x01A17, 0x01A18, 0],
61
+ [0x01A1B, 0x01A1B, 0], [0x01A56, 0x01A56, 0], [0x01A58, 0x01A5E, 0],
62
+ [0x01A60, 0x01A60, 0], [0x01A62, 0x01A62, 0], [0x01A65, 0x01A6C, 0],
63
+ [0x01A73, 0x01A7C, 0], [0x01A7F, 0x01A7F, 0], [0x01AB0, 0x01ACE, 0],
64
+ [0x01B00, 0x01B03, 0], [0x01B34, 0x01B3A, 0], [0x01B3C, 0x01B3C, 0],
65
+ [0x01B42, 0x01B42, 0], [0x01B6B, 0x01B73, 0], [0x01B80, 0x01B81, 0],
66
+ [0x01BA2, 0x01BA5, 0], [0x01BA8, 0x01BA9, 0], [0x01BAB, 0x01BAD, 0],
67
+ [0x01BE6, 0x01BE6, 0], [0x01BE8, 0x01BE9, 0], [0x01BED, 0x01BED, 0],
68
+ [0x01BEF, 0x01BF1, 0], [0x01C2C, 0x01C33, 0], [0x01C36, 0x01C37, 0],
69
+ [0x01CD0, 0x01CD2, 0], [0x01CD4, 0x01CE0, 0], [0x01CE2, 0x01CE8, 0],
70
+ [0x01CED, 0x01CED, 0], [0x01CF4, 0x01CF4, 0], [0x01CF8, 0x01CF9, 0],
71
+ [0x01DC0, 0x01DFF, 0], [0x0200B, 0x0200F, 0], [0x02028, 0x0202E, 0],
72
+ [0x02060, 0x0206F, 0], [0x020D0, 0x020F0, 0], [0x0231A, 0x0231B, 2],
73
+ [0x02329, 0x0232A, 2], [0x023E9, 0x023EC, 2], [0x023F0, 0x023F0, 2],
74
+ [0x023F3, 0x023F3, 2], [0x025FD, 0x025FE, 2], [0x02614, 0x02615, 2],
75
+ [0x02648, 0x02653, 2], [0x0267F, 0x0267F, 2], [0x02693, 0x02693, 2],
76
+ [0x026A1, 0x026A1, 2], [0x026AA, 0x026AB, 2], [0x026BD, 0x026BE, 2],
77
+ [0x026C4, 0x026C5, 2], [0x026CE, 0x026CE, 2], [0x026D4, 0x026D4, 2],
78
+ [0x026EA, 0x026EA, 2], [0x026F2, 0x026F3, 2], [0x026F5, 0x026F5, 2],
79
+ [0x026FA, 0x026FA, 2], [0x026FD, 0x026FD, 2], [0x02705, 0x02705, 2],
80
+ [0x0270A, 0x0270B, 2], [0x02728, 0x02728, 2], [0x0274C, 0x0274C, 2],
81
+ [0x0274E, 0x0274E, 2], [0x02753, 0x02755, 2], [0x02757, 0x02757, 2],
82
+ [0x02795, 0x02797, 2], [0x027B0, 0x027B0, 2], [0x027BF, 0x027BF, 2],
83
+ [0x02B1B, 0x02B1C, 2], [0x02B50, 0x02B50, 2], [0x02B55, 0x02B55, 2],
84
+ [0x02CEF, 0x02CF1, 0], [0x02D7F, 0x02D7F, 0], [0x02DE0, 0x02DFF, 0],
85
+ [0x02E3A, 0x02E3A, 3], [0x02E3B, 0x02E3B, 4], [0x02E80, 0x02E99, 2],
86
+ [0x02E9B, 0x02EF3, 2], [0x02F00, 0x02FD5, 2], [0x02FF0, 0x02FFB, 2],
87
+ [0x03000, 0x03029, 2], [0x0302A, 0x0302F, 0], [0x03031, 0x0303C, 2],
88
+ [0x0303E, 0x0303E, 2], [0x03041, 0x03096, 2], [0x03099, 0x0309A, 0],
89
+ [0x0309B, 0x030FF, 2], [0x03105, 0x0312F, 2], [0x03131, 0x0318E, 2],
90
+ [0x03190, 0x031E3, 2], [0x031F0, 0x0321E, 2], [0x03220, 0x03247, 2],
91
+ [0x03250, 0x03296, 2], [0x03298, 0x03298, 2], [0x0329A, 0x04DBF, 2],
92
+ [0x04E00, 0x0A48C, 2], [0x0A490, 0x0A4C6, 2], [0x0A66F, 0x0A672, 0],
93
+ [0x0A674, 0x0A67D, 0], [0x0A69E, 0x0A69F, 0], [0x0A6F0, 0x0A6F1, 0],
94
+ [0x0A802, 0x0A802, 0], [0x0A806, 0x0A806, 0], [0x0A80B, 0x0A80B, 0],
95
+ [0x0A825, 0x0A826, 0], [0x0A82C, 0x0A82C, 0], [0x0A8C4, 0x0A8C5, 0],
96
+ [0x0A8E0, 0x0A8F1, 0], [0x0A8FF, 0x0A8FF, 0], [0x0A926, 0x0A92D, 0],
97
+ [0x0A947, 0x0A951, 0], [0x0A960, 0x0A97C, 2], [0x0A980, 0x0A982, 0],
98
+ [0x0A9B3, 0x0A9B3, 0], [0x0A9B6, 0x0A9B9, 0], [0x0A9BC, 0x0A9BD, 0],
99
+ [0x0A9E5, 0x0A9E5, 0], [0x0AA29, 0x0AA2E, 0], [0x0AA31, 0x0AA32, 0],
100
+ [0x0AA35, 0x0AA36, 0], [0x0AA43, 0x0AA43, 0], [0x0AA4C, 0x0AA4C, 0],
101
+ [0x0AA7C, 0x0AA7C, 0], [0x0AAB0, 0x0AAB0, 0], [0x0AAB2, 0x0AAB4, 0],
102
+ [0x0AAB7, 0x0AAB8, 0], [0x0AABE, 0x0AABF, 0], [0x0AAC1, 0x0AAC1, 0],
103
+ [0x0AAEC, 0x0AAED, 0], [0x0AAF6, 0x0AAF6, 0], [0x0ABE5, 0x0ABE5, 0],
104
+ [0x0ABE8, 0x0ABE8, 0], [0x0ABED, 0x0ABED, 0], [0x0AC00, 0x0D7A3, 2],
105
+ [0x0F900, 0x0FAFF, 2], [0x0FB1E, 0x0FB1E, 0],
106
+ [0x0FE00, 0x0FE0F, 0], [0x0FE10, 0x0FE19, 2], [0x0FE20, 0x0FE2F, 0],
107
+ [0x0FE30, 0x0FE52, 2], [0x0FE54, 0x0FE66, 2], [0x0FE68, 0x0FE6B, 2],
108
+ [0x0FEFF, 0x0FEFF, 0], [0x0FF01, 0x0FF60, 2], [0x0FF9E, 0x0FF9F, 0],
109
+ [0x0FFE0, 0x0FFE6, 2], [0x0FFF0, 0x0FFFB, 0], [0x101FD, 0x101FD, 0],
110
+ [0x102E0, 0x102E0, 0], [0x10376, 0x1037A, 0], [0x10A01, 0x10A03, 0],
111
+ [0x10A05, 0x10A06, 0], [0x10A0C, 0x10A0F, 0], [0x10A38, 0x10A3A, 0],
112
+ [0x10A3F, 0x10A3F, 0], [0x10AE5, 0x10AE6, 0], [0x10D24, 0x10D27, 0],
113
+ [0x10EAB, 0x10EAC, 0], [0x10EFD, 0x10EFF, 0], [0x10F46, 0x10F50, 0],
114
+ [0x10F82, 0x10F85, 0], [0x11001, 0x11001, 0], [0x11038, 0x11046, 0],
115
+ [0x11070, 0x11070, 0], [0x11073, 0x11074, 0], [0x1107F, 0x11081, 0],
116
+ [0x110B3, 0x110B6, 0], [0x110B9, 0x110BA, 0], [0x110C2, 0x110C2, 0],
117
+ [0x11100, 0x11102, 0], [0x11127, 0x1112B, 0], [0x1112D, 0x11134, 0],
118
+ [0x11173, 0x11173, 0], [0x11180, 0x11181, 0], [0x111B6, 0x111BE, 0],
119
+ [0x111C9, 0x111CC, 0], [0x111CF, 0x111CF, 0], [0x1122F, 0x11231, 0],
120
+ [0x11234, 0x11234, 0], [0x11236, 0x11237, 0], [0x1123E, 0x1123E, 0],
121
+ [0x11241, 0x11241, 0], [0x112DF, 0x112DF, 0], [0x112E3, 0x112EA, 0],
122
+ [0x11300, 0x11301, 0], [0x1133B, 0x1133C, 0], [0x1133E, 0x1133E, 0],
123
+ [0x11340, 0x11340, 0], [0x11357, 0x11357, 0], [0x11366, 0x1136C, 0],
124
+ [0x11370, 0x11374, 0], [0x11438, 0x1143F, 0], [0x11442, 0x11444, 0],
125
+ [0x11446, 0x11446, 0], [0x1145E, 0x1145E, 0], [0x114B0, 0x114B0, 0],
126
+ [0x114B3, 0x114B8, 0], [0x114BA, 0x114BA, 0], [0x114BD, 0x114BD, 0],
127
+ [0x114BF, 0x114C0, 0], [0x114C2, 0x114C3, 0], [0x115AF, 0x115AF, 0],
128
+ [0x115B2, 0x115B5, 0], [0x115BC, 0x115BD, 0], [0x115BF, 0x115C0, 0],
129
+ [0x115DC, 0x115DD, 0], [0x11633, 0x1163A, 0], [0x1163D, 0x1163D, 0],
130
+ [0x1163F, 0x11640, 0], [0x116AB, 0x116AB, 0], [0x116AD, 0x116AD, 0],
131
+ [0x116B0, 0x116B5, 0], [0x116B7, 0x116B7, 0], [0x1171D, 0x1171F, 0],
132
+ [0x11722, 0x11725, 0], [0x11727, 0x1172B, 0], [0x1182F, 0x11837, 0],
133
+ [0x11839, 0x1183A, 0], [0x11930, 0x11930, 0], [0x1193B, 0x1193C, 0],
134
+ [0x1193E, 0x1193E, 0], [0x11943, 0x11943, 0], [0x119D4, 0x119D7, 0],
135
+ [0x119DA, 0x119DB, 0], [0x119E0, 0x119E0, 0], [0x11A01, 0x11A0A, 0],
136
+ [0x11A33, 0x11A38, 0], [0x11A3B, 0x11A3E, 0], [0x11A47, 0x11A47, 0],
137
+ [0x11A51, 0x11A56, 0], [0x11A59, 0x11A5B, 0], [0x11A8A, 0x11A96, 0],
138
+ [0x11A98, 0x11A99, 0], [0x11C30, 0x11C36, 0], [0x11C38, 0x11C3D, 0],
139
+ [0x11C3F, 0x11C3F, 0], [0x11C92, 0x11CA7, 0], [0x11CAA, 0x11CB0, 0],
140
+ [0x11CB2, 0x11CB3, 0], [0x11CB5, 0x11CB6, 0], [0x11D31, 0x11D36, 0],
141
+ [0x11D3A, 0x11D3A, 0], [0x11D3C, 0x11D3D, 0], [0x11D3F, 0x11D45, 0],
142
+ [0x11D47, 0x11D47, 0], [0x11D90, 0x11D91, 0], [0x11D95, 0x11D95, 0],
143
+ [0x11D97, 0x11D97, 0], [0x11EF3, 0x11EF4, 0], [0x11F00, 0x11F01, 0],
144
+ [0x11F36, 0x11F3A, 0], [0x11F40, 0x11F40, 0], [0x11F42, 0x11F42, 0],
145
+ [0x13430, 0x13440, 0], [0x13447, 0x13455, 0], [0x16AF0, 0x16AF4, 0],
146
+ [0x16B30, 0x16B36, 0], [0x16F4F, 0x16F4F, 0], [0x16F8F, 0x16F92, 0],
147
+ [0x16FE0, 0x16FE3, 2], [0x16FE4, 0x16FE4, 0], [0x16FF0, 0x16FF1, 2],
148
+ [0x17000, 0x187F7, 2], [0x18800, 0x18CD5, 2], [0x18D00, 0x18D08, 2],
149
+ [0x1AFF0, 0x1AFF3, 2], [0x1AFF5, 0x1AFFB, 2], [0x1AFFD, 0x1AFFE, 2],
150
+ [0x1B000, 0x1B122, 2], [0x1B132, 0x1B132, 2], [0x1B150, 0x1B152, 2],
151
+ [0x1B155, 0x1B155, 2], [0x1B164, 0x1B167, 2], [0x1B170, 0x1B2FB, 2],
152
+ [0x1BC9D, 0x1BC9E, 0], [0x1BCA0, 0x1BCA3, 0], [0x1CF00, 0x1CF2D, 0],
153
+ [0x1CF30, 0x1CF46, 0], [0x1D165, 0x1D165, 0], [0x1D167, 0x1D169, 0],
154
+ [0x1D16E, 0x1D182, 0], [0x1D185, 0x1D18B, 0], [0x1D1AA, 0x1D1AD, 0],
155
+ [0x1D242, 0x1D244, 0], [0x1DA00, 0x1DA36, 0], [0x1DA3B, 0x1DA6C, 0],
156
+ [0x1DA75, 0x1DA75, 0], [0x1DA84, 0x1DA84, 0], [0x1DA9B, 0x1DA9F, 0],
157
+ [0x1DAA1, 0x1DAAF, 0], [0x1E000, 0x1E006, 0], [0x1E008, 0x1E018, 0],
158
+ [0x1E01B, 0x1E021, 0], [0x1E023, 0x1E024, 0], [0x1E026, 0x1E02A, 0],
159
+ [0x1E08F, 0x1E08F, 0], [0x1E130, 0x1E136, 0], [0x1E2AE, 0x1E2AE, 0],
160
+ [0x1E2EC, 0x1E2EF, 0], [0x1E4EC, 0x1E4EF, 0], [0x1E8D0, 0x1E8D6, 0],
161
+ [0x1E944, 0x1E94A, 0], [0x1F004, 0x1F004, 2], [0x1F0CF, 0x1F0CF, 2],
162
+ [0x1F18E, 0x1F18E, 2], [0x1F191, 0x1F19A, 2], [0x1F1E6, 0x1F201, 2],
163
+ [0x1F210, 0x1F236, 2], [0x1F238, 0x1F23B, 2], [0x1F240, 0x1F248, 2],
164
+ [0x1F250, 0x1F251, 2], [0x1F300, 0x1F320, 2], [0x1F32D, 0x1F335, 2],
165
+ [0x1F337, 0x1F37C, 2], [0x1F37E, 0x1F393, 2], [0x1F3A0, 0x1F3CA, 2],
166
+ [0x1F3CF, 0x1F3D3, 2], [0x1F3E0, 0x1F3F0, 2], [0x1F3F4, 0x1F3F4, 2],
167
+ [0x1F3F8, 0x1F3FA, 2], [0x1F3FB, 0x1F3FF, 0], [0x1F400, 0x1F43E, 2],
168
+ [0x1F440, 0x1F440, 2], [0x1F442, 0x1F4FC, 2], [0x1F4FF, 0x1F53D, 2],
169
+ [0x1F54B, 0x1F54E, 2], [0x1F550, 0x1F567, 2], [0x1F57A, 0x1F57A, 2],
170
+ [0x1F595, 0x1F596, 2], [0x1F5A4, 0x1F5A4, 2], [0x1F5FB, 0x1F64F, 2],
171
+ [0x1F680, 0x1F6C5, 2], [0x1F6CC, 0x1F6CC, 2], [0x1F6D0, 0x1F6D2, 2],
172
+ [0x1F6D5, 0x1F6D7, 2], [0x1F6DC, 0x1F6DF, 2], [0x1F6EB, 0x1F6EC, 2],
173
+ [0x1F6F4, 0x1F6FC, 2], [0x1F7E0, 0x1F7EB, 2], [0x1F7F0, 0x1F7F0, 2],
174
+ [0x1F90C, 0x1F93A, 2], [0x1F93C, 0x1F945, 2], [0x1F947, 0x1F9FF, 2],
175
+ [0x1FA70, 0x1FA7C, 2], [0x1FA80, 0x1FA88, 2], [0x1FA90, 0x1FABD, 2],
176
+ [0x1FABF, 0x1FAC5, 2], [0x1FACE, 0x1FADB, 2], [0x1FAE0, 0x1FAE8, 2],
177
+ [0x1FAF0, 0x1FAF8, 2], [0x20000, 0x2FFFD, 2], [0x30000, 0x3FFFD, 2],
178
+ [0xE0000, 0xE0FFF, 0]
179
+ ].freeze
180
+
181
+ # [first, last] ranges with the Extended_Pictographic grapheme
182
+ # property (as uniseg classifies it; regional indicators excluded).
183
+ EXTENDED_PICTOGRAPHIC = [
184
+ [0x000A9, 0x000A9], [0x000AE, 0x000AE], [0x0203C, 0x0203C], [0x02049, 0x02049],
185
+ [0x02122, 0x02122], [0x02139, 0x02139], [0x02194, 0x02199], [0x021A9, 0x021AA],
186
+ [0x0231A, 0x0231B], [0x02328, 0x02328], [0x02388, 0x02388], [0x023CF, 0x023CF],
187
+ [0x023E9, 0x023F3], [0x023F8, 0x023FA], [0x024C2, 0x024C2], [0x025AA, 0x025AB],
188
+ [0x025B6, 0x025B6], [0x025C0, 0x025C0], [0x025FB, 0x025FE], [0x02600, 0x02605],
189
+ [0x02607, 0x02612], [0x02614, 0x02685], [0x02690, 0x02705], [0x02708, 0x02712],
190
+ [0x02714, 0x02714], [0x02716, 0x02716], [0x0271D, 0x0271D], [0x02721, 0x02721],
191
+ [0x02728, 0x02728], [0x02733, 0x02734], [0x02744, 0x02744], [0x02747, 0x02747],
192
+ [0x0274C, 0x0274C], [0x0274E, 0x0274E], [0x02753, 0x02755], [0x02757, 0x02757],
193
+ [0x02763, 0x02767], [0x02795, 0x02797], [0x027A1, 0x027A1], [0x027B0, 0x027B0],
194
+ [0x027BF, 0x027BF], [0x02934, 0x02935], [0x02B05, 0x02B07], [0x02B1B, 0x02B1C],
195
+ [0x02B50, 0x02B50], [0x02B55, 0x02B55], [0x03030, 0x03030], [0x0303D, 0x0303D],
196
+ [0x03297, 0x03297], [0x03299, 0x03299], [0x1F000, 0x1F0FF], [0x1F10D, 0x1F10F],
197
+ [0x1F12F, 0x1F12F], [0x1F16C, 0x1F171], [0x1F17E, 0x1F17F], [0x1F18E, 0x1F18E],
198
+ [0x1F191, 0x1F19A], [0x1F1AD, 0x1F1E5], [0x1F201, 0x1F20F], [0x1F21A, 0x1F21A],
199
+ [0x1F22F, 0x1F22F], [0x1F232, 0x1F23A], [0x1F23C, 0x1F23F], [0x1F249, 0x1F3FA],
200
+ [0x1F400, 0x1F53D], [0x1F546, 0x1F64F], [0x1F680, 0x1F6FF], [0x1F774, 0x1F77F],
201
+ [0x1F7D5, 0x1F7FF], [0x1F80C, 0x1F80F], [0x1F848, 0x1F84F], [0x1F85A, 0x1F85F],
202
+ [0x1F888, 0x1F88F], [0x1F8AE, 0x1F8FF], [0x1F90C, 0x1F93A], [0x1F93C, 0x1F945],
203
+ [0x1F947, 0x1FAFF], [0x1FC00, 0x1FFFD]
204
+ ].freeze
205
+
206
+ # Clusters starting with these keep only the first rune's width.
207
+ REGIONAL_INDICATOR = (0x1F1E6..0x1F1FF)
208
+ HANGUL_L = [(0x1100..0x115F), (0xA960..0xA97C)].freeze
209
+
210
+ module_function
211
+
212
+ def width(cp)
213
+ r = WIDTHS.bsearch { |(_, hi, _)| hi >= cp }
214
+ r && r[0] <= cp ? r[2] : 1
215
+ end
216
+
217
+ def extended_pictographic?(cp)
218
+ r = EXTENDED_PICTOGRAPHIC.bsearch { |(_, hi)| hi >= cp }
219
+ !r.nil? && r[0] <= cp
220
+ end
221
+
222
+ def width_of_first_only?(cp)
223
+ REGIONAL_INDICATOR.cover?(cp) || HANGUL_L.any? { |range| range.cover?(cp) }
224
+ end
225
+ end
226
+ end
227
+ end
228
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Pure-Ruby Bubbletea: a drop-in for the bubbletea gem (0.1.4). The Ruby layer (messages, commands,
4
+ # model, runner) is upstream's, copied unchanged; native.rb replaces the Go extension
5
+ # (Bubbletea::Program and the module functions) with pure Ruby. Never loads the real gem.
6
+
7
+ require_relative "bubbletea/version"
8
+ require_relative "bubbletea/native"
9
+ require_relative "bubbletea/messages"
10
+ require_relative "bubbletea/commands"
11
+ require_relative "bubbletea/model"
12
+ require_relative "bubbletea/runner"
13
+
14
+ module Bubbletea
15
+ class Error < StandardError; end
16
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Border type names, same as lipgloss-ruby 0.2.2 lib/lipgloss/border.rb (MIT). The border glyphs and
4
+ # how they are drawn live in style/border.rb.
5
+ module Lipgloss
6
+ module Border
7
+ NORMAL = :normal
8
+ ROUNDED = :rounded
9
+ THICK = :thick
10
+ DOUBLE = :double
11
+ ASCII = :ascii
12
+ HIDDEN = :hidden
13
+ BLOCK = :block
14
+ OUTER_HALF_BLOCK = :outer_half_block
15
+ INNER_HALF_BLOCK = :inner_half_block
16
+ end
17
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Same as lipgloss-ruby 0.2.2 lib/lipgloss/color.rb (MIT). How these are turned into escape sequences
4
+ # lives in termenv.rb.
5
+ module Lipgloss
6
+ module ANSIColor
7
+ COLORS = {
8
+ black: "0",
9
+ red: "1",
10
+ green: "2",
11
+ yellow: "3",
12
+ blue: "4",
13
+ magenta: "5",
14
+ cyan: "6",
15
+ white: "7",
16
+ bright_black: "8",
17
+ bright_red: "9",
18
+ bright_green: "10",
19
+ bright_yellow: "11",
20
+ bright_blue: "12",
21
+ bright_magenta: "13",
22
+ bright_cyan: "14",
23
+ bright_white: "15"
24
+ }.freeze
25
+
26
+ def self.resolve(value)
27
+ case value
28
+ when Symbol then COLORS.fetch(value) { raise ArgumentError, "Unknown ANSI color: #{value.inspect}" }
29
+ when String then value
30
+ when Integer then value.to_s
31
+ else raise ArgumentError, "ANSI color must be a Symbol, String, or Integer, got #{value.class}"
32
+ end
33
+ end
34
+ end
35
+
36
+ # Adaptive color that changes based on terminal background.
37
+ class AdaptiveColor
38
+ attr_reader :light, :dark
39
+
40
+ def initialize(light:, dark:)
41
+ @light = light
42
+ @dark = dark
43
+ end
44
+
45
+ def to_h
46
+ { light: @light, dark: @dark }
47
+ end
48
+ end
49
+
50
+ # Complete color with explicit values for each color profile.
51
+ class CompleteColor
52
+ attr_reader :true_color, :ansi256, :ansi
53
+
54
+ def initialize(true_color:, ansi256:, ansi:)
55
+ @true_color = true_color
56
+ @ansi256 = ANSIColor.resolve(ansi256)
57
+ @ansi = ANSIColor.resolve(ansi)
58
+ end
59
+
60
+ def to_h
61
+ { true_color: @true_color, ansi256: @ansi256, ansi: @ansi }
62
+ end
63
+ end
64
+
65
+ # Complete color per profile, with separate values for light and dark backgrounds.
66
+ class CompleteAdaptiveColor
67
+ attr_reader :light, :dark
68
+
69
+ def initialize(light:, dark:)
70
+ @light = light
71
+ @dark = dark
72
+ end
73
+
74
+ def to_h
75
+ { light: @light.to_h, dark: @dark.to_h }
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,166 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lipgloss
4
+ # Same API as the gem's C extension (ext/lipgloss/color.c) backed by go/color.go: blends of hex
5
+ # colors in Luv, RGB or HCL space.
6
+ module ColorBlend
7
+ LUV = :luv
8
+ RGB = :rgb
9
+ HCL = :hcl
10
+
11
+ Colorful = R2UI::Compat::Gloss::Colorful
12
+ private_constant :Colorful
13
+
14
+ class << self
15
+ def blend(c1, c2, t, mode: nil, **)
16
+ blend_with(blend_mode(mode), c1, c2, t)
17
+ end
18
+
19
+ def blend_luv(c1, c2, t)
20
+ blend_with(LUV, c1, c2, t)
21
+ end
22
+
23
+ def blend_rgb(c1, c2, t)
24
+ blend_with(RGB, c1, c2, t)
25
+ end
26
+
27
+ def blend_hcl(c1, c2, t)
28
+ blend_with(HCL, c1, c2, t)
29
+ end
30
+
31
+ def blends(c1, c2, steps, mode: nil, **)
32
+ check_string(c1)
33
+ check_string(c2)
34
+ mode = blend_mode(mode)
35
+ a = c_string(c1)
36
+ b = c_string(c2)
37
+ n = num2int(steps)
38
+ color1 = Colorful.hex(a)
39
+ return [] if color1.nil?
40
+
41
+ color2 = Colorful.hex(b)
42
+ return [] if color2.nil?
43
+
44
+ Array.new([n, 0].max) do |i|
45
+ t = n == 1 ? 0.0 : i.to_f / (n - 1).to_f
46
+ mix(mode, color1, color2, t).hex
47
+ end
48
+ end
49
+
50
+ def grid(x0y0, x1y0, x0y1, x1y1, x_steps, y_steps, mode: nil, **)
51
+ corners = [x0y0, x1y0, x0y1, x1y1]
52
+ corners.each { |c| check_string(c) }
53
+ mode = blend_mode(mode)
54
+ corners = corners.map { |c| c_string(c) }
55
+ nx = num2int(x_steps)
56
+ ny = num2int(y_steps)
57
+ c00, c10, c01, c11 = corners.map { |c| Colorful.hex(c) || (return []) }
58
+
59
+ left = Array.new([ny, 0].max) do |y|
60
+ t = ny == 1 ? 0.0 : y.to_f / ny.to_f
61
+ [mix(mode, c00, c01, t), mix(mode, c10, c11, t)]
62
+ end
63
+ left.map do |x0, x1|
64
+ Array.new([nx, 0].max) do |x|
65
+ t = nx == 1 ? 0.0 : x.to_f / nx.to_f
66
+ mix(mode, x0, x1, t).hex
67
+ end
68
+ end
69
+ end
70
+
71
+ private
72
+
73
+ # go/color.go lipgloss_color_blend_*: an unparsable color returns c1 unchanged.
74
+ def blend_with(mode, c1, c2, t)
75
+ check_string(c1)
76
+ check_string(c2)
77
+ a = c_string(c1)
78
+ b = c_string(c2)
79
+ t = num2dbl(t)
80
+ color1 = Colorful.hex(a)
81
+ return a.dup.force_encoding(Encoding::UTF_8) if color1.nil?
82
+
83
+ color2 = Colorful.hex(b)
84
+ return a.dup.force_encoding(Encoding::UTF_8) if color2.nil?
85
+
86
+ mix(mode, color1, color2, t).hex
87
+ end
88
+
89
+ def mix(mode, a, b, t)
90
+ case mode
91
+ when RGB then a.blend_rgb(b, t)
92
+ when HCL then a.blend_hcl(b, t)
93
+ else a.blend_luv(b, t)
94
+ end
95
+ end
96
+
97
+ # blend_mode_from_symbol: nil and unknown symbols mean LUV; SYM2ID on a non-Symbol raises.
98
+ def blend_mode(mode)
99
+ return LUV if mode.nil?
100
+ raise TypeError, "wrong argument type #{type_name(mode)} (expected Symbol)" unless mode.is_a?(Symbol)
101
+
102
+ [LUV, RGB, HCL].include?(mode) ? mode : LUV
103
+ end
104
+
105
+ def check_string(value)
106
+ return if value.is_a?(String)
107
+
108
+ raise TypeError, "wrong argument type #{type_name(value)} (expected String)"
109
+ end
110
+
111
+ def type_name(value)
112
+ case value
113
+ when nil then "nil"
114
+ when true then "true"
115
+ when false then "false"
116
+ else value.class.to_s
117
+ end
118
+ end
119
+
120
+ # StringValueCStr: rejects embedded NUL bytes.
121
+ def c_string(str)
122
+ raise ArgumentError, "string contains null byte" if str.include?("\0")
123
+
124
+ str
125
+ end
126
+
127
+ # NUM2DBL
128
+ def num2dbl(value)
129
+ case value
130
+ when Float then value
131
+ when Numeric then value.to_f
132
+ when String then raise TypeError, "no implicit conversion to float from string"
133
+ when nil, true, false then raise TypeError, "no implicit conversion to float from #{value.inspect}"
134
+ else raise TypeError, "can't convert #{value.class} into Float"
135
+ end
136
+ end
137
+
138
+ # NUM2INT
139
+ def num2int(value)
140
+ int = case value
141
+ when Integer then value
142
+ when Float
143
+ raise RangeError, "float #{value} out of range of integer" unless value.finite? && value.abs < 2**63
144
+
145
+ value.to_i
146
+ when nil then raise TypeError, "no implicit conversion from nil to integer"
147
+ else
148
+ unless value.respond_to?(:to_int)
149
+ raise TypeError, "no implicit conversion of #{type_name(value)} into Integer"
150
+ end
151
+
152
+ value.to_int
153
+ end
154
+ unless int.between?(-2**31, 2**31 - 1)
155
+ raise RangeError, "integer #{int} too #{int.negative? ? 'small' : 'big'} to convert to 'int'"
156
+ end
157
+
158
+ int
159
+ end
160
+ end
161
+ end
162
+
163
+ def self.has_dark_background?
164
+ R2UI::Compat::Gloss::Renderer.has_dark_background?
165
+ end
166
+ end