Skip to content

isene/crust

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

35 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Crust - Rust TUI Library

Rust License Platform Dependencies Stay Amazing

Pure Rust terminal UI library with pane-based layout, ANSI 256-color support, diff-based rendering, input handling, popups, and Unicode support. Feature clone of rcurses.

Foundation library for pointer, scroll, kastrup, and tock.


Quick Start

[dependencies]
crust = { version = "0.1", path = "../crust" }
use crust::{Crust, Pane, Input};

fn main() {
    Crust::init();
    let (cols, rows) = Crust::terminal_size();
    let mut pane = Pane::new(1, 1, cols, rows - 1, 255, 0);
    pane.border = true;
    pane.border_refresh();
    pane.say("Hello from crust!");
    Input::getchr(None);
    Crust::cleanup();
}

Features

  • Pane - Positioned rectangle with content, borders, scrolling, diff-based rendering
  • Popup - Modal dialog with selection (returns chosen index)
  • Input - Key event reading with rcurses-compatible names (UP, DOWN, C-A, F1, etc.)
  • Cursor - Full cursor positioning and control
  • Style - fg/bg/bold/italic/underline/reverse/blink with 256-color and RGB

API Reference

Pane

let mut pane = Pane::new(x, y, w, h, fg, bg);
pane.border = true;         // Border drawn OUTSIDE pane area
pane.scroll = true;         // Show scroll indicators
pane.align = Align::Left;   // Left, Center, Right

pane.set_text("content");   // Set content (preserves scroll)
pane.say("text");           // Set + refresh + reset scroll
pane.refresh();             // Diff-based render (only changed lines)
pane.full_refresh();        // Force complete repaint
pane.border_refresh();      // Redraw border only
pane.clear();               // Clear content and screen area

pane.lineup() / linedown()  // Scroll by line
pane.pageup() / pagedown()  // Scroll by page
pane.top() / bottom()       // Jump to extremes

let s = pane.ask("Prompt: ", "default"); // Single-line input

Input

let key = Input::getchr(None);           // Block until key
let key = Input::getchr(Some(5));        // 5-second timeout

// Returns: "UP", "DOWN", "LEFT", "RIGHT", "ENTER", "ESC",
//          "PgUP", "PgDOWN", "HOME", "END", "TAB", "S-TAB",
//          "C-A".."C-Z", "F1".."F12", "S-UP", "S-DOWN", etc.

Style

use crust::style;
style::fg("text", 196)           // Foreground color
style::bg("text", 226)           // Background color
style::fb("text", 255, 0)        // Both
style::bold("text")              // Bold
style::italic("text")            // Italic
style::underline("text")         // Underline
style::reverse("text")           // Reverse video
style::coded("text", "196,0,bi") // Coded: fg,bg,attrs
style::styled("text", "196,0,bi")  // Alias for coded()

Popup

let mut popup = Popup::centered(40, 20, 255, 234);
let selection = popup.modal("line1\nline2\nline3");
// Returns Some(index) on Enter, None on ESC

Architecture

Border is drawn outside the pane area (matching rcurses). The pane's (x, y, w, h) IS the content area. content_area() always returns (x, y, w, h). Line truncation preserves ANSI codes. Tab expansion and ANSI reset restoration ensure correct rendering in all panes.

Part of the Fe2O3 Rust Terminal Suite

See the Fe₂O₃ suite overview and the landing page for the full list of projects.

Tool Clones Type
rush rsh Shell
crust rcurses TUI library
glow termpix Image display
plot termchart Charts
pointer RTFM File manager

License

Unlicense - public domain.

Credits

Created by Geir Isene (https://isene.org) with extensive pair-programming with Claude Code.

About

Rust TUI library. Feature clone of rcurses for terminal pane management, input, colors, and Unicode.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages