├── .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 | 57 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/copyright/r3bl.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/dictionaries/project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 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 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 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 | /// ![Editor component lifecycle 36 | /// diagram](https://raw.githubusercontent.com/r3bl-org/r3bl-open-core/main/docs/memory-architecture.drawio.svg) 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::>() 45 | + std::mem::size_of::>() 46 | + self.sel_list.get_mem_size() 47 | } 48 | } 49 | 50 | impl GetMemSize for EditorHistory { 51 | fn get_mem_size(&self) -> usize { 52 | let versions_size = get_mem_size::ring_buffer_size(&self.versions); 53 | let cur_index_field_size = std::mem::size_of::(); 54 | versions_size + cur_index_field_size 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tui/src/tui/editor/editor_buffer/system_clipboard_service_provider.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 copypasta_ext::{copypasta::ClipboardProvider, x11_fork::ClipboardContext}; 19 | 20 | use super::{ClipboardResult, ClipboardService}; 21 | use crate::{throws, DEBUG_TUI_COPY_PASTE}; 22 | 23 | pub struct SystemClipboard; 24 | 25 | impl ClipboardService for SystemClipboard { 26 | fn try_to_put_content_into_clipboard( 27 | &mut self, 28 | content: String, 29 | ) -> ClipboardResult<()> { 30 | throws!({ 31 | let mut ctx = ClipboardContext::new()?; 32 | ctx.set_contents(content.clone())?; 33 | 34 | DEBUG_TUI_COPY_PASTE.then(|| { 35 | // % is Display, ? is Debug. 36 | tracing::debug!( 37 | message = "📋📋📋 Selected Text was copied to clipboard", 38 | copied = %content, 39 | ); 40 | }); 41 | }) 42 | } 43 | 44 | fn try_to_get_content_from_clipboard(&mut self) -> ClipboardResult { 45 | let mut ctx = ClipboardContext::new()?; 46 | let content = ctx.get_contents()?; 47 | 48 | Ok(content) 49 | } 50 | } 51 | 52 | pub mod clipboard_test_fixtures { 53 | use super::{ClipboardResult, ClipboardService}; 54 | 55 | #[derive(Debug, Default)] 56 | pub struct TestClipboard { 57 | pub content: String, 58 | } 59 | 60 | impl ClipboardService for TestClipboard { 61 | fn try_to_put_content_into_clipboard( 62 | &mut self, 63 | content: String, 64 | ) -> ClipboardResult<()> { 65 | self.content = content; 66 | Ok(()) 67 | } 68 | 69 | fn try_to_get_content_from_clipboard(&mut self) -> ClipboardResult { 70 | Ok(self.content.clone()) 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /tui/src/tui/editor/editor_component/editor_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 crate::{EditorBuffer, FlexBoxId}; 19 | 20 | /// This marker trait is meant to be implemented by whatever state struct is being used to 21 | /// store the editor buffer for this re-usable editor component. 22 | /// 23 | /// It is used in the `where` clause of the [crate::EditorComponent] to ensure that the 24 | /// generic type `S` implements this trait, guaranteeing that it holds a hash map of 25 | /// [EditorBuffer]s w/ key of [FlexBoxId]. 26 | pub trait HasEditorBuffers { 27 | fn get_mut_editor_buffer(&mut self, id: FlexBoxId) -> Option<&mut EditorBuffer>; 28 | fn insert_editor_buffer(&mut self, id: FlexBoxId, buffer: EditorBuffer); 29 | fn contains_editor_buffer(&self, id: FlexBoxId) -> bool; 30 | } 31 | -------------------------------------------------------------------------------- /tui/src/tui/editor/editor_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 editor_component_struct; 20 | pub mod editor_component_traits; 21 | pub mod editor_event; 22 | 23 | // Re-export. 24 | pub use editor_component_struct::*; 25 | pub use editor_component_traits::*; 26 | pub use editor_event::*; 27 | -------------------------------------------------------------------------------- /tui/src/tui/editor/editor_engine/editor_macros.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 | /// Helper macros just for this module. 19 | /// Check to see if buffer is empty and return early if it is. 20 | #[macro_export] 21 | macro_rules! empty_check_early_return { 22 | ($arg_buffer: expr, @None) => { 23 | if $arg_buffer.is_empty() { 24 | return None; 25 | } 26 | }; 27 | 28 | ($arg_buffer: expr, @Nothing) => { 29 | if $arg_buffer.is_empty() { 30 | return; 31 | } 32 | }; 33 | } 34 | 35 | /// Check to see if multiline mode is disabled and return early if it is. 36 | #[macro_export] 37 | macro_rules! multiline_disabled_check_early_return { 38 | ($arg_engine: expr, @None) => { 39 | if let $crate::LineMode::SingleLine = $arg_engine.config_options.multiline_mode { 40 | return None; 41 | } 42 | }; 43 | 44 | ($arg_engine: expr, @Nothing) => { 45 | if let $crate::LineMode::SingleLine = $arg_engine.config_options.multiline_mode { 46 | return; 47 | } 48 | }; 49 | } 50 | -------------------------------------------------------------------------------- /tui/src/tui/editor/editor_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 caret_mut; 20 | pub mod content_mut; 21 | pub mod editor_macros; 22 | pub mod engine_internal_api; 23 | pub mod engine_public_api; 24 | pub mod engine_struct; 25 | pub mod scroll_editor_content; 26 | pub mod select_mode; 27 | pub mod validate_buffer_mut; 28 | pub mod validate_scroll_on_resize; 29 | 30 | // Re-export. 31 | pub use engine_public_api::*; 32 | pub use engine_struct::*; 33 | pub use select_mode::*; 34 | pub use validate_buffer_mut::*; 35 | pub use validate_scroll_on_resize::*; 36 | -------------------------------------------------------------------------------- /tui/src/tui/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. 19 | pub mod editor_buffer; 20 | pub mod editor_component; 21 | pub mod editor_engine; 22 | 23 | // Re-export. 24 | pub use editor_buffer::*; 25 | pub use editor_component::*; 26 | pub use editor_engine::*; 27 | 28 | // Tests. 29 | pub mod editor_test_fixtures; 30 | pub mod test_editor; 31 | -------------------------------------------------------------------------------- /tui/src/tui/global_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 strum_macros::AsRefStr; 19 | 20 | #[repr(u8)] 21 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 22 | pub enum MinSize { 23 | Col = 65, 24 | Row = 11, 25 | } 26 | 27 | #[repr(usize)] 28 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 29 | pub enum DefaultSize { 30 | GlobalDataCacheSize = 1_000_000, 31 | } 32 | 33 | #[derive(Debug, Eq, PartialEq, AsRefStr)] 34 | pub enum BorderGlyphCharacter { 35 | #[strum(to_string = "╮")] 36 | TopRight, 37 | 38 | #[strum(to_string = "╭")] 39 | TopLeft, 40 | 41 | #[strum(to_string = "╯")] 42 | BottomRight, 43 | 44 | #[strum(to_string = "╰")] 45 | BottomLeft, 46 | 47 | #[strum(to_string = "─")] 48 | Horizontal, 49 | 50 | #[strum(to_string = "│")] 51 | Vertical, 52 | 53 | #[strum(to_string = "┤")] 54 | LineUpDownLeft, 55 | 56 | #[strum(to_string = "├")] 57 | LineUpDownRight, 58 | } 59 | 60 | pub const DEFAULT_CURSOR_CHAR: &str = "▒"; 61 | pub const DEFAULT_SYN_HI_FILE_EXT: &str = "md"; 62 | -------------------------------------------------------------------------------- /tui/src/tui/layout/flex_box_id.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 | use std::{fmt::Debug, ops::Deref}; 18 | 19 | /// This works w/ the [int-enum](https://crates.io/crates/int-enum) crate in order to 20 | /// allow for the definition of enums that are represented in memory as [u8]s. 21 | #[derive(Default, Copy, Clone, PartialEq, Eq, Hash)] 22 | pub struct FlexBoxId { 23 | pub inner: u8, 24 | } 25 | 26 | impl FlexBoxId { 27 | pub fn new(arg_id: impl Into) -> Self { 28 | Self { 29 | inner: arg_id.into(), 30 | } 31 | } 32 | } 33 | 34 | impl From for u8 { 35 | fn from(id: FlexBoxId) -> Self { id.inner } 36 | } 37 | 38 | impl From for FlexBoxId { 39 | fn from(id: u8) -> Self { Self { inner: id } } 40 | } 41 | 42 | impl Deref for FlexBoxId { 43 | type Target = u8; 44 | 45 | fn deref(&self) -> &Self::Target { &self.inner } 46 | } 47 | 48 | impl Debug for FlexBoxId { 49 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 50 | write!(f, "❬{}❭", self.inner) 51 | } 52 | } 53 | 54 | #[cfg(test)] 55 | mod tests { 56 | use super::*; 57 | 58 | #[test] 59 | fn test_flex_box_id_default() { 60 | let id = FlexBoxId::default(); 61 | assert_eq!(id.inner, 0); 62 | } 63 | 64 | #[test] 65 | fn test_flex_box_id_from_u8() { 66 | let id = FlexBoxId::from(42u8); 67 | assert_eq!(id.inner, 42); 68 | } 69 | 70 | #[test] 71 | fn test_u8_from_flex_box_id() { 72 | let id = FlexBoxId::new(42); 73 | let value: u8 = id.into(); 74 | assert_eq!(value, 42); 75 | } 76 | 77 | #[test] 78 | fn test_flex_box_id_deref() { 79 | let id = FlexBoxId::new(42); 80 | assert_eq!(*id, 42); 81 | } 82 | 83 | #[test] 84 | fn test_flex_box_id_debug() { 85 | let id = FlexBoxId::new(42); 86 | assert_eq!(format!("{id:?}"), "❬42❭"); 87 | } 88 | 89 | #[test] 90 | fn test_flex_box_id_display() { 91 | let id = FlexBoxId::new(42); 92 | assert_eq!(format!("{id:?}"), "❬42❭"); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /tui/src/tui/layout/layout_and_positioning_traits.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::{FlexBox, FlexBoxProps, SurfaceProps}; 19 | use crate::{CommonResult, Pos, Size}; 20 | 21 | /// Public API interface to create nested & responsive layout based UIs. 22 | pub trait LayoutManagement { 23 | /// Set the origin pos (x, y) & surface size (width, height) of our box (container). 24 | fn surface_start(&mut self, bounds_props: SurfaceProps) -> CommonResult<()>; 25 | 26 | fn surface_end(&mut self) -> CommonResult<()>; 27 | 28 | /// Add a new layout on the stack w/ the direction & (width, height) percentages. 29 | fn box_start(&mut self, flex_box_props: FlexBoxProps) -> CommonResult<()>; 30 | 31 | fn box_end(&mut self) -> CommonResult<()>; 32 | } 33 | 34 | /// Methods that actually perform the layout and positioning. 35 | pub trait PerformPositioningAndSizing { 36 | /// Update `box_cursor_pos`. This needs to be called before adding a new [FlexBox]. 37 | fn update_insertion_pos_for_next_box( 38 | &mut self, 39 | allocated_size: Size, 40 | ) -> CommonResult; 41 | 42 | /// Get the [FlexBox] at the "top" of the `stack`. 43 | fn current_box(&mut self) -> CommonResult<&mut FlexBox>; 44 | 45 | fn no_boxes_added(&self) -> bool; 46 | 47 | /// Add the first [FlexBox] to the [crate::Surface]. 48 | /// 1. This one is explicitly sized. 49 | /// 2. there can be only one. 50 | fn add_root_box(&mut self, props: FlexBoxProps) -> CommonResult<()>; 51 | 52 | /// Add non-root [FlexBox]. 53 | fn add_non_root_box(&mut self, props: FlexBoxProps) -> CommonResult<()>; 54 | } 55 | -------------------------------------------------------------------------------- /tui/src/tui/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 source files. 19 | pub mod flex_box; 20 | pub mod flex_box_id; 21 | pub mod layout_and_positioning_traits; 22 | pub mod layout_error; 23 | pub mod partial_flex_box; 24 | pub mod props; 25 | pub mod surface; 26 | 27 | // Re-export the public items. 28 | pub use flex_box::*; 29 | pub use flex_box_id::*; 30 | pub use layout_and_positioning_traits::*; 31 | pub use layout_error::*; 32 | pub use partial_flex_box::*; 33 | pub use props::*; 34 | pub use surface::*; 35 | 36 | // Tests. 37 | mod test_surface_2_col_complex; 38 | mod test_surface_2_col_simple; 39 | -------------------------------------------------------------------------------- /tui/src/tui/md_parser/atomics/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 take_text_between; 20 | pub mod take_text_until_eol_or_end; 21 | 22 | // Re-export. 23 | pub use take_text_between::*; 24 | pub use take_text_until_eol_or_end::*; 25 | -------------------------------------------------------------------------------- /tui/src/tui/md_parser/block/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 parse_block_code; 20 | pub mod parse_block_heading; 21 | pub mod parse_block_markdown_text_until_eol_or_eoi; 22 | pub mod parse_block_smart_list; 23 | 24 | // Re-export. 25 | pub use parse_block_code::*; 26 | pub use parse_block_heading::*; 27 | pub use parse_block_markdown_text_until_eol_or_eoi::*; 28 | pub use parse_block_smart_list::*; 29 | -------------------------------------------------------------------------------- /tui/src/tui/md_parser/extended/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 parse_metadata_kcsv; 20 | pub mod parse_metadata_kv; 21 | 22 | // Re-exports. 23 | pub use parse_metadata_kcsv::*; 24 | pub use parse_metadata_kv::*; 25 | -------------------------------------------------------------------------------- /tui/src/tui/md_parser/fragment/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 parse_fragments_in_a_line; 20 | pub mod plain_parser_catch_all; 21 | pub mod specialized_parser_delim_matchers; 22 | pub mod specialized_parsers; 23 | 24 | // Re-export. 25 | pub use parse_fragments_in_a_line::*; 26 | pub use plain_parser_catch_all::*; 27 | pub use specialized_parser_delim_matchers::*; 28 | pub use specialized_parsers::*; 29 | -------------------------------------------------------------------------------- /tui/src/tui/rsx/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 layout_macros; 20 | pub mod render_macros; 21 | 22 | // Re-export. 23 | -------------------------------------------------------------------------------- /tui/src/tui/syntax_highlighting/md_parser_syn_hi/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 | //! This module holds the integration or glue code that ties together: 19 | //! 1. [crate::md_parser] - Responsible for parsing Markdown into a [crate::MdDocument] 20 | //! data structure. 21 | //! 2. [crate::syntax_highlighting] - Responsible for converting a [crate::MdDocument] 22 | //! into a list of tuples of [crate::TuiStyle] and [String]. 23 | //! 3. [crate::editor] - Responsible for displaying the [crate::MdDocument] to the user. 24 | 25 | // Attach. 26 | pub mod md_parser_stylesheet; 27 | pub mod md_parser_syn_hi_impl; 28 | 29 | // Re-export. 30 | pub use md_parser_stylesheet::*; 31 | pub use md_parser_syn_hi_impl::*; 32 | -------------------------------------------------------------------------------- /tui/src/tui/syntax_highlighting/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 convert_syntect_to_styled_text; 20 | pub mod intermediate_types; 21 | pub mod md_parser_syn_hi; 22 | pub mod pattern_matcher; 23 | pub mod r3bl_syntect_theme; 24 | 25 | // Re-export 26 | pub use convert_syntect_to_styled_text::*; 27 | pub use intermediate_types::*; 28 | pub use md_parser_syn_hi::*; 29 | pub use pattern_matcher::*; 30 | pub use r3bl_syntect_theme::*; 31 | -------------------------------------------------------------------------------- /tui/src/tui/syntax_highlighting/r3bl_syntect_theme.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::io::{BufReader, Cursor}; 19 | 20 | use syntect::highlighting::{Theme, ThemeSet}; 21 | 22 | pub fn try_load_r3bl_theme() -> std::io::Result { 23 | // Load bytes from file asset. 24 | let theme_bytes = include_bytes!("assets/r3bl.tmTheme"); 25 | 26 | // Cursor implements Seek for the byte array. 27 | let cursor = Cursor::new(theme_bytes); 28 | 29 | // Wrap the cursor in a BufReader. 30 | let mut buf_reader = BufReader::new(cursor); 31 | 32 | // Load the theme from the BufReader. 33 | let Ok(theme) = ThemeSet::load_from_reader(&mut buf_reader) else { 34 | return Err(std::io::Error::new( 35 | std::io::ErrorKind::InvalidData, 36 | "Failed to load theme", 37 | )); 38 | }; 39 | 40 | Ok(theme) 41 | } 42 | 43 | pub fn load_default_theme() -> Theme { 44 | let theme_set = ThemeSet::load_defaults(); 45 | theme_set.themes["base16-ocean.dark"].clone() 46 | } 47 | 48 | #[cfg(test)] 49 | mod tests { 50 | use crate::{throws, try_load_r3bl_theme}; 51 | 52 | /// Use a [std::io::Cursor] as a fake [std::fs::File]: 53 | /// 54 | #[test] 55 | fn load_theme() -> std::io::Result<()> { 56 | throws!({ 57 | let theme = try_load_r3bl_theme()?; 58 | dbg!(&theme); 59 | }); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tui/src/tui/syntax_highlighting/test_assets/valid-content.md: -------------------------------------------------------------------------------- 1 | # My Heading 2 | 3 | My paragraph. Some text in `code` format. Some text with _emphasis_. Some text with **strong**. 4 | 5 | Some text with ~~strikethrough~~, which isn't supported in 6 | [tmTheme format](https://www.sublimetext.com/docs/color_schemes_tmtheme.html). 7 | 8 | ## My Subheading 9 | 10 | Unordered list: 11 | 12 | - a 13 | - b 14 | - c 15 | 16 | Ordered list: 17 | 18 | 1. d 19 | 2. e 20 | 3. f 21 | 22 | > my block quote 23 | 24 | ```rs 25 | fn main() { 26 | println!("Hello, world!"); 27 | } 28 | ``` 29 | 30 | [My Link](http://example.com) 31 | 32 | ![My Image](http://example.com/image.jpg) 33 | 34 | [Another link][link_alias] 35 | 36 | | a | b | 37 | | --- | --- | 38 | | c | d | 39 | 40 | [link_alias]: http://example.com 41 | 42 | --- END --- 43 | -------------------------------------------------------------------------------- /tui/src/tui/terminal_lib_backends/crossterm_backend/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 debug; 20 | pub mod offscreen_buffer_paint_impl; 21 | pub mod render_op_impl; 22 | 23 | // Re-export. 24 | pub use debug::*; 25 | pub use offscreen_buffer_paint_impl::*; 26 | pub use render_op_impl::*; 27 | -------------------------------------------------------------------------------- /tui/src/tui/terminal_lib_backends/raw_mode.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::{RenderOp, RenderOps, RenderOpsLocalData}; 19 | use crate::{LockedOutputDevice, Size}; 20 | 21 | /// To use this directly, you need to make sure to create an instance using 22 | /// [start](RawMode::start) which enables raw mode and then make sure to call 23 | /// [end](RawMode::end) when you are done. 24 | #[derive(Debug, Clone)] 25 | pub struct RawMode; 26 | 27 | impl RawMode { 28 | pub fn start( 29 | window_size: Size, 30 | locked_output_device: LockedOutputDevice<'_>, 31 | is_mock: bool, 32 | ) { 33 | let mut skip_flush = false; 34 | RenderOps::route_paint_render_op_to_backend( 35 | &mut RenderOpsLocalData::default(), 36 | &mut skip_flush, 37 | &RenderOp::EnterRawMode, 38 | window_size, 39 | locked_output_device, 40 | is_mock, 41 | ); 42 | } 43 | 44 | pub fn end( 45 | window_size: Size, 46 | locked_output_device: LockedOutputDevice<'_>, 47 | is_mock: bool, 48 | ) { 49 | let mut skip_flush = false; 50 | RenderOps::route_paint_render_op_to_backend( 51 | &mut RenderOpsLocalData::default(), 52 | &mut skip_flush, 53 | &RenderOp::ExitRawMode, 54 | window_size, 55 | locked_output_device, 56 | is_mock, 57 | ); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tui/src/tui/terminal_lib_backends/termion_backend/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 | -------------------------------------------------------------------------------- /tui/src/tui/terminal_lib_backends/z_order.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 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 21 | pub enum ZOrder { 22 | Normal, 23 | High, 24 | Glass, 25 | } 26 | 27 | impl ZOrder { 28 | /// Contains the priority that is used to paint the different groups of 29 | /// [crate::RenderOp] items. 30 | pub fn get_render_order() -> [ZOrder; 3] { 31 | [ZOrder::Normal, ZOrder::High, ZOrder::Glass] 32 | } 33 | } 34 | 35 | impl Default for ZOrder { 36 | fn default() -> Self { Self::Normal } 37 | } 38 | -------------------------------------------------------------------------------- /tui/src/tui/terminal_window/default_input_handler.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::Continuation; 19 | use crate::InputEvent; 20 | 21 | pub struct DefaultInputEventHandler; 22 | 23 | impl DefaultInputEventHandler { 24 | /// This function does **not** consume the `input_event` argument. [InputEvent] 25 | /// implements [Copy] (no need to pass references into this function). 26 | pub fn no_consume( 27 | input_event: InputEvent, 28 | exit_keys: &[InputEvent], 29 | ) -> Continuation { 30 | // Early return if any request_shutdown key sequence is pressed. 31 | if input_event.matches(exit_keys) { 32 | return Continuation::Exit; 33 | } 34 | Continuation::Continue 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tui/src/tui/terminal_window/event_routing_support.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 crate::Size; 19 | 20 | /// This works w/ the main event loop to let it know whether it should request_shutdown or 21 | /// resize after an input event has occurred (and has been passed thru the input event 22 | /// routing system). 23 | #[derive(Clone, Debug, PartialEq, Eq)] 24 | #[non_exhaustive] 25 | pub enum Continuation { 26 | Exit, 27 | Continue, 28 | ResizeAndContinue(Size), 29 | Return, 30 | Break, 31 | Result(T), 32 | } 33 | 34 | /// This works w/ the input event routing system to provide the caller w/ information 35 | /// about whether an even has been consumed or not. If it has been consumed, is a render 36 | /// necessary. 37 | #[derive(Clone, Debug, PartialEq, Eq)] 38 | #[non_exhaustive] 39 | pub enum EventPropagation { 40 | ConsumedRender, 41 | Consumed, 42 | Propagate, 43 | ExitMainEventLoop, 44 | } 45 | -------------------------------------------------------------------------------- /tui/src/tui/terminal_window/manage_focus/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 files. 19 | pub mod component_registry; 20 | pub mod has_focus; 21 | 22 | // Re-export. 23 | pub use component_registry::*; 24 | pub use has_focus::*; 25 | -------------------------------------------------------------------------------- /tui/src/tui/terminal_window/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 files. 19 | pub mod app; 20 | pub mod component; 21 | pub mod default_input_handler; 22 | pub mod event_routing_support; 23 | pub mod main_event_loop; 24 | pub mod manage_focus; 25 | pub mod shared_global_data; 26 | pub mod terminal_window_api; 27 | pub mod terminal_window_type_aliases; 28 | 29 | // Re-export. 30 | pub use app::*; 31 | pub use component::*; 32 | pub use default_input_handler::*; 33 | pub use event_routing_support::*; 34 | pub use main_event_loop::*; 35 | pub use manage_focus::*; 36 | pub use shared_global_data::*; 37 | pub use terminal_window_api::*; 38 | pub use terminal_window_type_aliases::*; 39 | -------------------------------------------------------------------------------- /tui/src/tui/terminal_window/terminal_window_api.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 super::{main_event_loop_impl, BoxedSafeApp, GlobalData}; 21 | use crate::{get_size, CommonResult, FlexBoxId, InputDevice, InputEvent, OutputDevice}; 22 | 23 | pub struct TerminalWindow; 24 | 25 | #[derive(Debug)] 26 | pub enum TerminalWindowMainThreadSignal 27 | where 28 | AS: Debug + Default + Clone + Sync + Send, 29 | { 30 | /// Exit the main event loop. 31 | Exit, 32 | /// Render the app. 33 | Render(Option), 34 | /// Apply an app signal to the app. 35 | ApplyAppSignal(AS), 36 | } 37 | 38 | impl TerminalWindow { 39 | /// This is the main event loop for the entire application. It is responsible for 40 | /// handling all input events, and dispatching them to the [crate::App] for 41 | /// processing. It is also responsible for rendering the [crate::App] after each input 42 | /// event. It is also responsible for handling all signals sent from the [crate::App] 43 | /// to the main event loop (eg: request_shutdown, re-render, apply app signal, etc). 44 | pub async fn main_event_loop( 45 | app: BoxedSafeApp, 46 | exit_keys: &[InputEvent], 47 | state: S, 48 | ) -> CommonResult<( 49 | /* global_data */ GlobalData, 50 | /* event stream */ InputDevice, 51 | /* stdout */ OutputDevice, 52 | )> 53 | where 54 | S: Debug + Default + Clone + Sync + Send, 55 | AS: Debug + Default + Clone + Sync + Send + 'static, 56 | { 57 | let initial_size = get_size()?; 58 | let input_device = InputDevice::new_event_stream(); 59 | let output_device = OutputDevice::new_stdout(); 60 | 61 | main_event_loop_impl( 62 | app, 63 | exit_keys, 64 | state, 65 | initial_size, 66 | input_device, 67 | output_device, 68 | ) 69 | .await 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /tui/src/tui/terminal_window/terminal_window_type_aliases.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::{App, Component}; 19 | 20 | // App. 21 | pub type SafeApp = dyn App + Send + Sync; 22 | pub type BoxedSafeApp = Box>; 23 | 24 | // Component. 25 | pub type SafeComponent = dyn Component + Send + Sync; 26 | pub type BoxedSafeComponent = Box>; 27 | --------------------------------------------------------------------------------