Crate tuinix

Crate tuinix 

Source
Expand description

A library for building terminal user interface (TUI) applications on Unix systems with minimum dependencies.

tuinix provides a lightweight foundation for building terminal-based user interfaces with minimal dependencies (only libc is required). The library offers a clean API for:

  • Managing terminal state (raw mode, alternate screen)
  • Capturing and processing keyboard input
  • Drawing styled text with ANSI colors
  • Handling terminal resize events
  • Creating efficient terminal frames with differential updates

§Basic Example

This example demonstrates basic terminal UI functionality including initializing the terminal, drawing styled text, processing keyboard events, and handling terminal resizing.

use std::{fmt::Write, time::Duration};

use tuinix::{Terminal, TerminalColor, TerminalEvent, TerminalFrame, TerminalInput, TerminalStyle};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize terminal
    let mut terminal = Terminal::new()?;

    // Create a frame with the terminal's dimensions
    let mut frame: TerminalFrame = TerminalFrame::new(terminal.size());

    // Add styled content to the frame
    let title_style = TerminalStyle::new().bold().fg_color(TerminalColor::GREEN);

    writeln!(
        frame,
        "{}Welcome to tuinix!{}",
        title_style,
        TerminalStyle::RESET
    )?;
    writeln!(frame, "\nPress any key ('q' to quit)")?;

    // Draw the frame to the terminal
    terminal.draw(frame)?;

    // Process input events with a timeout
    loop {
        match terminal.poll_event(&[], &[], Some(Duration::from_millis(100)))? {
            Some(TerminalEvent::Input(input)) => {
                let TerminalInput::Key(input) = input else {
                    continue;  // Skip mouse events
                };

                // Check if 'q' was pressed
                if let tuinix::KeyCode::Char('q') = input.code {
                    break;
                }

                // Display the input
                let mut frame: TerminalFrame = TerminalFrame::new(terminal.size());
                writeln!(frame, "Key pressed: {:?}", input)?;
                writeln!(frame, "\nPress any key ('q' to quit)")?;
                terminal.draw(frame)?;
            }
            Some(TerminalEvent::Resize(size)) => {
                // Terminal was resized, update UI if needed
                let mut frame: TerminalFrame = TerminalFrame::new(size);
                writeln!(frame, "Terminal resized to {}x{}", size.cols, size.rows)?;
                writeln!(frame, "\nPress any key ('q' to quit)")?;
                terminal.draw(frame)?;
            }
            Some(TerminalEvent::FdReady { .. }) => unreachable!(),
            None => {
                // Timeout elapsed, no events to process
            }
        }
    }

    Ok(())
}

For integration with external event loop libraries like mio, see the nonblocking.rs example.

Structs§

FixedCharWidthEstimator
A character width estimator that assumes most characters have a fixed width of 1 column.
KeyInput
Keyboard input.
MouseInput
Mouse input.
Terminal
Terminal interface for building TUI (Terminal User Interface) applications.
TerminalColor
Terminal color (RGB).
TerminalFrame
A frame buffer representing the terminal display state.
TerminalPosition
Position within a terminal.
TerminalRegion
A rectangular region within a terminal, defined by a position and size.
TerminalSize
Dimensions of a Terminal or TerminalFrame.
TerminalStyle
Styling options for terminal text output.

Enums§

KeyCode
Key code.
MouseEvent
Mouse event types.
TerminalEvent
Terminal event returned by Terminal::poll_event().
TerminalInput
User input.

Traits§

EstimateCharWidth
Trait for estimating the display width of characters in a terminal.

Functions§

set_nonblocking
Sets a file descriptor to non-blocking mode.
try_nonblocking
Handles the result of a non-blocking I/O operation by converting ErrorKind::WouldBlock errors to Ok(None).
try_uninterrupted
Handles the result of an I/O operation that might be interrupted by converting ErrorKind::Interrupted errors to Ok(None).