reflex-terminal 0.1.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 (46) hide show
  1. checksums.yaml +7 -0
  2. data/.doc/ext/reflex-terminal/native.cpp +19 -0
  3. data/.doc/ext/reflex-terminal/renderer.cpp +110 -0
  4. data/.doc/ext/reflex-terminal/terminal.cpp +530 -0
  5. data/.github/PULL_REQUEST_TEMPLATE.md +12 -0
  6. data/.github/workflows/release-gem.yml +60 -0
  7. data/.github/workflows/tag.yml +35 -0
  8. data/.github/workflows/test.yml +46 -0
  9. data/.github/workflows/utils.rb +127 -0
  10. data/CONTRIBUTING.md +7 -0
  11. data/ChangeLog.md +6 -0
  12. data/Gemfile +5 -0
  13. data/LICENSE +21 -0
  14. data/README.md +100 -0
  15. data/Rakefile +44 -0
  16. data/VERSION +1 -0
  17. data/examples/terminal.rb +101 -0
  18. data/ext/reflex-terminal/defs.h +17 -0
  19. data/ext/reflex-terminal/extconf.rb +29 -0
  20. data/ext/reflex-terminal/native.cpp +19 -0
  21. data/ext/reflex-terminal/renderer.cpp +118 -0
  22. data/ext/reflex-terminal/terminal.cpp +572 -0
  23. data/include/reflex/terminal.h +233 -0
  24. data/include/reflex-terminal/defs.h +36 -0
  25. data/include/reflex-terminal/renderer.h +57 -0
  26. data/include/reflex-terminal/ruby/renderer.h +41 -0
  27. data/include/reflex-terminal/ruby/terminal.h +43 -0
  28. data/include/reflex-terminal/ruby.h +11 -0
  29. data/include/reflex-terminal.h +13 -0
  30. data/lib/reflex/bell_event.rb +15 -0
  31. data/lib/reflex/terminal.rb +168 -0
  32. data/lib/reflex/terminal_view.rb +268 -0
  33. data/lib/reflex-terminal/ext.rb +2 -0
  34. data/lib/reflex-terminal/extension.rb +41 -0
  35. data/lib/reflex-terminal.rb +7 -0
  36. data/reflex-terminal.gemspec +39 -0
  37. data/src/pty.cpp +236 -0
  38. data/src/renderer.cpp +365 -0
  39. data/src/terminal.cpp +1547 -0
  40. data/src/terminal.h +66 -0
  41. data/src/win32/pty.cpp +387 -0
  42. data/test/helper.rb +11 -0
  43. data/test/test_renderer.rb +113 -0
  44. data/test/test_terminal.rb +683 -0
  45. data/test/test_terminal_view.rb +182 -0
  46. metadata +152 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d7279668d5fe73e778c224a568ae79b829c138117f4d1458d73278451847a7f5
4
+ data.tar.gz: 157ebc265844d375f75b258f87890ce561e93a5c2225b64800e6063f02d53d1e
5
+ SHA512:
6
+ metadata.gz: f3ebfbc2b62e3b3d2d2194d9c278518a2bb2966b34e6f6e8a8bf48ae44f862a520e75742746107db912847989bf09355c805c4799836c73f87739d0f19c99471
7
+ data.tar.gz: a402b3b23959dc21c314a2d39ddda704363f0740a9603ed1ee5cfeb8e590ae6ce77ec9c44cf4edc4e0f7033d4ab428cb67a3b5fef3f1719f20edc2348b5757b7
@@ -0,0 +1,19 @@
1
+ #include "defs.h"
2
+
3
+
4
+ void Init_reflex_terminal ();
5
+ void Init_reflex_terminal_renderer ();
6
+
7
+
8
+ extern "C" void
9
+ Init_reflex_terminal_ext ()
10
+ {
11
+ RUCY_TRY
12
+
13
+ Rucy::init();
14
+
15
+ Init_reflex_terminal();
16
+ Init_reflex_terminal_renderer();
17
+
18
+ RUCY_CATCH
19
+ }
@@ -0,0 +1,110 @@
1
+ #include "reflex-terminal/ruby/renderer.h"
2
+
3
+
4
+ #include <rays/ruby/bounds.h>
5
+ #include <rays/ruby/font.h>
6
+ #include <rays/ruby/painter.h>
7
+ #include <reflex-terminal/ruby/terminal.h>
8
+ #include "defs.h"
9
+
10
+
11
+ RUCY_DEFINE_VALUE_FROM_TO(REFLEX_TERMINAL_EXPORT, ReflexTerminal::Renderer)
12
+
13
+ #define THIS to<ReflexTerminal::Renderer*>(self)
14
+
15
+ #define CHECK RUCY_CHECK_OBJ(ReflexTerminal::Renderer, self)
16
+
17
+
18
+ static
19
+ VALUE alloc(VALUE klass)
20
+ {
21
+ return new_type<ReflexTerminal::Renderer>(klass);
22
+ }
23
+
24
+ static
25
+ VALUE set_font(VALUE self, VALUE font)
26
+ {
27
+ CHECK;
28
+ THIS->set_font(to<Rays::Font&>(font));
29
+ return font;
30
+ }
31
+
32
+ static
33
+ VALUE get_font(VALUE self)
34
+ {
35
+ CHECK;
36
+ return value(THIS->font());
37
+ }
38
+
39
+ static
40
+ VALUE get_cell_width(VALUE self)
41
+ {
42
+ CHECK;
43
+ return value(THIS->cell_width());
44
+ }
45
+
46
+ static
47
+ VALUE get_cell_height(VALUE self)
48
+ {
49
+ CHECK;
50
+ return value(THIS->cell_height());
51
+ }
52
+
53
+ static
54
+ VALUE bake_glyphs(VALUE self, VALUE terminal)
55
+ {
56
+ CHECK;
57
+ THIS->bake_glyphs(to<Reflex::Terminal&>(terminal));
58
+ return self;
59
+ }
60
+
61
+ static
62
+ VALUE get_glyph_count(VALUE self)
63
+ {
64
+ CHECK;
65
+ return value(THIS->glyph_count());
66
+ }
67
+
68
+ static
69
+ VALUE draw(VALUE self, VALUE painter, VALUE terminal, VALUE bounds)
70
+ {
71
+ CHECK;
72
+ THIS->draw(
73
+ to<Rays::Painter*>(painter),
74
+ to<Reflex::Terminal&>(terminal),
75
+ to<Rays::Bounds>(bounds));
76
+ return self;
77
+ }
78
+
79
+
80
+ static Class cRenderer;
81
+
82
+ void
83
+ Init_reflex_terminal_renderer ()
84
+ {
85
+ Module mReflexTerminal = rb_define_module("ReflexTerminal");
86
+
87
+ cRenderer = rb_define_class_under(mReflexTerminal, "Renderer", rb_cObject);
88
+ rb_define_alloc_func(cRenderer, alloc);
89
+ rb_define_method(cRenderer, "font=", RUBY_METHOD_FUNC(set_font), 1);
90
+ rb_define_method(cRenderer, "font", RUBY_METHOD_FUNC(get_font), 0);
91
+ rb_define_method(cRenderer, "cell_width", RUBY_METHOD_FUNC(get_cell_width), 0);
92
+ rb_define_method(cRenderer, "cell_height", RUBY_METHOD_FUNC(get_cell_height), 0);
93
+ rb_define_method(cRenderer, "bake_glyphs", RUBY_METHOD_FUNC(bake_glyphs), 1);
94
+ rb_define_method(cRenderer, "glyph_count", RUBY_METHOD_FUNC(get_glyph_count), 0);
95
+ rb_define_method(cRenderer, "draw", RUBY_METHOD_FUNC(draw), 3);
96
+ }
97
+
98
+
99
+ namespace ReflexTerminal
100
+ {
101
+
102
+
103
+ Class
104
+ renderer_class ()
105
+ {
106
+ return cRenderer;
107
+ }
108
+
109
+
110
+ }// ReflexTerminal
@@ -0,0 +1,530 @@
1
+ #include "reflex-terminal/ruby/terminal.h"
2
+
3
+
4
+ #include <xot/exception.h>
5
+ #include <rays/ruby/color.h>
6
+ #include <reflex/ruby/event.h>
7
+ #include "defs.h"
8
+
9
+
10
+ RUCY_DEFINE_VALUE_FROM_TO(REFLEX_TERMINAL_EXPORT, Reflex::Terminal)
11
+
12
+ RUCY_DEFINE_CONVERT_TO(REFLEX_TERMINAL_EXPORT, Reflex::Terminal::OptionAsAlt)
13
+
14
+ #define THIS to<Reflex::Terminal*>(self)
15
+
16
+ #define CHECK RUCY_CHECK_OBJECT(Reflex::Terminal, self)
17
+
18
+
19
+ static
20
+ VALUE alloc(VALUE klass)
21
+ {
22
+ return new_type<Reflex::Terminal>(klass);
23
+ }
24
+
25
+ static
26
+ VALUE initialize(VALUE self, VALUE columns, VALUE rows, VALUE scrollback)
27
+ {
28
+ RUCY_CHECK_OBJ(Reflex::Terminal, self);
29
+
30
+ *THIS = Reflex::Terminal(to<int>(columns), to<int>(rows), to<size_t>(scrollback));
31
+ return self;
32
+ }
33
+
34
+ static
35
+ VALUE initialize_copy(VALUE self, VALUE obj)
36
+ {
37
+ Xot::invalid_state_error(__FILE__, __LINE__, "can not duplicate Terminal");
38
+ }
39
+
40
+ static
41
+ VALUE update(VALUE self)
42
+ {
43
+ CHECK;
44
+ return value(THIS->update());
45
+ }
46
+
47
+ static
48
+ VALUE reset(VALUE self)
49
+ {
50
+ CHECK;
51
+ THIS->reset();
52
+ return self;
53
+ }
54
+
55
+ static
56
+ VALUE resize(VALUE self, VALUE columns, VALUE rows, VALUE cell_width, VALUE cell_height, VALUE screen_width, VALUE screen_height)
57
+ {
58
+ CHECK;
59
+ THIS->resize(
60
+ to<int>(columns), to<int>(rows),
61
+ to<int>(cell_width), to<int>(cell_height),
62
+ to<int>(screen_width), to<int>(screen_height));
63
+ return self;
64
+ }
65
+
66
+ static
67
+ VALUE feed(VALUE self, VALUE bytes)
68
+ {
69
+ CHECK;
70
+ if (!bytes.is_s())
71
+ Rucy::type_error(__FILE__, __LINE__, "bytes must be a String");
72
+
73
+ // feed() takes a raw byte stream, so avoid to<const char*>/c_str()
74
+ // (StringValueCStr rejects NUL bytes) and Value#size (character
75
+ // count, not the byte length)
76
+ RubyValue str = bytes.value();
77
+ THIS->feed(RSTRING_PTR(str), RSTRING_LEN(str));
78
+ return self;
79
+ }
80
+
81
+ static
82
+ VALUE read_pending_input(VALUE self)
83
+ {
84
+ CHECK;
85
+ // a raw byte stream for the child process
86
+ Reflex::String input = THIS->read_pending_input();
87
+ return value(input.data(), input.size(), rb_ascii8bit_encoding());
88
+ }
89
+
90
+ static
91
+ VALUE spawn(VALUE self, VALUE args, VALUE envs)
92
+ {
93
+ CHECK;
94
+
95
+ Reflex::StringList list;
96
+ for (size_t i = 0, size = args.size(); i < size; ++i)
97
+ list.emplace_back(args[i].c_str());
98
+
99
+ Reflex::Terminal::EnvMap map;
100
+ Value names = envs.call("keys");
101
+ for (size_t i = 0, size = names.size(); i < size; ++i)
102
+ {
103
+ Value name = names[i];
104
+ Value value = envs.get(name);
105
+ if (value)
106
+ map[name.c_str()] = value.c_str();
107
+ else
108
+ map[name.c_str()] = std::nullopt;// nil removes the variable
109
+ }
110
+
111
+ THIS->spawn(list, map);
112
+ return self;
113
+ }
114
+
115
+ static
116
+ VALUE close(VALUE self)
117
+ {
118
+ CHECK;
119
+ THIS->close();
120
+ return self;
121
+ }
122
+
123
+ static
124
+ VALUE write(VALUE self, VALUE bytes)
125
+ {
126
+ CHECK;
127
+ if (!bytes.is_s())
128
+ Rucy::type_error(__FILE__, __LINE__, "bytes must be a String");
129
+
130
+ // write() takes a raw byte stream (see feed)
131
+ RubyValue str = bytes.value();
132
+ THIS->write(RSTRING_PTR(str), RSTRING_LEN(str));
133
+ return self;
134
+ }
135
+
136
+ static
137
+ VALUE write_key(VALUE self, VALUE event)
138
+ {
139
+ CHECK;
140
+ THIS->write_key(to<Reflex::KeyEvent&>(event));
141
+ return self;
142
+ }
143
+
144
+ static
145
+ VALUE write_pointer(VALUE self, VALUE event)
146
+ {
147
+ CHECK;
148
+ THIS->write_pointer(to<Reflex::PointerEvent&>(event));
149
+ return self;
150
+ }
151
+
152
+ static
153
+ VALUE write_wheel(VALUE self, VALUE event)
154
+ {
155
+ CHECK;
156
+ THIS->write_wheel(to<Reflex::WheelEvent&>(event));
157
+ return self;
158
+ }
159
+
160
+ static
161
+ VALUE paste(VALUE self, VALUE text)
162
+ {
163
+ CHECK;
164
+ if (!text.is_s())
165
+ Rucy::type_error(__FILE__, __LINE__, "text must be a String");
166
+
167
+ RubyValue str = text.value();
168
+ THIS->paste(RSTRING_PTR(str), RSTRING_LEN(str));
169
+ return self;
170
+ }
171
+
172
+ static
173
+ VALUE is_alive(VALUE self)
174
+ {
175
+ CHECK;
176
+ return value(THIS->is_alive());
177
+ }
178
+
179
+ static
180
+ VALUE is_mouse_tracking(VALUE self)
181
+ {
182
+ CHECK;
183
+ return value(THIS->is_mouse_tracking());
184
+ }
185
+
186
+ static
187
+ VALUE select(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2)
188
+ {
189
+ CHECK;
190
+ THIS->select(to<int>(x1), to<int>(y1), to<int>(x2), to<int>(y2));
191
+ return self;
192
+ }
193
+
194
+ static
195
+ VALUE select_rect(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2)
196
+ {
197
+ CHECK;
198
+ THIS->select_rect(to<int>(x1), to<int>(y1), to<int>(x2), to<int>(y2));
199
+ return self;
200
+ }
201
+
202
+ static
203
+ VALUE select_word(VALUE self, VALUE x, VALUE y)
204
+ {
205
+ CHECK;
206
+ THIS->select_word(to<int>(x), to<int>(y));
207
+ return self;
208
+ }
209
+
210
+ static
211
+ VALUE select_line(VALUE self, VALUE y)
212
+ {
213
+ CHECK;
214
+ THIS->select_line(to<int>(y));
215
+ return self;
216
+ }
217
+
218
+ static
219
+ VALUE deselect(VALUE self)
220
+ {
221
+ CHECK;
222
+ THIS->deselect();
223
+ return self;
224
+ }
225
+
226
+ static
227
+ VALUE has_selection(VALUE self)
228
+ {
229
+ CHECK;
230
+ return value(THIS->has_selection());
231
+ }
232
+
233
+ static
234
+ VALUE get_selected_text(VALUE self)
235
+ {
236
+ CHECK;
237
+ Reflex::String text = THIS->selected_text();
238
+ return value(text.c_str(), text.size(), rb_utf8_encoding());
239
+ }
240
+
241
+ static
242
+ VALUE scroll_to(VALUE self, VALUE row)
243
+ {
244
+ CHECK;
245
+ THIS->scroll_to(to<int>(row));
246
+ return self;
247
+ }
248
+
249
+ static
250
+ VALUE scroll_by(VALUE self, VALUE rows)
251
+ {
252
+ CHECK;
253
+ THIS->scroll_by(to<int>(rows));
254
+ return self;
255
+ }
256
+
257
+ static
258
+ VALUE get_scroll(VALUE self)
259
+ {
260
+ CHECK;
261
+ return value(THIS->scroll());
262
+ }
263
+
264
+ static
265
+ VALUE each_line(VALUE self)
266
+ {
267
+ CHECK;
268
+
269
+ for (const auto& line : THIS->lines())
270
+ yield(value(line.c_str(), line.size(), rb_utf8_encoding()));
271
+ return self;
272
+ }
273
+
274
+ static
275
+ VALUE each_span(VALUE self)
276
+ {
277
+ CHECK;
278
+
279
+ const auto& rows = THIS->spans();
280
+ for (size_t y = 0; y < rows.size(); ++y)
281
+ {
282
+ for (const auto& span : rows[y])
283
+ {
284
+ yield(
285
+ value(span.x), value((int) y), value(span.width),
286
+ value(span.text.c_str(), span.text.size(), rb_utf8_encoding()),
287
+ span.fg == Reflex::Terminal::Span::COLOR_NONE ? nil() : value(span.fg),
288
+ span.bg == Reflex::Terminal::Span::COLOR_NONE ? nil() : value(span.bg),
289
+ value(span.attribs));
290
+ }
291
+ }
292
+ return self;
293
+ }
294
+
295
+ static
296
+ VALUE set_option_as_alt(VALUE self, VALUE state)
297
+ {
298
+ CHECK;
299
+ THIS->set_option_as_alt(to<Reflex::Terminal::OptionAsAlt>(state));
300
+ return state;
301
+ }
302
+
303
+ static
304
+ VALUE get_option_as_alt(VALUE self)
305
+ {
306
+ CHECK;
307
+ return value((int) THIS->option_as_alt());
308
+ }
309
+
310
+ static
311
+ VALUE get_columns(VALUE self)
312
+ {
313
+ CHECK;
314
+ return value(THIS->columns());
315
+ }
316
+
317
+ static
318
+ VALUE get_rows(VALUE self)
319
+ {
320
+ CHECK;
321
+ return value(THIS->rows());
322
+ }
323
+
324
+ static
325
+ VALUE get_cursor(VALUE self)
326
+ {
327
+ CHECK;
328
+
329
+ Reflex::Terminal::Cursor cursor = THIS->cursor();
330
+ Value values[] = {
331
+ value(cursor.x),
332
+ value(cursor.y),
333
+ value((int) cursor.style),
334
+ value(cursor.visible)
335
+ };
336
+ return array(values, 4);
337
+ }
338
+
339
+ static Reflex::Terminal::ColorIndex
340
+ to_color_index (Value index)
341
+ {
342
+ int i = to<int>(index);
343
+ if (i < Reflex::Terminal::COLOR_FOREGROUND || Reflex::Terminal::COLOR_PALETTE_LAST < i)
344
+ Rucy::argument_error(__FILE__, __LINE__, "invalid color index: %d", i);
345
+
346
+ return (Reflex::Terminal::ColorIndex) i;
347
+ }
348
+
349
+ static
350
+ VALUE set_default_color(VALUE self, VALUE index, VALUE color)
351
+ {
352
+ CHECK;
353
+ THIS->set_default_color(to_color_index(index), to<Rays::Color>(color));
354
+ }
355
+
356
+ static
357
+ VALUE clear_default_color(VALUE self, VALUE index)
358
+ {
359
+ CHECK;
360
+ THIS->clear_default_color(to_color_index(index));
361
+ }
362
+
363
+ static
364
+ VALUE get_default_color(VALUE self, VALUE index)
365
+ {
366
+ CHECK;
367
+
368
+ Rays::Color color;
369
+ if (THIS->get_default_color(to_color_index(index), &color))
370
+ return value(color);
371
+ }
372
+
373
+ static
374
+ VALUE get_color(VALUE self, VALUE index)
375
+ {
376
+ CHECK;
377
+
378
+ Rays::Color color;
379
+ if (THIS->get_color(to_color_index(index), &color))
380
+ return value(color);
381
+ }
382
+
383
+ static
384
+ VALUE get_title(VALUE self)
385
+ {
386
+ CHECK;
387
+ return value(THIS->title(), rb_utf8_encoding());
388
+ }
389
+
390
+ static
391
+ VALUE get_history_rows(VALUE self)
392
+ {
393
+ CHECK;
394
+ return value(THIS->history_rows());
395
+ }
396
+
397
+ static
398
+ VALUE get_history_lines(VALUE self, VALUE offset, VALUE size)
399
+ {
400
+ CHECK;
401
+
402
+ Value result = array(NULL, 0);// a std::vector<Value> would be invisible to the gc
403
+ for (const auto& line : THIS->get_history_lines(to<int>(offset), to<int>(size)))
404
+ result.push(value(line.c_str(), line.size(), rb_utf8_encoding()));
405
+ return result;
406
+ }
407
+
408
+ static
409
+ VALUE get_bells(VALUE self)
410
+ {
411
+ CHECK;
412
+ return value(THIS->bells());
413
+ }
414
+
415
+
416
+ static Class cTerminal;
417
+
418
+ void
419
+ Init_reflex_terminal ()
420
+ {
421
+ Module mReflex = rb_define_module("Reflex");
422
+
423
+ cTerminal = rb_define_class_under(mReflex, "Terminal", rb_cObject);
424
+ rb_define_alloc_func(cTerminal, alloc);
425
+ cTerminal.define_private_method("initialize!", initialize);
426
+ rb_define_private_method(cTerminal, "initialize_copy", RUBY_METHOD_FUNC(initialize_copy), 1);
427
+ rb_define_method(cTerminal, "update", RUBY_METHOD_FUNC(update), 0);
428
+ rb_define_method(cTerminal, "reset", RUBY_METHOD_FUNC(reset), 0);
429
+ cTerminal.define_method("resize!", resize);
430
+ rb_define_method(cTerminal, "feed", RUBY_METHOD_FUNC(feed), 1);
431
+ rb_define_method(cTerminal, "read_pending_input", RUBY_METHOD_FUNC(read_pending_input), 0);
432
+ cTerminal.define_method("spawn!", spawn);
433
+ rb_define_method(cTerminal, "close", RUBY_METHOD_FUNC(close), 0);
434
+ rb_define_method(cTerminal, "write", RUBY_METHOD_FUNC(write), 1);
435
+ rb_define_method(cTerminal, "write_key", RUBY_METHOD_FUNC(write_key), 1);
436
+ rb_define_method(cTerminal, "write_pointer", RUBY_METHOD_FUNC(write_pointer), 1);
437
+ rb_define_method(cTerminal, "write_wheel", RUBY_METHOD_FUNC(write_wheel), 1);
438
+ rb_define_method(cTerminal, "paste", RUBY_METHOD_FUNC(paste), 1);
439
+ cTerminal.define_method("alive?", is_alive);
440
+ cTerminal.define_method("mouse_tracking?", is_mouse_tracking);
441
+ rb_define_method(cTerminal, "select", RUBY_METHOD_FUNC(select), 4);
442
+ rb_define_method(cTerminal, "select_rect", RUBY_METHOD_FUNC(select_rect), 4);
443
+ rb_define_method(cTerminal, "select_word", RUBY_METHOD_FUNC(select_word), 2);
444
+ rb_define_method(cTerminal, "select_line", RUBY_METHOD_FUNC(select_line), 1);
445
+ rb_define_method(cTerminal, "deselect", RUBY_METHOD_FUNC(deselect), 0);
446
+ cTerminal.define_method( "selection?", has_selection);
447
+ rb_define_method(cTerminal, "selected_text", RUBY_METHOD_FUNC(get_selected_text), 0);
448
+ rb_define_method(cTerminal, "scroll_to", RUBY_METHOD_FUNC(scroll_to), 1);
449
+ rb_define_method(cTerminal, "scroll_by", RUBY_METHOD_FUNC(scroll_by), 1);
450
+ rb_define_method(cTerminal, "scroll", RUBY_METHOD_FUNC(get_scroll), 0);
451
+ cTerminal.define_private_method("each_line!", each_line);
452
+ cTerminal.define_private_method("each_span!", each_span);
453
+ rb_define_method(cTerminal, "option_as_alt=", RUBY_METHOD_FUNC(set_option_as_alt), 1);
454
+ rb_define_method(cTerminal, "option_as_alt", RUBY_METHOD_FUNC(get_option_as_alt), 0);
455
+ rb_define_method(cTerminal, "columns", RUBY_METHOD_FUNC(get_columns), 0);
456
+ rb_define_method(cTerminal, "rows", RUBY_METHOD_FUNC(get_rows), 0);
457
+ rb_define_method(cTerminal, "cursor", RUBY_METHOD_FUNC(get_cursor), 0);
458
+ cTerminal.define_private_method( "set_default_color!", set_default_color);
459
+ cTerminal.define_private_method("clear_default_color!", clear_default_color);
460
+ cTerminal.define_private_method( "get_default_color!", get_default_color);
461
+ cTerminal.define_private_method( "get_color!", get_color);
462
+ rb_define_method(cTerminal, "title", RUBY_METHOD_FUNC(get_title), 0);
463
+ rb_define_method(cTerminal, "history_rows", RUBY_METHOD_FUNC(get_history_rows), 0);
464
+ cTerminal.define_private_method("get_history_lines!", get_history_lines);
465
+ rb_define_method(cTerminal, "bells", RUBY_METHOD_FUNC(get_bells), 0);
466
+
467
+ cTerminal.define_const("BOLD", Reflex::Terminal::Span::BOLD);
468
+ cTerminal.define_const("ITALIC", Reflex::Terminal::Span::ITALIC);
469
+ cTerminal.define_const("FAINT", Reflex::Terminal::Span::FAINT);
470
+ cTerminal.define_const("BLINK", Reflex::Terminal::Span::BLINK);
471
+ cTerminal.define_const("INVISIBLE", Reflex::Terminal::Span::INVISIBLE);
472
+ cTerminal.define_const("STRIKETHROUGH", Reflex::Terminal::Span::STRIKETHROUGH);
473
+ cTerminal.define_const("OVERLINE", Reflex::Terminal::Span::OVERLINE);
474
+ cTerminal.define_const("INVERSE", Reflex::Terminal::Span::INVERSE);
475
+ cTerminal.define_const("SELECTED", Reflex::Terminal::Span::SELECTED);
476
+ cTerminal.define_const("UNDERLINE_SHIFT", Reflex::Terminal::Span::UNDERLINE_SHIFT);
477
+ cTerminal.define_const("UNDERLINE_MASK", Reflex::Terminal::Span::UNDERLINE_MASK);
478
+
479
+ cTerminal.define_const("CURSOR_BAR", Reflex::Terminal::Cursor::BAR);
480
+ cTerminal.define_const("CURSOR_BLOCK", Reflex::Terminal::Cursor::BLOCK);
481
+ cTerminal.define_const("CURSOR_UNDERLINE", Reflex::Terminal::Cursor::UNDERLINE);
482
+ cTerminal.define_const("CURSOR_BLOCK_HOLLOW", Reflex::Terminal::Cursor::BLOCK_HOLLOW);
483
+
484
+ cTerminal.define_const("COLOR_FOREGROUND", Reflex::Terminal::COLOR_FOREGROUND);
485
+ cTerminal.define_const("COLOR_BACKGROUND", Reflex::Terminal::COLOR_BACKGROUND);
486
+ cTerminal.define_const("COLOR_CURSOR", Reflex::Terminal::COLOR_CURSOR);
487
+ cTerminal.define_const("COLOR_PALETTE_FIRST", Reflex::Terminal::COLOR_PALETTE_FIRST);
488
+ cTerminal.define_const("COLOR_PALETTE_LAST", Reflex::Terminal::COLOR_PALETTE_LAST);
489
+
490
+ cTerminal.define_const("OPTION_AS_ALT_OFF", Reflex::Terminal::OPTION_AS_ALT_OFF);
491
+ cTerminal.define_const("OPTION_AS_ALT_ON", Reflex::Terminal::OPTION_AS_ALT_ON);
492
+ cTerminal.define_const("OPTION_AS_ALT_LEFT", Reflex::Terminal::OPTION_AS_ALT_LEFT);
493
+ cTerminal.define_const("OPTION_AS_ALT_RIGHT", Reflex::Terminal::OPTION_AS_ALT_RIGHT);
494
+ }
495
+
496
+
497
+ namespace Rucy
498
+ {
499
+
500
+
501
+ template <> REFLEX_TERMINAL_EXPORT Reflex::Terminal::OptionAsAlt
502
+ value_to<Reflex::Terminal::OptionAsAlt> (
503
+ int argc, const Value* argv, bool convert)
504
+ {
505
+ if (argc <= 0 || !argv)
506
+ argument_error(__FILE__, __LINE__);
507
+
508
+ int state = value_to<int>(*argv, convert);
509
+ if (state < 0 || Reflex::Terminal::OPTION_AS_ALT_MAX <= state)
510
+ argument_error(__FILE__, __LINE__, "invalid option_as_alt state");
511
+
512
+ return (Reflex::Terminal::OptionAsAlt) state;
513
+ }
514
+
515
+
516
+ }// Rucy
517
+
518
+
519
+ namespace Reflex
520
+ {
521
+
522
+
523
+ Class
524
+ terminal_class ()
525
+ {
526
+ return cTerminal;
527
+ }
528
+
529
+
530
+ }// Reflex
@@ -0,0 +1,12 @@
1
+ ## Pull Requests Not Accepted 🚫
2
+
3
+ Thank you for your interest in contributing!
4
+ However, this repository does not accept pull requests directly.
5
+
6
+ ### Where to Contribute?
7
+
8
+ Please submit your changes to the [xord/all](https://github.com/xord/all) monorepo, which serves as the primary repository for all our main libraries.
9
+
10
+ For more details, please refer to our [contribution guidelines](../CONTRIBUTING.md).
11
+
12
+ Thanks for your understanding! 🙌