summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xscripts/add-lints.bash6
-rw-r--r--src/display/src/color_mode.rs13
-rw-r--r--src/display/src/crossterm.rs2
-rw-r--r--src/display/src/display_color.rs19
-rw-r--r--src/display/src/lib.rs54
-rw-r--r--src/display/src/mockcrossterm.rs12
-rw-r--r--src/display/src/size.rs4
-rw-r--r--src/display/src/testutil.rs2
-rw-r--r--src/display/src/tui.rs15
9 files changed, 122 insertions, 5 deletions
diff --git a/scripts/add-lints.bash b/scripts/add-lints.bash
index 246ffc4..cda29f9 100755
--- a/scripts/add-lints.bash
+++ b/scripts/add-lints.bash
@@ -61,7 +61,11 @@ content="\
)]
// enable all of Clippy's lints
#![deny(clippy::all, clippy::cargo, clippy::nursery, clippy::pedantic, clippy::restriction)]
-#![allow(clippy::blanket_clippy_restriction_lints)]
+#![allow(
+ clippy::blanket_clippy_restriction_lints,
+ clippy::implicit_return,
+ clippy::missing_docs_in_private_items,
+)]
#![deny(
rustdoc::bare_urls,
rustdoc::broken_intra_doc_links,
diff --git a/src/display/src/color_mode.rs b/src/display/src/color_mode.rs
index 4887de6..da3f5d7 100644
--- a/src/display/src/color_mode.rs
+++ b/src/display/src/color_mode.rs
@@ -1,19 +1,32 @@
use super::color_mode::ColorMode::{EightBit, FourBit, TrueColor};
+/// Represents the color mode of a terminal interface.
#[derive(Copy, Clone, Debug, PartialEq)]
+#[allow(clippy::exhaustive_enums)]
pub enum ColorMode {
+ /// Supports 2 colors.
TwoTone,
+ /// Supports 8 colors.
ThreeBit,
+ /// Supports 16 colors.
FourBit,
+ /// Supports 256 colors.
EightBit,
+ /// Supports 24 bits of color.
TrueColor,
}
impl ColorMode {
+ /// Supports 4 bit or more of color.
+ #[inline]
+ #[must_use]
pub fn has_minimum_four_bit_color(self) -> bool {
self == FourBit || self == EightBit || self == TrueColor
}
+ /// Has true color support.
+ #[inline]
+ #[must_use]
pub fn has_true_color(self) -> bool {
self == TrueColor
}
diff --git a/src/display/src/crossterm.rs b/src/display/src/crossterm.rs
index 3ddc4bc..1c2b8a2 100644
--- a/src/display/src/crossterm.rs
+++ b/src/display/src/crossterm.rs
@@ -26,6 +26,7 @@ use crossterm::{
use super::{color_mode::ColorMode, size::Size, tui::Tui, utils::detect_color_mode};
+/// A thin wrapper over the [Crossterm library](https://github.com/crossterm-rs/crossterm).
#[derive(Debug)]
pub struct CrossTerm {
color_mode: ColorMode,
@@ -149,6 +150,7 @@ impl Tui for CrossTerm {
}
impl CrossTerm {
+ /// Create a new instance.
#[inline]
#[must_use]
pub fn new() -> Self {
diff --git a/src/display/src/display_color.rs b/src/display/src/display_color.rs
index 30b314e..1c7ba87 100644
--- a/src/display/src/display_color.rs
+++ b/src/display/src/display_color.rs
@@ -1,22 +1,41 @@
+/// An abstraction of colors to display.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[allow(clippy::exhaustive_enums)]
pub enum DisplayColor {
+ /// The color for the break action.
ActionBreak,
+ /// The color for the drop action.
ActionDrop,
+ /// The color for the edit action.
ActionEdit,
+ /// The color for the exec action.
ActionExec,
+ /// The color for the fixup action.
ActionFixup,
+ /// The color for the pick action.
ActionPick,
+ /// The color for the reword action.
ActionReword,
+ /// The color for the squash action.
ActionSquash,
+ /// The color for the label action.
ActionLabel,
+ /// The color for the reset action.
ActionReset,
+ /// The color for the merge action.
ActionMerge,
+ /// The color for added lines in a diff.
DiffAddColor,
+ /// The color for changed lines in a diff.
DiffChangeColor,
+ /// The color for removed lines in a diff.
DiffRemoveColor,
+ /// The color for context lines in a diff.
DiffContextColor,
+ /// The color for whitespace characters in a diff.
DiffWhitespaceColor,
+ /// The color for indicator text.
IndicatorColor,
+ /// The color for the standard text.
Normal,
}
diff --git a/src/display/src/lib.rs b/src/display/src/lib.rs
index f2bf203..9fd7327 100644
--- a/src/display/src/lib.rs
+++ b/src/display/src/lib.rs
@@ -50,7 +50,7 @@
#![allow(
clippy::blanket_clippy_restriction_lints,
clippy::implicit_return,
- clippy::missing_docs_in_private_items,
+ clippy::missing_docs_in_private_items
)]
#![deny(
rustdoc::bare_urls,
@@ -63,8 +63,6 @@
)]
// LINT-REPLACE-END
#![allow(
- missing_docs,
- rustdoc::missing_crate_level_docs,
clippy::as_conversions,
clippy::cast_possible_truncation,
clippy::default_numeric_fallback,
@@ -78,6 +76,33 @@
clippy::unwrap_used,
clippy::wildcard_enum_match_arm
)]
+
+//! Git Interactive Rebase Tool - Display Module
+//!
+//! # Description
+//! This module is used to handle working with the terminal display.
+//!
+//! ```
+//! use config::Config;
+//! use display::{CrossTerm, Display, DisplayColor};
+//! let config = Config::new().expect("Could not load config");
+//! let tui = CrossTerm::new();
+//! let mut display = Display::new(tui, &config.theme);
+//!
+//! display.start();
+//! display.clear();
+//! display.draw_str("Hello world!");
+//! display.color(DisplayColor::IndicatorColor, false);
+//! display.set_style(false, true, false);
+//! display.draw_str("Hello colorful, underlined world!");
+//! display.refresh();
+//! display.end();
+//! ```
+//!
+//! ## Test Utilities
+//! To facilitate testing the usages of this crate, a set of testing utilities are provided. Since
+//! these utilities are not tested, and often are optimized for developer experience than
+//! performance should only be used in test code.
mod color_mode;
mod crossterm;
mod display_color;
@@ -92,8 +117,9 @@ use anyhow::Result;
use config::Theme;
use self::utils::register_selectable_color_pairs;
-pub use self::{crossterm::CrossTerm, display_color::DisplayColor, size::Size, tui::Tui};
+pub use self::{color_mode::ColorMode, crossterm::CrossTerm, display_color::DisplayColor, size::Size, tui::Tui};
+/// A high level interface to the terminal display.
#[derive(Debug)]
pub struct Display<T: Tui> {
action_break: (Colors, Colors),
@@ -118,6 +144,7 @@ pub struct Display<T: Tui> {
}
impl<T: Tui> Display<T> {
+ /// Create a new display instance.
#[inline]
pub fn new(tui: T, theme: &Theme) -> Self {
let color_mode = tui.get_color_mode();
@@ -253,11 +280,13 @@ impl<T: Tui> Display<T> {
}
}
+ /// Draws a string of text to the terminal interface.
#[inline]
pub fn draw_str(&mut self, s: &str) -> Result<()> {
self.tui.print(s)
}
+ /// Clear the terminal interface and reset any style and color attributes.
#[inline]
pub fn clear(&mut self) -> Result<()> {
self.color(DisplayColor::Normal, false)?;
@@ -265,11 +294,16 @@ impl<T: Tui> Display<T> {
self.tui.reset()
}
+ /// Force a refresh of the terminal interface. This normally should be called after after all
+ /// text has been drawn to the terminal interface. This is considered a slow operation, so
+ /// should be called only as needed.
#[inline]
pub fn refresh(&mut self) -> Result<()> {
self.tui.flush()
}
+ /// Set the color of text drawn to the terminal interface. This will only change text drawn to
+ /// the terminal after this function call.
#[inline]
pub fn color(&mut self, color: DisplayColor, selected: bool) -> Result<()> {
self.tui.set_color(
@@ -320,6 +354,8 @@ impl<T: Tui> Display<T> {
)
}
+ /// Set the style attributes of text drawn to the terminal interface. This will only change text
+ /// drawn to the terminal after this function call.
#[inline]
pub fn set_style(&mut self, dim: bool, underline: bool, reverse: bool) -> Result<()> {
self.set_dim(dim)?;
@@ -327,33 +363,43 @@ impl<T: Tui> Display<T> {
self.set_reverse(reverse)
}
+ /// Get the width and height of the terminal interface. This can be a slow operation, so should
+ /// not be called unless absolutely needed.
#[inline]
pub fn get_window_size(&self) -> Size {
self.tui.get_size()
}
+ /// Reset the cursor position to the start of the line.
#[inline]
pub fn ensure_at_line_start(&mut self) -> Result<()> {
self.tui.move_to_column(1)
}
+ /// Move the cursor position `right` characters from the end of the line.
#[inline]
pub fn move_from_end_of_line(&mut self, right: u16) -> Result<()> {
let width = self.get_window_size().width();
self.tui.move_to_column(width as u16 - right + 1)
}
+ /// Move the cursor to the next line.
#[inline]
pub fn next_line(&mut self) -> Result<()> {
self.tui.move_next_line()
}
+ /// Start the terminal interface interactions. This should be called before any terminal
+ /// interactions are performed.
#[inline]
pub fn start(&mut self) -> Result<()> {
self.tui.start()?;
self.tui.flush()
}
+ /// End the terminal interface interactions. This should be called after all terminal
+ /// interactions are complete. This resets the terminal interface to the default state, and
+ /// should be called on program exit.
#[inline]
pub fn end(&mut self) -> Result<()> {
self.tui.end()?;
diff --git a/src/display/src/mockcrossterm.rs b/src/display/src/mockcrossterm.rs
index ab30a46..f8bdb7e 100644
--- a/src/display/src/mockcrossterm.rs
+++ b/src/display/src/mockcrossterm.rs
@@ -6,6 +6,7 @@ use crossterm::{
use super::{color_mode::ColorMode, size::Size, tui::Tui, utils::detect_color_mode};
+/// The state of the `CrossTerm` instance.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum State {
New,
@@ -13,6 +14,7 @@ pub enum State {
Ended,
}
+/// A mocked version of `CrossTerm`, useful for testing.
#[derive(Debug)]
pub struct CrossTerm {
attributes: Attributes,
@@ -129,6 +131,7 @@ impl Tui for CrossTerm {
}
impl CrossTerm {
+ /// Create a new mocked version of `CrossTerm`.
#[inline]
#[must_use]
pub fn new() -> Self {
@@ -144,53 +147,62 @@ impl CrossTerm {
}
}
+ /// Get a representation of the rendered output.
#[inline]
#[must_use]
pub const fn get_output(&self) -> &Vec<String> {
&self.output
}
+ /// Get the current state.
#[inline]
#[must_use]
pub const fn get_state(&self) -> State {
self.state
}
+ /// Are colors enabled.
#[inline]
#[must_use]
pub fn is_colors_enabled(&self, colors: Colors) -> bool {
self.colors == colors
}
+ /// Does the current style attributes contained dimmed.
#[inline]
#[must_use]
pub fn is_dimmed(&self) -> bool {
self.attributes.has(Attribute::Dim)
}
+ /// Does the current style attributes contained reverse.
#[inline]
#[must_use]
pub fn is_reverse(&self) -> bool {
self.attributes.has(Attribute::Reverse)
}
+ /// Does the current style attributes contained underlined.
#[inline]
#[must_use]
pub fn is_underline(&self) -> bool {
self.attributes.has(Attribute::Underlined)
}
+ /// Update the size.
#[inline]
pub fn set_size(&mut self, size: Size) {
self.size = size;
}
+ /// Get the current cursor position.
#[inline]
#[must_use]
pub const fn get_position(&self) -> (u16, u16) {
self.position
}
+ /// Has the output been flushed.
#[inline]
#[must_use]
pub const fn is_dirty(&self) -> bool {
diff --git a/src/display/src/size.rs b/src/display/src/size.rs
index f20d054..57dd612 100644
--- a/src/display/src/size.rs
+++ b/src/display/src/size.rs
@@ -1,3 +1,4 @@
+/// Represents a terminal window size.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Size {
width: usize,
@@ -5,18 +6,21 @@ pub struct Size {
}
impl Size {
+ /// Create a new instance with a width and height.
#[inline]
#[must_use]
pub const fn new(width: usize, height: usize) -> Self {
Self { width, height }
}
+ /// Get the width.
#[inline]
#[must_use]
pub const fn width(&self) -> usize {
self.width
}
+ /// Get the height.
#[inline]
#[must_use]
pub const fn height(&self) -> usize {
diff --git a/src/display/src/testutil.rs b/src/display/src/testutil.rs
index 8b2a926..29d1ccc 100644
--- a/src/display/src/testutil.rs
+++ b/src/display/src/testutil.rs
@@ -1,6 +1,8 @@
+//! Utilities for writing tests that interact with the display.
pub use super::mockcrossterm::CrossTerm;
use super::*;
+/// Assert the the content of the Display is an expected value.
#[inline]
pub fn assert_output(display: &Display<CrossTerm>, expected: &[&str]) {
assert_eq!(display.tui.get_output().join(""), format!("{}\n", expected.join("\n")));
diff --git a/src/display/src/tui.rs b/src/display/src/tui.rs
index caf74da..c352075 100644
--- a/src/display/src/tui.rs
+++ b/src/display/src/tui.rs
@@ -3,20 +3,35 @@ use crossterm::{event::Event, style::Colors};
use super::{color_mode::ColorMode, Size};
+/// An interface that describes interactions with a terminal interface.
pub trait Tui {
+ /// Get the supported color mode.
fn get_color_mode(&self) -> ColorMode;
+ /// Reset the terminal interface to a default state.
fn reset(&mut self) -> Result<()>;
+ /// Flush the contents printed to the terminal interface.
fn flush(&mut self) -> Result<()>;
+ /// Print text to the terminal interface.
fn print(&mut self, s: &str) -> Result<()>;
+ /// Set the color attribute of text printed to the terminal interface.
fn set_color(&mut self, colors: Colors) -> Result<()>;
+ /// Set the dimmed style attribute of text printed to the terminal interface.
fn set_dim(&mut self, dim: bool) -> Result<()>;
+ /// Set the underlined style attribute of text printed to the terminal interface.
fn set_underline(&mut self, underline: bool) -> Result<()>;
+ /// Set the reversed style attribute of text printed to the terminal interface.
fn set_reverse(&mut self, reverse: bool) -> Result<()>;
+ /// Read the next input event from the terminal interface.
fn read_event() -> Result<Option<Event>>
where Self: Sized;
+ /// Get the number of columns and rows of the terminal interface.
fn get_size(&self) -> Size;
+ /// Move the cursor position `x` characters from the start of the line.
fn move_to_column(&mut self, x: u16) -> Result<()>;
+ /// Move the cursor to the next line.
fn move_next_line(&mut self) -> Result<()>;
+ /// Start the terminal interface interactions.
fn start(&mut self) -> Result<()>;
+ /// End the terminal interface interactions.
fn end(&mut self) -> Result<()>;
}