From 616fddad3e8557d3a4248fd25d00c256eab2c827 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sat, 13 Mar 2021 16:52:33 -0500 Subject: docs --- src/lib.rs | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index ca58146..27723fb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,71 @@ #![allow(clippy::collapsible_if)] +//! `textmode` is a library for terminal interaction built on top of a real +//! terminal parsing library. It allows you to do arbitrary drawing operations +//! on an in-memory screen, and then update the visible terminal output to +//! reflect the in-memory screen via an optimized diff algorithm when you are +//! finished. Being built on a real terminal parsing library means that while +//! normal curses-like operations are available: +//! +//! ```no_run +//! use textmode::Textmode; +//! # #[cfg(feature = "async")] +//! # fn main() -> textmode::Result<()> { +//! # futures_lite::future::block_on(async { run().await }) +//! # } +//! # #[cfg(feature = "async")] +//! # async fn run() -> textmode::Result<()> { +//! let mut tm = textmode::Output::new().await?; +//! tm.clear(); +//! tm.move_to(5, 5); +//! tm.set_fgcolor(textmode::color::RED); +//! tm.write_str("foo"); +//! tm.refresh().await?; +//! # Ok(()) +//! # } +//! # #[cfg(not(feature = "async"))] +//! # fn main() -> textmode::Result<()> { +//! # let mut tm = textmode::blocking::Output::new()?; +//! # tm.clear(); +//! # tm.move_to(5, 5); +//! # tm.set_fgcolor(textmode::color::RED); +//! # tm.write_str("foo"); +//! # tm.refresh()?; +//! # Ok(()) +//! # } +//! ``` +//! +//! you can also write data containing arbitrary terminal escape codes to the +//! output and they will also do the right thing: +//! +//! ```no_run +//! # use textmode::Textmode; +//! # #[cfg(feature = "async")] +//! # fn main() -> textmode::Result<()> { +//! # futures_lite::future::block_on(async { run().await }) +//! # } +//! # #[cfg(feature = "async")] +//! # async fn run() -> textmode::Result<()> { +//! # let mut tm = textmode::Output::new().await?; +//! tm.write(b"\x1b[34m\x1b[3;9Hbar\x1b[m"); +//! tm.refresh().await?; +//! # Ok(()) +//! # } +//! # #[cfg(not(feature = "async"))] +//! # fn main() -> textmode::Result<()> { +//! # let mut tm = textmode::blocking::Output::new()?; +//! # tm.write(b"\x1b[34m\x1b[3;9Hbar\x1b[m"); +//! # tm.refresh()?; +//! # Ok(()) +//! # } +//! ``` +//! +//! This module is split into two main parts: [`Output`](Output) and +//! [`Input`](Input). See the documentation for those types for more details. +//! Additionally, the [`blocking`] module provides an equivalent interface +//! with blocking calls instead of async. + +/// Blocking interface. pub mod blocking; pub mod color; @@ -21,24 +87,32 @@ pub use input::{Input, RawGuard}; const INIT: &[u8] = b"\x1b7\x1b[?47h\x1b[2J\x1b[H\x1b[?25h"; const DEINIT: &[u8] = b"\x1b[?47l\x1b8\x1b[?25h"; +/// Provides the methods used to manipulate the in-memory screen. pub trait Textmode: private::Output { + /// Returns the in-memory screen itself. This is the screen that will be + /// drawn on the next call to `refresh`. fn screen(&self) -> &vt100::Screen { self.next().screen() } + /// Writes a sequence of bytes, potentially containing terminal escape + /// sequences, to the in-memory screen. fn write(&mut self, buf: &[u8]) { self.next_mut().process(buf); } + /// Sets the terminal size for the in-memory screen. fn set_size(&mut self, rows: u16, cols: u16) { self.cur_mut().set_size(rows, cols); self.next_mut().set_size(rows, cols); } + /// Writes a string of printable characters to the in-memory screen. fn write_str(&mut self, text: &str) { self.write(text.as_bytes()); } + /// Moves the in-memory screen's cursor. fn move_to(&mut self, row: u16, col: u16) { self.write(b"\x1b["); self.write_u16(row + 1); @@ -47,18 +121,23 @@ pub trait Textmode: private::Output { self.write(b"H"); } + /// Clears the in-memory screen. fn clear(&mut self) { self.write(b"\x1b[2J"); } + /// Clears the line containing the cursor on the in-memory screen. fn clear_line(&mut self) { self.write(b"\x1b[K"); } + /// Clears the in-memory screen's currently active drawing attributes. fn reset_attributes(&mut self) { self.write(b"\x1b[m"); } + /// Sets the foreground color for subsequent drawing operations to the + /// in-memory screen. fn set_fgcolor(&mut self, color: vt100::Color) { match color { vt100::Color::Default => { @@ -91,6 +170,8 @@ pub trait Textmode: private::Output { } } + /// Sets the background color for subsequent drawing operations to the + /// in-memory screen. fn set_bgcolor(&mut self, color: vt100::Color) { match color { vt100::Color::Default => { @@ -123,6 +204,8 @@ pub trait Textmode: private::Output { } } + /// Sets whether subsequent text drawn to the in-memory screen should be + /// bold. fn set_bold(&mut self, bold: bool) { if bold { self.write(b"\x1b[1m"); @@ -131,6 +214,8 @@ pub trait Textmode: private::Output { } } + /// Sets whether subsequent text drawn to the in-memory screen should be + /// italic. fn set_italic(&mut self, italic: bool) { if italic { self.write(b"\x1b[3m"); @@ -139,6 +224,8 @@ pub trait Textmode: private::Output { } } + /// Sets whether subsequent text drawn to the in-memory screen should be + /// underlined. fn set_underline(&mut self, underline: bool) { if underline { self.write(b"\x1b[4m"); @@ -147,6 +234,8 @@ pub trait Textmode: private::Output { } } + /// Sets whether subsequent text drawn to the in-memory screen should have + /// its colors inverted. fn set_inverse(&mut self, inverse: bool) { if inverse { self.write(b"\x1b[7m"); -- cgit v1.2.3-54-g00ecf