uncurses/lib.rs
1//! `uncurses` is a terminal toolkit library for building terminal user
2//! interfaces. It hands you the pieces (a cell grid with a diffing
3//! renderer, a typed input decoder, ANSI escape helpers, and a raw-mode
4//! terminal handle) and stays out of the way: you own the event loop and
5//! decide when bytes hit the wire. There is no terminfo database and no
6//! widget tree.
7//!
8//! # Where to start
9//!
10//! Two routes cover most needs. Pick the one that fits your use case.
11//!
12//! - **[`screen::Screen`]** is the facade and the home of the
13//! diffing renderer. It owns a terminal and an [`event::EventSource`],
14//! tracks the live terminal across frames, and emits only the cells that
15//! changed. It also manages raw mode, capability detection, sane default
16//! modes, and teardown. Reach for it to drive an interactive app, in
17//! either inline or fullscreen layout. See the [`screen`] module docs for
18//! the full lifecycle.
19//! - **[`buffer::TextBuffer`]** (and any [`buffer::Surface`]) is the
20//! stateless route. Paint a full frame into an in-memory grid and
21//! serialize it to escape bytes with the [`text::Encode`] trait. There is
22//! no renderer and no terminal session, which makes it the tool for
23//! one-shot frames, snapshot tests, transcripts, and append-style output.
24//!
25//! # Quick start with `Screen`
26//!
27//! ```no_run
28//! use uncurses::buffer::SurfaceMut;
29//! use uncurses::color::Color;
30//! use uncurses::screen::Screen;
31//! use uncurses::style::Style;
32//! use uncurses::text::TextSurface;
33//!
34//! # fn main() -> std::io::Result<()> {
35//! let mut screen = Screen::stdio()?;
36//! screen.init()?; // raw mode + capability detection
37//!
38//! let style = Style::default().bold().fg(Color::Green);
39//! screen.set_str((0, 0), "Hello, terminal!", style);
40//! screen.render()?; // stage the diff and flush it
41//!
42//! screen.finish() // tear down modes and restore the terminal
43//! # }
44//! ```
45//!
46//! # Quick start with `TextBuffer`
47//!
48//! Paint a [`buffer::TextBuffer`] and serialize it yourself, with no
49//! terminal involved:
50//!
51//! ```rust
52//! use uncurses::buffer::TextBuffer;
53//! use uncurses::color::Color;
54//! use uncurses::style::Style;
55//! use uncurses::text::{Encode, TextSurface};
56//!
57//! let mut frame = TextBuffer::new(80, 24);
58//! let style = Style::default()
59//! .bold()
60//! .fg(Color::Green);
61//! frame.set_str((0, 0), "Hello, terminal!", style);
62//!
63//! // Serialize the painted grid to escape bytes you can write anywhere.
64//! let bytes = frame.display().to_string();
65//! assert!(bytes.contains("Hello, terminal!"));
66//! ```
67//!
68//! # The module map
69//!
70//! | Module | What lives there |
71//! | --- | --- |
72//! | [`screen`] | The self-managing [`Screen`](screen::Screen) facade and its diffing renderer. |
73//! | [`buffer`] | Cell-grid storage ([`Buffer`](buffer::Buffer), [`TextBuffer`](buffer::TextBuffer), [`Window`](buffer::Window)) and the [`Surface`](buffer::Surface) / [`SurfaceMut`](buffer::SurfaceMut) traits every drawable shares. |
74//! | [`text`] | Text shaping, width measurement, the [`TextSurface`](text::TextSurface) painting trait that adds `set_str` to any surface, and the [`Encode`](text::Encode) trait that serializes a surface to escapes. |
75//! | [`style`] | [`Style`](style::Style), colors, attributes, and SGR plus hyperlink (OSC 8) encoding. |
76//! | [`color`] | Color types and capability [`Profile`](color::Profile)s with automatic downsampling. |
77//! | [`event`] | The [`EventSource`](event::EventSource) decoder, typed [`Event`](event::Event) values, and (with the `async` feature) an `EventStream`. |
78//! | [`ansi`] | Raw escape-sequence encoders and parsers for the cursor, modes, colors, queries, and the long tail of terminal control. |
79//! | [`terminal`] | The [`Terminal`](terminal::Terminal) handle, raw-mode lifecycle, window-size queries, and environment snapshot. |
80//! | [`cell`] | The [`Cell`](cell::Cell) value type. |
81//! | [`unicode`] | Grapheme-cluster segmentation and other Unicode text primitives. |
82//! | [`layout`] | [`Position`](layout::Position), [`Size`](layout::Size), and [`Rect`](layout::Rect) geometry. |
83//!
84//! # Output buffering and flushing
85//!
86//! Painting is infallible. Drawing cells with
87//! [`set_str`](text::TextSurface::set_str),
88//! [`set_cell`](screen::Screen::set_cell), and friends only updates an
89//! in-memory frame; nothing is written until you call
90//! [`render`](screen::Screen::render), which diffs that frame against the
91//! terminal and writes just the changed cells.
92//!
93//! Mode changes are applied immediately. Entering the alternate screen,
94//! hiding the cursor, enabling mouse reporting, setting the title, and similar
95//! switches write their escape sequence on the spot. A stateless
96//! [`TextBuffer`](buffer::TextBuffer) has no writer of its own:
97//! [`encode`](text::Encode::encode) hands you the bytes and you decide where
98//! they go.
99
100#![cfg_attr(docsrs, feature(doc_cfg))]
101#![cfg_attr(uncurses_bench, feature(test))]
102
103#[cfg(not(any(feature = "icu", feature = "unicode-rs")))]
104compile_error!(
105 "uncurses requires one of the `icu` or `unicode-rs` features to be enabled (the default)"
106);
107
108pub mod ansi;
109pub mod buffer;
110pub mod cell;
111pub mod color;
112pub mod event;
113pub mod layout;
114pub mod screen;
115pub mod style;
116pub mod terminal;
117pub mod text;
118pub mod unicode;
119
120pub(crate) mod renderer;
121
122#[cfg(debug_assertions)]
123mod trace;