Skip to main content

Crate rich_interact

Crate rich_interact 

Source
Expand description

Interactive terminal components for rs-rich (#451): the layer between printing and a full TUI framework.

A Component is a state machine: it handles one Event and renders one View. Two drivers run it:

  • blocking: run takes the terminal, drives the component to an Outcome and gives the terminal back, like Prompt.ask;
  • event loop: an EventLoop runs one or more components at once, with ticks and timers, and repaints only when something changed.

Views are painted through rich_ext::frame::Frame::diff, cell by cell, so an idle loop writes nothing. Around them:

  • session: raw mode, the alternate screen, mouse and paste, restored on every way out, including a panic, Ctrl+C and a hand-off to another program (#489), driven by crossterm, or by termion or termwiz behind the features of those names (BackendKind), and each frame written as one synchronized update where the terminal has it;
  • event: keys, mouse, resizes and pastes, from whichever drives the terminal;
  • viewport: a scrollable window over rendered lines (#495);
  • item: one item model behind every picker (#452);
  • policy: with no terminal, under CI or with TERM=dumb, a component asks line by line, returns its default, or fails, as the caller chooses, and never blocks on a pipe (#492);
  • headless: scripted events in, frames out, for tests;
  • components: Select, MultiSelect, TableSelect, TreeSelect, Input, TextArea, Confirm, Form, Pager, Paginator, FilePicker, ColorPicker, AssetPicker, ThemePicker, Reorder (#720), and DatePicker, TimePicker and DateTimePicker (#719, on the datetime types), LogView (#724, a live view of log records), built on the above with a fuzzy matcher, ApprovalQueue (#471, a review of pending items) and Jump (#484, one fuzzy box over several sources), and with the data feature DataExplorer, for JSON, YAML, TOML and the other formats rich_ext::data reads;
  • clipboard: copy to the terminal’s clipboard with OSC 52, when it takes it.

Components compose (0.0.14): compose has containers that are components themselves (Column, Row, Stack, Split, Tabs, Layers), with focus, routing and bubbling (Flow::Ignored); kit has the line helpers and state types the built-ins are made of; and keymap declares, rebinds and lists every component’s keys. On top of those, overlay has a command palette, a help overlay, a shortcut sheet and an action menu read from the keymap, and chrome a status bar and breadcrumbs; Overlays wires them all into any component.

Mouse support (#476) is opt-in per component (Component::mouse): clicks, drags and the wheel arrive in the component’s own coordinates, a click on a hyperlink arrives as Event::Link, and the border beside a preview drags. Actions (#491) attach to list items, table rows, tree nodes and file entries through Actions and an ActionTarget, and open in a modal menu (Ctrl+K); a region takes actions too, through Overlays::actions; plugins register them through rs-rich-plugin-api. Plugins register whole components too, and PluginView mounts one by name beside the built-ins (plugin).

use rich_interact::{headless, Component, Context, Event, Flow, KeyCode, Outcome, View};

/// Counts Up presses; Enter returns the count.
struct Counter(u32);

impl Component for Counter {
    type Output = u32;
    fn handle(&mut self, event: &Event, _: &Context<'_>) -> Flow<u32> {
        match event.key().map(|key| key.code) {
            Some(KeyCode::Up) => self.0 += 1,
            Some(KeyCode::Enter) => return Flow::Done(self.0),
            _ => {}
        }
        Flow::Continue
    }
    fn render(&self, context: &Context<'_>) -> View {
        View::new(context.markup(&format!("count: [bold]{}[/]", self.0)))
    }
}

let script = headless::Script::new().keys("up up enter");
let (outcome, record) = headless::run(Counter(0), script, 40, 5);
assert_eq!(outcome.unwrap(), Outcome::Done(2));
assert_eq!(record.last_frame(), "count: 2");

Re-exports§

pub use chrome::Breadcrumbs;
pub use chrome::StatusBar;
pub use chrome::StatusItem;
pub use component::Component;
pub use component::Context;
pub use component::Flow;
pub use component::View;
pub use components::Answers;
pub use components::ApprovalQueue;
pub use components::ApprovalReport;
pub use components::AssetKind;
pub use components::AssetPicker;
pub use components::Choice;
pub use components::ColorFormat;
pub use components::ColorPicker;
pub use components::Confirm;
pub use components::DatePicker;
pub use components::DateTimePicker;
pub use components::Decision;
pub use components::FileMode;
pub use components::FilePicker;
pub use components::Form;
pub use components::Input;
pub use components::Jump;
pub use components::JumpIndex;
pub use components::JumpSource;
pub use components::Jumped;
pub use components::LogEvent;
pub use components::LogView;
pub use components::MultiSelect;
pub use components::Pager;
pub use components::PreviewLayout;
pub use components::Reorder;
pub use components::Select;
pub use components::Suggestion;
pub use components::TableSelect;
pub use components::TextArea;
pub use components::Theme;
pub use components::ThemePicker;
pub use components::TimePicker;
pub use components::TreeSelect;
pub use components::Value;
pub use components::Verdict;
pub use components::Paginator;
pub use components::PaginatorStyle;
pub use compose::Axis;
pub use compose::Column;
pub use compose::ComponentExt;
pub use compose::Label;
pub use compose::Layer;
pub use compose::LayerHandle;
pub use compose::Layers;
pub use compose::Rect;
pub use compose::Row;
pub use compose::Size;
pub use compose::Split;
pub use compose::Stack;
pub use compose::Tabs;
pub use event::Button;
pub use event::Event;
pub use event::HeldButton;
pub use event::Key;
pub use event::KeyCode;
pub use event::ModifierKey;
pub use event::Modifiers;
pub use event::Mouse;
pub use event::MouseKind;
pub use event::Releases;
pub use event::Subcell;
pub use event_loop::Error;
pub use event_loop::EventLoop;
pub use event_loop::Handle;
pub use event_loop::LoopOptions;
pub use event_loop::Outcome;
pub use event_loop::RunOptions;
pub use event_loop::degrade;
pub use event_loop::run;
pub use event_loop::run_with_graphics;
pub use item::Action;
pub use item::ActionFilter;
pub use item::ActionTarget;
pub use item::Actions;
pub use item::Item;
pub use item::Preview;
pub use item::TargetKind;
pub use keymap::Binding;
pub use keymap::Keymap;
pub use overlay::Command;
pub use overlay::Help;
pub use overlay::Menu;
pub use overlay::Overlays;
pub use overlay::Palette;
pub use overlay::Shortcuts;
pub use plugin::PluginView;
pub use policy::Fallback;
pub use policy::LineIo;
pub use policy::NotInteractive;
pub use policy::Policy;
pub use policy::Reason;
pub use push::PushBackend;
pub use push::PushPort;
pub use session::Backend;
pub use session::BackendKind;
pub use session::Output;
pub use session::Session;
pub use session::SessionOptions;
pub use session::Waker;
pub use session::synchronized_update;
pub use viewport::Viewport;

Modules§

caret
The text caret’s shape: a block, a bar or an underline, set on the terminal’s own cursor with DECSCUSR (CSI n SP q), which xterm, the kitty, WezTerm, iTerm2, Windows Terminal, foot, Alacritty and the VTE terminals follow. A terminal that does not know it ignores it.
chrome
Chrome: a status bar (#481) and breadcrumbs (#482), the lines round a view that say where you are and what you can do (0.0.14 workstream 2).
clipboard
Copy from a component to the terminal’s clipboard (#488).
component
The component contract: one event in, one view out.
components
Ready-made components (0.0.13 workstream 3), built from the crate’s primitives: Item, Viewport and the fuzzy matcher. Each works under both drivers, degrades to a line-based prompt without a terminal, and is styled by one Theme.
compose
Composition: containers that are themselves components (0.0.14 workstream 1, #478, #479, #480).
dates
Dates as people type them: tomorrow, eow, monday, 3d, 2026-11-01, read relative to a given now. Generic: a todo list’s due dates, a log viewer’s since, a calendar’s jump; the names are Taskwarrior’s, which most such tools share.
datetime
Dates and times of day (#719), without a time zone: what the date and time pickers (DatePicker, TimePicker, DateTimePicker) and intuiTUIve’s calendar choose. Hand-rolled, with no dependency: a Date is a day of the proleptic Gregorian calendar, a Time a time of day to the second, and a DateTime the two together. Each parses the ISO 8601 form it prints (2026-10-17, 14:30, 2026-10-17 14:30), and a time also parses a 12-hour clock (2:30 pm).
edit
A text buffer for editors: lines of text, a caret on a grapheme boundary, a selection, a character limit, and undo and redo.
edit_keys
Editor keys: what a text editor’s keys do, as actions in a Keymap, so they can be rebound, listed and swapped for a preset.
event
Input events: keys, mouse, resizes, pastes and ticks.
event_loop
The event loop, and the blocking run built on it.
fuzzy
Fuzzy matching for pickers: a pattern’s characters in order, anywhere in the candidate, scored so that the matches people mean rank first.
headless
The headless driver: scripted events in, painted frames out.
item
The universal item model (#452): one type behind every picker.
keymap
The keymap registry: what each key does, declared rather than matched inline, so it can be rebound and listed (0.0.14 workstream 1).
kit
The building-block kit: the pieces the built-in components are made of, public so your own components can use them too (0.0.14 workstream 1).
overlay
Overlays: a command palette, a help overlay, a shortcut sheet and an action menu, all read from the keymap, and a wrapper that puts them over any component (0.0.14 workstream 2: #453, #473, #474, #475).
paint
Painting views into a region of the terminal, cell by cell.
plugin
Components from plugins (0.0.14 workstream 4): a PluginComponent that a plugin registered by name with PluginRegistrar::component, mounted as a Component beside the built-ins.
policy
When the terminal is not interactive (#492): detect it, and degrade without control sequences and without blocking.
push
A backend for push driving: the host owns the clock and the screen.
session
The terminal session: raw mode, the alternate screen, mouse and paste modes, the kitty keyboard protocol, synchronized output, and their restoration on every way out (#489).
viewport
A scrollable window over rendered lines (#495).