diff options
Diffstat (limited to 'helix-tui/src/style.rs')
-rw-r--r-- | helix-tui/src/style.rs | 281 |
1 files changed, 0 insertions, 281 deletions
diff --git a/helix-tui/src/style.rs b/helix-tui/src/style.rs deleted file mode 100644 index f322d304..00000000 --- a/helix-tui/src/style.rs +++ /dev/null @@ -1,281 +0,0 @@ -//! `style` contains the primitives used to control how your user interface will look. - -use bitflags::bitflags; - -#[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub enum Color { - Reset, - Black, - Red, - Green, - Yellow, - Blue, - Magenta, - Cyan, - Gray, - DarkGray, - LightRed, - LightGreen, - LightYellow, - LightBlue, - LightMagenta, - LightCyan, - White, - Rgb(u8, u8, u8), - Indexed(u8), -} - -bitflags! { - /// Modifier changes the way a piece of text is displayed. - /// - /// They are bitflags so they can easily be composed. - /// - /// ## Examples - /// - /// ```rust - /// # use helix_tui::style::Modifier; - /// - /// let m = Modifier::BOLD | Modifier::ITALIC; - /// ``` - #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] - pub struct Modifier: u16 { - const BOLD = 0b0000_0000_0001; - const DIM = 0b0000_0000_0010; - const ITALIC = 0b0000_0000_0100; - const UNDERLINED = 0b0000_0000_1000; - const SLOW_BLINK = 0b0000_0001_0000; - const RAPID_BLINK = 0b0000_0010_0000; - const REVERSED = 0b0000_0100_0000; - const HIDDEN = 0b0000_1000_0000; - const CROSSED_OUT = 0b0001_0000_0000; - } -} - -/// Style let you control the main characteristics of the displayed elements. -/// -/// ```rust -/// # use helix_tui::style::{Color, Modifier, Style}; -/// Style::default() -/// .fg(Color::Black) -/// .bg(Color::Green) -/// .add_modifier(Modifier::ITALIC | Modifier::BOLD); -/// ``` -/// -/// It represents an incremental change. If you apply the styles S1, S2, S3 to a cell of the -/// terminal buffer, the style of this cell will be the result of the merge of S1, S2 and S3, not -/// just S3. -/// -/// ```rust -/// # use helix_tui::style::{Color, Modifier, Style}; -/// # use helix_tui::buffer::Buffer; -/// # use helix_tui::layout::Rect; -/// let styles = [ -/// Style::default().fg(Color::Blue).add_modifier(Modifier::BOLD | Modifier::ITALIC), -/// Style::default().bg(Color::Red), -/// Style::default().fg(Color::Yellow).remove_modifier(Modifier::ITALIC), -/// ]; -/// let mut buffer = Buffer::empty(Rect::new(0, 0, 1, 1)); -/// for style in &styles { -/// buffer.get_mut(0, 0).set_style(*style); -/// } -/// assert_eq!( -/// Style { -/// fg: Some(Color::Yellow), -/// bg: Some(Color::Red), -/// add_modifier: Modifier::BOLD, -/// sub_modifier: Modifier::empty(), -/// }, -/// buffer.get(0, 0).style(), -/// ); -/// ``` -/// -/// The default implementation returns a `Style` that does not modify anything. If you wish to -/// reset all properties until that point use [`Style::reset`]. -/// -/// ``` -/// # use helix_tui::style::{Color, Modifier, Style}; -/// # use helix_tui::buffer::Buffer; -/// # use helix_tui::layout::Rect; -/// let styles = [ -/// Style::default().fg(Color::Blue).add_modifier(Modifier::BOLD | Modifier::ITALIC), -/// Style::reset().fg(Color::Yellow), -/// ]; -/// let mut buffer = Buffer::empty(Rect::new(0, 0, 1, 1)); -/// for style in &styles { -/// buffer.get_mut(0, 0).set_style(*style); -/// } -/// assert_eq!( -/// Style { -/// fg: Some(Color::Yellow), -/// bg: Some(Color::Reset), -/// add_modifier: Modifier::empty(), -/// sub_modifier: Modifier::empty(), -/// }, -/// buffer.get(0, 0).style(), -/// ); -/// ``` -#[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct Style { - pub fg: Option<Color>, - pub bg: Option<Color>, - pub add_modifier: Modifier, - pub sub_modifier: Modifier, -} - -impl Default for Style { - fn default() -> Style { - Style { - fg: None, - bg: None, - add_modifier: Modifier::empty(), - sub_modifier: Modifier::empty(), - } - } -} - -impl Style { - /// Returns a `Style` resetting all properties. - pub fn reset() -> Style { - Style { - fg: Some(Color::Reset), - bg: Some(Color::Reset), - add_modifier: Modifier::empty(), - sub_modifier: Modifier::all(), - } - } - - /// Changes the foreground color. - /// - /// ## Examples - /// - /// ```rust - /// # use helix_tui::style::{Color, Style}; - /// let style = Style::default().fg(Color::Blue); - /// let diff = Style::default().fg(Color::Red); - /// assert_eq!(style.patch(diff), Style::default().fg(Color::Red)); - /// ``` - pub fn fg(mut self, color: Color) -> Style { - self.fg = Some(color); - self - } - - /// Changes the background color. - /// - /// ## Examples - /// - /// ```rust - /// # use helix_tui::style::{Color, Style}; - /// let style = Style::default().bg(Color::Blue); - /// let diff = Style::default().bg(Color::Red); - /// assert_eq!(style.patch(diff), Style::default().bg(Color::Red)); - /// ``` - pub fn bg(mut self, color: Color) -> Style { - self.bg = Some(color); - self - } - - /// Changes the text emphasis. - /// - /// When applied, it adds the given modifier to the `Style` modifiers. - /// - /// ## Examples - /// - /// ```rust - /// # use helix_tui::style::{Color, Modifier, Style}; - /// let style = Style::default().add_modifier(Modifier::BOLD); - /// let diff = Style::default().add_modifier(Modifier::ITALIC); - /// let patched = style.patch(diff); - /// assert_eq!(patched.add_modifier, Modifier::BOLD | Modifier::ITALIC); - /// assert_eq!(patched.sub_modifier, Modifier::empty()); - /// ``` - pub fn add_modifier(mut self, modifier: Modifier) -> Style { - self.sub_modifier.remove(modifier); - self.add_modifier.insert(modifier); - self - } - - /// Changes the text emphasis. - /// - /// When applied, it removes the given modifier from the `Style` modifiers. - /// - /// ## Examples - /// - /// ```rust - /// # use helix_tui::style::{Color, Modifier, Style}; - /// let style = Style::default().add_modifier(Modifier::BOLD | Modifier::ITALIC); - /// let diff = Style::default().remove_modifier(Modifier::ITALIC); - /// let patched = style.patch(diff); - /// assert_eq!(patched.add_modifier, Modifier::BOLD); - /// assert_eq!(patched.sub_modifier, Modifier::ITALIC); - /// ``` - pub fn remove_modifier(mut self, modifier: Modifier) -> Style { - self.add_modifier.remove(modifier); - self.sub_modifier.insert(modifier); - self - } - - /// Results in a combined style that is equivalent to applying the two individual styles to - /// a style one after the other. - /// - /// ## Examples - /// ``` - /// # use helix_tui::style::{Color, Modifier, Style}; - /// let style_1 = Style::default().fg(Color::Yellow); - /// let style_2 = Style::default().bg(Color::Red); - /// let combined = style_1.patch(style_2); - /// assert_eq!( - /// Style::default().patch(style_1).patch(style_2), - /// Style::default().patch(combined)); - /// ``` - pub fn patch(mut self, other: Style) -> Style { - self.fg = other.fg.or(self.fg); - self.bg = other.bg.or(self.bg); - - self.add_modifier.remove(other.sub_modifier); - self.add_modifier.insert(other.add_modifier); - self.sub_modifier.remove(other.add_modifier); - self.sub_modifier.insert(other.sub_modifier); - - self - } -} - -#[cfg(test)] -mod tests { - use super::*; - - fn styles() -> Vec<Style> { - vec![ - Style::default(), - Style::default().fg(Color::Yellow), - Style::default().bg(Color::Yellow), - Style::default().add_modifier(Modifier::BOLD), - Style::default().remove_modifier(Modifier::BOLD), - Style::default().add_modifier(Modifier::ITALIC), - Style::default().remove_modifier(Modifier::ITALIC), - Style::default().add_modifier(Modifier::ITALIC | Modifier::BOLD), - Style::default().remove_modifier(Modifier::ITALIC | Modifier::BOLD), - ] - } - - #[test] - fn combined_patch_gives_same_result_as_individual_patch() { - let styles = styles(); - for &a in &styles { - for &b in &styles { - for &c in &styles { - for &d in &styles { - let combined = a.patch(b.patch(c.patch(d))); - - assert_eq!( - Style::default().patch(a).patch(b).patch(c).patch(d), - Style::default().patch(combined) - ); - } - } - } - } - } -} |