aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md21
-rw-r--r--src/attrs.rs6
-rw-r--r--src/cell.rs19
-rw-r--r--src/lib.rs18
-rw-r--r--src/screen.rs82
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
}