Rendering
The tui crate uses a frame-based rendering model. Components produce Frame values (a list of styled lines), and the Renderer efficiently updates the terminal by diffing frames.
A Frame is a list of Line values with an optional cursor position:
use tui::{Frame, Line, Style, Cursor};
let frame = Frame::new(vec![ Line::new("Hello, world!"), Line::styled("Error!", Color::Red),]).with_cursor(Cursor::visible(0, 5));| Method | Description |
|---|---|
new(lines) | Create from a vec of lines |
with_cursor(cursor) | Set cursor position |
lines() | Get lines slice |
cursor() | Get cursor state |
into_lines() | Consume into vec of lines |
Line and Span
Section titled “Line and Span”A Line contains styled Span segments:
use tui::{Line, Style};use crossterm::style::Color;
// Plain textlet line = Line::new("Hello");
// Styled textlet line = Line::styled("Error", Color::Red);
// Multiple spanslet mut line = Line::new("Status: ");line.push_styled("OK", Color::Green);
// Methodsline.display_width(); // Unicode-aware widthline.plain_text(); // Strip stylesline.soft_wrap(80); // Wrap at column widthSpan-level control:
use tui::rendering::span::Span;
let span = Span::with_style("bold text", Style::fg(Color::White).bold());use tui::Style;use crossterm::style::Color;
let style = Style::fg(Color::Green) .bold() .italic() .underline();
// Available modifiersStyle::fg(color) // foreground color .bg_color(color) // background color .bold() .italic() .underline() .dim() .strikethrough()A Theme defines the full color palette for rendering:
use tui::Theme;use crossterm::style::Color;
let theme = Theme::builder() .fg(Color::White) .bg(Color::Black) .accent(Color::Cyan) .error(Color::Red) .success(Color::Green) .warning(Color::Yellow) .heading(Color::Blue) .code_fg(Color::White) .code_bg(Color::DarkGrey) // ... all 24 color slots .build()?;The theme is passed to the Renderer and used by built-in components for consistent styling.
Renderer
Section titled “Renderer”The Renderer manages terminal output with efficient diff-based updates:
use tui::Renderer;
let mut renderer = Renderer::new(std::io::stdout(), theme, (80, 24));
// Render a framerenderer.render_frame(|ctx| { my_component.render(ctx)})?;
// Handle terminal resizerenderer.on_resize((new_width, new_height));
// Push content to scrollback (above the viewport)renderer.push_to_scrollback(&lines)?;
// Clear screenrenderer.clear_screen()?;The renderer only redraws lines that changed between frames, keeping terminal I/O minimal.
TerminalSession
Section titled “TerminalSession”Manages raw mode, alternate screen, and cleanup:
use tui::TerminalSession;
let session = TerminalSession::new()?;// Terminal is now in raw mode with alternate screen
// ... render loop ...
drop(session); // Restores terminal on dropMarkdown rendering (feature: syntax)
Section titled “Markdown rendering (feature: syntax)”use tui::render_markdown;
let frame = render_markdown("# Hello\n\nSome **bold** text", 80, &theme);// Returns a Frame with styled linesSyntax highlighting (feature: syntax)
Section titled “Syntax highlighting (feature: syntax)”use tui::SyntaxHighlighter;
let highlighter = SyntaxHighlighter::new(&theme);let lines = highlighter.highlight("fn main() {}", "rs");