From 8cd3ca2c07b29e61f18c0c34db8b34b36a42e03b Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Mon, 4 Nov 2019 09:17:05 -0500 Subject: docs --- README.md | 21 +++++++++++++-- src/attrs.rs | 6 +++++ src/cell.rs | 19 ++++++++++++++ src/lib.rs | 18 +++++++++++++ src/screen.rs | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 144 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f038a33..29c25d5 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,19 @@ -This crate parses terminal data into an in-memory representation of the -screen. Building requires glib-2.0, gcc, and flex. +# vt100 + +This crate parses a terminal byte stream and provides an in-memory +representation of the rendered contents. + +## Overview + +This is essentially the terminal parser component of a graphical terminal +emulator pulled out into a separate crate. This can be used to not only +build graphical terminal emulators, but also many other types of +applications that need to interact with a terminal data stream directly, +such as terminal multiplexers or terminal recording applications. + +## Synopsis + +```rust +let mut screen = vt100::Screen::new(24, 80); +screen.process(b"this text is \x1b[31mRED\x1b[m"); +``` diff --git a/src/attrs.rs b/src/attrs.rs index 2fffd2b..f1b59a6 100644 --- a/src/attrs.rs +++ b/src/attrs.rs @@ -1,7 +1,13 @@ +/// Represents a foreground or background color for cells. #[derive(Eq, PartialEq, Debug, Copy, Clone)] pub enum Color { + /// The default terminal color. Default, + + /// An indexed terminal color. Idx(u8), + + /// An RGB terminal color. The parameters are (red, green, blue). Rgb(u8, u8, u8), } diff --git a/src/cell.rs b/src/cell.rs index 2f83d73..3c92076 100644 --- a/src/cell.rs +++ b/src/cell.rs @@ -1,5 +1,6 @@ use unicode_normalization::UnicodeNormalization as _; +/// Represents a single terminal cell. #[derive(Clone, Debug, Default)] pub struct Cell { contents: String, @@ -7,6 +8,7 @@ pub struct Cell { } impl Cell { + /// Creates a new cell. pub fn new() -> Self { Self::default() } @@ -31,14 +33,21 @@ impl Cell { self.attrs.clear(); } + /// Returns the text contents of the cell. + /// + /// Can include multiple unicode characters if combining characters are + /// used, but will contain at most one character with a non-zero character + /// width. pub fn contents(&self) -> &str { &self.contents } + /// Returns whether the cell contains any text data. pub fn has_contents(&self) -> bool { self.contents != "" } + /// Returns whether the text data in the cell represents a wide character. pub fn is_wide(&self) -> bool { crate::unicode::str_width(&self.contents) > 1 } @@ -47,26 +56,36 @@ impl Cell { &self.attrs } + /// Returns the foreground color of the cell. pub fn fgcolor(&self) -> crate::attrs::Color { self.attrs.fgcolor } + /// Returns the background color of the cell. pub fn bgcolor(&self) -> crate::attrs::Color { self.attrs.bgcolor } + /// Returns whether the cell should be rendered with the bold text + /// attribute. pub fn bold(&self) -> bool { self.attrs.bold() } + /// Returns whether the cell should be rendered with the italic text + /// attribute. pub fn italic(&self) -> bool { self.attrs.italic() } + /// Returns whether the cell should be rendered with the underlined text + /// attribute. pub fn underline(&self) -> bool { self.attrs.underline() } + /// Returns whether the cell should be rendered with the inverse text + /// attribute. pub fn inverse(&self) -> bool { self.attrs.inverse() } diff --git a/src/lib.rs b/src/lib.rs index 5f5ce31..3054403 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,21 @@ +//! This crate parses a terminal byte stream and provides an in-memory +//! representation of the rendered contents. +//! +//! # Overview +//! +//! This is essentially the terminal parser component of a graphical terminal +//! emulator pulled out into a separate crate. This can be used to not only +//! build graphical terminal emulators, but also many other types of +//! applications that need to interact with a terminal data stream directly, +//! such as terminal multiplexers or terminal recording applications. +//! +//! # Synopsis +//! +//! ``` +//! let mut screen = vt100::Screen::new(24, 80); +//! screen.process(b"this text is \x1b[31mRED\x1b[m"); +//! ``` + #![warn(clippy::pedantic)] #![warn(clippy::nursery)] #![allow(clippy::missing_const_for_fn)] diff --git a/src/screen.rs b/src/screen.rs index d29c907..c630ecf 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -17,13 +17,28 @@ enum Mode { BracketedPaste, } +/// The xterm mouse handling mode currently in use. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum MouseProtocolMode { + /// Mouse handling is disabled. None, + + /// Mouse button events should be reported on button press. Also known as + /// X10 mouse mode. Press, + + /// Mouse button events should be reported on button press and release. + /// Also known as VT200 mouse mode. PressRelease, + // Highlight, + /// Mouse button events should be reported on button press and release, as + /// well as when the mouse moves between cells while a button is held down. ButtonMotion, + + /// Mouse button events should be reported on button press and release, + /// and mouse motion events should be reported when the mouse moves + /// between cells regardless of whether a button is held down or not. AnyMotion, // DecLocator, } @@ -34,10 +49,16 @@ impl Default for MouseProtocolMode { } } +/// The encoding to use for the enabled `MouseProtocolMode`. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum MouseProtocolEncoding { + /// Default single-printable-byte encoding. Default, + + /// UTF-8-based encoding. Utf8, + + /// SGR-like encoding. Sgr, // Urxvt, } @@ -744,12 +765,14 @@ impl vte::Perform for State { fn unhook(&mut self) {} } +/// Represents a terminal screen. pub struct Screen { parser: vte::Parser, state: State, } impl Screen { + /// Creates a new terminal screen of the given size. pub fn new(rows: u16, cols: u16) -> Self { Self { parser: vte::Parser::new(), @@ -757,12 +780,15 @@ impl Screen { } } + /// Processes the contents of the given byte string, and updates the + /// in-memory terminal state. pub fn process(&mut self, bytes: &[u8]) { for byte in bytes { self.parser.advance(&mut self.state, *byte); } } + /// Resizes the terminal. pub fn set_size(&mut self, rows: u16, cols: u16) { self.state.grid.set_size(crate::grid::Size { rows, cols }); self.state @@ -770,11 +796,19 @@ impl Screen { .set_size(crate::grid::Size { rows, cols }); } + /// Returns the current size of the terminal. + /// + /// The return value will be (rows, cols). pub fn size(&self) -> (u16, u16) { let size = self.state.grid().size(); (size.rows, size.cols) } + /// Returns the text contents of the subset of the terminal given by the + /// parameters. + /// + /// This will not include any formatting information, and will be in plain + /// text format. pub fn contents( &self, row_start: u16, @@ -787,6 +821,14 @@ impl Screen { .contents(row_start, col_start, row_end, col_end) } + /// Returns the formatted contents of the subset of the terminal given by + /// the parameters. + /// + /// Formatting information will be included inline as terminal escape + /// codes. The result will be suitable for feeding directly to a raw + /// terminal parser, and will result in the same visual output. Internal + /// terminal modes (such as application keypad mode or alternate screen + /// mode) will not be included here. pub fn contents_formatted( &self, row_start: u16, @@ -799,79 +841,119 @@ impl Screen { .contents_formatted(row_start, col_start, row_end, col_end) } + /// Returns the `Cell` object at the given location in the terminal, if it + /// exists. pub fn cell(&self, row: u16, col: u16) -> Option<&crate::cell::Cell> { self.state.cell(crate::grid::Pos { row, col }) } + /// Returns the current cursor position of the terminal. + /// + /// The return value will be (row, col). pub fn cursor_position(&self) -> (u16, u16) { let pos = self.state.grid().pos(); (pos.row, pos.col) } + /// Returns the currently active foreground color. + /// + /// This is the foreground color which will be used when writing text to a + /// new cell. pub fn fgcolor(&self) -> crate::attrs::Color { self.state.attrs.fgcolor } + /// Returns the currently active background color. + /// + /// This is the background color which will be used when writing text to a + /// new cell. pub fn bgcolor(&self) -> crate::attrs::Color { self.state.attrs.bgcolor } + /// Returns whether the bold text attribute is active. + /// + /// If true, text written to a new cell will have the bold text attribute. pub fn bold(&self) -> bool { self.state.attrs.bold() } + /// Returns whether the italic text attribute is active. + /// + /// If true, text written to a new cell will have the italic text attribute. pub fn italic(&self) -> bool { self.state.attrs.italic() } + /// Returns whether the underline text attribute is active. + /// + /// If true, text written to a new cell will have the underline text + /// attribute. pub fn underline(&self) -> bool { self.state.attrs.underline() } + /// Returns whether the inverse text attribute is active. + /// + /// If true, text written to a new cell will have the inverse text + /// attribute. pub fn inverse(&self) -> bool { self.state.attrs.inverse() } + /// Returns the terminal's window title. pub fn title(&self) -> &str { &self.state.title } + /// Returns the terminal's icon name. pub fn icon_name(&self) -> &str { &self.state.icon_name } + /// Returns whether an audible bell has occurred since the last time this + /// method was called. pub fn check_audible_bell(&mut self) -> bool { self.state.check_output(Output::AudibleBell) } + /// Returns whether an visual bell has occurred since the last time this + /// method was called. pub fn check_visual_bell(&mut self) -> bool { self.state.check_output(Output::VisualBell) } + /// Returns whether the terminal should be in application keypad mode. pub fn application_keypad(&self) -> bool { self.state.mode(Mode::ApplicationKeypad) } + /// Returns whether the terminal should be in application cursor mode. pub fn application_cursor(&self) -> bool { self.state.mode(Mode::ApplicationCursor) } + /// Returns whether the terminal should be in hide cursor mode. pub fn hide_cursor(&self) -> bool { self.state.mode(Mode::HideCursor) } + /// Returns whether the terminal should be in alternate screen mode. pub fn alternate_screen(&self) -> bool { self.state.mode(Mode::AlternateScreen) } + /// Returns whether the terminal should be in bracketed paste mode. pub fn bracketed_paste(&self) -> bool { self.state.mode(Mode::BracketedPaste) } + /// Returns the currently active `MouseProtocolMode` pub fn mouse_protocol_mode(&self) -> MouseProtocolMode { self.state.mouse_protocol_mode } + /// Returns the currently active `MouseProtocolEncoding` pub fn mouse_protocol_encoding(&self) -> MouseProtocolEncoding { self.state.mouse_protocol_encoding } -- cgit v1.2.3-54-g00ecf