Skip to main content

uncurses/
lib.rs

1//! `uncurses` is a Rust library for building terminal user interfaces. It
2//! provides a direct, framework-free way to draw to the terminal and read
3//! input, giving you control over every cell and your own event loop, whether
4//! you run inline, take over the full screen, mix the two, or leave the
5//! console unmanaged and just shape your output. It hands you the pieces (a
6//! cell grid with a diffing renderer, a typed input decoder, ANSI escape
7//! helpers, and a raw-mode terminal handle) and decides nothing for you.
8//! There is no terminfo database and no widget tree.
9//!
10//! # Where to start
11//!
12//! Three routes cover most needs. Pick the one that fits your use case.
13//!
14//! - **[`program::Program`]** is the interactive facade. It owns a terminal,
15//!   an [`event::EventSource`], and a `Screen` to draw with. It manages raw
16//!   mode, terminal modes, capability tracking, and teardown, and hands you
17//!   the screen through [`screen`](program::Program::screen) /
18//!   [`screen_mut`](program::Program::screen_mut). Reach for it to drive an
19//!   interactive app, inline or fullscreen. See the [`program`] module docs
20//!   for the full lifecycle.
21//! - **[`screen::Screen`]** is the diffing renderer on its own: a cell grid, a
22//!   renderer, and any [`Write`](std::io::Write). You paint cells and call
23//!   [`render`](screen::Screen::render); it emits only what changed. It reads
24//!   no input and touches no terminal mode, so it stands alone for
25//!   output-only programs, tests, and offscreen rendering.
26//! - **[`buffer::TextBuffer`]** (and any [`buffer::Surface`]) is the
27//!   stateless route. Paint a full frame into an in-memory grid and
28//!   serialize it to escape bytes with the [`text::Encode`] trait. There is
29//!   no renderer and no terminal session, which makes it the tool for
30//!   one-shot frames, snapshot tests, transcripts, and append-style output.
31//!
32//! # Quick start with `Program`
33//!
34//! ```no_run
35//! use uncurses::color::Color;
36//! use uncurses::program::Program;
37//! use uncurses::style::Style;
38//! use uncurses::text::TextSurface;
39//!
40//! # fn main() -> std::io::Result<()> {
41//! let mut program = Program::stdio()?;
42//! program.init()?; // raw mode
43//!
44//! let style = Style::default().bold().fg(Color::Green);
45//! let screen = program.screen_mut();
46//! screen.set_str((0, 0), "Hello, terminal!", style);
47//! screen.render()?; // stage the diff and flush it
48//!
49//! program.finish() // tear down modes and restore the terminal
50//! # }
51//! ```
52//!
53//! # Quick start with `TextBuffer`
54//!
55//! Paint a [`buffer::TextBuffer`] and serialize it yourself, with no
56//! terminal involved:
57//!
58//! ```rust
59//! use uncurses::buffer::TextBuffer;
60//! use uncurses::color::Color;
61//! use uncurses::style::Style;
62//! use uncurses::text::{Encode, TextSurface};
63//!
64//! let mut frame = TextBuffer::new(80, 24);
65//! let style = Style::default()
66//!     .bold()
67//!     .fg(Color::Green);
68//! frame.set_str((0, 0), "Hello, terminal!", style);
69//!
70//! // Serialize the painted grid to escape bytes you can write anywhere.
71//! let bytes = frame.display().to_string();
72//! assert!(bytes.contains("Hello, terminal!"));
73//! ```
74//!
75//! # The module map
76//!
77//! | Module | What lives there |
78//! | --- | --- |
79//! | [`screen`] | The self-managing [`Screen`](screen::Screen) facade and its diffing renderer. |
80//! | [`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. |
81//! | [`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. |
82//! | [`style`] | [`Style`](style::Style), colors, attributes, and SGR plus hyperlink (OSC 8) encoding. |
83//! | [`color`] | Color types and capability [`Profile`](color::Profile)s with automatic downsampling. |
84//! | [`event`] | The [`EventSource`](event::EventSource) decoder, typed [`Event`](event::Event) values, and (with the `async` feature) an `EventStream`. |
85//! | [`ansi`] | Raw escape-sequence encoders and parsers for the cursor, modes, colors, queries, and the long tail of terminal control. |
86//! | [`terminal`] | The [`Terminal`](terminal::Terminal) handle, raw-mode lifecycle, window-size queries, and environment lookups. |
87//! | [`cell`] | The [`Cell`](cell::Cell) value type. |
88//! | [`unicode`] | Grapheme-cluster segmentation and other Unicode text primitives. |
89//! | [`layout`] | [`Position`](layout::Position), [`Size`](layout::Size), and [`Rect`](layout::Rect) geometry. |
90//!
91//! # Output buffering and flushing
92//!
93//! Painting is infallible. Drawing cells with
94//! [`set_str`](text::TextSurface::set_str),
95//! [`set_cell`](screen::Screen::set_cell), and friends only updates an
96//! in-memory frame; nothing is written until you call
97//! [`render`](screen::Screen::render), which diffs that frame against the
98//! terminal and writes just the changed cells.
99//!
100//! Mode changes are applied immediately. Entering the alternate screen,
101//! hiding the cursor, enabling mouse reporting, setting the title, and similar
102//! switches write their escape sequence on the spot. A stateless
103//! [`TextBuffer`](buffer::TextBuffer) has no writer of its own:
104//! [`encode`](text::Encode::encode) hands you the bytes and you decide where
105//! they go.
106
107#![cfg_attr(docsrs, feature(doc_cfg))]
108#![cfg_attr(uncurses_bench, feature(test))]
109
110#[cfg(not(any(feature = "icu", feature = "unicode-rs")))]
111compile_error!(
112    "uncurses requires one of the `icu` or `unicode-rs` features to be enabled (the default)"
113);
114
115/// The `libc` crate this was built against, re-exported so the platform types
116/// in the public API are nameable without depending on `libc` directly and
117/// matching its major version by hand. [`terminal::State`] exposes
118/// `libc::termios` values.
119#[cfg(unix)]
120pub use libc;
121
122pub mod ansi;
123pub mod buffer;
124pub mod cell;
125pub mod color;
126pub mod event;
127pub mod layout;
128pub mod program;
129pub mod screen;
130pub mod style;
131pub mod terminal;
132pub mod text;
133pub mod unicode;
134
135pub(crate) mod renderer;
136
137#[cfg(all(test, unix, not(target_os = "l4re")))]
138mod testutil;
139
140#[cfg(debug_assertions)]
141mod trace;