reflex-terminal 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.
- checksums.yaml +4 -4
- data/.doc/ext/reflex-terminal/renderer.cpp +33 -1
- data/.doc/ext/reflex-terminal/terminal.cpp +26 -10
- data/.github/workflows/release-gem.yml +4 -49
- data/.github/workflows/tag.yml +5 -28
- data/.github/workflows/test.yml +3 -37
- data/ChangeLog.md +23 -0
- data/Gemfile.lock +26 -0
- data/README.md +2 -2
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/examples/terminal.rb +24 -13
- data/ext/reflex-terminal/renderer.cpp +37 -1
- data/ext/reflex-terminal/terminal.cpp +27 -10
- data/include/reflex/terminal.h +30 -5
- data/include/reflex-terminal/renderer.h +8 -0
- data/lib/reflex/terminal.rb +3 -2
- data/lib/reflex/terminal_view.rb +76 -10
- data/reflex-terminal.gemspec +5 -5
- data/src/pty.cpp +33 -4
- data/src/renderer.cpp +350 -80
- data/src/terminal.cpp +237 -105
- data/src/win32/pty.cpp +2 -2
- data/test/test_renderer.rb +122 -4
- data/test/test_terminal.rb +163 -8
- data/test/test_terminal_view.rb +1 -1
- metadata +12 -12
- data/.github/workflows/utils.rb +0 -127
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a6e0b7d10bc9bcd23a887eb1c7b7450e2548b866d693066548de2b8b92644f83
|
|
4
|
+
data.tar.gz: 25d679af879028eb020c409e4f4fc785fa6509659b8fb1d7fd5a1970898ebb20
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cd630a04c08654a92b15af99559f06f01fc97e3f791754c5ab095b8378981be041116fc29595719f4822bf9498837aef4943e2245db6d3fbee58b44a9a4a9970
|
|
7
|
+
data.tar.gz: 5965365cc65e87173cbfd7904655c56d65c7ed97308da7f06453e513fe50bd83a036de7fa1c952d8a912d15539dc948f75286c1106c06314573e9845ef7eb33b
|
|
@@ -12,7 +12,7 @@ RUCY_DEFINE_VALUE_FROM_TO(REFLEX_TERMINAL_EXPORT, ReflexTerminal::Renderer)
|
|
|
12
12
|
|
|
13
13
|
#define THIS to<ReflexTerminal::Renderer*>(self)
|
|
14
14
|
|
|
15
|
-
#define CHECK
|
|
15
|
+
#define CHECK RUCY_CHECK_PTR(ReflexTerminal::Renderer, self)
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
static
|
|
@@ -65,6 +65,34 @@ VALUE get_glyph_count(VALUE self)
|
|
|
65
65
|
return value(THIS->glyph_count());
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
static
|
|
69
|
+
VALUE set_blink_visible(VALUE self, VALUE visible)
|
|
70
|
+
{
|
|
71
|
+
CHECK;
|
|
72
|
+
THIS->set_blink_visible(to<bool>(visible));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static
|
|
76
|
+
VALUE is_blink_visible(VALUE self)
|
|
77
|
+
{
|
|
78
|
+
CHECK;
|
|
79
|
+
return value(THIS->blink_visible());
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
static
|
|
83
|
+
VALUE set_background_alpha(VALUE self, VALUE alpha)
|
|
84
|
+
{
|
|
85
|
+
CHECK;
|
|
86
|
+
THIS->set_background_alpha(to<float>(alpha));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
static
|
|
90
|
+
VALUE get_background_alpha(VALUE self)
|
|
91
|
+
{
|
|
92
|
+
CHECK;
|
|
93
|
+
return value(THIS->background_alpha());
|
|
94
|
+
}
|
|
95
|
+
|
|
68
96
|
static
|
|
69
97
|
VALUE draw(VALUE self, VALUE painter, VALUE terminal, VALUE bounds)
|
|
70
98
|
{
|
|
@@ -92,6 +120,10 @@ Init_reflex_terminal_renderer ()
|
|
|
92
120
|
rb_define_method(cRenderer, "cell_height", RUBY_METHOD_FUNC(get_cell_height), 0);
|
|
93
121
|
rb_define_method(cRenderer, "bake_glyphs", RUBY_METHOD_FUNC(bake_glyphs), 1);
|
|
94
122
|
rb_define_method(cRenderer, "glyph_count", RUBY_METHOD_FUNC(get_glyph_count), 0);
|
|
123
|
+
rb_define_method(cRenderer, "blink_visible=", RUBY_METHOD_FUNC(set_blink_visible), 1);
|
|
124
|
+
cRenderer.define_method("blink_visible?", is_blink_visible);
|
|
125
|
+
rb_define_method(cRenderer, "background_alpha=", RUBY_METHOD_FUNC(set_background_alpha), 1);
|
|
126
|
+
rb_define_method(cRenderer, "background_alpha", RUBY_METHOD_FUNC(get_background_alpha), 0);
|
|
95
127
|
rb_define_method(cRenderer, "draw", RUBY_METHOD_FUNC(draw), 3);
|
|
96
128
|
}
|
|
97
129
|
|
|
@@ -13,7 +13,7 @@ RUCY_DEFINE_CONVERT_TO(REFLEX_TERMINAL_EXPORT, Reflex::Terminal::OptionAsAlt)
|
|
|
13
13
|
|
|
14
14
|
#define THIS to<Reflex::Terminal*>(self)
|
|
15
15
|
|
|
16
|
-
#define CHECK
|
|
16
|
+
#define CHECK RUCY_CHECK_OBJ(Reflex::Terminal, self)
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
static
|
|
@@ -25,7 +25,7 @@ VALUE alloc(VALUE klass)
|
|
|
25
25
|
static
|
|
26
26
|
VALUE initialize(VALUE self, VALUE columns, VALUE rows, VALUE scrollback)
|
|
27
27
|
{
|
|
28
|
-
|
|
28
|
+
RUCY_CHECK_PTR(Reflex::Terminal, self);
|
|
29
29
|
|
|
30
30
|
*THIS = Reflex::Terminal(to<int>(columns), to<int>(rows), to<size_t>(scrollback));
|
|
31
31
|
return self;
|
|
@@ -57,9 +57,9 @@ VALUE resize(VALUE self, VALUE columns, VALUE rows, VALUE cell_width, VALUE cell
|
|
|
57
57
|
{
|
|
58
58
|
CHECK;
|
|
59
59
|
THIS->resize(
|
|
60
|
-
to<int>(columns),
|
|
61
|
-
to<
|
|
62
|
-
to<int>(screen_width),
|
|
60
|
+
to<int>(columns), to<int>(rows),
|
|
61
|
+
to<Reflex::coord>(cell_width), to<Reflex::coord>(cell_height),
|
|
62
|
+
to<int>(screen_width), to<int>(screen_height));
|
|
63
63
|
return self;
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -176,6 +176,13 @@ VALUE is_alive(VALUE self)
|
|
|
176
176
|
return value(THIS->is_alive());
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
+
static
|
|
180
|
+
VALUE is_blinking(VALUE self)
|
|
181
|
+
{
|
|
182
|
+
CHECK;
|
|
183
|
+
return value(THIS->is_blinking());
|
|
184
|
+
}
|
|
185
|
+
|
|
179
186
|
static
|
|
180
187
|
VALUE is_mouse_tracking(VALUE self)
|
|
181
188
|
{
|
|
@@ -235,7 +242,7 @@ VALUE get_selected_text(VALUE self)
|
|
|
235
242
|
{
|
|
236
243
|
CHECK;
|
|
237
244
|
Reflex::String text = THIS->selected_text();
|
|
238
|
-
return value(text.c_str(), text.size()
|
|
245
|
+
return value(text.c_str(), text.size());
|
|
239
246
|
}
|
|
240
247
|
|
|
241
248
|
static
|
|
@@ -267,7 +274,7 @@ VALUE each_line(VALUE self)
|
|
|
267
274
|
CHECK;
|
|
268
275
|
|
|
269
276
|
for (const auto& line : THIS->lines())
|
|
270
|
-
yield(value(line.c_str(), line.size()
|
|
277
|
+
yield(value(line.c_str(), line.size()));
|
|
271
278
|
return self;
|
|
272
279
|
}
|
|
273
280
|
|
|
@@ -283,9 +290,10 @@ VALUE each_span(VALUE self)
|
|
|
283
290
|
{
|
|
284
291
|
yield(
|
|
285
292
|
value(span.x), value((int) y), value(span.width),
|
|
286
|
-
value(span.text.c_str(), span.text.size()
|
|
293
|
+
value(span.text.c_str(), span.text.size()),
|
|
287
294
|
span.fg == Reflex::Terminal::Span::COLOR_NONE ? nil() : value(span.fg),
|
|
288
295
|
span.bg == Reflex::Terminal::Span::COLOR_NONE ? nil() : value(span.bg),
|
|
296
|
+
span.ul == Reflex::Terminal::Span::COLOR_NONE ? nil() : value(span.ul),
|
|
289
297
|
value(span.attribs));
|
|
290
298
|
}
|
|
291
299
|
}
|
|
@@ -384,7 +392,7 @@ static
|
|
|
384
392
|
VALUE get_title(VALUE self)
|
|
385
393
|
{
|
|
386
394
|
CHECK;
|
|
387
|
-
return value(THIS->title()
|
|
395
|
+
return value(THIS->title());
|
|
388
396
|
}
|
|
389
397
|
|
|
390
398
|
static
|
|
@@ -401,7 +409,7 @@ VALUE get_history_lines(VALUE self, VALUE offset, VALUE size)
|
|
|
401
409
|
|
|
402
410
|
Value result = array(NULL, 0);// a std::vector<Value> would be invisible to the gc
|
|
403
411
|
for (const auto& line : THIS->get_history_lines(to<int>(offset), to<int>(size)))
|
|
404
|
-
result.push(value(line.c_str(), line.size()
|
|
412
|
+
result.push(value(line.c_str(), line.size()));
|
|
405
413
|
return result;
|
|
406
414
|
}
|
|
407
415
|
|
|
@@ -437,6 +445,7 @@ Init_reflex_terminal ()
|
|
|
437
445
|
rb_define_method(cTerminal, "write_wheel", RUBY_METHOD_FUNC(write_wheel), 1);
|
|
438
446
|
rb_define_method(cTerminal, "paste", RUBY_METHOD_FUNC(paste), 1);
|
|
439
447
|
cTerminal.define_method("alive?", is_alive);
|
|
448
|
+
cTerminal.define_method("blinking?", is_blinking);
|
|
440
449
|
cTerminal.define_method("mouse_tracking?", is_mouse_tracking);
|
|
441
450
|
rb_define_method(cTerminal, "select", RUBY_METHOD_FUNC(select), 4);
|
|
442
451
|
rb_define_method(cTerminal, "select_rect", RUBY_METHOD_FUNC(select_rect), 4);
|
|
@@ -476,6 +485,13 @@ Init_reflex_terminal ()
|
|
|
476
485
|
cTerminal.define_const("UNDERLINE_SHIFT", Reflex::Terminal::Span::UNDERLINE_SHIFT);
|
|
477
486
|
cTerminal.define_const("UNDERLINE_MASK", Reflex::Terminal::Span::UNDERLINE_MASK);
|
|
478
487
|
|
|
488
|
+
cTerminal.define_const("UNDERLINE_NONE", Reflex::Terminal::Span::UNDERLINE_NONE);
|
|
489
|
+
cTerminal.define_const("UNDERLINE_SINGLE", Reflex::Terminal::Span::UNDERLINE_SINGLE);
|
|
490
|
+
cTerminal.define_const("UNDERLINE_DOUBLE", Reflex::Terminal::Span::UNDERLINE_DOUBLE);
|
|
491
|
+
cTerminal.define_const("UNDERLINE_CURLY", Reflex::Terminal::Span::UNDERLINE_CURLY);
|
|
492
|
+
cTerminal.define_const("UNDERLINE_DOTTED", Reflex::Terminal::Span::UNDERLINE_DOTTED);
|
|
493
|
+
cTerminal.define_const("UNDERLINE_DASHED", Reflex::Terminal::Span::UNDERLINE_DASHED);
|
|
494
|
+
|
|
479
495
|
cTerminal.define_const("CURSOR_BAR", Reflex::Terminal::Cursor::BAR);
|
|
480
496
|
cTerminal.define_const("CURSOR_BLOCK", Reflex::Terminal::Cursor::BLOCK);
|
|
481
497
|
cTerminal.define_const("CURSOR_UNDERLINE", Reflex::Terminal::Cursor::UNDERLINE);
|
|
@@ -9,52 +9,7 @@ permissions:
|
|
|
9
9
|
|
|
10
10
|
jobs:
|
|
11
11
|
release:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
uses: ruby/setup-ruby@v1
|
|
17
|
-
with:
|
|
18
|
-
ruby-version: 3.2
|
|
19
|
-
|
|
20
|
-
- name: checkout
|
|
21
|
-
uses: actions/checkout@v4
|
|
22
|
-
|
|
23
|
-
- name: setup gems
|
|
24
|
-
run: bundle install
|
|
25
|
-
|
|
26
|
-
- name: setup dependencies
|
|
27
|
-
run: "ruby -I.github/workflows -rutils -e 'setup_dependencies'"
|
|
28
|
-
|
|
29
|
-
- name: packages
|
|
30
|
-
run: bundle exec rake packages
|
|
31
|
-
|
|
32
|
-
- name: setup zig
|
|
33
|
-
if: github.event.repository.name == 'reflex-terminal'
|
|
34
|
-
uses: mlugg/setup-zig@v2
|
|
35
|
-
with:
|
|
36
|
-
version: 0.16.0
|
|
37
|
-
|
|
38
|
-
- name: test
|
|
39
|
-
run: bundle exec rake test
|
|
40
|
-
|
|
41
|
-
- name: create gem
|
|
42
|
-
id: gem
|
|
43
|
-
run: |
|
|
44
|
-
bundle exec rake gem
|
|
45
|
-
echo path=$(ruby -e 'print Dir.glob("*.gem").first') >> $GITHUB_OUTPUT
|
|
46
|
-
|
|
47
|
-
- name: create github release
|
|
48
|
-
env:
|
|
49
|
-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
50
|
-
run: ruby -I.github/workflows -rutils -e 'release(*ARGV)' ./${{ steps.gem.outputs.path }}
|
|
51
|
-
|
|
52
|
-
- name: upload to rubygems
|
|
53
|
-
env:
|
|
54
|
-
GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_AUTH_TOKEN }}
|
|
55
|
-
run: |
|
|
56
|
-
mkdir -p $HOME/.gem
|
|
57
|
-
touch $HOME/.gem/credentials
|
|
58
|
-
chmod 0600 $HOME/.gem/credentials
|
|
59
|
-
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
|
60
|
-
bundle exec rake upload
|
|
12
|
+
uses: xord/xot/.github/workflows/release-gem.yml@master
|
|
13
|
+
with:
|
|
14
|
+
zig: true
|
|
15
|
+
secrets: inherit
|
data/.github/workflows/tag.yml
CHANGED
|
@@ -1,35 +1,12 @@
|
|
|
1
1
|
name: Tag
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
-
|
|
4
|
+
workflow_run:
|
|
5
|
+
workflows: [Test]
|
|
6
|
+
types: [completed]
|
|
5
7
|
branches: [master]
|
|
6
8
|
|
|
7
9
|
jobs:
|
|
8
10
|
tag:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
steps:
|
|
12
|
-
- name: ruby 3.2
|
|
13
|
-
uses: ruby/setup-ruby@v1
|
|
14
|
-
with:
|
|
15
|
-
ruby-version: 3.2
|
|
16
|
-
|
|
17
|
-
- name: checkout
|
|
18
|
-
uses: actions/checkout@v4
|
|
19
|
-
with:
|
|
20
|
-
fetch-depth: 0
|
|
21
|
-
token: ${{ secrets.PAT }}
|
|
22
|
-
|
|
23
|
-
- name: setup dependencies
|
|
24
|
-
run: "ruby -I.github/workflows -rutils -e 'setup_dependencies only: :xot'"
|
|
25
|
-
|
|
26
|
-
- name: setup user name and email
|
|
27
|
-
run: |
|
|
28
|
-
git config --global user.email "xordog@gmail.com"
|
|
29
|
-
git config --global user.name "xord"
|
|
30
|
-
|
|
31
|
-
- name: tag versions
|
|
32
|
-
run: "ruby -I.github/workflows -rutils -e 'tag_versions'"
|
|
33
|
-
|
|
34
|
-
- name: push tags
|
|
35
|
-
run: git push origin --tags
|
|
11
|
+
uses: xord/xot/.github/workflows/tag.yml@master
|
|
12
|
+
secrets: inherit
|
data/.github/workflows/test.yml
CHANGED
|
@@ -7,40 +7,6 @@ on:
|
|
|
7
7
|
|
|
8
8
|
jobs:
|
|
9
9
|
test:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
- name: ruby 3.2
|
|
14
|
-
uses: ruby/setup-ruby@v1
|
|
15
|
-
with:
|
|
16
|
-
ruby-version: 3.2
|
|
17
|
-
|
|
18
|
-
- name: checkout
|
|
19
|
-
uses: actions/checkout@v4
|
|
20
|
-
|
|
21
|
-
- name: setup gems
|
|
22
|
-
run: bundle install
|
|
23
|
-
|
|
24
|
-
- name: setup dependencies
|
|
25
|
-
run: "ruby -I.github/workflows -rutils -e 'setup_dependencies'"
|
|
26
|
-
|
|
27
|
-
- name: packages
|
|
28
|
-
run: bundle exec rake verbose packages
|
|
29
|
-
|
|
30
|
-
- name: setup zig
|
|
31
|
-
if: github.event.repository.name == 'reflex-terminal'
|
|
32
|
-
uses: mlugg/setup-zig@v2
|
|
33
|
-
with:
|
|
34
|
-
version: 0.16.0
|
|
35
|
-
|
|
36
|
-
- name: vendor
|
|
37
|
-
run: bundle exec rake vendor
|
|
38
|
-
|
|
39
|
-
- name: lib
|
|
40
|
-
run: bundle exec rake verbose lib
|
|
41
|
-
|
|
42
|
-
- name: ext
|
|
43
|
-
run: bundle exec rake verbose ext
|
|
44
|
-
|
|
45
|
-
- name: test
|
|
46
|
-
run: bundle exec rake verbose test
|
|
10
|
+
uses: xord/xot/.github/workflows/test.yml@master
|
|
11
|
+
with:
|
|
12
|
+
zig: true
|
data/ChangeLog.md
CHANGED
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
# reflex-terminal ChangeLog
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## [v0.2.0] - 2026-11-04
|
|
5
|
+
|
|
6
|
+
- [BREAKING] each_span yields (x, y, width, text, fg, bg, ul, flags), with the underline color beside the other colors
|
|
7
|
+
- [BREAKING] Leave the focus to the application, instead of TerminalView taking it when attached
|
|
8
|
+
- [BREAKING] Update libghostty-vt to the latest main, which requires Zig 0.17.0
|
|
9
|
+
- Draw bold and italic faces, underlines, strikethrough, overline, the underline color of SGR 58, and concealed and blinking text
|
|
10
|
+
- Draw faint text faintly
|
|
11
|
+
- Let the terminal take Japanese input
|
|
12
|
+
- Let the terminal background be seen through, by background_alpha:
|
|
13
|
+
- Let the terminal example change its font size
|
|
14
|
+
|
|
15
|
+
- Fix the build on Windows
|
|
16
|
+
- Fix the wheel never scrolling the terminal
|
|
17
|
+
- Fix the text of a released key being written a second time
|
|
18
|
+
- Fix the gaps between glyphs being a pixel wider here and there
|
|
19
|
+
- Fix the antialiased edges of glyphs being drawn too thin
|
|
20
|
+
- Fix the cursor not moving on screen until the next blink
|
|
21
|
+
- Fix the mouse position drifting toward the right edge
|
|
22
|
+
- Fix the function keys of macOS typing a character under the kitty keyboard protocol
|
|
23
|
+
- Fix the child process living on after the pty is closed
|
|
24
|
+
- Fix a canceled press leaving a selection or a button held
|
|
25
|
+
|
|
26
|
+
|
|
4
27
|
## [v0.1.0] - 2026-08-04
|
|
5
28
|
|
|
6
29
|
- Initial release
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
GEM
|
|
2
|
+
remote: https://rubygems.org/
|
|
3
|
+
specs:
|
|
4
|
+
power_assert (3.1.0)
|
|
5
|
+
rake (13.4.2)
|
|
6
|
+
test-unit (3.7.8)
|
|
7
|
+
power_assert
|
|
8
|
+
yard (0.9.45)
|
|
9
|
+
|
|
10
|
+
PLATFORMS
|
|
11
|
+
ruby
|
|
12
|
+
|
|
13
|
+
DEPENDENCIES
|
|
14
|
+
rake
|
|
15
|
+
test-unit
|
|
16
|
+
yard
|
|
17
|
+
|
|
18
|
+
CHECKSUMS
|
|
19
|
+
bundler (4.0.20) sha256=7978a8ac648767f5e635bc522445b79e80a52b907a39a36c2d8085ed6bc762ae
|
|
20
|
+
power_assert (3.1.0) sha256=fefe98ed5d3140628138f3f9f9194d6ece01f1320e69700d3c928adca7518251
|
|
21
|
+
rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701
|
|
22
|
+
test-unit (3.7.8) sha256=689d1ca53f4d46f678b4e5d68d8e4294f87fc5e8b9238cc4de7c5727e8d65943
|
|
23
|
+
yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51
|
|
24
|
+
|
|
25
|
+
BUNDLED WITH
|
|
26
|
+
4.0.20
|
data/README.md
CHANGED
|
@@ -55,9 +55,9 @@ encoded key and mouse events.
|
|
|
55
55
|
|
|
56
56
|
- macOS, Linux or Windows
|
|
57
57
|
- Ruby 3.0+
|
|
58
|
-
- [Zig](https://ziglang.org/) **0.
|
|
58
|
+
- [Zig](https://ziglang.org/) **0.17.0** — required to build libghostty-vt
|
|
59
59
|
from source into `vendor/ghostty/`. On macOS `rake packages` installs it
|
|
60
|
-
through Homebrew; elsewhere take the 0.
|
|
60
|
+
through Homebrew; elsewhere take the 0.17.0 build for your platform from
|
|
61
61
|
the [downloads page](https://ziglang.org/download/) and put it on `PATH`,
|
|
62
62
|
since packaged versions rarely match the one the pinned ghostty commit
|
|
63
63
|
asks for.
|
data/Rakefile
CHANGED
|
@@ -24,7 +24,7 @@ use_external_library 'https://github.com/ghostty-org/ghostty',
|
|
|
24
24
|
# verified commit on ghostty's main branch. (Release tags up to v1.3.1 do
|
|
25
25
|
# not contain the terminal/render C APIs.) Bump intentionally, then run
|
|
26
26
|
# 'rake vendor:ghostty:update' and re-run the tests.
|
|
27
|
-
commit: '
|
|
27
|
+
commit: '9ee02ae601d3eec567723287e1c20bd0e9f1489c',# requires Zig 0.17.0
|
|
28
28
|
incdirs: 'zig-out/include',
|
|
29
29
|
srcdirs: 'NOSRC',
|
|
30
30
|
defs: 'GHOSTTY_STATIC',
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.2.0
|
data/examples/terminal.rb
CHANGED
|
@@ -25,14 +25,22 @@ def pasteable?()
|
|
|
25
25
|
!Reflex::Clipboard.text.to_s.empty?
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
def resize_font(view, step)
|
|
29
|
+
view.font_size = (view.font_size + step).clamp 6..96
|
|
30
|
+
end
|
|
31
|
+
|
|
28
32
|
|
|
29
33
|
terminal = Reflex::Terminal.new.spawn
|
|
30
|
-
view = Reflex::TerminalView.new
|
|
31
|
-
|
|
34
|
+
view = Reflex::TerminalView.new(
|
|
35
|
+
terminal: terminal, font_size: 18, background_alpha: 0.8)
|
|
32
36
|
taken = []
|
|
33
37
|
flash = 0
|
|
34
38
|
flash_timer = nil
|
|
35
39
|
|
|
40
|
+
view.after :on_attach do |e|
|
|
41
|
+
view.focus
|
|
42
|
+
end
|
|
43
|
+
|
|
36
44
|
view.after :on_draw do |e|
|
|
37
45
|
next if flash <= 0
|
|
38
46
|
e.painter.fill 1, flash
|
|
@@ -42,13 +50,18 @@ view.after :on_draw do |e|
|
|
|
42
50
|
end
|
|
43
51
|
|
|
44
52
|
view.before :on_key_down do |e|
|
|
45
|
-
#
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
53
|
+
# ctrl+c is the interrupt, so everywhere but macos takes shift as well
|
|
54
|
+
prefix = (Xot.osx? ? %i[command] : %i[control shift]).sort
|
|
55
|
+
# a '+' needs shift wherever the layout puts it
|
|
56
|
+
shifted = (prefix | [:shift]).sort
|
|
57
|
+
|
|
58
|
+
case [e.chars, e.code, e.modifiers.sort]
|
|
59
|
+
in ['+' | '=', _, ^prefix | ^shifted] then resize_font view, 2
|
|
60
|
+
in ['-', _, ^prefix | ^shifted] then resize_font view, -2
|
|
61
|
+
in [_, Reflex::KEY_NUM_PLUS, ^prefix] then resize_font view, 2
|
|
62
|
+
in [_, Reflex::KEY_NUM_MINUS, ^prefix] then resize_font view, -2
|
|
63
|
+
in [_, Reflex::KEY_C, ^prefix] then copy terminal
|
|
64
|
+
in [_, Reflex::KEY_V, ^prefix] then paste terminal
|
|
52
65
|
else next
|
|
53
66
|
end
|
|
54
67
|
|
|
@@ -63,10 +76,7 @@ view.before :on_key_up do |e|
|
|
|
63
76
|
:skip if taken.delete e.code
|
|
64
77
|
end
|
|
65
78
|
|
|
66
|
-
|
|
67
|
-
# own and swallows the mouse up, which would leave the window believing the
|
|
68
|
-
# button was still down and every later drag starting where it was clicked
|
|
69
|
-
view.before :on_pointer_up do |e|
|
|
79
|
+
view.after :on_pointer_down do |e|
|
|
70
80
|
next unless e.right?
|
|
71
81
|
m = Reflex::Menu.new
|
|
72
82
|
|
|
@@ -94,6 +104,7 @@ end
|
|
|
94
104
|
win = Reflex::Window.new do
|
|
95
105
|
title 'Terminal Example'
|
|
96
106
|
frame 100, 100, 720, 450
|
|
107
|
+
transparent true
|
|
97
108
|
end
|
|
98
109
|
win.add view
|
|
99
110
|
win.show
|
|
@@ -12,7 +12,7 @@ RUCY_DEFINE_VALUE_FROM_TO(REFLEX_TERMINAL_EXPORT, ReflexTerminal::Renderer)
|
|
|
12
12
|
|
|
13
13
|
#define THIS to<ReflexTerminal::Renderer*>(self)
|
|
14
14
|
|
|
15
|
-
#define CHECK
|
|
15
|
+
#define CHECK RUCY_CHECK_PTR(ReflexTerminal::Renderer, self)
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
static
|
|
@@ -72,6 +72,38 @@ RUCY_DEF0(get_glyph_count)
|
|
|
72
72
|
}
|
|
73
73
|
RUCY_END
|
|
74
74
|
|
|
75
|
+
static
|
|
76
|
+
RUCY_DEF1(set_blink_visible, visible)
|
|
77
|
+
{
|
|
78
|
+
CHECK;
|
|
79
|
+
THIS->set_blink_visible(to<bool>(visible));
|
|
80
|
+
}
|
|
81
|
+
RUCY_END
|
|
82
|
+
|
|
83
|
+
static
|
|
84
|
+
RUCY_DEF0(is_blink_visible)
|
|
85
|
+
{
|
|
86
|
+
CHECK;
|
|
87
|
+
return value(THIS->blink_visible());
|
|
88
|
+
}
|
|
89
|
+
RUCY_END
|
|
90
|
+
|
|
91
|
+
static
|
|
92
|
+
RUCY_DEF1(set_background_alpha, alpha)
|
|
93
|
+
{
|
|
94
|
+
CHECK;
|
|
95
|
+
THIS->set_background_alpha(to<float>(alpha));
|
|
96
|
+
}
|
|
97
|
+
RUCY_END
|
|
98
|
+
|
|
99
|
+
static
|
|
100
|
+
RUCY_DEF0(get_background_alpha)
|
|
101
|
+
{
|
|
102
|
+
CHECK;
|
|
103
|
+
return value(THIS->background_alpha());
|
|
104
|
+
}
|
|
105
|
+
RUCY_END
|
|
106
|
+
|
|
75
107
|
static
|
|
76
108
|
RUCY_DEF3(draw, painter, terminal, bounds)
|
|
77
109
|
{
|
|
@@ -100,6 +132,10 @@ Init_reflex_terminal_renderer ()
|
|
|
100
132
|
cRenderer.define_method("cell_height", get_cell_height);
|
|
101
133
|
cRenderer.define_method("bake_glyphs", bake_glyphs);
|
|
102
134
|
cRenderer.define_method( "glyph_count", get_glyph_count);
|
|
135
|
+
cRenderer.define_method("blink_visible=", set_blink_visible);
|
|
136
|
+
cRenderer.define_method("blink_visible?", is_blink_visible);
|
|
137
|
+
cRenderer.define_method("background_alpha=", set_background_alpha);
|
|
138
|
+
cRenderer.define_method("background_alpha", get_background_alpha);
|
|
103
139
|
cRenderer.define_method("draw", draw);
|
|
104
140
|
}
|
|
105
141
|
|
|
@@ -13,7 +13,7 @@ RUCY_DEFINE_CONVERT_TO(REFLEX_TERMINAL_EXPORT, Reflex::Terminal::OptionAsAlt)
|
|
|
13
13
|
|
|
14
14
|
#define THIS to<Reflex::Terminal*>(self)
|
|
15
15
|
|
|
16
|
-
#define CHECK
|
|
16
|
+
#define CHECK RUCY_CHECK_OBJ(Reflex::Terminal, self)
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
static
|
|
@@ -26,7 +26,7 @@ RUCY_END
|
|
|
26
26
|
static
|
|
27
27
|
RUCY_DEF3(initialize, columns, rows, scrollback)
|
|
28
28
|
{
|
|
29
|
-
|
|
29
|
+
RUCY_CHECK_PTR(Reflex::Terminal, self);
|
|
30
30
|
|
|
31
31
|
*THIS = Reflex::Terminal(to<int>(columns), to<int>(rows), to<size_t>(scrollback));
|
|
32
32
|
return self;
|
|
@@ -62,9 +62,9 @@ RUCY_DEF6(resize, columns, rows, cell_width, cell_height, screen_width, screen_h
|
|
|
62
62
|
{
|
|
63
63
|
CHECK;
|
|
64
64
|
THIS->resize(
|
|
65
|
-
to<int>(columns),
|
|
66
|
-
to<
|
|
67
|
-
to<int>(screen_width),
|
|
65
|
+
to<int>(columns), to<int>(rows),
|
|
66
|
+
to<Reflex::coord>(cell_width), to<Reflex::coord>(cell_height),
|
|
67
|
+
to<int>(screen_width), to<int>(screen_height));
|
|
68
68
|
return self;
|
|
69
69
|
}
|
|
70
70
|
RUCY_END
|
|
@@ -192,6 +192,14 @@ RUCY_DEF0(is_alive)
|
|
|
192
192
|
}
|
|
193
193
|
RUCY_END
|
|
194
194
|
|
|
195
|
+
static
|
|
196
|
+
RUCY_DEF0(is_blinking)
|
|
197
|
+
{
|
|
198
|
+
CHECK;
|
|
199
|
+
return value(THIS->is_blinking());
|
|
200
|
+
}
|
|
201
|
+
RUCY_END
|
|
202
|
+
|
|
195
203
|
static
|
|
196
204
|
RUCY_DEF0(is_mouse_tracking)
|
|
197
205
|
{
|
|
@@ -258,7 +266,7 @@ RUCY_DEF0(get_selected_text)
|
|
|
258
266
|
{
|
|
259
267
|
CHECK;
|
|
260
268
|
Reflex::String text = THIS->selected_text();
|
|
261
|
-
return value(text.c_str(), text.size()
|
|
269
|
+
return value(text.c_str(), text.size());
|
|
262
270
|
}
|
|
263
271
|
RUCY_END
|
|
264
272
|
|
|
@@ -294,7 +302,7 @@ RUCY_DEF0(each_line)
|
|
|
294
302
|
CHECK;
|
|
295
303
|
|
|
296
304
|
for (const auto& line : THIS->lines())
|
|
297
|
-
yield(value(line.c_str(), line.size()
|
|
305
|
+
yield(value(line.c_str(), line.size()));
|
|
298
306
|
return self;
|
|
299
307
|
}
|
|
300
308
|
RUCY_END
|
|
@@ -311,9 +319,10 @@ RUCY_DEF0(each_span)
|
|
|
311
319
|
{
|
|
312
320
|
yield(
|
|
313
321
|
value(span.x), value((int) y), value(span.width),
|
|
314
|
-
value(span.text.c_str(), span.text.size()
|
|
322
|
+
value(span.text.c_str(), span.text.size()),
|
|
315
323
|
span.fg == Reflex::Terminal::Span::COLOR_NONE ? nil() : value(span.fg),
|
|
316
324
|
span.bg == Reflex::Terminal::Span::COLOR_NONE ? nil() : value(span.bg),
|
|
325
|
+
span.ul == Reflex::Terminal::Span::COLOR_NONE ? nil() : value(span.ul),
|
|
317
326
|
value(span.attribs));
|
|
318
327
|
}
|
|
319
328
|
}
|
|
@@ -422,7 +431,7 @@ static
|
|
|
422
431
|
RUCY_DEF0(get_title)
|
|
423
432
|
{
|
|
424
433
|
CHECK;
|
|
425
|
-
return value(THIS->title()
|
|
434
|
+
return value(THIS->title());
|
|
426
435
|
}
|
|
427
436
|
RUCY_END
|
|
428
437
|
|
|
@@ -441,7 +450,7 @@ RUCY_DEF2(get_history_lines, offset, size)
|
|
|
441
450
|
|
|
442
451
|
Value result = array(NULL, 0);// a std::vector<Value> would be invisible to the gc
|
|
443
452
|
for (const auto& line : THIS->get_history_lines(to<int>(offset), to<int>(size)))
|
|
444
|
-
result.push(value(line.c_str(), line.size()
|
|
453
|
+
result.push(value(line.c_str(), line.size()));
|
|
445
454
|
return result;
|
|
446
455
|
}
|
|
447
456
|
RUCY_END
|
|
@@ -479,6 +488,7 @@ Init_reflex_terminal ()
|
|
|
479
488
|
cTerminal.define_method("write_wheel", write_wheel);
|
|
480
489
|
cTerminal.define_method("paste", paste);
|
|
481
490
|
cTerminal.define_method("alive?", is_alive);
|
|
491
|
+
cTerminal.define_method("blinking?", is_blinking);
|
|
482
492
|
cTerminal.define_method("mouse_tracking?", is_mouse_tracking);
|
|
483
493
|
cTerminal.define_method( "select", select);
|
|
484
494
|
cTerminal.define_method( "select_rect", select_rect);
|
|
@@ -518,6 +528,13 @@ Init_reflex_terminal ()
|
|
|
518
528
|
cTerminal.define_const("UNDERLINE_SHIFT", Reflex::Terminal::Span::UNDERLINE_SHIFT);
|
|
519
529
|
cTerminal.define_const("UNDERLINE_MASK", Reflex::Terminal::Span::UNDERLINE_MASK);
|
|
520
530
|
|
|
531
|
+
cTerminal.define_const("UNDERLINE_NONE", Reflex::Terminal::Span::UNDERLINE_NONE);
|
|
532
|
+
cTerminal.define_const("UNDERLINE_SINGLE", Reflex::Terminal::Span::UNDERLINE_SINGLE);
|
|
533
|
+
cTerminal.define_const("UNDERLINE_DOUBLE", Reflex::Terminal::Span::UNDERLINE_DOUBLE);
|
|
534
|
+
cTerminal.define_const("UNDERLINE_CURLY", Reflex::Terminal::Span::UNDERLINE_CURLY);
|
|
535
|
+
cTerminal.define_const("UNDERLINE_DOTTED", Reflex::Terminal::Span::UNDERLINE_DOTTED);
|
|
536
|
+
cTerminal.define_const("UNDERLINE_DASHED", Reflex::Terminal::Span::UNDERLINE_DASHED);
|
|
537
|
+
|
|
521
538
|
cTerminal.define_const("CURSOR_BAR", Reflex::Terminal::Cursor::BAR);
|
|
522
539
|
cTerminal.define_const("CURSOR_BLOCK", Reflex::Terminal::Cursor::BLOCK);
|
|
523
540
|
cTerminal.define_const("CURSOR_UNDERLINE", Reflex::Terminal::Cursor::UNDERLINE);
|