├── .github
├── FUNDING.yml
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── design_plan.md
│ └── missing-feature.md
├── .gitignore
├── .idea
├── .gitignore
├── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── copyright
│ ├── profiles_settings.xml
│ └── r3bl.xml
├── dictionaries
│ └── project.xml
├── icon.svg
├── inspectionProfiles
│ ├── Project_Default.xml
│ └── profiles_settings.xml
├── modules.xml
├── r3bl-open-core.iml
├── rust.xml
└── vcs.xml
├── .prettierrc
├── .vscode
├── extensions.json
├── launch.json
└── settings.json
├── 1.code-search
├── 2.code-search
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Cargo.lock
├── Cargo.toml
├── LICENSE
├── README.md
├── analytics_schema
├── Cargo.toml
├── README.md
└── src
│ ├── analytics_data.rs
│ └── lib.rs
├── bacon.toml
├── cmdr
├── Cargo.toml
├── README.md
├── docker
│ ├── Dockerfile
│ ├── README.md
│ ├── docker-compose.yml
│ └── install.bash
├── r3bl-cmdr-eap.svg
├── r3bl-cmdr.svg
├── r3bl-term.svg
├── run.nu
├── src
│ ├── analytics_client
│ │ ├── analytics_action.rs
│ │ ├── config_folder.rs
│ │ ├── http_client.rs
│ │ ├── mod.rs
│ │ ├── proxy_machine_id.rs
│ │ ├── report_analytics.rs
│ │ ├── ui_str.rs
│ │ └── upgrade_check.rs
│ ├── bin
│ │ ├── edi.rs
│ │ ├── giti.rs
│ │ └── rc.rs
│ ├── common
│ │ ├── fmt.rs
│ │ ├── mod.rs
│ │ └── ui_templates.rs
│ ├── edi
│ │ ├── app_main.rs
│ │ ├── clap_config.rs
│ │ ├── launcher.rs
│ │ ├── mod.rs
│ │ ├── state.rs
│ │ ├── ui_str.rs
│ │ └── ui_templates.rs
│ ├── giti
│ │ ├── branch
│ │ │ ├── branch_checkout_command.rs
│ │ │ ├── branch_command.rs
│ │ │ ├── branch_delete_command.rs
│ │ │ ├── branch_new_command.rs
│ │ │ └── mod.rs
│ │ ├── clap_config.rs
│ │ ├── common_types.rs
│ │ ├── git.rs
│ │ ├── mod.rs
│ │ └── ui_str.rs
│ ├── lib.rs
│ └── rc
│ │ ├── app.rs
│ │ └── mod.rs
└── videos
│ ├── edi.gif
│ └── giti.gif
├── config.toml
├── deny.toml
├── docs
├── README.md
├── compositor.svg
├── contributing_guides
│ ├── BRANCH.md
│ ├── COMMIT_MESSAGE.md
│ ├── ISSUE.md
│ ├── PULL_REQUEST.md
│ └── STYLE_GUIDE.md
├── dd_autocomplete.md
├── dd_compositor.md
├── dd_editor_component.md
├── diagrams.drawio
├── diagrams.drawio.svg
├── memory-architecture.drawio.svg
├── r3bl_terminal_async_clip_ffmpeg.gif
└── release-guide.md
├── done.md
├── r3bl-term.svg
├── run.nu
├── rust-toolchain.toml
├── rustfmt.toml
├── scratch.rs
├── script_lib.nu
├── todo.md
└── tui
├── Cargo.toml
├── README.md
├── examples
├── choose_interactive.rs
├── choose_quiz_game.rs
├── choose_with_and_without_readline_async.rs
├── readline_async.rs
├── shell_async.rs
├── spinner.rs
└── tui_apps
│ ├── ex_app_no_layout
│ ├── app_main.rs
│ ├── launcher.rs
│ ├── mod.rs
│ └── state.rs
│ ├── ex_app_with_1col_layout
│ ├── app_main.rs
│ ├── launcher.rs
│ ├── mod.rs
│ ├── single_column_component.rs
│ └── state.rs
│ ├── ex_app_with_2col_layout
│ ├── app_main.rs
│ ├── column_render_component.rs
│ ├── launcher.rs
│ ├── mod.rs
│ └── state.rs
│ ├── ex_editor
│ ├── app_main.rs
│ ├── app_signal.rs
│ ├── launcher.rs
│ ├── mod.rs
│ └── state.rs
│ ├── ex_pitch
│ ├── app_main.rs
│ ├── launcher.rs
│ ├── mod.rs
│ ├── slide0.md
│ ├── slide1.md
│ ├── slide10.md
│ ├── slide11.md
│ ├── slide2.md
│ ├── slide3.md
│ ├── slide3_1.md
│ ├── slide4.md
│ ├── slide5.md
│ ├── slide6.md
│ ├── slide7.md
│ ├── slide8.md
│ ├── slide9.md
│ └── state.rs
│ ├── ex_rc
│ ├── app_main.rs
│ ├── launcher.rs
│ ├── mod.rs
│ ├── slide1.md
│ ├── slide2.md
│ ├── slide3.md
│ └── state.rs
│ └── main.rs
├── r3bl-tui.svg
├── run.nu
└── src
├── core
├── ansi
│ ├── ansi_escape_codes.rs
│ ├── ansi_styled_text.rs
│ ├── ast_color.rs
│ ├── convert.rs
│ ├── detect_color_support.rs
│ ├── mod.rs
│ └── transform_color.rs
├── common
│ ├── common_enums.rs
│ ├── common_math.rs
│ ├── common_result_and_error.rs
│ ├── get_mem_size.rs
│ ├── miette_setup_global_report_handler.rs
│ ├── mod.rs
│ ├── ordered_map.rs
│ ├── rate_limiter.rs
│ ├── ring_buffer.rs
│ ├── ring_buffer_heap.rs
│ ├── ring_buffer_stack.rs
│ ├── telemetry.rs
│ └── time_duration.rs
├── decl_macros
│ ├── macros.rs
│ └── mod.rs
├── glyphs.rs
├── log
│ ├── custom_event_formatter.rs
│ ├── log_public_api.rs
│ ├── mod.rs
│ ├── rolling_file_appender_impl.rs
│ ├── tracing_config.rs
│ └── tracing_init.rs
├── misc
│ ├── calc_str_len.rs
│ ├── formatter.rs
│ ├── friendly_random_id.rs
│ ├── mod.rs
│ └── string_helpers.rs
├── mod.rs
├── script
│ ├── apt_install.rs
│ ├── command_impl
│ │ ├── command_run_result.rs
│ │ ├── command_runner.rs
│ │ └── mod.rs
│ ├── crates_api.rs
│ ├── directory_change.rs
│ ├── directory_create.rs
│ ├── download.rs
│ ├── environment.rs
│ ├── fs_path.rs
│ ├── github_api.rs
│ ├── http_client.rs
│ ├── mod.rs
│ ├── permissions.rs
│ └── temp_dir.rs
├── stack_alloc_types
│ ├── constructors.rs
│ ├── into_existing.rs
│ ├── items.rs
│ ├── list_of.rs
│ ├── make_new.rs
│ ├── memory_allocator.rs
│ ├── mod.rs
│ ├── sizes.rs
│ └── usize_fmt.rs
├── storage
│ ├── kv.rs
│ └── mod.rs
├── term.rs
├── terminal_io
│ ├── input_device.rs
│ ├── mod.rs
│ ├── output_device.rs
│ ├── shared_writer.rs
│ └── terminal_io_type_aliases.rs
├── test_fixtures
│ ├── input_device_fixtures
│ │ ├── async_input_stream_mock.rs
│ │ ├── input_device_ext_mock.rs
│ │ └── mod.rs
│ ├── mod.rs
│ ├── output_device_fixtures
│ │ ├── mod.rs
│ │ ├── output_device_ext.rs
│ │ └── stdout_mock.rs
│ └── tcp_stream_fixtures
│ │ ├── mock_async_stream.rs
│ │ ├── mock_socket.rs
│ │ └── mod.rs
└── tui_core
│ ├── color_wheel
│ ├── color_wheel_impl.rs
│ ├── color_wheel_types.rs
│ ├── config.rs
│ ├── lolcat_api.rs
│ ├── lolcat_impl.rs
│ └── mod.rs
│ ├── color_wheel_core
│ ├── ansi_256_color_gradients.rs
│ ├── color_helpers.rs
│ ├── color_wheel_control.rs
│ ├── mod.rs
│ ├── policies.rs
│ └── truecolor_gradient.rs
│ ├── dimens
│ ├── caret.rs
│ ├── col_index.rs
│ ├── col_width.rs
│ ├── dim.rs
│ ├── dimens_check_overflows.rs
│ ├── mod.rs
│ ├── pc.rs
│ ├── pos.rs
│ ├── req_size_pc.rs
│ ├── row_height.rs
│ ├── row_index.rs
│ └── scr_ofs.rs
│ ├── graphemes
│ ├── byte_index.rs
│ ├── gc_string.rs
│ ├── gc_string_ext.rs
│ ├── mod.rs
│ ├── seg.rs
│ └── seg_index.rs
│ ├── mod.rs
│ ├── spinner_impl
│ ├── mod.rs
│ ├── spinner_constants.rs
│ ├── spinner_print.rs
│ ├── spinner_render.rs
│ └── spinner_style.rs
│ ├── tui_style
│ ├── crossterm_color_converter.rs
│ ├── hex_color_parser.rs
│ ├── mod.rs
│ ├── tui_color.rs
│ ├── tui_style_impl.rs
│ ├── tui_style_lite.rs
│ └── tui_stylesheet.rs
│ ├── tui_styled_text
│ ├── mod.rs
│ ├── tui_styled_text_impl.rs
│ └── tui_styled_texts_impl.rs
│ └── units
│ ├── bounds_check.rs
│ ├── ch_unit.rs
│ ├── index.rs
│ ├── length.rs
│ ├── mod.rs
│ └── unit_check_overflows.rs
├── lib.rs
├── network_io
├── bincode_serde.rs
├── compress.rs
├── length_prefix_protocol.rs
├── mod.rs
└── protocol_types.rs
├── readline_async
├── choose_api.rs
├── choose_impl
│ ├── components
│ │ ├── apply_style_macro.rs
│ │ ├── mod.rs
│ │ └── select_component.rs
│ ├── crossterm_macros.rs
│ ├── event_loop.rs
│ ├── function_component.rs
│ ├── keypress_reader_sync.rs
│ ├── mod.rs
│ ├── scroll.rs
│ ├── state.rs
│ └── style.rs
├── mod.rs
├── readline_async_api.rs
├── readline_async_impl
│ ├── line_state.rs
│ ├── mod.rs
│ ├── readline.rs
│ └── readline_history.rs
└── spinner.rs
└── tui
├── animator
├── animator_struct.rs
└── mod.rs
├── cmd_line_args
├── args.rs
├── cli_args.rs
└── mod.rs
├── dialog
├── dialog_buffer
│ ├── dialog_buffer_struct.rs
│ └── mod.rs
├── dialog_component
│ ├── dialog_component_struct.rs
│ ├── dialog_component_traits.rs
│ ├── dialog_event.rs
│ └── mod.rs
├── dialog_engine
│ ├── dialog_engine_api.rs
│ ├── dialog_engine_struct.rs
│ └── mod.rs
├── mod.rs
└── test_dialog.rs
├── editor
├── editor_buffer
│ ├── buffer_struct.rs
│ ├── caret_locate.rs
│ ├── clipboard_support.rs
│ ├── cur_index.rs
│ ├── history.rs
│ ├── mod.rs
│ ├── render_cache.rs
│ ├── selection_list.rs
│ ├── selection_range.rs
│ ├── selection_support.rs
│ ├── sizing.rs
│ └── system_clipboard_service_provider.rs
├── editor_component
│ ├── editor_component_struct.rs
│ ├── editor_component_traits.rs
│ ├── editor_event.rs
│ └── mod.rs
├── editor_engine
│ ├── caret_mut.rs
│ ├── content_mut.rs
│ ├── editor_macros.rs
│ ├── engine_internal_api.rs
│ ├── engine_public_api.rs
│ ├── engine_struct.rs
│ ├── mod.rs
│ ├── scroll_editor_content.rs
│ ├── select_mode.rs
│ ├── validate_buffer_mut.rs
│ └── validate_scroll_on_resize.rs
├── editor_test_fixtures.rs
├── mod.rs
└── test_editor.rs
├── global_constants.rs
├── layout
├── flex_box.rs
├── flex_box_id.rs
├── layout_and_positioning_traits.rs
├── layout_error.rs
├── mod.rs
├── partial_flex_box.rs
├── props.rs
├── surface.rs
├── test_surface_2_col_complex.rs
└── test_surface_2_col_simple.rs
├── md_parser
├── atomics
│ ├── mod.rs
│ ├── take_text_between.rs
│ └── take_text_until_eol_or_end.rs
├── block
│ ├── mod.rs
│ ├── parse_block_code.rs
│ ├── parse_block_heading.rs
│ ├── parse_block_markdown_text_until_eol_or_eoi.rs
│ └── parse_block_smart_list.rs
├── convert_to_plain_text.rs
├── extended
│ ├── mod.rs
│ ├── parse_metadata_kcsv.rs
│ └── parse_metadata_kv.rs
├── fragment
│ ├── mod.rs
│ ├── parse_fragments_in_a_line.rs
│ ├── plain_parser_catch_all.rs
│ ├── specialized_parser_delim_matchers.rs
│ └── specialized_parsers.rs
├── md_parser_types.rs
├── mod.rs
└── parse_markdown.rs
├── mod.rs
├── rsx
├── layout_macros.rs
├── mod.rs
└── render_macros.rs
├── syntax_highlighting
├── assets
│ └── r3bl.tmTheme
├── convert_syntect_to_styled_text.rs
├── intermediate_types.rs
├── md_parser_syn_hi
│ ├── md_parser_stylesheet.rs
│ ├── md_parser_syn_hi_impl.rs
│ └── mod.rs
├── mod.rs
├── pattern_matcher.rs
├── r3bl_syntect_theme.rs
└── test_assets
│ └── valid-content.md
├── terminal_lib_backends
├── crossterm_backend
│ ├── debug.rs
│ ├── mod.rs
│ ├── offscreen_buffer_paint_impl.rs
│ └── render_op_impl.rs
├── enhanced_keys.rs
├── input_device_ext.rs
├── input_event.rs
├── key_press.rs
├── mod.rs
├── modifier_keys_mask.rs
├── mouse_input.rs
├── offscreen_buffer.rs
├── offscreen_buffer_pool.rs
├── paint.rs
├── raw_mode.rs
├── render_op.rs
├── render_pipeline.rs
├── render_pipeline_to_offscreen_buffer.rs
├── render_tui_styled_texts.rs
├── termion_backend
│ └── mod.rs
├── test_input_event.rs
├── test_keypress.rs
├── test_mouse_input.rs
├── test_render_pipeline.rs
└── z_order.rs
└── terminal_window
├── app.rs
├── component.rs
├── default_input_handler.rs
├── event_routing_support.rs
├── main_event_loop.rs
├── manage_focus
├── component_registry.rs
├── has_focus.rs
└── mod.rs
├── mod.rs
├── shared_global_data.rs
├── terminal_window_api.rs
└── terminal_window_type_aliases.rs
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: nazmulidris
4 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Something doesn't work as expected or is broken.
4 | title: ''
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Platform** e.g. PopOS 22.04, macOS Monterey, Windows 11, ...
11 | **Terminal software** e.g. tilix, gnome-terminal, Apple Terminal.app, ...
12 |
13 | Describe the problem you are observing.
14 |
15 | ## Steps to reproduce
16 | 1. minimal posssible steps necessary
17 | 2. to cause the problem
18 |
19 | ## Screenshots/Screencaptures
20 |
21 | Very helpful if the display doesn't seem to work
22 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/design_plan.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Planning and/or design work
3 | about: Some planning task needs to be started, or some system needs to be designed
4 | title: ''
5 | labels: ["design", "plan"]
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Plan some work to be done** - ...
11 |
12 | **Design a system** - ...
13 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/missing-feature.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: New feature request
3 | about: Suggest an idea for r3bl-open-core library
4 | title: '[feature request] '
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | Let us know about a new feature you want to see in r3bl-open-core library.
11 |
12 | ## References
13 |
14 | If the feature you are interested in exists in other CLI or TUI apps, please share links to documentation or screenshots to easily communicate the desired behavior!
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package-lock.json
3 | /target
4 | **/target
5 | docs/*.bkp
6 | docs/*.dtmp
7 | log.txt
8 | crash_log.txt
9 | **/flamegraph.svg
10 | **/perf.data
11 | **/perf.data.old
12 | *.log
13 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/copyright/r3bl.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/dictionaries/project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/r3bl-open-core.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/.idea/rust.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 100,
3 | "proseWrap": "always",
4 | "semi": false
5 | }
6 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r3bl-org/r3bl-open-core/fe1182a0f6c40f38852f2204b9895bef546aeed7/.vscode/launch.json
--------------------------------------------------------------------------------
/1.code-search:
--------------------------------------------------------------------------------
1 | # Query: (00:|01:|02:|NAV:|CS:|REFACTOR:|PERF: \\[|DO_NOT_COMMIT:|REVIEW:)
2 | # Flags: CaseSensitive RegExp
3 | # Including: *.rs
4 | # ContextLines: 2
5 |
6 | No Results
7 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of conduct
2 |
3 |
4 | Before you start contributing, please take a moment to read the
5 | [code of conduct](https://www.rust-lang.org/policies/code-of-conduct). We expect all contributors to
6 | abide by this code of conduct in all interactions related to the project.
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | # https://doc.rust-lang.org/book/ch14-03-cargo-workspaces.html#creating-the-second-package-in-the-workspace
2 |
3 | # Make sure to keep this in sync with `run` nushell script `$workspace_folders`.
4 | [workspace]
5 | members = ["analytics_schema", "cmdr", "tui"]
6 |
7 | # https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions
8 | resolver = "3"
9 |
10 | # https://github.com/trailofbits/cargo-unmaintained
11 | [workspace.metadata.unmaintained]
12 | ignore = ["gethostname", "objs", "home", "proc-macro-error", "wayland-commons"]
13 |
14 | # https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html
15 | # https://www.linkedin.com/posts/marcoieni_i-finally-found-some-time-to-review-all-the-activity-7307355034642452481-EVLZ
16 | [workspace.lints.rust]
17 | ambiguous_negative_literals = "warn"
18 | closure_returning_async_block = "warn"
19 | explicit_outlives_requirements = "warn"
20 | if_let_rescope = "warn"
21 | impl_trait_overcaptures = "warn"
22 | impl_trait_redundant_captures = "warn"
23 | let_underscore_drop = "warn"
24 | macro_use_extern_crate = "warn"
25 | missing_debug_implementations = "warn"
26 | non_ascii_indents = "warn"
27 | redundant_imports = "warn"
28 | redundant_lifetimes = "warn"
29 | single_use_lifetimes = "warn"
30 | trivial_casts = "warn"
31 | trivial_numeric_casts = "warn"
32 | unit_bindings = "warn"
33 | unsafe_attr_outside_unsafe = "warn"
34 | unused = "warn"
35 | unused_import_braces = "warn"
36 |
--------------------------------------------------------------------------------
/analytics_schema/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "r3bl_analytics_schema"
3 | description = "Support crate for r3bl-cmdr, r3bl-base"
4 | version = "0.0.3"
5 | edition = "2024"
6 | repository = "https://github.com/r3bl-org/r3bl-open-core/tree/main/analytics_schema"
7 | documentation = "https://docs.rs/analytics_schema"
8 | homepage = "https://r3bl.com"
9 | license = "Apache-2.0"
10 |
11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
12 |
13 | [dependencies]
14 | # serde-json.
15 | serde = { version = "1.0.219", features = ["derive"] }
16 | serde_json = "1.0.140"
17 |
18 | # Uuid.
19 | uuid = { version = "1.16.0", features = [
20 | "v4", # Lets you generate random UUIDs
21 | "fast-rng", # Use a faster (but still sufficiently random) RNG
22 | "macro-diagnostics", # Enable better diagnostics for compile-time UUIDs
23 | ] }
24 |
25 | # For smallstr & smallvec.
26 | smallstr = { version = "0.3.0", features = ["std", "union"] }
27 | smallvec = { version = "1.15.0", features = [
28 | "union",
29 | "const_generics",
30 | "const_new",
31 | "serde", # small needs `server` feature flag here, but not in other Cargo.toml files in this workspace.
32 | ] }
33 |
--------------------------------------------------------------------------------
/cmdr/docker/Dockerfile:
--------------------------------------------------------------------------------
1 | # Get the base image.
2 | FROM ubuntu:24.04
3 |
4 | # This is the working directory in the container.
5 | WORKDIR /app
6 |
7 | # Copy the current directory to the container.
8 | COPY install.bash .
9 |
10 | # Run the install script.
11 | RUN chmod +x install.bash
12 |
13 | CMD ["/bin/bash", "-c", "/app/install.bash"]
--------------------------------------------------------------------------------
/cmdr/docker/README.md:
--------------------------------------------------------------------------------
1 | # Run the build in docker
2 |
3 | ```shell
4 | cd cmdr && nu run.nu build-release-in-docker
5 | ```
6 |
7 | # Install docker & docker compose
8 |
9 | ```shell
10 | sudo apt update
11 | sudo apt install -y docker.io docker-compose
12 | ```
13 |
14 | # Verify install of docker & docker compose
15 |
16 | ```shell
17 | sudo docker run hello-world
18 | docker compose version
19 | ```
20 |
21 | # Run docker without sudo, requires logout
22 |
23 | ```shell
24 | sudo groupadd docker
25 | sudo usermod -aG docker $USER
26 | gnome-session-quit --logout --force --no-prompt
27 | ```
28 |
29 | # Enable docker to start at boot
30 |
31 | ```shell
32 | sudo systemctl enable docker
33 | ```
34 |
35 | # Uninstall docker
36 |
37 | ```shell
38 | # Remove Docker Engine
39 | sudo apt purge -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
40 |
41 | # Remove Docker data (be careful, this removes all containers, images, volumes)
42 | sudo rm -rf /var/lib/docker
43 | sudo rm -rf /var/lib/containerd
44 | ```
--------------------------------------------------------------------------------
/cmdr/docker/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | cmdr:
5 | build:
6 | context: .
7 | dockerfile: Dockerfile
8 | container_name: r3bl-cmdr
9 | volumes: [ ]
10 | # Mount your local directory to the container for development
11 | # Uncomment and modify the paths as needed
12 | # - ../:/app/project
13 | # If your application exposes ports, you can uncomment and configure them
14 | # ports:
15 | # - "8080:8080"
16 | # If your application needs environment variables, you can add them here
17 | # environment:
18 | # - VAR_NAME=value
19 | # If you want the container to restart automatically
20 | restart: unless-stopped
--------------------------------------------------------------------------------
/cmdr/docker/install.bash:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #
4 | # Copyright (c) 2025 R3BL LLC
5 | # All rights reserved.
6 | #
7 | # Licensed under the Apache License, Version 2.0 (the "License");
8 | # you may not use this file except in compliance with the License.
9 | # You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing, software
14 | # distributed under the License is distributed on an "AS IS" BASIS,
15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | # See the License for the specific language governing permissions and
17 | # limitations under the License.
18 | #
19 |
20 | apt-get update -y
21 | apt-get upgrade -y
22 | apt-get install -y curl gcc build-essential
23 |
24 | # More info: https://rust-lang.github.io/rustup/installation/index.html
25 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
26 |
27 | . "$HOME/.cargo/env"
28 | cargo install r3bl-cmdr
29 |
30 | edi --version
31 | giti --version
32 | rc --version
--------------------------------------------------------------------------------
/cmdr/src/analytics_client/analytics_action.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use std::fmt::{Formatter, Result};
19 |
20 | #[derive(Clone, Copy, Debug, PartialEq)]
21 | pub enum AnalyticsAction {
22 | GitiBranchDelete,
23 | GitiFailedToRun,
24 | GitiAppStart,
25 | EdiAppStart,
26 | EdiFileNew,
27 | EdiFileOpenSingle,
28 | EdiFileOpenMultiple,
29 | EdiFileSave,
30 | MachineIdProxyCreate,
31 | }
32 |
33 | impl std::fmt::Display for AnalyticsAction {
34 | fn fmt(&self, f: &mut Formatter<'_>) -> Result {
35 | #[rustfmt::skip]
36 | let action = match self {
37 | AnalyticsAction::GitiAppStart => "giti app start",
38 | AnalyticsAction::GitiBranchDelete => "giti branch delete",
39 | AnalyticsAction::GitiFailedToRun => "giti failed to run",
40 | AnalyticsAction::EdiAppStart => "edi app start",
41 | AnalyticsAction::EdiFileNew => "edi file new",
42 | AnalyticsAction::EdiFileOpenSingle => "edi file open one file",
43 | AnalyticsAction::EdiFileOpenMultiple => "edi file open many files",
44 | AnalyticsAction::EdiFileSave => "edi file save",
45 | AnalyticsAction::MachineIdProxyCreate => "proxy machine id create",
46 | };
47 | write!(f, "{action}")
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/cmdr/src/analytics_client/http_client.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use r3bl_tui::inline_string;
19 | use reqwest::{Client, Response};
20 |
21 | use crate::DEBUG_ANALYTICS_CLIENT_MOD;
22 |
23 | pub async fn make_get_request(
24 | url: &str,
25 | ) -> core::result::Result {
26 | let client = Client::new();
27 | let response = client.get(url).send().await?;
28 | if response.status().is_success() {
29 | // Handle successful response.
30 | DEBUG_ANALYTICS_CLIENT_MOD.then(|| {
31 | tracing::debug!(
32 | message = "GET request succeeded.",
33 | response = %inline_string!("{response:#?}")
34 | );
35 | });
36 | Ok(response)
37 | } else {
38 | // Handle error response.
39 | // % is Display, ? is Debug.
40 | tracing::error!(
41 | message = "GET request failed.",
42 | response = %inline_string!("{response:#?}")
43 | );
44 | response.error_for_status()
45 | }
46 | }
47 |
48 | pub async fn make_post_request(
49 | url: &str,
50 | data: &serde_json::Value,
51 | ) -> core::result::Result {
52 | let client = Client::new();
53 | let response = client.post(url).json(data).send().await?;
54 | if response.status().is_success() {
55 | // Handle successful response.
56 | DEBUG_ANALYTICS_CLIENT_MOD.then(|| {
57 | // % is Display, ? is Debug.
58 | tracing::debug!(
59 | message = "POST request succeeded.",
60 | response = %inline_string!("{response:#?}")
61 | );
62 | });
63 | Ok(response)
64 | } else {
65 | // Handle error response.
66 | tracing::error!(
67 | message = "POST request failed.",
68 | response = %inline_string!("{response:#?}")
69 | );
70 | response.error_for_status()
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/cmdr/src/analytics_client/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach files.
19 | pub mod analytics_action;
20 | pub mod config_folder;
21 | pub mod http_client;
22 | pub mod proxy_machine_id;
23 | pub mod report_analytics;
24 | pub mod ui_str;
25 | pub mod upgrade_check;
26 |
27 | // Re-export.
28 | pub use analytics_action::*;
29 | pub use config_folder::*;
30 | pub use http_client::*;
31 | pub use proxy_machine_id::*;
32 | pub use report_analytics::*;
33 | pub use ui_str::*;
34 | pub use upgrade_check::*;
35 |
--------------------------------------------------------------------------------
/cmdr/src/bin/rc.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use r3bl_cmdr::rc::run_app;
19 | use r3bl_tui::{CommonResult, set_jemalloc_in_main, throws};
20 |
21 | #[tokio::main]
22 | #[allow(clippy::needless_return)]
23 | async fn main() -> CommonResult<()> {
24 | set_jemalloc_in_main!();
25 |
26 | throws!({
27 | run_app().await?;
28 | })
29 | }
30 |
--------------------------------------------------------------------------------
/cmdr/src/common/fmt.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use std::fmt::Display;
19 |
20 | use r3bl_tui::{InlineString,
21 | fg_frozen_blue,
22 | fg_lizard_green,
23 | fg_silver_metallic,
24 | fg_slate_gray,
25 | fg_soft_pink,
26 | inline_string};
27 |
28 | pub fn colon() -> InlineString { dim(":") }
29 |
30 | pub fn comma() -> InlineString { dim(",") }
31 |
32 | pub fn period() -> InlineString { dim(".") }
33 |
34 | pub fn exclamation() -> InlineString { dim("!") }
35 |
36 | /// Normal or default text style.
37 | pub fn normal(arg_text: impl Display) -> InlineString {
38 | let text = inline_string!("{}", arg_text);
39 | fg_silver_metallic(text).to_small_str()
40 | }
41 |
42 | /// Error text style.
43 | pub fn error(arg_text: impl Display) -> InlineString {
44 | let text = inline_string!("{}", arg_text);
45 | fg_soft_pink(text).to_small_str()
46 | }
47 |
48 | /// Emphasis text style to highlight.
49 | pub fn emphasis(arg_text: impl Display) -> InlineString {
50 | let text = inline_string!("{}", arg_text);
51 | fg_lizard_green(text).to_small_str()
52 | }
53 |
54 | pub fn emphasis_delete(arg_text: impl Display) -> InlineString {
55 | let text = inline_string!("{}", arg_text);
56 | fg_soft_pink(text).to_small_str()
57 | }
58 |
59 | /// De-emphasize (dim) text.
60 | pub fn dim(arg_text: impl Display) -> InlineString {
61 | let text = inline_string!("{}", arg_text);
62 | fg_slate_gray(text).to_small_str()
63 | }
64 |
65 | /// This is for `readline_async` prompt segment. This the part of the prompt which
66 | /// gives the user instruction, e.g.: `Branch name to create `.
67 | pub fn prompt_seg_normal(arg_text: impl Display) -> InlineString {
68 | let text = inline_string!("{}", arg_text);
69 | fg_frozen_blue(text).to_small_str()
70 | }
71 |
72 | /// This is for `readline_async` prompt segment. This is the part of the prompt
73 | /// which gives the user bailout directions, e.g.: `(Ctrl+C exits)`.
74 | pub fn prompt_seg_bail(arg_text: impl Display) -> InlineString {
75 | let text = inline_string!("{}", arg_text);
76 | fg_soft_pink(text)
77 | .italic()
78 | .bg_moonlight_blue()
79 | .to_small_str()
80 | }
81 |
--------------------------------------------------------------------------------
/cmdr/src/common/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach.
19 | pub mod fmt;
20 | pub mod ui_templates;
21 |
22 | // Re-export.
23 | pub use fmt::*;
24 | pub use ui_templates::*;
25 |
--------------------------------------------------------------------------------
/cmdr/src/edi/clap_config.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use clap::{Args, Parser};
19 |
20 | /// More info:
21 | #[derive(Debug, Parser)]
22 | #[command(bin_name = "edi")]
23 | #[command(
24 | about = "🦜 Edit Markdown with style 💖\n\x1b[38;5;206mEarly access preview \x1b[0m🐣"
25 | )]
26 | #[command(version)]
27 | #[command(next_line_help = true)]
28 | #[command(arg_required_else_help(false))]
29 | /// More info:
30 | #[command(
31 | /* cspell:disable-next-line */
32 | help_template = "{about}\nVersion: {bin} {version} 💻\n\nProvide file paths, separated by spaces, to edit in edi. Or no arguments to edit a new file.\nUSAGE 📓:\n edi [\x1b[32mfile paths\x1b[0m] [\x1b[34moptions\x1b[0m]\n\n[options]\n{options}",
33 | subcommand_help_heading("Command")
34 | )]
35 | pub struct CLIArg {
36 | #[arg(name = "file paths")]
37 | pub file_paths: Vec,
38 |
39 | #[command(flatten)]
40 | pub global_options: GlobalOption,
41 | }
42 |
43 | #[derive(Debug, Args)]
44 | pub struct GlobalOption {
45 | #[arg(
46 | global = true,
47 | long,
48 | short = 'l',
49 | help = "Log app output to a file named `log.txt` for debugging."
50 | )]
51 | pub enable_logging: bool,
52 |
53 | #[arg(
54 | global = true,
55 | long,
56 | short = 'n',
57 | help = "Disable anonymous data collection for analytics to improve the product; this data does not include IP addresses, or any other private user data, like user, branch, or repo names"
58 | )]
59 | pub no_analytics: bool,
60 | }
61 |
--------------------------------------------------------------------------------
/cmdr/src/edi/launcher.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use r3bl_tui::{CommonResult,
19 | InputEvent,
20 | ModifierKeysMask,
21 | TerminalWindow,
22 | key_press,
23 | throws};
24 |
25 | use crate::edi::{AppMain, constructor};
26 |
27 | pub async fn run_app(maybe_file_path: Option<&str>) -> CommonResult<()> {
28 | throws!({
29 | // Create a new state from the file path.
30 | let state = constructor::new(maybe_file_path);
31 |
32 | // Create a new app.
33 | let app = AppMain::new_boxed();
34 |
35 | // Exit if these keys are pressed.
36 | let exit_keys = &[InputEvent::Keyboard(
37 | key_press! { @char ModifierKeysMask::new().with_ctrl(), 'q' },
38 | )];
39 |
40 | // Create a window.
41 | _ = TerminalWindow::main_event_loop(app, exit_keys, state).await?;
42 | })
43 | }
44 |
--------------------------------------------------------------------------------
/cmdr/src/edi/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Include.
19 | pub mod app_main;
20 | pub mod clap_config;
21 | pub mod launcher;
22 | pub mod state;
23 | pub mod ui_str;
24 | pub mod ui_templates;
25 |
26 | // Reexport.
27 | pub use app_main::*;
28 | pub use clap_config::*;
29 | pub use launcher::*;
30 | pub use state::*;
31 | pub use ui_str::*;
32 | pub use ui_templates::*;
33 |
--------------------------------------------------------------------------------
/cmdr/src/edi/ui_str.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use r3bl_tui::{InlineString, inline_string};
19 |
20 | use crate::get_self_bin_name;
21 |
22 | pub fn multiple_files_not_supported_yet() -> InlineString {
23 | inline_string!(
24 | "{} currently only allows you to edit one file at a time. Select one:",
25 | get_self_bin_name()
26 | )
27 | }
28 |
--------------------------------------------------------------------------------
/cmdr/src/edi/ui_templates.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use r3bl_tui::{DefaultIoDevices,
19 | HowToChoose,
20 | InlineString,
21 | InlineVec,
22 | StyleSheet,
23 | ast,
24 | ast_line,
25 | choose,
26 | height,
27 | inline_vec};
28 |
29 | use super::CLIArg;
30 | use crate::{common, edi::ui_str, prefix_single_select_instruction_header};
31 |
32 | /// Ask the user to select a file to edit, and return the selected file path (if there is
33 | /// one).
34 | pub async fn handle_multiple_files_not_supported_yet(
35 | cli_arg: CLIArg,
36 | ) -> Option {
37 | let mut default_io_devices = DefaultIoDevices::default();
38 | let file_path_options = cli_arg
39 | .file_paths
40 | .iter()
41 | .map(|file| file.as_str())
42 | .collect::>();
43 | let header_with_instructions = {
44 | let last_line = ast_line![ast(
45 | ui_str::multiple_files_not_supported_yet(),
46 | common::ui_templates::header_style_default()
47 | )];
48 | prefix_single_select_instruction_header(inline_vec![last_line])
49 | };
50 | choose(
51 | header_with_instructions,
52 | file_path_options.as_slice(),
53 | Some(height(5)),
54 | None,
55 | HowToChoose::Single,
56 | StyleSheet::default(),
57 | default_io_devices.as_mut_tuple(),
58 | )
59 | .await
60 | .ok()
61 | .and_then(|items| items.into_iter().next())
62 | }
63 |
--------------------------------------------------------------------------------
/cmdr/src/giti/branch/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach.
19 | pub mod branch_checkout_command;
20 | pub mod branch_command;
21 | pub mod branch_delete_command;
22 | pub mod branch_new_command;
23 |
24 | // Re-export.
25 | pub use branch_checkout_command::*;
26 | pub use branch_command::*;
27 | pub use branch_delete_command::*;
28 | pub use branch_new_command::*;
29 |
--------------------------------------------------------------------------------
/cmdr/src/giti/common_types.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
19 |
20 | use r3bl_tui::ItemsOwned;
21 |
22 | /// Detailed information about a sub command that has run successfully.
23 | #[derive(Debug, Clone, Default)]
24 | pub struct BranchDeleteDetails {
25 | pub maybe_deleted_branches: Option,
26 | }
27 |
28 | /// Detailed information about a sub command that has run successfully.
29 | #[derive(Debug, Clone, Default)]
30 | pub struct BranchNewDetails {
31 | pub maybe_created_branch: Option,
32 | }
33 |
34 | /// Detailed information about a sub command that has run successfully.
35 | #[derive(Debug, Clone, Default)]
36 | pub struct BranchCheckoutDetails {
37 | pub maybe_checked_out_branch: Option,
38 | }
39 |
40 | /// Information about command and subcommand that has run successfully. Eg: `giti branch
41 | /// delete` or `giti branch checkout` or `giti branch new`.
42 | #[derive(Debug, Clone)]
43 | pub enum CommandRunDetails {
44 | BranchDelete(BranchDeleteDetails),
45 | BranchNew(BranchNewDetails),
46 | BranchCheckout(BranchCheckoutDetails),
47 | Commit,
48 | Remote,
49 | Noop,
50 | }
51 |
52 | impl Display for CommandRunDetails {
53 | fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
54 | match self {
55 | CommandRunDetails::BranchDelete(details) => {
56 | write!(
57 | f,
58 | " BranchDelete: {A:?}",
59 | A = details.maybe_deleted_branches
60 | )
61 | }
62 | CommandRunDetails::BranchNew(details) => {
63 | write!(f, " BranchNew: {A:?}", A = details.maybe_created_branch)
64 | }
65 | CommandRunDetails::BranchCheckout(details) => {
66 | write!(
67 | f,
68 | " BranchCheckout: {A:?}",
69 | A = details.maybe_checked_out_branch
70 | )
71 | }
72 | CommandRunDetails::Commit => write!(f, " Commit"),
73 | CommandRunDetails::Remote => write!(f, " Remote"),
74 | CommandRunDetails::Noop => write!(f, " Noop"),
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/cmdr/src/giti/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach.
19 | pub mod branch;
20 | pub mod clap_config;
21 | pub mod common_types;
22 | pub mod git;
23 | pub mod ui_str;
24 |
25 | // Re-export.
26 | pub use branch::*;
27 | pub use clap_config::*;
28 | pub use common_types::*;
29 | pub use git::*;
30 | pub use ui_str::*;
31 |
--------------------------------------------------------------------------------
/cmdr/src/rc/app.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | use r3bl_tui::{CommonResult, ok};
18 |
19 | pub async fn run_app() -> CommonResult<()> {
20 | println!("TODO: Implement the r3bl-cmdr shell app 🌞");
21 | println!("https://github.com/r3bl-org/r3bl-open-core/issues/363");
22 | ok!()
23 | }
24 |
--------------------------------------------------------------------------------
/cmdr/src/rc/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | pub mod app;
19 |
20 | pub use app::*;
21 |
--------------------------------------------------------------------------------
/cmdr/videos/edi.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r3bl-org/r3bl-open-core/fe1182a0f6c40f38852f2204b9895bef546aeed7/cmdr/videos/edi.gif
--------------------------------------------------------------------------------
/cmdr/videos/giti.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r3bl-org/r3bl-open-core/fe1182a0f6c40f38852f2204b9895bef546aeed7/cmdr/videos/giti.gif
--------------------------------------------------------------------------------
/config.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | rustflags = ["-Z", "threads=28"]
3 |
--------------------------------------------------------------------------------
/deny.toml:
--------------------------------------------------------------------------------
1 | # Docs:
2 | # - https://embarkstudios.github.io/cargo-deny/checks/cfg.html
3 | # - https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html
4 |
5 | [licenses]
6 | allow = [
7 | "CDLA-Permissive-2.0",
8 | "MIT",
9 | "Apache-2.0",
10 | "BSL-1.0",
11 | "ISC",
12 | "BSD-3-Clause",
13 | "Zlib",
14 | "OpenSSL",
15 | "ISC",
16 | "MPL-2.0",
17 | ]
18 |
19 | # Add exceptions for ring crate
20 | [[licenses.exceptions]]
21 | name = "ring"
22 | version = "=0.17.8"
23 | allow = ["OpenSSL", "ISC", "MIT"]
24 |
25 | [[licenses.exceptions]]
26 | name = "unicode-ident"
27 | allow = ["Unicode-DFS-2016"]
28 |
29 | [[licenses.exceptions]]
30 | name = "is_ci"
31 | allow = ["ISC"]
32 |
33 | [advisories]
34 | # If you add a crate in the array below, eg: `yaml-rust@0.4.5` then it will be checked to
35 | # see if it was yanked on or not. So to prevent warnings or failed advisory warnings, you
36 | # can add the `RUSTSEC...` identifier instead.
37 | ignore = [
38 | "RUSTSEC-2024-0320", # "instant@0.1.13"
39 | "RUSTSEC-2024-0384", # "hashbrown@0.15.0"
40 | "RUSTSEC-2024-0402", # "yaml-rust@0.4.5"
41 | "RUSTSEC-2024-0421", # "idna v0.5.0"
42 | ]
43 |
--------------------------------------------------------------------------------
/docs/contributing_guides/BRANCH.md:
--------------------------------------------------------------------------------
1 | # Guide to naming a 🌳 branch
2 |
3 |
4 |
5 |
6 | - [🎈 Why is it important to write good branch names?](#-why-is-it-important-to-write-good-branch-names)
7 | - [✏️ How to name a branch](#-how-to-name-a-branch)
8 | - [🌺 Examples](#-examples)
9 | - [Example 1](#example-1)
10 | - [Example 2](#example-2)
11 |
12 |
13 |
14 | ## 🎈 Why is it important to write good branch names?
15 |
16 |
17 | If you name your branches properly, it will be easier for you and others to find them.
18 |
19 | ## ✏️ How to name a branch
20 |
21 |
22 |
23 | - **Use `username/change` format**: Use your GitHub username, followed by a slash (/), followed by a
24 | short description of the change. For example, `nazmulidris/add-section-to-style-guide`.
25 | - **Use a descriptive name**: If possible use a name similar to the **title of the issue** you are
26 | working on.
27 |
28 | ## 🌺 Examples
29 |
30 |
31 |
32 | ### Example 1
33 |
34 |
35 |
36 | ```
37 | nazmulidris/add-section-to-style-guide
38 | ```
39 |
40 | **Breaking down the branch name**:
41 |
42 | - **`nazmulidris`**: GitHub username.
43 | - **`add-section-to-style-guide`**: This is the descriptive name with the issue number.
44 |
45 | ### Example 2
46 |
47 |
48 |
49 | ```
50 | nazmulidris/201-add-section-to-style-guide
51 | ```
52 |
53 | **Breaking down the branch name**:
54 |
55 | - **`nazmulidris`**: GitHub username.
56 | - **`201`**: This is the issue number.
57 | - **`add-section-to-style-guide`**: This is a short descriptive name.
58 |
--------------------------------------------------------------------------------
/docs/r3bl_terminal_async_clip_ffmpeg.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r3bl-org/r3bl-open-core/fe1182a0f6c40f38852f2204b9895bef546aeed7/docs/r3bl_terminal_async_clip_ffmpeg.gif
--------------------------------------------------------------------------------
/rust-toolchain.toml:
--------------------------------------------------------------------------------
1 | [toolchain]
2 | # channel = "stable"
3 | channel = "nightly"
4 |
--------------------------------------------------------------------------------
/rustfmt.toml:
--------------------------------------------------------------------------------
1 | # https://rust-lang.github.io/rustfmt/
2 |
3 | # width
4 | max_width = 90
5 |
6 | # comment wrapping (make sure to run `rustfmt +nightly` for this to work as of May 2025.
7 | comment_width = 90
8 | wrap_comments = true
9 |
10 | # function
11 | fn_params_layout = "Tall" # Possible values: "Compressed", "Tall", "Vertical"
12 | fn_single_line = true
13 |
14 | # imports
15 | imports_indent = "Visual"
16 | imports_layout = "HorizontalVertical"
17 | imports_granularity = "Crate"
18 | group_imports = "StdExternalCrate"
19 | reorder_imports = true
20 |
21 | # modules
22 | reorder_modules = true
23 |
24 | # misc
25 | hard_tabs = false
26 | tab_spaces = 4
27 | trailing_comma = "Vertical"
28 | color = "Always"
29 | empty_item_single_line = true
30 | trailing_semicolon = true
31 |
--------------------------------------------------------------------------------
/scratch.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | /*
19 | Open vscode connected to a remote machine via SSH:
20 | code --remote ssh-remote+nazmul-desktop.local /home/nazmul/github/r3bl-open-core/
21 | */
22 |
23 | /*
24 | Run cargo clippy & fix:
25 | cargo clippy --fix --no-deps --allow-dirty --allow-staged ; cargo fix --workspace
26 | --allow-dirty --allow-staged ; cargo fmt --all
27 | */
28 |
29 | call_if_true!(DEBUG_TUI_COMPOSITOR, {
30 | let message = inline_string!(
31 | "print_plain_text() {ar} {ch}",
32 | ar = glyphs::RIGHT_ARROW_GLYPH,
33 | ch = glyphs::PAINT_GLYPH,
34 | );
35 | let details = inline_string!(
36 | "insertion at: display_row_index: {a}, display_col_index: {b}, window_size: {c:?},
37 | text: '{d}',
38 | width: {e:?}",
39 | a = display_row_index,
40 | b = display_col_index,
41 | c = my_offscreen_buffer.window_size,
42 | d = str!(clip_2_gcs),
43 | e = clip_2_gcs.get_display_width(),
44 | );
45 | // % is Display, ? is Debug.
46 | tracing::info! {
47 | message = %message,
48 | details = %details
49 | };
50 | });
51 |
52 | call_if_true!(DEBUG_TUI_MOD, {
53 | let message = format!("ColumnComponent::render {ch}", ch = glyphs::RENDER_GLYPH);
54 | // % is Display, ? is Debug.
55 | tracing::info!(
56 | message = message,
57 | current_box = ?current_box,
58 | box_origin_pos = ?box_origin_pos,
59 | box_bounds_size = ?box_bounds_size,
60 | content_pos = ?content_cursor_pos,
61 | render_pipeline = ?pipeline,
62 | );
63 | });
64 |
--------------------------------------------------------------------------------
/todo.md:
--------------------------------------------------------------------------------
1 | # modernize `choose` and `giti` codebase: https://github.com/r3bl-org/r3bl-open-core/issues/427
2 |
3 | - [ ] use `InlineString` & `InlineVec` in `giti` codebase (for sake of consistency)
4 | - [ ] fix clap args using `color_print::cstr` instead of directly embedding ansi escape sequences in
5 | the clap macro attributes `clap_config.rs`. see `rust_scratch/tcp-api-server` for examples
6 | - [ ] make sure that analytics calls are made consistent throughout the giti codebase (currently
7 | they do nothing but this will get things ready for the new `r3bl_base` that will be self
8 | hosted in our homelab); currently `delete.rs` has analytics calls
9 | - [ ] rewrite `giti` code to use the newtypes, like width, height, etc. and introduce newtypes, etc
10 | where needed
11 |
12 | # minor perf in `tui` and `edi`: https://github.com/r3bl-org/r3bl-open-core/issues/428
13 |
14 | - [ ] replace `HashMap` with `BTreeMap` (better cache locality performance). `HashMap` is great for
15 | random access, `BTreeMap` is good for cache locality and iteration which is the primary use
16 | case for most code in `r3bl_open_core` repo
17 | - [ ] add fps counter row to bottom of `edi`, just like in the `tui/examples/demo/*` add an
18 | FPS/telemetry display to bottom of `edi`
19 |
20 | # make release of `r3bl-cmdr` and `r3bl_tui`
21 |
22 | - [ ] make sure `cmdr` docker file works (with `pkg-config` and `libssl-dev` removed):
23 | https://github.com/r3bl-org/r3bl-open-core/issues/426
24 | - [ ] release `r3bl_tui`, `r3bl_cmdr`: https://github.com/r3bl-org/r3bl-open-core/issues/429
25 | - [ ] close this: https://github.com/r3bl-org/r3bl-open-core/issues/391
26 |
27 | # create sub-issues for `giti`: https://github.com/r3bl-org/r3bl-open-core/issues/423
28 |
29 | - [ ] `giti branch rename` -> rename an existing branch to other
30 | - [ ] `giti show ` -> choose an older version of a file to checkout to `Downloads` and
31 | optionally view in the `editor_component` itself in a TUI applet
32 | - [ ] `giti develop *` -> choose issues using TUI app as part of the flow
33 | - [ ] `giti commit`
34 | - [ ] `giti delete *` -> switch to main and pull (delete remotes)
35 | - [ ] `giti --manual` -> show the user guide for giti using the TUI MD component w/ search, jump to
36 | headings, etc
37 |
38 | # test `giti` user flow
39 |
40 | - [ ] devise an approach to do this
41 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_app_no_layout/launcher.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use super::{AppMain, State};
19 | use crate::{key_press, throws, CommonResult, InputEvent, TerminalWindow};
20 |
21 | pub async fn run_app() -> CommonResult<()> {
22 | throws!({
23 | // Create an App (renders & responds to user input).
24 | let app = AppMain::new_boxed();
25 |
26 | // Exit if these keys are pressed.
27 | let exit_keys = &[InputEvent::Keyboard(key_press! { @char 'x' })];
28 |
29 | // Create a window.
30 | _ = TerminalWindow::main_event_loop(app, exit_keys, State::default()).await?
31 | });
32 | }
33 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_app_no_layout/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach sources.
19 | pub mod app_main;
20 | pub mod launcher;
21 | pub mod state;
22 |
23 | // Re-export only inside this module.
24 | pub(super) use app_main::*;
25 | pub(super) use state::*;
26 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_app_no_layout/state.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use std::fmt::{Debug, Formatter};
19 |
20 | /// Action.
21 | #[derive(Default, Clone, Debug)]
22 | #[non_exhaustive]
23 | #[allow(dead_code)]
24 | pub enum AppSignal {
25 | Add,
26 | Sub,
27 | Clear,
28 | #[default]
29 | Noop,
30 | }
31 |
32 | /// State.
33 | #[derive(Clone, PartialEq, Eq, Default)]
34 | pub struct State {
35 | pub counter: isize,
36 | }
37 |
38 | impl Debug for State {
39 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
40 | write!(f, "State {{ counter: {:?} }}", self.counter)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_app_with_1col_layout/launcher.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use r3bl_tui::{key_press, throws, CommonResult, InputEvent, TerminalWindow};
19 |
20 | use super::{AppMain, State};
21 |
22 | pub async fn run_app() -> CommonResult<()> {
23 | throws!({
24 | // Create an App (renders & responds to user input).
25 | let app = AppMain::new_boxed();
26 |
27 | // Exit if these keys are pressed.
28 | let exit_keys = &[InputEvent::Keyboard(key_press! { @char 'x' })];
29 |
30 | // Create a window.
31 | _ = TerminalWindow::main_event_loop(app, exit_keys, State::default()).await?
32 | });
33 | }
34 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_app_with_1col_layout/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach sources.
19 | pub mod app_main;
20 | pub mod launcher;
21 | pub mod single_column_component;
22 | pub mod state;
23 |
24 | // Re-export only inside this module.
25 | pub use app_main::*;
26 | pub use single_column_component::*;
27 | pub use state::*;
28 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_app_with_1col_layout/state.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use std::fmt::{Debug, Formatter};
19 |
20 | use r3bl_tui::InlineVec;
21 | use smallvec::smallvec;
22 |
23 | /// Reducer.
24 | #[derive(Default)]
25 | pub struct Reducer;
26 |
27 | /// Action.
28 | #[derive(Default, Clone, Debug)]
29 | #[non_exhaustive]
30 | #[allow(dead_code)]
31 | pub enum AppSignal {
32 | AddPop(i32),
33 | SubPop(i32),
34 | Clear,
35 | #[default]
36 | Noop,
37 | }
38 |
39 | /// State.
40 | #[derive(Clone, PartialEq, Eq)]
41 | pub struct State {
42 | pub stack: InlineVec,
43 | }
44 |
45 | impl Default for State {
46 | fn default() -> Self {
47 | Self {
48 | stack: smallvec![0],
49 | }
50 | }
51 | }
52 |
53 | impl Debug for State {
54 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
55 | write!(f, "State {{ stack: {:?} }}", self.stack)
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_app_with_2col_layout/launcher.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use r3bl_tui::{key_press, throws, CommonResult, InputEvent, TerminalWindow};
19 |
20 | use super::{AppMain, State};
21 |
22 | pub async fn run_app() -> CommonResult<()> {
23 | throws!({
24 | // Create an App (renders & responds to user input).
25 | let app = AppMain::new_boxed();
26 |
27 | // Exit if these keys are pressed.
28 | let exit_keys = &[InputEvent::Keyboard(key_press! { @char 'x' })];
29 |
30 | // Create a window.
31 | _ = TerminalWindow::main_event_loop(app, exit_keys, State::default()).await?
32 | });
33 | }
34 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_app_with_2col_layout/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach sources.
19 | pub mod app_main;
20 | pub mod column_render_component;
21 | pub mod launcher;
22 | pub mod state;
23 |
24 | // Re-export only inside this module.
25 | pub use app_main::*;
26 | pub use column_render_component::*;
27 | pub use state::*;
28 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_app_with_2col_layout/state.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use std::fmt::{Debug, Formatter};
19 |
20 | use r3bl_tui::InlineVec;
21 | use smallvec::smallvec;
22 |
23 | /// State.
24 | #[derive(Clone, PartialEq, Eq)]
25 | pub struct State {
26 | pub stack: InlineVec,
27 | }
28 |
29 | impl Default for State {
30 | fn default() -> Self {
31 | Self {
32 | stack: smallvec![0],
33 | }
34 | }
35 | }
36 |
37 | impl Debug for State {
38 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
39 | write!(f, "State {{ stack: {:?} }}", self.stack)
40 | }
41 | }
42 |
43 | /// Action.
44 | #[derive(Default, Clone, Debug)]
45 | #[non_exhaustive]
46 | #[allow(dead_code)]
47 | pub enum AppSignal {
48 | Startup,
49 | AddPop(i32),
50 | SubPop(i32),
51 | Clear,
52 | #[default]
53 | Noop,
54 | }
55 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_editor/app_signal.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use std::fmt::Debug;
19 |
20 | #[derive(Default, Clone, Debug)]
21 | #[non_exhaustive]
22 | pub enum AppSignal {
23 | #[default]
24 | Noop,
25 | }
26 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_editor/launcher.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use r3bl_tui::{key_press,
19 | throws,
20 | CommonResult,
21 | InputEvent,
22 | ModifierKeysMask,
23 | TerminalWindow};
24 |
25 | use super::{AppMain, State};
26 |
27 | pub async fn run_app() -> CommonResult<()> {
28 | throws!({
29 | // Create an App (renders & responds to user input).
30 | let app = AppMain::new_boxed();
31 |
32 | // Exit if these keys are pressed.
33 | let exit_keys = &[InputEvent::Keyboard(
34 | key_press! { @char ModifierKeysMask::new().with_ctrl(), 'q' },
35 | )];
36 |
37 | // Create a window.
38 | _ = TerminalWindow::main_event_loop(app, exit_keys, State::default()).await?
39 | });
40 | }
41 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_editor/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach sources.
19 | pub mod app_main;
20 | pub mod app_signal;
21 | pub mod launcher;
22 | pub mod state;
23 |
24 | // Re-export only inside this module.
25 | pub use app_main::*;
26 | pub use app_signal::*;
27 | pub use state::*;
28 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_pitch/launcher.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use r3bl_tui::{key_press,
19 | throws,
20 | CommonResult,
21 | InputEvent,
22 | ModifierKeysMask,
23 | TerminalWindow};
24 |
25 | use super::{state::State, AppMain};
26 |
27 | pub async fn run_app() -> CommonResult<()> {
28 | throws!({
29 | // Create an App (renders & responds to user input).
30 | let app = AppMain::new_boxed();
31 |
32 | // Exit if these keys are pressed.
33 | let exit_keys = &[InputEvent::Keyboard(
34 | key_press! { @char ModifierKeysMask::new().with_ctrl(), 'q' },
35 | )];
36 |
37 | // Create a window.
38 | _ = TerminalWindow::main_event_loop(app, exit_keys, State::default()).await?
39 | });
40 | }
41 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_pitch/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach sources.
19 | pub mod app_main;
20 | pub mod launcher;
21 | pub mod state;
22 |
23 | // Re-export only inside this module.
24 | pub use app_main::*;
25 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_pitch/slide0.md:
--------------------------------------------------------------------------------
1 | # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
2 | # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
3 | # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
4 | # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
5 | # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
6 | # xxxxxxxxxxxxxx MAKE YOUR TERMINAL FONT SIZE LARGER SO YOU xxxxxxxxxxxxxxxxxxx |
7 | # xxxxxxxxxxxxxx CAN ONLY SEE THIS ON THE SCREEN xxxxxxxxxxxxxxxxxxx |
8 | # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
9 | # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
10 | # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
11 | # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
12 | # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
13 | # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
14 | # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
15 | # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
16 | # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
17 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_pitch/slide1.md:
--------------------------------------------------------------------------------
1 | # R3BL → engineered for happiness 🌞
2 |
3 |
4 |
5 |
6 | ╭────────────────────────────────────╮
7 | │ mission to enhance developer: │
8 | │ ❯ 🚀 productivity │
9 | │ ❯ 🌍 efficiency │
10 | │ ❯ 📖 knowledge capture & sharing │
11 | │ ❯ ⚗️ workflow management │
12 | ╰────────────────────────────────────╯
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_pitch/slide10.md:
--------------------------------------------------------------------------------
1 | # Product Market Fit & Community Engagement 🦜
2 |
3 | ## r3bl-open-core crate & repo
4 | - [x] crates.io : 1.2M 📦
5 | - [x] github.com: 344 🌟
6 |
7 | ## YouTube channel
8 | - [x] 512 subscribers
9 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_pitch/slide11.md:
--------------------------------------------------------------------------------
1 | # Team 💪
2 |
3 | ## Nazmul Idris
4 | - Ex-Google SWE, entrepreneur, designer, leader
5 | - HsingI-er, racer, healer, storyteller
6 | - Raised 1.5M seed round in 2015 for trnql (1st startup)
7 |
8 | - We are committed to energy efficiency & sustainability
9 | with Rust 🌱
10 |
11 | - All R3BL software is written w/ ❤️ in Rust 🦀 in
12 | California 🗽
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_pitch/slide2.md:
--------------------------------------------------------------------------------
1 | # Context is challenging in a remote & async world 🌐
2 |
3 | There isn't a cohesive environment in which developers can
4 | capture context around a problem they are solving ... for
5 | _themselves_, or to communicate to **others** on their team
6 |
7 | Tools to capture parts of context today:
8 |
9 | 1. GitHub issues & PRs, JIRA tickets
10 | 2. Temporal conversations on Slack, Discord, Chat
11 | 3. Git repos
12 | 4. Documents in Notion, Google docs, sheets
13 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_pitch/slide3.md:
--------------------------------------------------------------------------------
1 | # Developers don’t have the right tools 🧰
2 |
3 | Existing tools are optimized for sharing details
4 | about parts of a "thing", not the entire "thing"
5 |
6 | ⌨️ Developers live in the `terminal` (on macOS, Windows,
7 | Linux) especially in cloud computing environments over SSH
8 |
9 | 🖥️ There hasn't been any innovation in the UX of software
10 | written for _headless_ environments (no video card / over SSH)
11 | since the 90s (`vim`)
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_pitch/slide3_1.md:
--------------------------------------------------------------------------------
1 | # 2022 Stackoverflow Developer Survey 🗳️
2 |
3 | 62% spend more than 30 minutes a day searching for answers
4 | or solutions to problems. 25% spend more than an hour / day.
5 |
6 | ╭─────────────────────────────────────────────────╮
7 | │ This includes time spent searching on your own, │
8 | │ asking a colleague, and waiting for a response. │
9 | ╰─────────────────────────────────────────────────╯
10 |
11 | For a team of 50 developers, the amount of time spent searching
12 | for answers/solutions adds up to between 333-651 hours of
13 | time lost per week across the entire team.
14 |
15 | [survey](https://survey.stackoverflow.co/2022/#integrated-development-environment)
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_pitch/slide4.md:
--------------------------------------------------------------------------------
1 | # Our solution for the individual 🙋
2 |
3 | **R3BL CMDR** (Rebel Commander) is a Text User Interface app.
4 |
5 | _TUIs are a new breed of app_ - they run in a terminal
6 | (`over SSH` or locally on macOS, Windows, Linux) w/ benefits
7 | of a GUI desktop or web app.
8 |
9 | They are efficient and consume `local` host's CPU cores,
10 | memory, and energy.
11 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_pitch/slide5.md:
--------------------------------------------------------------------------------
1 | # Our solution for the individual 🙋
2 |
3 | R3BL CMDR empowers developers to do all this in a `terminal`
4 |
5 | ## NOTES & JOURNAL
6 | - Capture content immediately, organize and link later
7 |
8 | ## ISSUES
9 | - Connect to GitHub API to manage issues across repos
10 |
11 | ## RUN DOCS
12 | - Edit MD files & execute embedded code w/out browser
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_pitch/slide6.md:
--------------------------------------------------------------------------------
1 | # Our solution for the individual 🙋
2 |
3 | ## DIAGRAMS
4 | - Easily create text based diagrams for better documentation
5 |
6 | ## GIT FRONT END
7 | - Manage git workflow from directly in app
8 |
9 | ## LOGGER
10 | - Analyze, format, search log files ergonomically
11 |
12 | ## JOURNEYS & JUMP POINTS
13 | - Capture, save, share flows through docs, source, issues
14 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_pitch/slide7.md:
--------------------------------------------------------------------------------
1 | # Our solution for the individual 🙋
2 |
3 | ## WORKFLOW AUTOMATION
4 | - Sync settings, backup keys, run scripts
5 |
6 | ## MAX
7 | - Perform tasks w/ autocompletion launcher, AI powered 🤖
8 |
9 | ╭────────────╮
10 | │ TUI 🤝 GUI │
11 | ╰────────────╯
12 | - We plan to make a GUI version of MAX and CMDR 🔮
13 | - We plan to make IDEA plugins and VSCode extensions 🧩
14 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_pitch/slide8.md:
--------------------------------------------------------------------------------
1 | # Our solution for teams 🙋👱💁
2 |
3 | ## R3BL BASE (Rebel Base)
4 | Set of services written in Rust 🦀 & hosted in the cloud ☁️ .
5 |
6 | - It is subscription based & provides:
7 | 1. 📓 Multi-user notes editing & comments
8 | 2. 📅 Calendar
9 | 3. 📒 Contacts
10 | 4. 📽️ Slides
11 | 5. 💬 Messaging / chat
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_pitch/slide9.md:
--------------------------------------------------------------------------------
1 | # Business model 💰
2 |
3 | - TUI engine is free and open source (FOSS)
4 | - R3BL CMDR product is closed source & freemium subscription
5 | - R3BL BASE product is closed source & subscription
6 | - Business model is similar to JetBrains
7 |
8 | ╭──────────────────────────────────────────────────────────────╮
9 | │ Rust is reliable, efficient, fast, cheap to host services ⚡ │
10 | ╰──────────────────────────────────────────────────────────────╯
11 |
12 | [97% RAM reduction](https://youtu.be/XdMgH3eV6BA)
13 | [700 CPU reduction](https://tinyurl.com/547fkr9t)
14 | [70% less CPU and 67% less memory](https://tinyurl.com/33hx8539)
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_rc/launcher.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use r3bl_tui::{key_press,
19 | throws,
20 | CommonResult,
21 | InputEvent,
22 | ModifierKeysMask,
23 | TerminalWindow};
24 |
25 | use super::{AppMain, State};
26 |
27 | pub async fn run_app() -> CommonResult<()> {
28 | throws!({
29 | // Create an App (renders & responds to user input).
30 | let app = AppMain::new_boxed();
31 |
32 | // Exit if these keys are pressed.
33 | let exit_keys = &[InputEvent::Keyboard(
34 | key_press! { @char ModifierKeysMask::new().with_ctrl(), 'q' },
35 | )];
36 |
37 | // Create a window.
38 | _ = TerminalWindow::main_event_loop(app, exit_keys, State::default()).await?;
39 | });
40 | }
41 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_rc/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach sources.
19 | pub mod app_main;
20 | pub mod launcher;
21 | pub mod state;
22 |
23 | // Re-export only inside this module.
24 | pub use app_main::*;
25 | pub use state::*;
26 |
--------------------------------------------------------------------------------
/tui/examples/tui_apps/ex_rc/slide1.md:
--------------------------------------------------------------------------------
1 | # ✅ Todo list
2 |
3 | ## 🚀 continue building r3bl_cmdr:
4 | - [ ] flush out core editor component features (copy, paste, select, etc)
5 | - [x] analytics measurement @done(23-04-20 15:52)
6 |
7 | ## 🐒 r3bl_cmdr:
8 | - [ ] notes editor
9 | - [ ] github issues
10 | - [ ] analytics measurement
11 | - [x] dashboard for weather etc @done(23-04-20 15:52)
12 | - [x] alpha release @done(23-04-20 15:52)
13 |
14 | ## 🦜 release new version
15 | - [x] update `CHANGELOG.md` @done(23-04-20 15:52)
16 | - [x] update `README.md` @done(23-04-20 15:52)
17 | - [x] update `lib.rs` @done(23-04-20 15:53)
18 | - [x] create new tag @done(23-04-20 19:35)
19 | - [x] publish to crates.io @done(23-04-20 19:35)
20 |
--------------------------------------------------------------------------------
/tui/src/core/common/common_enums.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #[derive(Debug, Clone, PartialEq, Copy, Default)]
19 | pub enum ContainsResult {
20 | #[default]
21 | DoesNotContain,
22 | DoesContain,
23 | }
24 |
--------------------------------------------------------------------------------
/tui/src/core/common/get_mem_size.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | pub trait GetMemSize {
19 | fn get_mem_size(&self) -> usize;
20 | }
21 |
22 | /// Calculates the total memory size of a slice of items that implement [GetMemSize].
23 | /// This is useful when you need to calculate the total memory size of a collection of
24 | /// items (eg [Vec] or [smallvec::SmallVec] of [crate::GCString]).
25 | pub fn slice_size(slice: &[T]) -> usize {
26 | slice.iter().map(|item| item.get_mem_size()).sum::()
27 | }
28 |
29 | /// Calculates the total memory size of an iterator of items that implement
30 | /// [GetMemSize]. This is useful when you need to calculate the total memory size of
31 | /// an iterator of items (eg: from [crate::RingBufferHeap] or
32 | /// [crate::RingBufferStack]) that contains items that are [Option] of [GetMemSize].
33 | pub fn iter_size>>(iter: I) -> usize {
34 | iter.map(|item| item.as_ref().map_or(0, |item| item.get_mem_size()))
35 | .sum::()
36 | }
37 |
38 | pub fn ring_buffer_size(
39 | ring_buffer: &crate::RingBufferHeap,
40 | ) -> usize {
41 | ring_buffer
42 | .iter()
43 | .map(|item| item.get_mem_size())
44 | .sum::()
45 | }
46 |
--------------------------------------------------------------------------------
/tui/src/core/common/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach sources.
19 | pub mod common_enums;
20 | pub mod common_math;
21 | pub mod common_result_and_error;
22 | pub mod get_mem_size;
23 | pub mod miette_setup_global_report_handler;
24 | pub mod ordered_map;
25 | pub mod rate_limiter;
26 | pub mod ring_buffer;
27 | pub mod ring_buffer_heap;
28 | pub mod ring_buffer_stack;
29 | pub mod telemetry;
30 | pub mod time_duration;
31 |
32 | // Re-export.
33 | pub use common_enums::*;
34 | pub use common_math::*;
35 | pub use common_result_and_error::*;
36 | pub use get_mem_size::*;
37 | pub use miette_setup_global_report_handler::*;
38 | pub use ordered_map::*;
39 | pub use rate_limiter::*;
40 | pub use ring_buffer::*;
41 | pub use ring_buffer_heap::*;
42 | pub use ring_buffer_stack::*;
43 | pub use telemetry::*;
44 | pub use time_duration::*;
45 |
--------------------------------------------------------------------------------
/tui/src/core/common/ring_buffer.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use crate::{idx, len, Index, InlineVec, Length};
19 |
20 | /// There are two implementations of this trait:
21 | /// - [super::RingBufferStack] which uses a fixed-size array on the stack.
22 | /// - [super::RingBufferHeap] which uses a [Vec] on the heap.
23 | pub trait RingBuffer {
24 | fn len(&self) -> Length;
25 |
26 | fn is_full(&self) -> bool { self.len() == len(N) }
27 |
28 | fn clear(&mut self);
29 |
30 | fn get(&self, arg_index: impl Into) -> Option<&T>;
31 |
32 | fn is_empty(&self) -> bool { self.len() == len(0) }
33 |
34 | fn first(&self) -> Option<&T> { self.get(idx(0)) }
35 |
36 | fn last(&self) -> Option<&T> { self.get(self.len().convert_to_index()) }
37 |
38 | fn add(&mut self, value: T);
39 |
40 | fn remove(&mut self) -> Option;
41 |
42 | fn remove_head(&mut self) -> Option;
43 |
44 | fn truncate(&mut self, arg_index: impl Into);
45 |
46 | fn push(&mut self, value: T) { self.add(value); }
47 |
48 | fn pop(&mut self) -> Option { self.remove_head() }
49 |
50 | /// Returns a view of the underlying internal storage of the struct that implements
51 | /// this trait.
52 | fn as_slice_raw(&self) -> &[Option];
53 |
54 | /// Take a [RingBuffer::as_slice_raw] which yields an slice of [`Option<&T>`], then
55 | /// remove the [None] items, and return a [`InlineVec<&T>`].
56 | /// - This uses [Iterator::filter_map] function.
57 | /// - Even though `T` is not cloned, the collection has to be allocated and moved to
58 | /// the caller, via return. A slice can't be returned because it would be owned by
59 | /// this function.
60 | fn as_slice(&self) -> InlineVec<&T> {
61 | let slice = self.as_slice_raw();
62 | let acc: InlineVec<&T> =
63 | slice.iter().filter_map(|style| style.as_ref()).collect();
64 | acc
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/tui/src/core/decl_macros/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach sources.
19 | pub mod macros;
20 |
--------------------------------------------------------------------------------
/tui/src/core/log/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach sources.
19 | pub mod custom_event_formatter;
20 | pub mod log_public_api;
21 | pub mod rolling_file_appender_impl;
22 | pub mod tracing_config;
23 | pub mod tracing_init;
24 |
25 | // Re-export.
26 | pub use custom_event_formatter::*;
27 | pub use log_public_api::*;
28 | pub use rolling_file_appender_impl::*;
29 | pub use tracing_config::*;
30 | pub use tracing_init::*;
31 |
--------------------------------------------------------------------------------
/tui/src/core/log/rolling_file_appender_impl.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use std::path::PathBuf;
19 |
20 | /// Note that if you wrap this up in a non blocking writer, it doesn't work. Here's an
21 | /// example of this:
22 | /// `tracing_appender::non_blocking(try_create_rolling_file_appender("foo")?)`
23 | pub fn try_create(
24 | path_str: &str,
25 | ) -> miette::Result {
26 | let path = PathBuf::from(&path_str);
27 |
28 | let parent = path.parent().ok_or_else(|| {
29 | miette::miette!(
30 | format!("Can't access current folder {}. It might not exist, or don't have required permissions.",
31 | path.display())
32 | )
33 | })?;
34 |
35 | let file_stem = path.file_name().ok_or_else(|| {
36 | miette::miette!(format!(
37 | "Can't access file name {}. It might not exist, or don't have required permissions.",
38 | path.display()
39 | ))
40 | })?;
41 |
42 | Ok(tracing_appender::rolling::never(parent, file_stem))
43 | }
44 |
--------------------------------------------------------------------------------
/tui/src/core/misc/formatter.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use crate::InlineString;
19 |
20 | /// This macro is used to format an option. If the option is [Some], it will return the
21 | /// value. It is meant for use with [std::fmt::Formatter::debug_struct].
22 | ///
23 | /// When using this, make sure to import [FormatOptionMsg] as well, like this:
24 | ///
25 | /// ```
26 | /// use r3bl_tui::{fmt_option, FormatOptionMsg};
27 | ///
28 | /// struct FooStruct {
29 | /// pub insertion_pos_for_next_box: Option,
30 | /// }
31 | ///
32 | /// impl std::fmt::Debug for FooStruct {
33 | /// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 | /// f.debug_struct("FlexBox")
35 | /// .field(
36 | /// "insertion_pos_for_next_box",
37 | /// fmt_option!(&self.insertion_pos_for_next_box),
38 | /// )
39 | /// .finish()
40 | /// }
41 | /// }
42 | #[macro_export]
43 | macro_rules! fmt_option {
44 | ($opt:expr) => {
45 | match ($opt) {
46 | Some(v) => v,
47 | None => &$crate::FormatOptionMsg::None,
48 | }
49 | };
50 | }
51 |
52 | #[derive(Clone, Copy, Debug)]
53 | pub enum FormatOptionMsg {
54 | None,
55 | }
56 |
57 | /// Marker trait to "remember" which types can be converted to plain text.
58 | pub trait ConvertToPlainText {
59 | fn to_plain_text(&self) -> InlineString;
60 | }
61 |
62 | /// Marker trait to "remember" which types support pretty printing for debugging.
63 | pub trait PrettyPrintDebug {
64 | fn pretty_print_debug(&self) -> InlineString;
65 | }
66 |
--------------------------------------------------------------------------------
/tui/src/core/misc/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach sources.
19 | pub mod calc_str_len;
20 | pub mod formatter;
21 | pub mod friendly_random_id;
22 | pub mod string_helpers;
23 |
24 | // Re-export.
25 | pub use calc_str_len::*;
26 | pub use formatter::*;
27 | pub use friendly_random_id::*;
28 | pub use string_helpers::*;
29 |
--------------------------------------------------------------------------------
/tui/src/core/script/command_impl/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach.
19 | pub mod command_run_result;
20 | pub mod command_runner;
21 |
22 | // Re-export.
23 | pub use command_run_result::*;
24 | pub use command_runner::*;
25 |
--------------------------------------------------------------------------------
/tui/src/core/script/http_client.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use miette::IntoDiagnostic;
19 |
20 | mod constants {
21 | pub const USER_AGENT: &str = "scripting.rs/1.0";
22 | }
23 |
24 | pub fn create_client_with_user_agent(
25 | user_agent: Option<&str>,
26 | ) -> miette::Result {
27 | let it = reqwest::Client::builder()
28 | .user_agent(user_agent.map_or_else(
29 | || constants::USER_AGENT.to_owned(),
30 | |user_agent| user_agent.to_owned(),
31 | ))
32 | .build();
33 | it.into_diagnostic()
34 | }
35 |
--------------------------------------------------------------------------------
/tui/src/core/script/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #![allow(clippy::literal_string_with_formatting_args)]
19 |
20 | // Attach sources.
21 | pub mod apt_install;
22 | pub mod command_impl;
23 | pub mod crates_api;
24 | pub mod directory_change;
25 | pub mod directory_create;
26 | pub mod download;
27 | pub mod environment;
28 | pub mod fs_path;
29 | pub mod github_api;
30 | pub mod http_client;
31 | pub mod permissions;
32 | pub mod temp_dir;
33 |
34 | // Re-export.
35 | pub use apt_install::*;
36 | pub use command_impl::*;
37 | pub use crates_api::*;
38 | pub use directory_change::*;
39 | pub use directory_create::*;
40 | pub use download::*;
41 | pub use environment::*;
42 | pub use fs_path::*;
43 | pub use github_api::*;
44 | pub use http_client::*;
45 | pub use permissions::*;
46 | pub use temp_dir::*;
47 |
48 | pub const SCRIPT_MOD_DEBUG: bool = true;
49 |
--------------------------------------------------------------------------------
/tui/src/core/stack_alloc_types/memory_allocator.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | /// `jemalloc` is a replacement for the default global allocator. It's optimized for
19 | /// multi-threaded use cases where lots of small objects are created and destroyed.
20 | /// The default allocator is the system allocator that's optimized for single threaded
21 | /// use cases.
22 | /// -
23 | /// -
24 | /// -
25 | /// -
26 | #[macro_export]
27 | macro_rules! set_jemalloc_in_main {
28 | () => {{
29 | #[cfg(not(target_env = "msvc"))]
30 | use tikv_jemallocator::Jemalloc;
31 |
32 | #[cfg(not(target_env = "msvc"))]
33 | #[global_allocator]
34 | static GLOBAL: Jemalloc = Jemalloc;
35 | }};
36 | }
37 |
--------------------------------------------------------------------------------
/tui/src/core/stack_alloc_types/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach.
19 | pub mod constructors;
20 | pub mod into_existing;
21 | pub mod items;
22 | pub mod list_of;
23 | pub mod make_new;
24 | pub mod memory_allocator;
25 | pub mod sizes;
26 | pub mod usize_fmt;
27 |
28 | // Re-export.
29 | pub use items::*;
30 | pub use list_of::*;
31 | pub use sizes::*;
32 | pub use usize_fmt::*;
33 |
--------------------------------------------------------------------------------
/tui/src/core/storage/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach sources.
19 | pub mod kv;
20 |
21 | // Re-export.
22 | pub use kv::*;
23 |
--------------------------------------------------------------------------------
/tui/src/core/terminal_io/input_device.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use crossterm::event::EventStream;
19 | use futures_util::{FutureExt, StreamExt};
20 | use miette::IntoDiagnostic;
21 |
22 | use crate::{CrosstermEventResult, PinnedInputStream};
23 |
24 | /// This struct represents an input device that can be used to read from the terminal. See
25 | /// [crate::InputDeviceExt] for testing features.
26 | pub struct InputDevice {
27 | pub resource: PinnedInputStream,
28 | }
29 |
30 | impl InputDevice {
31 | pub fn new_event_stream() -> InputDevice {
32 | InputDevice {
33 | resource: Box::pin(EventStream::new()),
34 | }
35 | }
36 | }
37 |
38 | impl InputDevice {
39 | pub async fn next(&mut self) -> miette::Result {
40 | match self.resource.next().fuse().await {
41 | Some(it) => it.into_diagnostic(),
42 | None => miette::bail!("Failed to get next event from input source."),
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/tui/src/core/terminal_io/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach sources.
19 | pub mod input_device;
20 | pub mod output_device;
21 | pub mod shared_writer;
22 | pub mod terminal_io_type_aliases;
23 |
24 | // Re-export.
25 | pub use input_device::*;
26 | pub use output_device::*;
27 | pub use shared_writer::*;
28 | pub use terminal_io_type_aliases::*;
29 |
--------------------------------------------------------------------------------
/tui/src/core/terminal_io/terminal_io_type_aliases.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use std::{io::Error, pin::Pin, sync::Arc};
19 |
20 | use crossterm::event::Event;
21 | use futures_core::Stream;
22 |
23 | /// Disambiguate the type of `StdMutex` from stdlib and tokio to avoid conflicts.
24 | pub type StdMutex = std::sync::Mutex;
25 |
26 | /// Type alias for a `Send`-able output device (raw terminal, SharedWriter, etc).
27 | pub type SendRawTerminal = dyn std::io::Write + Send;
28 | /// Type alias for a `Send`-able raw terminal wrapped in an `Arc`.
29 | pub type SafeRawTerminal = Arc>;
30 |
31 | /// Type alias for crossterm streaming (input) event result.
32 | pub type CrosstermEventResult = Result;
33 | /// Type alias for a pinned stream that is async safe. `T` is usually
34 | /// [CrosstermEventResult].
35 | pub type PinnedInputStream = Pin>>;
36 |
--------------------------------------------------------------------------------
/tui/src/core/test_fixtures/input_device_fixtures/async_input_stream_mock.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use std::time::Duration;
19 |
20 | use async_stream::stream;
21 |
22 | use crate::{InlineVec, PinnedInputStream};
23 |
24 | /// The main constructors are:
25 | /// - [super::InputDeviceExtMock::new_mock()]
26 | /// - [super::InputDeviceExtMock::new_mock_with_delay()]
27 | pub fn gen_input_stream(generator_vec: InlineVec) -> PinnedInputStream
28 | where
29 | T: Send + Sync + 'static,
30 | {
31 | let it = stream! {
32 | for item in generator_vec {
33 | yield item;
34 | }
35 | };
36 | Box::pin(it)
37 | }
38 |
39 | pub fn gen_input_stream_with_delay(
40 | generator_vec: InlineVec,
41 | delay: Duration,
42 | ) -> PinnedInputStream
43 | where
44 | T: Send + Sync + 'static,
45 | {
46 | let it = stream! {
47 | for item in generator_vec {
48 | tokio::time::sleep(delay).await;
49 | yield item;
50 | }
51 | };
52 | Box::pin(it)
53 | }
54 |
55 | #[cfg(test)]
56 | mod tests {
57 | use futures_util::StreamExt;
58 | use smallvec::smallvec;
59 |
60 | use super::*;
61 |
62 | #[tokio::test]
63 | #[allow(clippy::needless_return)]
64 | async fn test_gen_input_stream() {
65 | let mut input_stream = gen_input_stream(smallvec![1, 2, 3]);
66 | for _ in 1..=3 {
67 | input_stream.next().await;
68 | }
69 | pretty_assertions::assert_eq!(input_stream.next().await, None);
70 | }
71 |
72 | #[tokio::test]
73 | #[allow(clippy::needless_return)]
74 | async fn test_gen_input_stream_with_delay() {
75 | const DELAY: u64 = 100;
76 |
77 | // Start timer.
78 | let start_time = std::time::Instant::now();
79 |
80 | let mut input_stream =
81 | gen_input_stream_with_delay(smallvec![1, 2, 3], Duration::from_millis(DELAY));
82 | for _ in 1..=3 {
83 | input_stream.next().await;
84 | }
85 |
86 | // End timer.
87 | let end_time = std::time::Instant::now();
88 |
89 | pretty_assertions::assert_eq!(input_stream.next().await, None);
90 |
91 | assert!(end_time - start_time >= Duration::from_millis(DELAY * 3));
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/tui/src/core/test_fixtures/input_device_fixtures/input_device_ext_mock.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use std::time::Duration;
19 |
20 | use super::{gen_input_stream, gen_input_stream_with_delay};
21 | use crate::{CrosstermEventResult, InlineVec, InputDevice};
22 |
23 | pub trait InputDeviceExtMock {
24 | fn new_mock(generator_vec: InlineVec) -> InputDevice;
25 |
26 | fn new_mock_with_delay(
27 | generator_vec: InlineVec,
28 | delay: Duration,
29 | ) -> InputDevice;
30 | }
31 |
32 | impl InputDeviceExtMock for InputDevice {
33 | fn new_mock(generator_vec: InlineVec) -> InputDevice {
34 | InputDevice {
35 | resource: gen_input_stream(generator_vec),
36 | }
37 | }
38 |
39 | fn new_mock_with_delay(
40 | generator_vec: InlineVec,
41 | delay: Duration,
42 | ) -> InputDevice {
43 | InputDevice {
44 | resource: gen_input_stream_with_delay(generator_vec, delay),
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/tui/src/core/test_fixtures/input_device_fixtures/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach.
19 | pub mod async_input_stream_mock;
20 | pub mod input_device_ext_mock;
21 |
22 | // Re-export.
23 | pub use async_input_stream_mock::*;
24 | pub use input_device_ext_mock::*;
25 |
--------------------------------------------------------------------------------
/tui/src/core/test_fixtures/output_device_fixtures/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach.
19 | pub mod output_device_ext;
20 | pub mod stdout_mock;
21 |
22 | // Re-export.
23 | pub use output_device_ext::*;
24 | pub use stdout_mock::*;
25 |
--------------------------------------------------------------------------------
/tui/src/core/test_fixtures/output_device_fixtures/output_device_ext.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use std::sync::Arc;
19 |
20 | use crate::{OutputDevice, StdMutex, StdoutMock};
21 |
22 | pub trait OutputDeviceExt {
23 | fn new_mock() -> (OutputDevice, StdoutMock);
24 | }
25 |
26 | impl OutputDeviceExt for OutputDevice {
27 | fn new_mock() -> (OutputDevice, StdoutMock) {
28 | let stdout_mock = StdoutMock::default();
29 | let this = OutputDevice {
30 | resource: Arc::new(StdMutex::new(stdout_mock.clone())),
31 | is_mock: true,
32 | };
33 | (this, stdout_mock)
34 | }
35 | }
36 |
37 | #[cfg(test)]
38 | mod tests {
39 | use super::OutputDeviceExt;
40 | use crate::{lock_output_device_as_mut, LockedOutputDevice, OutputDevice};
41 |
42 | #[test]
43 | fn test_mock_output_device() {
44 | let (device, mock) = OutputDevice::new_mock();
45 | let mut_ref: LockedOutputDevice<'_> = lock_output_device_as_mut!(device);
46 | let _ = mut_ref.write_all(b"Hello, world!\n");
47 | assert_eq!(
48 | mock.get_copy_of_buffer_as_string_strip_ansi(),
49 | "Hello, world!\n"
50 | );
51 | }
52 |
53 | #[test]
54 | fn test_mock_output_device_is_mock() {
55 | let (device, _) = OutputDevice::new_mock();
56 | assert!(device.is_mock);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/tui/src/core/test_fixtures/tcp_stream_fixtures/mock_async_stream.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use std::{io::Result,
19 | pin::Pin,
20 | task::{Context, Poll}};
21 |
22 | use tokio::io::{AsyncRead, AsyncWrite};
23 |
24 | /// A mock struct for the [tokio::net::TcpStream].
25 | /// - Alternative to [`tokio_test::io::Builder`](https://docs.rs/tokio-test/latest/tokio_test/io/struct.Builder.html)
26 | /// in the `tokio-test` crate.
27 | /// - The difference is that [MockAsyncStream] allows access to the expected write buffer.
28 | pub struct MockAsyncStream {
29 | pub expected_buffer: Vec,
30 | }
31 |
32 | /// Implement the [AsyncWrite] trait for the mock struct. This struct also automatically
33 | /// implements [Unpin], because it contains no self-referencing pointers.
34 | impl AsyncWrite for MockAsyncStream {
35 | fn poll_write(
36 | mut self: Pin<&mut Self>,
37 | _cx: &mut Context<'_>,
38 | buf: &[u8],
39 | ) -> Poll> {
40 | self.expected_buffer.extend_from_slice(buf);
41 | Poll::Ready(Ok(buf.len()))
42 | }
43 |
44 | fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> {
45 | Poll::Ready(Ok(()))
46 | }
47 |
48 | fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> {
49 | Poll::Ready(Ok(()))
50 | }
51 | }
52 |
53 | /// Implement the [AsyncRead] trait for the mock struct. This struct also automatically
54 | /// implements [Unpin], because it contains no self-referencing pointers.
55 | impl AsyncRead for MockAsyncStream {
56 | fn poll_read(
57 | mut self: Pin<&mut Self>,
58 | _cx: &mut Context<'_>,
59 | buf: &mut tokio::io::ReadBuf<'_>,
60 | ) -> std::task::Poll> {
61 | let data = self.expected_buffer.as_slice();
62 | let len = std::cmp::min(data.len(), buf.remaining());
63 | buf.put_slice(&data[..len]);
64 | self.expected_buffer.drain(..len);
65 | Poll::Ready(Ok(()))
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/tui/src/core/test_fixtures/tcp_stream_fixtures/mock_socket.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use tokio::io::{duplex, split, DuplexStream, ReadHalf, WriteHalf};
19 |
20 | pub struct MockSocket {
21 | pub client_read: ReadHalf,
22 | pub client_write: WriteHalf,
23 | pub server_read: ReadHalf,
24 | pub server_write: WriteHalf,
25 | }
26 |
27 | /// A “channel” is created by [tokio::io::duplex] that can be used as in-memory IO
28 | /// types.
29 | ///
30 | /// Given a "channel":
31 | /// 1. Writing to the first of the pairs will allow that data to be read from the other.
32 | /// 2. Writing to the other pair will allow that data to be read from the first.
33 | pub fn get_mock_socket_halves() -> MockSocket {
34 | let (client_stream, server_stream) = duplex(1024);
35 |
36 | let (client_read, client_write) = split(client_stream);
37 |
38 | let (server_read, server_write) = split(server_stream);
39 |
40 | MockSocket {
41 | client_read,
42 | client_write,
43 | server_read,
44 | server_write,
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/tui/src/core/test_fixtures/tcp_stream_fixtures/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach.
19 | pub mod mock_async_stream;
20 | pub mod mock_socket;
21 |
22 | // Re-export.
23 | pub use mock_async_stream::*;
24 | pub use mock_socket::*;
25 |
--------------------------------------------------------------------------------
/tui/src/core/tui_core/color_wheel/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach.
19 | pub mod color_wheel_impl;
20 | pub mod color_wheel_types;
21 | pub mod config;
22 | pub mod lolcat_api;
23 | pub mod lolcat_impl;
24 |
25 | // Re-export.
26 | pub use color_wheel_impl::*;
27 | pub use color_wheel_types::*;
28 | pub use config::*;
29 | pub use lolcat_api::*;
30 | pub use lolcat_impl::*;
31 |
--------------------------------------------------------------------------------
/tui/src/core/tui_core/color_wheel_core/color_helpers.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use super::ColorWheelControl;
19 |
20 | /// More info on luminance:
21 | /// -
22 | /// -
23 | pub fn calc_fg_color(bg: (u8, u8, u8)) -> (u8, u8, u8) {
24 | let luminance =
25 | 0.2126 * (bg.0 as f32) + 0.7152 * (bg.1 as f32) + 0.0722 * (bg.2 as f32);
26 | if luminance < 140.0 {
27 | (255, 255, 255)
28 | } else {
29 | (0, 0, 0)
30 | }
31 | }
32 |
33 | pub fn get_color_tuple(c: &ColorWheelControl) -> (u8, u8, u8) {
34 | let i = *c.frequency * *c.seed / *c.spread;
35 | let red = i.sin() * 127.00 + 128.00;
36 | let green = (i + (std::f64::consts::PI * 2.00 / 3.00)).sin() * 127.00 + 128.00;
37 | let blue = (i + (std::f64::consts::PI * 4.00 / 3.00)).sin() * 127.00 + 128.00;
38 |
39 | (red as u8, green as u8, blue as u8)
40 | }
41 |
--------------------------------------------------------------------------------
/tui/src/core/tui_core/color_wheel_core/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach sources.
19 | pub mod ansi_256_color_gradients;
20 | pub mod color_helpers;
21 | pub mod color_wheel_control;
22 | pub mod policies;
23 | pub mod truecolor_gradient;
24 |
25 | // Re-export.
26 | pub use ansi_256_color_gradients::*;
27 | pub use color_wheel_control::*;
28 | pub use policies::*;
29 | pub use truecolor_gradient::*;
30 |
--------------------------------------------------------------------------------
/tui/src/core/tui_core/color_wheel_core/policies.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use crate::TuiStyle;
19 |
20 | #[derive(Clone, PartialEq, Eq, Hash, Debug)]
21 | pub enum GradientGenerationPolicy {
22 | /// The first time this method is called it will generate a gradient w/ the number
23 | /// of steps. Subsequent calls will use the same gradient and index **if** the
24 | /// number of steps is the same. However, if the number of steps are different,
25 | /// then a new gradient will be generated & the index reset.
26 | RegenerateGradientAndIndexBasedOnTextLength,
27 | /// The first time this method is called it will generate a gradient w/ the number
28 | /// of steps. Subsequent calls will use the same gradient and index.
29 | ReuseExistingGradientAndIndex,
30 | ReuseExistingGradientAndResetIndex,
31 | }
32 |
33 | #[derive(Clone, PartialEq, Eq, Hash, Debug)]
34 | pub enum TextColorizationPolicy {
35 | ColorEachCharacter(Option),
36 | ColorEachWord(Option),
37 | }
38 |
--------------------------------------------------------------------------------
/tui/src/core/tui_core/dimens/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach source files.
19 | pub mod caret;
20 | pub mod col_index;
21 | pub mod col_width;
22 | pub mod dim;
23 | pub mod dimens_check_overflows; // Don't re-export.
24 | pub mod pc;
25 | pub mod pos;
26 | pub mod req_size_pc;
27 | pub mod row_height;
28 | pub mod row_index;
29 | pub mod scr_ofs;
30 |
31 | // Re-export.
32 | pub use caret::*;
33 | pub use col_index::*;
34 | pub use col_width::*;
35 | pub use dim::*;
36 | pub use pc::*;
37 | pub use pos::*;
38 | pub use req_size_pc::*;
39 | pub use row_height::*;
40 | pub use row_index::*;
41 | pub use scr_ofs::*;
42 |
--------------------------------------------------------------------------------
/tui/src/core/tui_core/dimens/req_size_pc.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use std::fmt::{self, Debug};
19 |
20 | use super::Pc;
21 |
22 | /// Represents a percentage value for the requested size. It is used to calculate the
23 | /// requested size as a percentage of the parent size.
24 | ///
25 | /// # How to use it
26 | ///
27 | /// You can create it either of the following ways:
28 | /// 1. Use the [crate::req_size_pc!] macro. It uses the [crate::pc!] macro to do the
29 | /// [crate::Pc] conversion. Make sure to call this macro from a block that returns a
30 | /// [Result] type, since the `?` operator is used here.
31 | /// 2. Directly create it using the [ReqSizePc] struct with [crate::Pc] values.
32 | ///
33 | /// Note that [crate::Size], defined as:
34 | /// - height or [crate::Size::row_height],
35 | /// - width or [crate::Size::col_width].
36 | #[derive(Copy, Clone, Default, PartialEq, Eq, Hash)]
37 | pub struct ReqSizePc {
38 | pub width_pc: Pc,
39 | pub height_pc: Pc,
40 | }
41 |
42 | /// This must be called from a block that returns a [Result] type. Since the `?` operator
43 | /// is used here.
44 | #[macro_export]
45 | macro_rules! req_size_pc {
46 | (
47 | width: $arg_width: expr,
48 | height: $arg_height: expr
49 | ) => {
50 | $crate::ReqSizePc {
51 | width_pc: $crate::pc!($arg_width)?,
52 | height_pc: $crate::pc!($arg_height)?,
53 | }
54 | };
55 | }
56 |
57 | impl Debug for ReqSizePc {
58 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59 | write!(
60 | f,
61 | "[width:{w:?}, height:{h:?}]",
62 | w = self.width_pc,
63 | h = self.height_pc
64 | )
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/tui/src/core/tui_core/graphemes/byte_index.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use std::ops::{Deref, DerefMut};
19 |
20 | use crate::ChUnit;
21 |
22 | /// Represents a byte index inside of the underlying [crate::InlineString] of
23 | /// [super::GCString].
24 | #[derive(Debug, Copy, Clone, Default, PartialEq, Ord, PartialOrd, Eq, Hash)]
25 | pub struct ByteIndex(pub usize);
26 |
27 | pub fn byte_index(arg_byte_index: impl Into) -> ByteIndex {
28 | arg_byte_index.into()
29 | }
30 |
31 | impl Deref for ByteIndex {
32 | type Target = usize;
33 | fn deref(&self) -> &Self::Target { &self.0 }
34 | }
35 |
36 | impl DerefMut for ByteIndex {
37 | fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
38 | }
39 |
40 | impl From for ByteIndex {
41 | fn from(it: usize) -> Self { Self(it) }
42 | }
43 |
44 | impl From for ByteIndex {
45 | fn from(it: ChUnit) -> Self { Self(crate::usize(it)) }
46 | }
47 |
--------------------------------------------------------------------------------
/tui/src/core/tui_core/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | //! All the modules this crate are in support of the `r3bl_tui` crate.
19 |
20 | // Attach sources.
21 | pub mod color_wheel;
22 | pub mod color_wheel_core;
23 | pub mod dimens;
24 | pub mod graphemes;
25 | pub mod spinner_impl;
26 | pub mod tui_style;
27 | pub mod tui_styled_text;
28 | pub mod units;
29 |
30 | // Re-export.
31 | pub use color_wheel::*;
32 | pub use color_wheel_core::*;
33 | pub use dimens::*;
34 | pub use graphemes::*;
35 | pub use spinner_impl::*;
36 | pub use tui_style::*;
37 | pub use tui_styled_text::*;
38 | pub use units::*;
39 |
--------------------------------------------------------------------------------
/tui/src/core/tui_core/spinner_impl/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | pub mod spinner_constants;
19 | pub mod spinner_print;
20 | pub mod spinner_render;
21 | pub mod spinner_style;
22 |
23 | pub use spinner_constants::*;
24 | pub use spinner_print::*;
25 | pub use spinner_render::*;
26 | pub use spinner_style::*;
27 |
--------------------------------------------------------------------------------
/tui/src/core/tui_core/spinner_impl/spinner_constants.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use std::time::Duration;
19 |
20 | pub const DELAY_MS: u64 = 85;
21 | pub const DELAY_UNIT: Duration = Duration::from_millis(DELAY_MS);
22 | pub const ARTIFICIAL_UI_DELAY: Duration = Duration::from_millis(DELAY_MS * 25);
23 |
24 | /// More info:
25 | pub const BRAILLE_DOTS: [&str; 34] = [
26 | "⠁", "⠃", "⡇", "⠇", "⡎", "⢟", "⡯", "⡗", "⡞", "⡟", "⡷", "⡾", "⡾", "⣕", "⣗", "⣝", "⡣",
27 | "⡮", "⡯", "⡳", "⡵", "⣞", "⣟", "⣧", "⣮", "⣯", "⣷", "⣿", "⣼", "⡟", "⡏", "⠇", "⠃", "⠁",
28 | ];
29 |
30 | pub const BLOCK_DOTS: [&str; 8] = ["█", "▓", "▒", "░", "░", "▒", "▓", "█"];
31 |
--------------------------------------------------------------------------------
/tui/src/core/tui_core/spinner_impl/spinner_style.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use smallvec::smallvec;
19 |
20 | use crate::{ColorWheel, ColorWheelConfig, ColorWheelSpeed};
21 |
22 | #[derive(Debug, Clone, Copy)]
23 | pub enum SpinnerTemplate {
24 | Braille,
25 | Block,
26 | }
27 |
28 | #[derive(Debug, Clone)]
29 | #[allow(clippy::large_enum_variant)]
30 | pub enum SpinnerColor {
31 | None,
32 | ColorWheel(ColorWheel),
33 | }
34 |
35 | impl SpinnerColor {
36 | /// Gradients:
37 | pub fn default_color_wheel() -> SpinnerColor {
38 | let color_wheel_config = ColorWheelConfig::Rgb(
39 | // Stops.
40 | smallvec!["#12c2e9".into(), "#c471ed".into(), "#f64f59".into()],
41 | // Speed.
42 | ColorWheelSpeed::Fast,
43 | // Steps.
44 | 10,
45 | );
46 | let mut it = ColorWheel::new(smallvec![color_wheel_config]);
47 | it.generate_color_wheel(None);
48 | SpinnerColor::ColorWheel(it)
49 | }
50 | }
51 |
52 | #[derive(Debug, Clone)]
53 | pub struct SpinnerStyle {
54 | pub template: SpinnerTemplate,
55 | pub color: SpinnerColor,
56 | }
57 |
58 | impl Default for SpinnerStyle {
59 | fn default() -> Self {
60 | SpinnerStyle {
61 | template: SpinnerTemplate::Braille,
62 | color: SpinnerColor::default_color_wheel(),
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/tui/src/core/tui_core/tui_style/hex_color_parser.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | //! This module contains a parser that parses a hex color string into a [RgbValue] struct.
19 | //! The hex color string can be in the following format: `#RRGGBB`, eg: `#FF0000` for red.
20 |
21 | use std::num::ParseIntError;
22 |
23 | use nom::{bytes::complete::{tag, take_while_m_n},
24 | combinator::map_res,
25 | IResult,
26 | Parser};
27 |
28 | use super::RgbValue;
29 |
30 | /// Parse function that generate an [RgbValue] struct from a valid hex color string.
31 | pub fn parse_hex_color(input: &str) -> IResult<&str, RgbValue> {
32 | let (input, _) = tag("#")(input)?;
33 | let (input, (red, green, blue)) =
34 | (hex_primary::parse, hex_primary::parse, hex_primary::parse).parse(input)?;
35 | Ok((input, RgbValue { red, green, blue }))
36 | }
37 |
38 | mod hex_primary {
39 | use super::*;
40 |
41 | pub fn parse(input: &str) -> IResult<&str, u8> {
42 | map_res(take_while_m_n(2, 2, is_hex_digit), from_hex).parse(input)
43 | }
44 |
45 | fn from_hex(input: &str) -> Result {
46 | u8::from_str_radix(input, 16)
47 | }
48 |
49 | fn is_hex_digit(c: char) -> bool { c.is_ascii_hexdigit() }
50 | }
51 |
52 | #[cfg(test)]
53 | mod tests {
54 | use super::*;
55 |
56 | #[test]
57 | fn parse_valid_color() {
58 | assert_eq!(
59 | parse_hex_color("#2F14DF"),
60 | Ok((
61 | "",
62 | RgbValue {
63 | red: 47,
64 | green: 20,
65 | blue: 223,
66 | }
67 | ))
68 | );
69 | }
70 |
71 | #[test]
72 | fn parse_valid_color_with_rem() {
73 | let mut input = String::new();
74 | input.push_str("#2F14DF");
75 | input.push('🔅');
76 |
77 | let result = dbg!(parse_hex_color(&input));
78 |
79 | let Ok((remainder, color)) = result else {
80 | panic!();
81 | };
82 | assert_eq!(remainder, "🔅");
83 | assert_eq!(color, RgbValue::from_u8(47, 20, 223));
84 | }
85 |
86 | #[test]
87 | fn parse_invalid_color() {
88 | let result = dbg!(parse_hex_color("🔅#2F14DF"));
89 | assert!(result.is_err());
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/tui/src/core/tui_core/tui_style/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach sources.
19 | pub mod crossterm_color_converter;
20 | pub mod hex_color_parser;
21 | pub mod tui_color;
22 | pub mod tui_style_impl;
23 | pub mod tui_style_lite;
24 | pub mod tui_stylesheet;
25 |
26 | // Re-export.
27 | pub use crossterm_color_converter::*;
28 | pub use hex_color_parser::*;
29 | pub use tui_color::*;
30 | pub use tui_style_impl::*;
31 | pub use tui_stylesheet::*;
32 |
--------------------------------------------------------------------------------
/tui/src/core/tui_core/tui_styled_text/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach sources.
19 | pub mod tui_styled_text_impl;
20 | pub mod tui_styled_texts_impl;
21 |
22 | // Re-export.
23 | pub use tui_styled_text_impl::*;
24 | pub use tui_styled_texts_impl::*;
25 |
--------------------------------------------------------------------------------
/tui/src/core/tui_core/tui_styled_text/tui_styled_text_impl.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use sizing::StringTuiStyledText;
19 | use smallstr::SmallString;
20 | use smallvec::SmallVec;
21 |
22 | use crate::TuiStyle;
23 |
24 | pub(in crate::core::tui_core::tui_styled_text) mod sizing {
25 | use super::*;
26 |
27 | /// Default internal storage for [TuiStyledText], which is very small.
28 | pub(crate) type StringTuiStyledText = SmallString<[u8; MAX_CHARS_IN_SMALL_STRING]>;
29 | const MAX_CHARS_IN_SMALL_STRING: usize = 8;
30 |
31 | pub(crate) type VecTuiStyledText = SmallVec<[TuiStyledText; MAX_ITEMS_IN_SMALL_VEC]>;
32 | const MAX_ITEMS_IN_SMALL_VEC: usize = 32;
33 | }
34 |
35 | /// Macro to make building [TuiStyledText] easy.
36 | ///
37 | /// Here's an example.
38 | /// ```
39 | /// use r3bl_tui::*;
40 | ///
41 | /// let style = TuiStyle::default();
42 | /// let st = tui_styled_text!(@style: style, @text: "Hello World");
43 | /// ```
44 | #[macro_export]
45 | macro_rules! tui_styled_text {
46 | (
47 | @style: $style_arg: expr,
48 | @text: $text_arg: expr
49 | $(,)* /* Optional trailing comma https://stackoverflow.com/a/43143459/2085356. */
50 | ) => {
51 | $crate::TuiStyledText::new($style_arg, $text_arg.to_string())
52 | };
53 | }
54 |
55 | /// Use [tui_styled_text!] macro for easier construction.
56 | #[derive(Debug, Clone)]
57 | pub struct TuiStyledText {
58 | pub style: TuiStyle,
59 | pub text: StringTuiStyledText,
60 | }
61 |
62 | impl Default for TuiStyledText {
63 | fn default() -> Self {
64 | TuiStyledText {
65 | style: TuiStyle::default(),
66 | text: "".into(),
67 | }
68 | }
69 | }
70 |
71 | impl TuiStyledText {
72 | pub fn new(style: TuiStyle, arg_styled_text: impl Into) -> Self {
73 | TuiStyledText {
74 | style,
75 | text: arg_styled_text.into(),
76 | }
77 | }
78 |
79 | pub fn get_text(&self) -> &str { self.text.as_str() }
80 |
81 | pub fn get_style(&self) -> &TuiStyle { &self.style }
82 | }
83 |
--------------------------------------------------------------------------------
/tui/src/core/tui_core/units/bounds_check.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #[derive(Debug, PartialEq, Clone, Copy)]
19 | pub enum BoundsStatus {
20 | Within,
21 | Overflowed,
22 | }
23 |
24 | /// This trait "formalizes" the concept of checking for overflow. More specifically, when
25 | /// an index (row or col index) overflows a length (width or height).
26 | ///
27 | /// When `a` and `b` are both unsigned integers, the following are equivalent:
28 | /// - `a >= b`
29 | /// - `a > b-1`
30 | ///
31 | /// So, the following expressions are equivalent:
32 | /// - `row_index >= height`
33 | /// - `row_index > height - 1`
34 | ///
35 | /// # Examples
36 | ///
37 | /// ```
38 | /// use r3bl_tui::{
39 | /// BoundsCheck, BoundsStatus,
40 | /// RowHeight, RowIndex, ColIndex, ColWidth
41 | /// };
42 | ///
43 | /// let row_index = RowIndex::new(5);
44 | /// let height = RowHeight::new(5);
45 | /// assert_eq!(
46 | /// row_index.check_overflows(height),
47 | /// BoundsStatus::Overflowed);
48 | ///
49 | /// let col_index = ColIndex::new(3);
50 | /// let width = ColWidth::new(5);
51 | /// assert_eq!(
52 | /// col_index.check_overflows(width),
53 | /// BoundsStatus::Within);
54 | /// ```
55 | pub trait BoundsCheck {
56 | fn check_overflows(&self, max: OtherType) -> BoundsStatus;
57 | }
58 |
--------------------------------------------------------------------------------
/tui/src/core/tui_core/units/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach.
19 | pub mod bounds_check;
20 | pub mod ch_unit;
21 | pub mod index;
22 | pub mod length;
23 | pub mod unit_check_overflows; // Don't re-export.
24 |
25 | // Re-export.
26 | pub use bounds_check::*;
27 | pub use ch_unit::*;
28 | pub use index::*;
29 | pub use length::*;
30 |
--------------------------------------------------------------------------------
/tui/src/network_io/compress.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | use std::io::{Read, Write};
18 |
19 | use flate2::{read::GzDecoder, write::GzEncoder, Compression};
20 | use miette::IntoDiagnostic;
21 |
22 | use crate::{Buffer, BufferAtom};
23 |
24 | /// Compress the payload using the [flate2] crate.
25 | pub fn compress(data: &[BufferAtom]) -> miette::Result {
26 | let uncompressed_size = data.len();
27 | let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
28 | encoder.write_all(data).into_diagnostic()?;
29 | let it = encoder.finish().into_diagnostic();
30 | let compressed_size = it.as_ref().map(|it| it.len()).unwrap_or(0);
31 | tracing::info!(
32 | "Compression: {:.2} kb -> {:.2} kb ({:.2}%)",
33 | uncompressed_size as f64 / 1000.0,
34 | compressed_size as f64 / 1000.0,
35 | (compressed_size as f64 / uncompressed_size as f64) * 100.0
36 | );
37 | it
38 | }
39 |
40 | /// Decompress the payload using the [flate2] crate.
41 | pub fn decompress(data: &[BufferAtom]) -> miette::Result {
42 | let compressed_size = data.len();
43 | let mut decoder = GzDecoder::new(data);
44 | let mut decompressed_data = Vec::new();
45 | decoder
46 | .read_to_end(&mut decompressed_data)
47 | .into_diagnostic()?;
48 | let uncompressed_size = decompressed_data.len();
49 | tracing::info!(
50 | "Decompression: {:.2} kb -> {:.2} kb ({:.2}%)",
51 | uncompressed_size as f64 / 1000.0,
52 | compressed_size as f64 / 1000.0,
53 | (compressed_size as f64 / uncompressed_size as f64) * 100.0
54 | );
55 | Ok(decompressed_data)
56 | }
57 |
--------------------------------------------------------------------------------
/tui/src/network_io/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach.
19 | pub mod bincode_serde;
20 | pub mod compress;
21 | pub mod length_prefix_protocol;
22 | pub mod protocol_types;
23 |
24 | // Re-export.
25 | pub use bincode_serde::*;
26 | pub use compress::*;
27 | pub use length_prefix_protocol::*;
28 | pub use protocol_types::*;
29 |
--------------------------------------------------------------------------------
/tui/src/network_io/protocol_types.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | /// Type alias for type to read from the stream to get the length prefix.
19 | pub type LengthPrefixType = u64;
20 | /// Type aliases for the payload buffer type.
21 | pub type Buffer = Vec;
22 | pub type BufferAtom = u8;
23 |
--------------------------------------------------------------------------------
/tui/src/readline_async/choose_impl/components/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach sources & re-export.
19 | pub mod select_component;
20 | pub use select_component::*;
21 |
22 | // Attach sources & re-export.
23 | pub mod apply_style_macro;
24 |
--------------------------------------------------------------------------------
/tui/src/readline_async/choose_impl/keypress_reader_sync.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use crate::InputEvent;
19 |
20 | pub trait KeyPressReader {
21 | fn read_key_press(&mut self) -> Option;
22 | }
23 |
24 | pub struct CrosstermKeyPressReader;
25 |
26 | impl KeyPressReader for CrosstermKeyPressReader {
27 | fn read_key_press(&mut self) -> Option {
28 | let maybe_read = crossterm::event::read().ok()?;
29 | InputEvent::try_from(maybe_read).ok()
30 | }
31 | }
32 |
33 | pub struct TestVecKeyPressReader {
34 | pub key_press_vec: Vec,
35 | pub index: Option,
36 | }
37 |
38 | impl KeyPressReader for TestVecKeyPressReader {
39 | #[allow(clippy::unwrap_in_result)] /* This is only used in tests */
40 | fn read_key_press(&mut self) -> Option {
41 | // Increment index every time this function is called until the end of the vector
42 | // and then wrap around.
43 | match self.index {
44 | Some(index) => {
45 | if index < self.key_press_vec.len() - 1 {
46 | self.index = Some(index + 1);
47 | } else {
48 | self.index = Some(0);
49 | }
50 | }
51 | None => {
52 | self.index = Some(0);
53 | }
54 | }
55 |
56 | let index = self.index.unwrap();
57 |
58 | Some(self.key_press_vec[index])
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/tui/src/readline_async/readline_async_impl/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach.
19 | pub mod line_state;
20 | pub mod readline;
21 | pub mod readline_history;
22 |
23 | // Re-export.
24 | pub use line_state::*;
25 | pub use readline::*;
26 | pub use readline_history::*;
27 |
--------------------------------------------------------------------------------
/tui/src/tui/animator/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach.
19 | pub mod animator_struct;
20 |
21 | // Re-export.
22 | pub use animator_struct::*;
23 |
--------------------------------------------------------------------------------
/tui/src/tui/cmd_line_args/args.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use std::fmt::Debug;
19 |
20 | use crate::{DialogEngine, EditorBuffer, EditorEngine, FlexBoxId, GlobalData, HasFocus};
21 |
22 | pub struct RenderArgs<'a> {
23 | pub engine: &'a mut EditorEngine,
24 | pub buffer: &'a EditorBuffer,
25 | pub has_focus: &'a mut HasFocus,
26 | }
27 |
28 | pub struct EditorArgsMut<'a> {
29 | pub engine: &'a mut EditorEngine,
30 | pub buffer: &'a mut EditorBuffer,
31 | }
32 |
33 | /// [DialogEngine] args struct that holds references.
34 | ///
35 | /// 
37 | pub struct DialogEngineArgs<'a, S, AS>
38 | where
39 | S: Debug + Default + Clone + Sync + Send,
40 | AS: Debug + Default + Clone + Sync + Send,
41 | {
42 | pub self_id: FlexBoxId,
43 | pub global_data: &'a mut GlobalData,
44 | pub engine: &'a mut DialogEngine,
45 | pub has_focus: &'a mut HasFocus,
46 | }
47 |
--------------------------------------------------------------------------------
/tui/src/tui/cmd_line_args/cli_args.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | /// Helper trait and impl to convert [std::env::Args] to a [`Vec`] after removing
19 | /// the first item (which is the path to the executable).
20 | pub trait ArgsToStrings {
21 | fn filter_and_convert_to_strings(&self) -> Vec;
22 | fn as_str(my_vec: &[String]) -> Vec<&str>;
23 | }
24 |
25 | impl ArgsToStrings for std::env::Args {
26 | fn filter_and_convert_to_strings(&self) -> Vec {
27 | let mut list = std::env::args().collect::>();
28 | if !list.is_empty() {
29 | list.remove(0);
30 | }
31 | list
32 | }
33 |
34 | fn as_str(my_vec: &[String]) -> Vec<&str> {
35 | my_vec.iter().map(String::as_str).collect::>()
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/tui/src/tui/cmd_line_args/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach sources.
19 | pub mod args;
20 | pub mod cli_args;
21 |
22 | // Re-export.
23 | pub use args::*;
24 | pub use cli_args::*;
25 |
--------------------------------------------------------------------------------
/tui/src/tui/dialog/dialog_buffer/dialog_buffer_struct.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use std::fmt::{Debug, Formatter, Result};
19 |
20 | use crate::{ch,
21 | fmt_option,
22 | ChUnit,
23 | EditorBuffer,
24 | InlineString,
25 | ItemsOwned,
26 | DEFAULT_SYN_HI_FILE_EXT};
27 |
28 | /// Please do not construct this struct directly and use
29 | /// [new_empty](DialogBuffer::new_empty) instead.
30 | ///
31 | /// Stores the data for a modal dialog. It contains the text content in an [EditorBuffer]
32 | /// and a title that is displayed.
33 | #[derive(Clone, PartialEq)]
34 | pub struct DialogBuffer {
35 | pub editor_buffer: EditorBuffer,
36 | pub title: InlineString,
37 | pub maybe_results: Option,
38 | }
39 |
40 | impl DialogBuffer {
41 | pub fn get_results_count(&self) -> ChUnit {
42 | if let Some(ref it) = self.maybe_results {
43 | ch(it.len())
44 | } else {
45 | ch(0)
46 | }
47 | }
48 | }
49 |
50 | impl DialogBuffer {
51 | pub fn new_empty() -> Self {
52 | DialogBuffer {
53 | editor_buffer: EditorBuffer::new_empty(Some(DEFAULT_SYN_HI_FILE_EXT), None),
54 | title: InlineString::new(),
55 | maybe_results: None,
56 | }
57 | }
58 | }
59 |
60 | mod impl_debug_format {
61 | use super::*;
62 |
63 | impl Debug for DialogBuffer {
64 | fn fmt(&self, f: &mut Formatter<'_>) -> Result {
65 | let maybe_results: &dyn Debug = fmt_option!(&self.maybe_results);
66 | write! { f,
67 | "DialogBuffer [
68 | - title: {title}
69 | - maybe_results: {results:?}
70 | - editor_buffer.content: {content}
71 | ]",
72 | title = self.title,
73 | results = maybe_results,
74 | content = self.editor_buffer.get_as_string_with_comma_instead_of_newlines()
75 | }
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/tui/src/tui/dialog/dialog_buffer/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach.
19 | pub mod dialog_buffer_struct;
20 |
21 | // Re-export.
22 | pub use dialog_buffer_struct::*;
23 |
--------------------------------------------------------------------------------
/tui/src/tui/dialog/dialog_component/dialog_component_traits.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use tokio::sync::mpsc::Sender;
19 |
20 | use crate::{DialogBuffer, FlexBoxId, InlineString, TerminalWindowMainThreadSignal};
21 |
22 | /// This marker trait is meant to be implemented by whatever state struct is being used to
23 | /// store the dialog buffer for this re-usable editor component.
24 | ///
25 | /// It is used in the `where` clause of the [crate::DialogComponent] to ensure that the
26 | /// generic type `S` implements this trait, guaranteeing that it holds a single
27 | /// [DialogBuffer].
28 | pub trait HasDialogBuffers {
29 | fn get_mut_dialog_buffer(&mut self, id: FlexBoxId) -> Option<&mut DialogBuffer>;
30 | }
31 |
32 | #[derive(Debug)]
33 | pub enum DialogChoice {
34 | Yes(InlineString),
35 | No,
36 | }
37 |
38 | pub type OnDialogPressFn = fn(
39 | DialogChoice,
40 | &mut S,
41 | main_thread_channel_sender: &mut Sender>,
42 | );
43 |
44 | pub type OnDialogEditorChangeFn = fn(
45 | &mut S,
46 | main_thread_channel_sender: &mut Sender>,
47 | );
48 |
--------------------------------------------------------------------------------
/tui/src/tui/dialog/dialog_component/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach.
19 | pub mod dialog_component_struct;
20 | pub mod dialog_component_traits;
21 | pub mod dialog_event;
22 |
23 | // Re-export.
24 | pub use dialog_component_struct::*;
25 | pub use dialog_component_traits::*;
26 | pub use dialog_event::*;
27 |
--------------------------------------------------------------------------------
/tui/src/tui/dialog/dialog_engine/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach.
19 | pub mod dialog_engine_api;
20 | pub mod dialog_engine_struct;
21 |
22 | // Re-export.
23 | pub use dialog_engine_api::*;
24 | pub use dialog_engine_struct::*;
25 |
--------------------------------------------------------------------------------
/tui/src/tui/dialog/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach sources.
19 | pub mod dialog_buffer;
20 | pub mod dialog_component;
21 | pub mod dialog_engine;
22 |
23 | // Re-export.
24 | pub use dialog_buffer::*;
25 | pub use dialog_component::*;
26 | pub use dialog_engine::*;
27 |
28 | // Tests.
29 | pub mod test_dialog;
30 |
--------------------------------------------------------------------------------
/tui/src/tui/editor/editor_buffer/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022-2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // Attach.
19 | pub mod buffer_struct;
20 | pub mod caret_locate;
21 | pub mod clipboard_support;
22 | pub mod cur_index; // Not re-exported.
23 | pub mod history; // Not re-exported.
24 | pub mod render_cache; // Not re-exported.
25 | pub mod selection_list;
26 | pub mod selection_range;
27 | pub mod selection_support;
28 | pub mod sizing; // Not re-exported.
29 | pub mod system_clipboard_service_provider;
30 |
31 | // Re-export.
32 | pub use buffer_struct::*;
33 | pub use caret_locate::*;
34 | pub use clipboard_support::*;
35 | pub use selection_list::*;
36 | pub use selection_range::*;
37 | pub use selection_support::*;
38 | pub use system_clipboard_service_provider::*;
39 |
--------------------------------------------------------------------------------
/tui/src/tui/editor/editor_buffer/sizing.rs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 R3BL LLC
3 | * All rights reserved.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | use smallvec::SmallVec;
19 |
20 | use super::{cur_index::CurIndex, history::EditorHistory, EditorContent};
21 | use crate::{get_mem_size,
22 | CaretRaw,
23 | GCString,
24 | GetMemSize,
25 | InlineString,
26 | RingBufferHeap,
27 | ScrOfs,
28 | TinyInlineString};
29 |
30 | pub type VecEditorContentLines = SmallVec<[GCString; DEFAULT_EDITOR_LINES_SIZE]>;
31 | const DEFAULT_EDITOR_LINES_SIZE: usize = 32;
32 |
33 | /// The version history is stored on the heap, as a ring buffer.
34 | pub type HistoryBuffer = RingBufferHeap;
35 |
36 | /// This is the absolute maximum number of undo/redo steps that will ever be stored.
37 | pub const MAX_UNDO_REDO_SIZE: usize = 16;
38 |
39 | impl GetMemSize for EditorContent {
40 | fn get_mem_size(&self) -> usize {
41 | get_mem_size::slice_size(&self.lines)
42 | + std::mem::size_of::()
43 | + std::mem::size_of::()
44 | + std::mem::size_of::