refactor: modularize backends (#1508)

Backend code is now moved to `ratatui-crossterm`, `ratatui-termion` and
`ratatui-termwiz`. This should be backwards compatible with existing code.

Co-authored-by: Josh McKinney <joshka@users.noreply.github.com>
This commit is contained in:
Orhun Parmaksız 2024-11-24 02:23:40 +03:00 committed by GitHub
parent 3ae6bf1d6f
commit 217c57cd60
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 445 additions and 175 deletions

44
Cargo.lock generated
View file

@ -2162,13 +2162,14 @@ dependencies = [
"rand 0.8.5", "rand 0.8.5",
"rand_chacha 0.3.1", "rand_chacha 0.3.1",
"ratatui-core", "ratatui-core",
"ratatui-crossterm",
"ratatui-termion",
"ratatui-termwiz",
"ratatui-widgets", "ratatui-widgets",
"rstest", "rstest",
"serde", "serde",
"serde_json", "serde_json",
"strum", "strum",
"termion",
"termwiz",
"time", "time",
"tokio", "tokio",
"tracing", "tracing",
@ -2191,6 +2192,7 @@ dependencies = [
"palette", "palette",
"paste", "paste",
"pretty_assertions", "pretty_assertions",
"ratatui",
"rstest", "rstest",
"serde", "serde",
"serde_json", "serde_json",
@ -2200,6 +2202,40 @@ dependencies = [
"unicode-width", "unicode-width",
] ]
[[package]]
name = "ratatui-crossterm"
version = "0.1.0"
dependencies = [
"crossterm",
"document-features",
"instability",
"ratatui",
"ratatui-core",
"rstest",
]
[[package]]
name = "ratatui-termion"
version = "0.1.0"
dependencies = [
"document-features",
"instability",
"ratatui-core",
"rstest",
"termion",
]
[[package]]
name = "ratatui-termwiz"
version = "0.1.0"
dependencies = [
"document-features",
"ratatui",
"ratatui-core",
"rstest",
"termwiz",
]
[[package]] [[package]]
name = "ratatui-widgets" name = "ratatui-widgets"
version = "0.3.0" version = "0.3.0"
@ -2570,9 +2606,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.132" version = "1.0.133"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
dependencies = [ dependencies = [
"itoa", "itoa",
"memchr", "memchr",

View file

@ -1,7 +1,15 @@
[workspace] [workspace]
resolver = "2" resolver = "2"
members = ["ratatui", "ratatui-core", "ratatui-widgets", "xtask"] members = ["ratatui", "ratatui-*", "xtask"]
default-members = ["ratatui", "ratatui-core", "ratatui-widgets"] default-members = [
"ratatui",
"ratatui-core",
"ratatui-crossterm",
# this is not included as it doesn't compile on windows
# "ratatui-termion",
"ratatui-termwiz",
"ratatui-widgets",
]
[workspace.package] [workspace.package]
authors = ["Florian Dehau <work@fdehau.com>", "The Ratatui Developers"] authors = ["Florian Dehau <work@fdehau.com>", "The Ratatui Developers"]
@ -12,19 +20,13 @@ keywords = ["tui", "terminal", "dashboard"]
categories = ["command-line-interface"] categories = ["command-line-interface"]
readme = "README.md" readme = "README.md"
license = "MIT" license = "MIT"
exclude = [ exclude = ["assets/*", ".github", "Makefile.toml", "CONTRIBUTING.md", "*.log", "tags"]
"assets/*",
".github",
"Makefile.toml",
"CONTRIBUTING.md",
"*.log",
"tags",
]
edition = "2021" edition = "2021"
rust-version = "1.74.0" rust-version = "1.74.0"
[workspace.dependencies] [workspace.dependencies]
bitflags = "2.6.0" bitflags = "2.6.0"
crossterm = "0.28.1"
document-features = "0.2.7" document-features = "0.2.7"
indoc = "2.0.5" indoc = "2.0.5"
instability = "0.3.3" instability = "0.3.3"
@ -32,13 +34,19 @@ itertools = "0.13.0"
pretty_assertions = "1.4.1" pretty_assertions = "1.4.1"
ratatui = { path = "ratatui" } ratatui = { path = "ratatui" }
ratatui-core = { path = "ratatui-core" } ratatui-core = { path = "ratatui-core" }
ratatui-crossterm = { path = "ratatui-crossterm" }
ratatui-termion = { path = "ratatui-termion" }
ratatui-termwiz = { path = "ratatui-termwiz" }
ratatui-widgets = { path = "ratatui-widgets" } ratatui-widgets = { path = "ratatui-widgets" }
rstest = "0.23.0" rstest = "0.23.0"
serde = { version = "1.0.215", features = ["derive"] } serde = { version = "1.0.215", features = ["derive"] }
serde_json = "1.0.133"
strum = { version = "0.26.3", features = ["derive"] } strum = { version = "0.26.3", features = ["derive"] }
termwiz = { version = "0.22.0" }
unicode-segmentation = "1.12.0" unicode-segmentation = "1.12.0"
# See <https://github.com/ratatui/ratatui/issues/1271> for information about why we pin unicode-width # See <https://github.com/ratatui/ratatui/issues/1271> for information about why we pin unicode-width
unicode-width = "=0.2.0" unicode-width = "=0.2.0"
termion = "4.0.0"
# Improve benchmark consistency # Improve benchmark consistency
[profile.bench] [profile.bench]

View file

@ -3,9 +3,15 @@ avoid-breaking-exported-api = false
# https://rust-lang.github.io/rust-clippy/master/index.html#/multiple_crate_versions # https://rust-lang.github.io/rust-clippy/master/index.html#/multiple_crate_versions
# ratatui -> bitflags v2.3 # ratatui -> bitflags v2.3
# termwiz -> wezterm-blob-leases -> mac_address -> nix -> bitflags v1.3.2 # termwiz -> wezterm-blob-leases -> mac_address -> nix -> bitflags v1.3.2
# (also, memoffset, syn, nix, strsim, windows-sys
# crossterm -> all the windows- deps https://github.com/ratatui/ratatui/pull/1064#issuecomment-2078848980 # crossterm -> all the windows- deps https://github.com/ratatui/ratatui/pull/1064#issuecomment-2078848980
allowed-duplicate-crates = [ allowed-duplicate-crates = [
"bitflags", "bitflags",
"memoffset",
"nix",
"strsim",
"syn",
"windows-sys",
"windows-targets", "windows-targets",
"windows_aarch64_gnullvm", "windows_aarch64_gnullvm",
"windows_aarch64_msvc", "windows_aarch64_msvc",

View file

@ -17,7 +17,13 @@ exclude.workspace = true
edition.workspace = true edition.workspace = true
rust-version.workspace = true rust-version.workspace = true
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[features] [features]
default = []
## enables conversions from colors in the [`palette`] crate to [`Color`](crate::style::Color). ## enables conversions from colors in the [`palette`] crate to [`Color`](crate::style::Color).
palette = ["dep:palette"] palette = ["dep:palette"]
@ -25,14 +31,14 @@ palette = ["dep:palette"]
## the Crossterm backend, and is not supported on Windows 7. ## the Crossterm backend, and is not supported on Windows 7.
underline-color = [] underline-color = []
## Use terminal scrolling regions to make some operations less prone to
## flickering. (i.e. Terminal::insert_before).
scrolling-regions = []
## enables serialization and deserialization of style and color types using the [`serde`] crate. ## enables serialization and deserialization of style and color types using the [`serde`] crate.
## This is useful if you want to save themes to a file. ## This is useful if you want to save themes to a file.
serde = ["dep:serde", "bitflags/serde", "compact_str/serde"] serde = ["dep:serde", "bitflags/serde", "compact_str/serde"]
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[dependencies] [dependencies]
bitflags = "2.3" bitflags = "2.3"
cassowary = "0.3" cassowary = "0.3"
@ -50,9 +56,13 @@ unicode-truncate = "2"
unicode-width.workspace = true unicode-width.workspace = true
[dev-dependencies] [dev-dependencies]
rstest.workspace = true
pretty_assertions.workspace = true pretty_assertions.workspace = true
serde_json = "1.0.132" ratatui = { workspace = true, features = ["crossterm", "termwiz"] }
rstest.workspace = true
serde_json.workspace = true
[target.'cfg(not(windows))'.dev-dependencies]
ratatui = { workspace = true, features = ["termion"] }
[lints.clippy] [lints.clippy]
# we often split up a module into multiple files with the main type in a file named after the # we often split up a module into multiple files with the main type in a file named after the

View file

@ -56,7 +56,7 @@
//! Each backend handles raw mode differently, so the behavior may vary depending on the backend //! Each backend handles raw mode differently, so the behavior may vary depending on the backend
//! being used. Be sure to consult the backend's specific documentation for exact details on how it //! being used. Be sure to consult the backend's specific documentation for exact details on how it
//! implements raw mode. //! implements raw mode.
//!
//! # Alternate Screen //! # Alternate Screen
//! //!
//! The alternate screen is a separate buffer that some terminals provide, distinct from the main //! The alternate screen is a separate buffer that some terminals provide, distinct from the main
@ -90,15 +90,15 @@
//! backend being used, and developers should consult the specific backend's documentation to //! backend being used, and developers should consult the specific backend's documentation to
//! understand how it implements mouse capture. //! understand how it implements mouse capture.
//! //!
//! [`TermionBackend`]: termion/struct.TermionBackend.html //! [`CrosstermBackend`]: https://docs.rs/ratatui/latest/ratatui/backend/struct.CrosstermBackend.html
//! [`Terminal`]: crate::terminal::Terminal //! [`TermionBackend`]: https://docs.rs/ratatui/latest/ratatui/backend/struct.TermionBackend.html
//! [`TermionBackend`]: termion/struct.TermionBackend.html //! [`TermwizBackend`]: https://docs.rs/ratatui/latest/ratatui/backend/struct.TermwizBackend.html
//! [`Terminal`]: https://docs.rs/ratatui/latest/ratatui/struct.Terminal.html
//! [Crossterm]: https://crates.io/crates/crossterm //! [Crossterm]: https://crates.io/crates/crossterm
//! [Termion]: https://crates.io/crates/termion //! [Termion]: https://crates.io/crates/termion
//! [Termwiz]: https://crates.io/crates/termwiz //! [Termwiz]: https://crates.io/crates/termwiz
//! [Examples]: https://github.com/ratatui/ratatui/tree/main/ratatui/examples/README.md //! [Examples]: https://github.com/ratatui/ratatui/tree/main/ratatui/examples/README.md
//! [Backend Comparison]: //! [Backend Comparison]: https://ratatui.rs/concepts/backends/comparison/
//! https://ratatui.rs/concepts/backends/comparison/
//! [Ratatui Website]: https://ratatui.rs //! [Ratatui Website]: https://ratatui.rs
use std::io; use std::io;
@ -109,21 +109,6 @@ use crate::{
layout::{Position, Size}, layout::{Position, Size},
}; };
#[cfg(feature = "crossterm")]
mod crossterm;
#[cfg(feature = "crossterm")]
pub use self::crossterm::{CrosstermBackend, FromCrossterm, IntoCrossterm};
#[cfg(all(not(windows), feature = "termion"))]
mod termion;
#[cfg(all(not(windows), feature = "termion"))]
pub use self::termion::{FromTermion, IntoTermion, TermionBackend};
#[cfg(feature = "termwiz")]
mod termwiz;
#[cfg(feature = "termwiz")]
pub use self::termwiz::{FromTermwiz, IntoTermwiz, TermwizBackend};
mod test; mod test;
pub use self::test::TestBackend; pub use self::test::TestBackend;
@ -162,7 +147,7 @@ pub struct WindowSize {
/// Most applications should not need to interact with the `Backend` trait directly as the /// Most applications should not need to interact with the `Backend` trait directly as the
/// [`Terminal`] struct provides a higher level interface for interacting with the terminal. /// [`Terminal`] struct provides a higher level interface for interacting with the terminal.
/// ///
/// [`Terminal`]: crate::terminal::Terminal /// [`Terminal`]: https://docs.rs/ratatui/latest/ratatui/struct.Terminal.html
pub trait Backend { pub trait Backend {
/// Draw the given content to the terminal screen. /// Draw the given content to the terminal screen.
/// ///

View file

@ -144,7 +144,7 @@ impl TestBackend {
#[track_caller] #[track_caller]
pub fn assert_buffer(&self, expected: &Buffer) { pub fn assert_buffer(&self, expected: &Buffer) {
// TODO: use assert_eq!() // TODO: use assert_eq!()
ratatui_core::assert_buffer_eq!(&self.buffer, expected); crate::assert_buffer_eq!(&self.buffer, expected);
} }
/// Asserts that the `TestBackend`'s scrollback buffer is equal to the expected buffer. /// Asserts that the `TestBackend`'s scrollback buffer is equal to the expected buffer.

View file

@ -38,6 +38,7 @@
//! //!
//! This project is licensed under the MIT License. See the [LICENSE](../LICENSE) file for details. //! This project is licensed under the MIT License. See the [LICENSE](../LICENSE) file for details.
pub mod backend;
pub mod buffer; pub mod buffer;
pub mod layout; pub mod layout;
pub mod style; pub mod style;

View file

@ -0,0 +1,45 @@
[package]
name = "ratatui-crossterm"
version = "0.1.0"
description = "Crossterm backend for the Ratatui Terminal UI library."
documentation = "https://docs.rs/ratatui-crossterm/"
readme = "README.md"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
keywords.workspace = true
categories.workspace = true
license.workspace = true
exclude.workspace = true
edition.workspace = true
rust-version.workspace = true
[features]
default = ["underline-color"]
## enables the backend code that sets the underline color.
## Underline color is only supported by the [`CrosstermBackend`](backend::CrosstermBackend) backend,
## and is not supported on Windows 7.
underline-color = []
## Use terminal scrolling regions to make Terminal::insert_before less prone to flickering.
scrolling-regions = ["ratatui-core/scrolling-regions"]
#! The following features are unstable and may change in the future:
## Enable all unstable features.
unstable = ["unstable-backend-writer"]
## Enables getting access to backends' writers.
unstable-backend-writer = []
[dependencies]
crossterm.workspace = true
document-features = { workspace = true, optional = true }
instability.workspace = true
ratatui-core = { workspace = true }
[dev-dependencies]
ratatui = { workspace = true, features = ["crossterm"] }
rstest.workspace = true

View file

@ -0,0 +1,10 @@
# Ratatui-crossterm
<!-- cargo-rdme start -->
This module provides the [`CrosstermBackend`] implementation for the [`Backend`] trait. It uses
the [Crossterm] crate to interact with the terminal.
[Crossterm]: https://crates.io/crates/crossterm
<!-- cargo-rdme end -->

View file

@ -1,9 +1,21 @@
// show the feature flags in the generated documentation
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/ratatui/ratatui/main/assets/logo.png",
html_favicon_url = "https://raw.githubusercontent.com/ratatui/ratatui/main/assets/favicon.ico"
)]
#![warn(missing_docs)]
//! This module provides the [`CrosstermBackend`] implementation for the [`Backend`] trait. It uses //! This module provides the [`CrosstermBackend`] implementation for the [`Backend`] trait. It uses
//! the [Crossterm] crate to interact with the terminal. //! the [Crossterm] crate to interact with the terminal.
//! //!
//! [Crossterm]: https://crates.io/crates/crossterm //! [Crossterm]: https://crates.io/crates/crossterm
#![cfg_attr(feature = "document-features", doc = "\n## Features")]
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
use std::io::{self, Write}; use std::io::{self, Write};
pub use crossterm;
#[cfg(feature = "underline-color")] #[cfg(feature = "underline-color")]
use crossterm::style::SetUnderlineColor; use crossterm::style::SetUnderlineColor;
use crossterm::{ use crossterm::{
@ -16,8 +28,7 @@ use crossterm::{
}, },
terminal::{self, Clear}, terminal::{self, Clear},
}; };
use ratatui_core::{
use crate::{
backend::{Backend, ClearType, WindowSize}, backend::{Backend, ClearType, WindowSize},
buffer::Cell, buffer::Cell,
layout::{Position, Size}, layout::{Position, Size},
@ -74,8 +85,8 @@ use crate::{
/// for more details on raw mode and alternate screen. /// for more details on raw mode and alternate screen.
/// ///
/// [`Write`]: std::io::Write /// [`Write`]: std::io::Write
/// [`Terminal`]: crate::terminal::Terminal /// [`Terminal`]: https://docs.rs/ratatui/latest/ratatui/struct.Terminal.html
/// [`backend`]: crate::backend /// [`backend`]: ratatui_core::backend
/// [Crossterm]: https://crates.io/crates/crossterm /// [Crossterm]: https://crates.io/crates/crossterm
/// [Examples]: https://github.com/ratatui/ratatui/tree/main/ratatui/examples/README.md /// [Examples]: https://github.com/ratatui/ratatui/tree/main/ratatui/examples/README.md
#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]

View file

@ -0,0 +1,35 @@
[package]
name = "ratatui-termion"
version = "0.1.0"
description = "Termion backend for the Ratatui Terminal UI library."
documentation = "https://docs.rs/ratatui-termion/"
readme = "README.md"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
keywords.workspace = true
categories.workspace = true
license.workspace = true
exclude.workspace = true
edition.workspace = true
rust-version.workspace = true
[package.metadata.docs.rs]
all-features = true
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
rustdoc-args = ["--cfg", "docsrs"]
[features]
default = []
## Use terminal scrolling regions to make Terminal::insert_before less prone to flickering.
scrolling-regions = ["ratatui-core/scrolling-regions"]
[dependencies]
document-features = { workspace = true, optional = true }
ratatui-core = { workspace = true }
termion.workspace = true
instability.workspace = true
[dev-dependencies]
rstest.workspace = true

11
ratatui-termion/README.md Normal file
View file

@ -0,0 +1,11 @@
# Ratatui-termion
<!-- cargo-rdme start -->
This module provides the [`TermionBackend`] implementation for the [`Backend`] trait. It uses
the [Termion] crate to interact with the terminal.
[`Backend`]: ratatui_core::backend::Backend
[Termion]: https://docs.rs/termion
<!-- cargo-rdme end -->

View file

@ -1,21 +1,32 @@
// show the feature flags in the generated documentation
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/ratatui/ratatui/main/assets/logo.png",
html_favicon_url = "https://raw.githubusercontent.com/ratatui/ratatui/main/assets/favicon.ico"
)]
#![warn(missing_docs)]
//! This module provides the [`TermionBackend`] implementation for the [`Backend`] trait. It uses //! This module provides the [`TermionBackend`] implementation for the [`Backend`] trait. It uses
//! the [Termion] crate to interact with the terminal. //! the [Termion] crate to interact with the terminal.
//! //!
//! [`Backend`]: crate::backend::Backend //! [`Backend`]: ratatui_core::backend::Backend
//! [`TermionBackend`]: crate::backend::TermionBackend
//! [Termion]: https://docs.rs/termion //! [Termion]: https://docs.rs/termion
#![cfg_attr(feature = "document-features", doc = "\n## Features")]
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
use std::{ use std::{
fmt, fmt,
io::{self, Write}, io::{self, Write},
}; };
use crate::{ use ratatui_core::{
backend::{Backend, ClearType, WindowSize}, backend::{Backend, ClearType, WindowSize},
buffer::Cell, buffer::Cell,
layout::{Position, Size}, layout::{Position, Size},
style::{Color, Modifier, Style}, style::{Color, Modifier, Style},
termion::{self, color as tcolor, color::Color as _, style as tstyle},
}; };
pub use termion;
use termion::{color as tcolor, color::Color as _, style as tstyle};
/// A [`Backend`] implementation that uses [Termion] to render to the terminal. /// A [`Backend`] implementation that uses [Termion] to render to the terminal.
/// ///
@ -61,7 +72,7 @@ use crate::{
/// ///
/// [`IntoRawMode::into_raw_mode()`]: termion::raw::IntoRawMode /// [`IntoRawMode::into_raw_mode()`]: termion::raw::IntoRawMode
/// [`IntoAlternateScreen::into_alternate_screen()`]: termion::screen::IntoAlternateScreen /// [`IntoAlternateScreen::into_alternate_screen()`]: termion::screen::IntoAlternateScreen
/// [`Terminal`]: crate::terminal::Terminal /// [`Terminal`]: ratatui::terminal::Terminal
/// [Termion]: https://docs.rs/termion /// [Termion]: https://docs.rs/termion
#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
pub struct TermionBackend<W> pub struct TermionBackend<W>
@ -532,8 +543,9 @@ impl fmt::Display for ResetRegion {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use ratatui_core::style::Stylize;
use super::*; use super::*;
use crate::style::Stylize;
#[test] #[test]
fn from_termion_color() { fn from_termion_color() {

View file

@ -0,0 +1,39 @@
[package]
name = "ratatui-termwiz"
version = "0.1.0"
description = "Termwiz backend for the Ratatui Terminal UI library."
documentation = "https://docs.rs/ratatui-termwiz/"
readme = "README.md"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
keywords.workspace = true
categories.workspace = true
license.workspace = true
exclude.workspace = true
edition.workspace = true
rust-version.workspace = true
[package.metadata.docs.rs]
all-features = true
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
rustdoc-args = ["--cfg", "docsrs"]
[features]
default = []
## Enables the backend code that sets the underline color.
## Underline color is not supported on Windows 7.
underline-color = []
## Use terminal scrolling regions to make Terminal::insert_before less prone to flickering.
scrolling-regions = ["ratatui-core/scrolling-regions"]
[dependencies]
document-features = { workspace = true, optional = true }
ratatui-core = { workspace = true }
termwiz.workspace = true
[dev-dependencies]
ratatui = { workspace = true, features = ["termwiz"] }
rstest.workspace = true

11
ratatui-termwiz/README.md Normal file
View file

@ -0,0 +1,11 @@
# Ratatui-termwiz
<!-- cargo-rdme start -->
This module provides the [`TermwizBackend`] implementation for the [`Backend`] trait. It uses
the [Termwiz] crate to interact with the terminal.
[`Backend`]: trait.Backend.html
[Termwiz]: https://crates.io/crates/termwiz
<!-- cargo-rdme end -->

View file

@ -1,24 +1,34 @@
//! This module provides the `TermwizBackend` implementation for the [`Backend`] trait. It uses the // show the feature flags in the generated documentation
//! [Termwiz] crate to interact with the terminal. #![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/ratatui/ratatui/main/assets/logo.png",
html_favicon_url = "https://raw.githubusercontent.com/ratatui/ratatui/main/assets/favicon.ico"
)]
#![warn(missing_docs)]
//! This module provides the [`TermwizBackend`] implementation for the [`Backend`] trait. It uses
//! the [Termwiz] crate to interact with the terminal.
//! //!
//! [`Backend`]: trait.Backend.html //! [`Backend`]: trait.Backend.html
//! [`TermwizBackend`]: crate::backend::TermionBackend
//! [Termwiz]: https://crates.io/crates/termwiz //! [Termwiz]: https://crates.io/crates/termwiz
#![cfg_attr(feature = "document-features", doc = "\n## Features")]
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
use std::{error::Error, io}; use std::{error::Error, io};
use crate::{ use ratatui_core::{
backend::{Backend, WindowSize}, backend::{Backend, WindowSize},
buffer::Cell, buffer::Cell,
layout::{Position, Size}, layout::{Position, Size},
style::{Color, Modifier, Style}, style::{Color, Modifier, Style},
termwiz::{ };
pub use termwiz;
use termwiz::{
caps::Capabilities, caps::Capabilities,
cell::{AttributeChange, Blink, CellAttributes, Intensity, Underline}, cell::{AttributeChange, Blink, CellAttributes, Intensity, Underline},
color::{AnsiColor, ColorAttribute, ColorSpec, LinearRgba, RgbColor, SrgbaTuple}, color::{AnsiColor, ColorAttribute, ColorSpec, LinearRgba, RgbColor, SrgbaTuple},
surface::{Change, CursorVisibility, Position as TermwizPosition}, surface::{Change, CursorVisibility, Position as TermwizPosition},
terminal::{buffered::BufferedTerminal, ScreenSize, SystemTerminal, Terminal}, terminal::{buffered::BufferedTerminal, ScreenSize, SystemTerminal, Terminal},
},
}; };
/// A [`Backend`] implementation that uses [Termwiz] to render to the terminal. /// A [`Backend`] implementation that uses [Termwiz] to render to the terminal.
@ -53,8 +63,8 @@ use crate::{
/// See the the [Examples] directory for more examples. See the [`backend`] module documentation /// See the the [Examples] directory for more examples. See the [`backend`] module documentation
/// for more details on raw mode and alternate screen. /// for more details on raw mode and alternate screen.
/// ///
/// [`backend`]: crate::backend /// [`backend`]: ratatui_core::backend
/// [`Terminal`]: crate::terminal::Terminal /// [`Terminal`]: https://docs.rs/ratatui/latest/ratatui/struct.Terminal.html
/// [`BufferedTerminal`]: termwiz::terminal::buffered::BufferedTerminal /// [`BufferedTerminal`]: termwiz::terminal::buffered::BufferedTerminal
/// [Termwiz]: https://crates.io/crates/termwiz /// [Termwiz]: https://crates.io/crates/termwiz
/// [Examples]: https://github.com/ratatui/ratatui/tree/main/ratatui/examples/README.md /// [Examples]: https://github.com/ratatui/ratatui/tree/main/ratatui/examples/README.md
@ -759,7 +769,7 @@ mod tests {
#[test] #[test]
fn from_cell_attribute_for_style() { fn from_cell_attribute_for_style() {
use crate::style::Stylize; use ratatui_core::style::Stylize;
#[cfg(feature = "underline-color")] #[cfg(feature = "underline-color")]
const STYLE: Style = Style::new() const STYLE: Style = Style::new()

View file

@ -1,6 +1,6 @@
[package] [package]
name = "ratatui-widgets" name = "ratatui-widgets"
description = "A collection of Ratatui widgets for building terminal user interfaces." description = "A collection of Ratatui widgets for building terminal user interfaces using Ratatui."
version = "0.3.0" version = "0.3.0"
readme = "README.md" readme = "README.md"
authors.workspace = true authors.workspace = true
@ -14,7 +14,13 @@ exclude.workspace = true
edition.workspace = true edition.workspace = true
rust-version.workspace = true rust-version.workspace = true
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[features] [features]
default = []
## enables serialization and deserialization of style and color types using the [`serde`] crate. ## enables serialization and deserialization of style and color types using the [`serde`] crate.
## This is useful if you want to save themes to a file. ## This is useful if you want to save themes to a file.
serde = ["dep:serde", "ratatui-core/serde"] serde = ["dep:serde", "ratatui-core/serde"]
@ -37,10 +43,6 @@ unstable = ["unstable-rendered-line-info"]
## See [Issue 293](https://github.com/ratatui/ratatui/issues/293) for more details. ## See [Issue 293](https://github.com/ratatui/ratatui/issues/293) for more details.
unstable-rendered-line-info = [] unstable-rendered-line-info = []
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[dependencies] [dependencies]
bitflags.workspace = true bitflags.workspace = true
itertools.workspace = true itertools.workspace = true

View file

@ -14,25 +14,102 @@ exclude.workspace = true
edition.workspace = true edition.workspace = true
rust-version.workspace = true rust-version.workspace = true
[package.metadata.docs.rs]
all-features = true
# see https://doc.rust-lang.org/nightly/rustdoc/scraped-examples.html
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
rustdoc-args = ["--cfg", "docsrs"]
[features]
#! The crate provides a set of optional features that can be enabled in your `Cargo.toml` file.
#!
## By default, we enable the crossterm backend as this is a reasonable choice for most applications
## as it is supported on Linux/Mac/Windows systems. We also enable the `underline-color` feature
## which allows you to set the underline color of text.
default = ["crossterm", "underline-color"]
#! Generally an application will only use one backend, so you should only enable one of the following features:
## enables the [`CrosstermBackend`](backend::CrosstermBackend) backend and adds a dependency on [`crossterm`].
crossterm = ["dep:ratatui-crossterm"]
## enables the [`TermionBackend`](backend::TermionBackend) backend and adds a dependency on [`termion`].
termion = ["dep:ratatui-termion"]
## enables the [`TermwizBackend`](backend::TermwizBackend) backend and adds a dependency on [`termwiz`].
termwiz = ["dep:ratatui-termwiz"]
#! The following optional features are available for all backends:
## enables serialization and deserialization of style and color types using the [`serde`] crate.
## This is useful if you want to save themes to a file.
serde = ["dep:serde", "ratatui-core/serde", "ratatui-widgets/serde"]
## enables conversions from colors in the [`palette`] crate to [`Color`](crate::style::Color).
palette = ["ratatui-core/palette", "dep:palette"]
## Use terminal scrolling regions to make some operations less prone to
## flickering. (i.e. Terminal::insert_before).
scrolling-regions = [
"ratatui-core/scrolling-regions",
"ratatui-crossterm?/scrolling-regions",
"ratatui-termion?/scrolling-regions",
"ratatui-termwiz?/scrolling-regions",
]
## enables all widgets.
all-widgets = ["widget-calendar"]
#! Widgets that add dependencies are gated behind feature flags to prevent unused transitive
#! dependencies. The available features are:
## enables the [`calendar`](widgets::calendar) widget module and adds a dependency on [`time`].
widget-calendar = ["ratatui-widgets/calendar"]
#! The following optional features are only available for some backends:
## Enables the backend code that sets the underline color.
## Underline color is only supported by the Crossterm and Termwiz backends, and is not supported on
## Windows 7.
underline-color = [
"ratatui-core/underline-color",
"ratatui-crossterm?/underline-color",
"ratatui-termwiz?/underline-color",
]
#! The following features are unstable and may change in the future:
## Enable all unstable features.
unstable = ["unstable-rendered-line-info", "unstable-widget-ref", "unstable-backend-writer"]
## Enables the [`Paragraph::line_count`](widgets::Paragraph::line_count)
## [`Paragraph::line_width`](widgets::Paragraph::line_width) methods
## which are experimental and may change in the future.
## See [Issue 293](https://github.com/ratatui/ratatui/issues/293) for more details.
unstable-rendered-line-info = ["ratatui-widgets/unstable-rendered-line-info"]
## enables the [`WidgetRef`] and [`StatefulWidgetRef`] traits which are experimental and may change
## in the future.
##
## [`WidgetRef`]: widgets::WidgetRef
## [`StatefulWidgetRef`]: widgets::StatefulWidgetRef
unstable-widget-ref = []
## Enables getting access to backends' writers. Only the Crossterm backend currently supports this.
unstable-backend-writer = ["ratatui-crossterm?/unstable-backend-writer"]
[dependencies] [dependencies]
crossterm = { version = "0.28.1", optional = true }
document-features = { workspace = true, optional = true } document-features = { workspace = true, optional = true }
indoc = "2" indoc = "2"
instability.workspace = true instability.workspace = true
itertools.workspace = true itertools.workspace = true
palette = { version = "0.7.6", optional = true } palette = { version = "0.7.6", optional = true }
ratatui-core = { workspace = true } ratatui-core = { workspace = true }
ratatui-crossterm = { workspace = true, optional = true }
ratatui-termwiz = { workspace = true, optional = true }
ratatui-widgets = { workspace = true } ratatui-widgets = { workspace = true }
serde = { workspace = true, optional = true } serde = { workspace = true, optional = true }
strum.workspace = true strum.workspace = true
termwiz = { version = "0.22.0", optional = true }
time = { version = "0.3.11", optional = true, features = ["local-offset"] } time = { version = "0.3.11", optional = true, features = ["local-offset"] }
# See <https://github.com/ratatui/ratatui/issues/1271> for information about why we pin unicode-width # See <https://github.com/ratatui/ratatui/issues/1271> for information about why we pin unicode-width
unicode-width.workspace = true unicode-width.workspace = true
[target.'cfg(not(windows))'.dependencies] [target.'cfg(not(windows))'.dependencies]
# termion is not supported on Windows ratatui-termion = { workspace = true, optional = true }
termion = { version = "4.0.0", optional = true }
[dev-dependencies] [dev-dependencies]
argh = "0.1.12" argh = "0.1.12"
@ -48,13 +125,8 @@ pretty_assertions = "1.4.0"
rand = "0.8.5" rand = "0.8.5"
rand_chacha = "0.3.1" rand_chacha = "0.3.1"
rstest = "0.23.0" rstest = "0.23.0"
serde_json = "1.0.109" serde_json.workspace = true
tokio = { version = "1.41.1", features = [ tokio = { version = "1.41.1", features = ["rt", "macros", "time", "rt-multi-thread"] }
"rt",
"macros",
"time",
"rt-multi-thread",
] }
tracing = "0.1.40" tracing = "0.1.40"
tracing-appender = "0.2.3" tracing-appender = "0.2.3"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
@ -101,79 +173,6 @@ string_to_string = "warn"
unnecessary_self_imports = "warn" unnecessary_self_imports = "warn"
use_self = "warn" use_self = "warn"
[features]
#! The crate provides a set of optional features that can be enabled in your `Cargo.toml` file.
#!
## By default, we enable the crossterm backend as this is a reasonable choice for most applications
## as it is supported on Linux/Mac/Windows systems. We also enable the `underline-color` feature
## which allows you to set the underline color of text.
default = ["crossterm", "underline-color"]
#! Generally an application will only use one backend, so you should only enable one of the following features:
## enables the [`CrosstermBackend`](backend::CrosstermBackend) backend and adds a dependency on [`crossterm`].
crossterm = ["dep:crossterm"]
## enables the [`TermionBackend`](backend::TermionBackend) backend and adds a dependency on [`termion`].
termion = ["dep:termion"]
## enables the [`TermwizBackend`](backend::TermwizBackend) backend and adds a dependency on [`termwiz`].
termwiz = ["dep:termwiz"]
#! The following optional features are available for all backends:
## enables serialization and deserialization of style and color types using the [`serde`] crate.
## This is useful if you want to save themes to a file.
serde = ["dep:serde", "ratatui-core/serde", "ratatui-widgets/serde"]
## enables conversions from colors in the [`palette`] crate to [`Color`](crate::style::Color).
palette = ["ratatui-core/palette", "dep:palette"]
## Use terminal scrolling regions to make some operations less prone to
## flickering. (i.e. Terminal::insert_before).
scrolling-regions = []
## enables all widgets.
all-widgets = ["widget-calendar"]
#! Widgets that add dependencies are gated behind feature flags to prevent unused transitive
#! dependencies. The available features are:
## enables the [`calendar`](widgets::calendar) widget module and adds a dependency on [`time`].
widget-calendar = ["ratatui-widgets/calendar"]
#! The following optional features are only available for some backends:
## enables the backend code that sets the underline color.
## Underline color is only supported by the [`CrosstermBackend`](backend::CrosstermBackend) backend,
## and is not supported on Windows 7.
underline-color = ["dep:crossterm", "ratatui-core/underline-color"]
#! The following features are unstable and may change in the future:
## Enable all unstable features.
unstable = [
"unstable-rendered-line-info",
"unstable-widget-ref",
"unstable-backend-writer",
]
## Enables the [`Paragraph::line_count`](widgets::Paragraph::line_count)
## [`Paragraph::line_width`](widgets::Paragraph::line_width) methods
## which are experimental and may change in the future.
## See [Issue 293](https://github.com/ratatui/ratatui/issues/293) for more details.
unstable-rendered-line-info = ["ratatui-widgets/unstable-rendered-line-info"]
## enables the [`WidgetRef`] and [`StatefulWidgetRef`] traits which are experimental and may change
## in the future.
##
## [`WidgetRef`]: widgets::WidgetRef
## [`StatefulWidgetRef`]: widgets::StatefulWidgetRef
unstable-widget-ref = []
## Enables getting access to backends' writers.
unstable-backend-writer = []
[package.metadata.docs.rs]
all-features = true
# see https://doc.rust-lang.org/nightly/rustdoc/scraped-examples.html
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
rustdoc-args = ["--cfg", "docsrs"]
[lib] [lib]
bench = false bench = false

View file

@ -326,25 +326,35 @@
//! [Forum]: https://forum.ratatui.rs //! [Forum]: https://forum.ratatui.rs
//! [Sponsors Badge]: https://img.shields.io/github/sponsors/ratatui?logo=github&style=flat-square&color=1370D3 //! [Sponsors Badge]: https://img.shields.io/github/sponsors/ratatui?logo=github&style=flat-square&color=1370D3
/// re-export the `crossterm` crate so that users don't have to add it as a dependency
#[cfg(feature = "crossterm")]
pub use crossterm;
/// re-export the `palette` crate so that users don't have to add it as a dependency /// re-export the `palette` crate so that users don't have to add it as a dependency
#[cfg(feature = "palette")] #[cfg(feature = "palette")]
pub use palette; pub use palette;
/// re-export the `crossterm` crate so that users don't have to add it as a dependency
#[cfg(feature = "crossterm")]
pub use ratatui_crossterm::crossterm;
/// re-export the `termion` crate so that users don't have to add it as a dependency
#[cfg(all(not(windows), feature = "termion"))]
pub use ratatui_termion::termion;
/// re-export the `termwiz` crate so that users don't have to add it as a dependency
#[cfg(feature = "termwiz")]
pub use ratatui_termwiz::termwiz;
#[cfg(feature = "crossterm")] #[cfg(feature = "crossterm")]
pub use terminal::{ pub use terminal::{
init, init_with_options, restore, try_init, try_init_with_options, try_restore, DefaultTerminal, init, init_with_options, restore, try_init, try_init_with_options, try_restore, DefaultTerminal,
}; };
pub use terminal::{CompletedFrame, Frame, Terminal, TerminalOptions, Viewport}; pub use terminal::{CompletedFrame, Frame, Terminal, TerminalOptions, Viewport};
/// re-export the `termion` crate so that users don't have to add it as a dependency
#[cfg(all(not(windows), feature = "termion"))]
pub use termion;
/// re-export the `termwiz` crate so that users don't have to add it as a dependency
#[cfg(feature = "termwiz")]
pub use termwiz;
pub mod backend; /// Re-exports for the backend implementations.
pub mod backend {
pub use ratatui_core::backend::{Backend, ClearType, TestBackend, WindowSize};
#[cfg(feature = "crossterm")]
pub use ratatui_crossterm::{CrosstermBackend, FromCrossterm, IntoCrossterm};
#[cfg(all(not(windows), feature = "termion"))]
pub use ratatui_termion::{FromTermion, IntoTermion, TermionBackend};
#[cfg(feature = "termwiz")]
pub use ratatui_termwiz::{FromTermwiz, IntoTermwiz, TermwizBackend};
}
pub use ratatui_core::{buffer, layout}; pub use ratatui_core::{buffer, layout};
pub mod prelude; pub mod prelude;
pub use ratatui_core::{style, symbols}; pub use ratatui_core::{style, symbols};

View file

@ -27,14 +27,15 @@
//! assert_eq!(text::Line::default(), ratatui::text::Line::from(vec![])); //! assert_eq!(text::Line::default(), ratatui::text::Line::from(vec![]));
//! ``` //! ```
pub use ratatui_core::backend::{self, Backend};
#[cfg(feature = "crossterm")] #[cfg(feature = "crossterm")]
pub use crate::backend::{CrosstermBackend, FromCrossterm, IntoCrossterm}; pub use ratatui_crossterm::{CrosstermBackend, FromCrossterm, IntoCrossterm};
#[cfg(all(not(windows), feature = "termion"))] #[cfg(all(not(windows), feature = "termion"))]
pub use crate::backend::{FromTermion, IntoTermion, TermionBackend}; pub use crate::backend::{FromTermion, IntoTermion, TermionBackend};
#[cfg(feature = "termwiz")] #[cfg(feature = "termwiz")]
pub use crate::backend::{FromTermwiz, IntoTermwiz, TermwizBackend}; pub use crate::backend::{FromTermwiz, IntoTermwiz, TermwizBackend};
pub use crate::{ pub use crate::{
backend::{self, Backend},
buffer::{self, Buffer}, buffer::{self, Buffer},
layout::{self, Alignment, Constraint, Direction, Layout, Margin, Position, Rect, Size}, layout::{self, Alignment, Constraint, Direction, Layout, Margin, Position, Rect, Size},
style::{self, Color, Modifier, Style, Stylize}, style::{self, Color, Modifier, Style, Stylize},

View file

@ -1,11 +1,14 @@
use std::io::{self, stdout, Stdout}; use std::io::{self, stdout, Stdout};
use crossterm::{ use ratatui_crossterm::{
crossterm::{
execute, execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
},
CrosstermBackend,
}; };
use crate::{backend::CrosstermBackend, terminal::TerminalOptions, Terminal}; use crate::{terminal::TerminalOptions, Terminal};
/// A type alias for the default terminal type. /// A type alias for the default terminal type.
/// ///

View file

@ -1,7 +1,8 @@
use std::io; use std::io;
use ratatui_core::backend::{Backend, ClearType};
use crate::{ use crate::{
backend::{Backend, ClearType},
buffer::{Buffer, Cell}, buffer::{Buffer, Cell},
layout::{Position, Rect, Size}, layout::{Position, Rect, Size},
CompletedFrame, Frame, TerminalOptions, Viewport, CompletedFrame, Frame, TerminalOptions, Viewport,

View file

@ -1,5 +1,11 @@
# xtask for ratatui # xtask for ratatui
See <https://github.com/matklad/cargo-xtask> for details <!-- cargo-rdme start -->
run with `cargo xtask ...` A simple task runner for the project.
See <https://github.com/matklad/cargo-xtask> for details on the xtask pattern.
Run `cargo xtask --help` for more information
<!-- cargo-rdme end -->

View file

@ -1,3 +1,9 @@
//! A simple task runner for the project.
//!
//! See <https://github.com/matklad/cargo-xtask> for details on the xtask pattern.
//!
//! Run `cargo xtask --help` for more information
use std::{fmt::Debug, io, process::Output, vec}; use std::{fmt::Debug, io, process::Output, vec};
use cargo_metadata::MetadataCommand; use cargo_metadata::MetadataCommand;
@ -99,6 +105,10 @@ enum Command {
#[command(visible_alias = "fmt")] #[command(visible_alias = "fmt")]
FixFormatting, FixFormatting,
/// Fix README.md (by running cargo-rdme)
#[command(visible_alias = "fr")]
FixReadme,
/// Fix typos in the project /// Fix typos in the project
#[command(visible_alias = "typos")] #[command(visible_alias = "typos")]
FixTypos, FixTypos,
@ -143,6 +153,7 @@ impl Command {
Command::LintMarkdown => lint_markdown(), Command::LintMarkdown => lint_markdown(),
Command::FixClippy => fix_clippy(), Command::FixClippy => fix_clippy(),
Command::FixFormatting => fix_format(), Command::FixFormatting => fix_format(),
Command::FixReadme => fix_readme(),
Command::FixTypos => fix_typos(), Command::FixTypos => fix_typos(),
Command::Test => test(), Command::Test => test(),
Command::TestBackend { backend } => test_backend(backend), Command::TestBackend { backend } => test_backend(backend),
@ -178,6 +189,13 @@ fn check_readme() -> Result<()> {
Ok(()) Ok(())
} }
fn fix_readme() -> Result<()> {
for package in get_workspace_packages()? {
run_cargo(vec!["rdme", "--workspace-project", &package])?;
}
Ok(())
}
/// Generate code coverage report /// Generate code coverage report
fn coverage() -> Result<()> { fn coverage() -> Result<()> {
run_cargo(vec![ run_cargo(vec![