diff options
Diffstat (limited to 'alacritty_terminal/src/term')
-rw-r--r-- | alacritty_terminal/src/term/color.rs | 147 | ||||
-rw-r--r-- | alacritty_terminal/src/term/mod.rs | 56 |
2 files changed, 150 insertions, 53 deletions
diff --git a/alacritty_terminal/src/term/color.rs b/alacritty_terminal/src/term/color.rs index 39def612..481b281c 100644 --- a/alacritty_terminal/src/term/color.rs +++ b/alacritty_terminal/src/term/color.rs @@ -1,5 +1,9 @@ use std::fmt; use std::ops::{Index, IndexMut, Mul}; +use std::str::FromStr; + +use serde::de::Visitor; +use serde::{Deserialize, Deserializer}; use crate::ansi; use crate::config::Colors; @@ -9,7 +13,7 @@ pub const COUNT: usize = 270; pub const RED: Rgb = Rgb { r: 0xff, g: 0x0, b: 0x0 }; pub const YELLOW: Rgb = Rgb { r: 0xff, g: 0xff, b: 0x0 }; -#[derive(Debug, Eq, PartialEq, Copy, Clone, Default, Serialize, Deserialize)] +#[derive(Debug, Eq, PartialEq, Copy, Clone, Default, Serialize)] pub struct Rgb { pub r: u8, pub g: u8, @@ -33,6 +37,99 @@ impl Mul<f32> for Rgb { } } +/// Deserialize an Rgb from a hex string +/// +/// This is *not* the deserialize impl for Rgb since we want a symmetric +/// serialize/deserialize impl for ref tests. +impl<'de> Deserialize<'de> for Rgb { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + struct RgbVisitor; + + // Used for deserializing reftests + #[derive(Deserialize)] + struct RgbDerivedDeser { + r: u8, + g: u8, + b: u8, + } + + impl<'a> Visitor<'a> for RgbVisitor { + type Value = Rgb; + + fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("hex color like 0xff00ff") + } + + fn visit_str<E>(self, value: &str) -> ::std::result::Result<Rgb, E> + where + E: ::serde::de::Error, + { + Rgb::from_str(&value[..]) + .map_err(|_| E::custom("failed to parse rgb; expected hex color like 0xff00ff")) + } + } + + // Return an error if the syntax is incorrect + let value = serde_yaml::Value::deserialize(deserializer)?; + + // Attempt to deserialize from struct form + if let Ok(RgbDerivedDeser { r, g, b }) = RgbDerivedDeser::deserialize(value.clone()) { + return Ok(Rgb { r, g, b }); + } + + // Deserialize from hex notation (either 0xff00ff or #ff00ff) + match value.deserialize_str(RgbVisitor) { + Ok(rgb) => Ok(rgb), + Err(err) => { + error!("Problem with config: {}; using color #000000", err); + Ok(Rgb::default()) + }, + } + } +} + +impl FromStr for Rgb { + type Err = (); + + fn from_str(s: &str) -> ::std::result::Result<Rgb, ()> { + let mut chars = s.chars(); + let mut rgb = Rgb::default(); + + macro_rules! component { + ($($c:ident),*) => { + $( + match chars.next().and_then(|c| c.to_digit(16)) { + Some(val) => rgb.$c = (val as u8) << 4, + None => return Err(()) + } + + match chars.next().and_then(|c| c.to_digit(16)) { + Some(val) => rgb.$c |= val as u8, + None => return Err(()) + } + )* + } + } + + match chars.next() { + Some('0') => { + if chars.next() != Some('x') { + return Err(()); + } + }, + Some('#') => (), + _ => return Err(()), + } + + component!(r, g, b); + + Ok(rgb) + } +} + /// List of indexed colors /// /// The first 16 entries are the standard ansi named colors. Items 16..232 are @@ -60,24 +157,24 @@ impl<'a> From<&'a Colors> for List { impl List { pub fn fill_named(&mut self, colors: &Colors) { // Normals - self[ansi::NamedColor::Black] = colors.normal.black; - self[ansi::NamedColor::Red] = colors.normal.red; - self[ansi::NamedColor::Green] = colors.normal.green; - self[ansi::NamedColor::Yellow] = colors.normal.yellow; - self[ansi::NamedColor::Blue] = colors.normal.blue; - self[ansi::NamedColor::Magenta] = colors.normal.magenta; - self[ansi::NamedColor::Cyan] = colors.normal.cyan; - self[ansi::NamedColor::White] = colors.normal.white; + self[ansi::NamedColor::Black] = colors.normal().black; + self[ansi::NamedColor::Red] = colors.normal().red; + self[ansi::NamedColor::Green] = colors.normal().green; + self[ansi::NamedColor::Yellow] = colors.normal().yellow; + self[ansi::NamedColor::Blue] = colors.normal().blue; + self[ansi::NamedColor::Magenta] = colors.normal().magenta; + self[ansi::NamedColor::Cyan] = colors.normal().cyan; + self[ansi::NamedColor::White] = colors.normal().white; // Brights - self[ansi::NamedColor::BrightBlack] = colors.bright.black; - self[ansi::NamedColor::BrightRed] = colors.bright.red; - self[ansi::NamedColor::BrightGreen] = colors.bright.green; - self[ansi::NamedColor::BrightYellow] = colors.bright.yellow; - self[ansi::NamedColor::BrightBlue] = colors.bright.blue; - self[ansi::NamedColor::BrightMagenta] = colors.bright.magenta; - self[ansi::NamedColor::BrightCyan] = colors.bright.cyan; - self[ansi::NamedColor::BrightWhite] = colors.bright.white; + self[ansi::NamedColor::BrightBlack] = colors.bright().black; + self[ansi::NamedColor::BrightRed] = colors.bright().red; + self[ansi::NamedColor::BrightGreen] = colors.bright().green; + self[ansi::NamedColor::BrightYellow] = colors.bright().yellow; + self[ansi::NamedColor::BrightBlue] = colors.bright().blue; + self[ansi::NamedColor::BrightMagenta] = colors.bright().magenta; + self[ansi::NamedColor::BrightCyan] = colors.bright().cyan; + self[ansi::NamedColor::BrightWhite] = colors.bright().white; self[ansi::NamedColor::BrightForeground] = colors.primary.bright_foreground.unwrap_or(colors.primary.foreground); @@ -106,14 +203,14 @@ impl List { }, None => { trace!("Deriving dim colors from normal colors"); - self[ansi::NamedColor::DimBlack] = colors.normal.black * 0.66; - self[ansi::NamedColor::DimRed] = colors.normal.red * 0.66; - self[ansi::NamedColor::DimGreen] = colors.normal.green * 0.66; - self[ansi::NamedColor::DimYellow] = colors.normal.yellow * 0.66; - self[ansi::NamedColor::DimBlue] = colors.normal.blue * 0.66; - self[ansi::NamedColor::DimMagenta] = colors.normal.magenta * 0.66; - self[ansi::NamedColor::DimCyan] = colors.normal.cyan * 0.66; - self[ansi::NamedColor::DimWhite] = colors.normal.white * 0.66; + self[ansi::NamedColor::DimBlack] = colors.normal().black * 0.66; + self[ansi::NamedColor::DimRed] = colors.normal().red * 0.66; + self[ansi::NamedColor::DimGreen] = colors.normal().green * 0.66; + self[ansi::NamedColor::DimYellow] = colors.normal().yellow * 0.66; + self[ansi::NamedColor::DimBlue] = colors.normal().blue * 0.66; + self[ansi::NamedColor::DimMagenta] = colors.normal().magenta * 0.66; + self[ansi::NamedColor::DimCyan] = colors.normal().cyan * 0.66; + self[ansi::NamedColor::DimWhite] = colors.normal().white * 0.66; }, } } diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs index 68a5fdcc..c83dc729 100644 --- a/alacritty_terminal/src/term/mod.rs +++ b/alacritty_terminal/src/term/mod.rs @@ -227,8 +227,8 @@ impl<'a> RenderableCellsIter<'a> { let cursor = &term.cursor.point; let cursor_visible = term.mode.contains(TermMode::SHOW_CURSOR) && grid.contains(cursor); let cursor_cell = if cursor_visible { - let offset_x = config.font().offset().x; - let offset_y = config.font().offset().y; + let offset_x = config.font.offset.x; + let offset_y = config.font.offset.y; let is_wide = grid[cursor].flags.contains(cell::Flags::WIDE_CHAR) && (cursor.col + 1) < grid.num_cols(); @@ -278,7 +278,7 @@ impl RenderableCell { let mut fg_rgb = Self::compute_fg_rgb(config, colors, cell.fg, cell.flags); let mut bg_rgb = Self::compute_bg_rgb(colors, cell.bg); - let selection_background = config.colors().selection.background; + let selection_background = config.colors.selection.background; if let (true, Some(col)) = (selected, selection_background) { // Override selection background with config colors bg_rgb = col; @@ -294,7 +294,7 @@ impl RenderableCell { } // Override selection text with config colors - if let (true, Some(col)) = (selected, config.colors().selection.text) { + if let (true, Some(col)) = (selected, config.colors.selection.text) { fg_rgb = col; } @@ -317,7 +317,7 @@ impl RenderableCell { // If no bright foreground is set, treat it like the BOLD flag doesn't exist (_, cell::Flags::DIM_BOLD) if ansi == NamedColor::Foreground - && config.colors().primary.bright_foreground.is_none() => + && config.colors.primary.bright_foreground.is_none() => { colors[NamedColor::DimForeground] }, @@ -389,7 +389,7 @@ impl<'a> Iterator for RenderableCellsIter<'a> { renderable_cell.inner = RenderableCellContent::Cursor((self.cursor_style, cursor_cell)); - if let Some(color) = self.config.cursor_cursor_color() { + if let Some(color) = self.config.colors.cursor.cursor { renderable_cell.fg = color; } @@ -401,7 +401,7 @@ impl<'a> Iterator for RenderableCellsIter<'a> { if self.cursor_style == CursorStyle::Block { std::mem::swap(&mut cell.bg, &mut cell.fg); - if let Some(color) = self.config.cursor_text_color() { + if let Some(color) = self.config.colors.cursor.text { cell.fg = color; } } @@ -563,9 +563,9 @@ fn cubic_bezier(p0: f64, p1: f64, p2: f64, p3: f64, x: f64) -> f64 { impl VisualBell { pub fn new(config: &Config) -> VisualBell { - let visual_bell_config = config.visual_bell(); + let visual_bell_config = &config.visual_bell; VisualBell { - animation: visual_bell_config.animation(), + animation: visual_bell_config.animation, duration: visual_bell_config.duration(), start_time: None, } @@ -658,8 +658,8 @@ impl VisualBell { } pub fn update_config(&mut self, config: &Config) { - let visual_bell_config = config.visual_bell(); - self.animation = visual_bell_config.animation(); + let visual_bell_config = &config.visual_bell; + self.animation = visual_bell_config.animation; self.duration = visual_bell_config.duration(); } } @@ -853,7 +853,7 @@ impl Term { let num_cols = size.cols(); let num_lines = size.lines(); - let history_size = config.scrolling().history as usize; + let history_size = config.scrolling.history() as usize; let grid = Grid::new(num_lines, num_cols, history_size, Cell::default()); let alt = Grid::new(num_lines, num_cols, 0 /* scroll history */, Cell::default()); @@ -862,7 +862,7 @@ impl Term { let scroll_region = Line(0)..grid.num_lines(); - let colors = color::List::from(config.colors()); + let colors = color::List::from(&config.colors); Term { next_title: None, @@ -874,8 +874,8 @@ impl Term { grid, alt_grid: alt, alt: false, - font_size: config.font().size(), - original_font_size: config.font().size(), + font_size: config.font.size, + original_font_size: config.font.size, active_charset: Default::default(), cursor: Default::default(), cursor_save: Default::default(), @@ -887,12 +887,12 @@ impl Term { colors, color_modified: [false; color::COUNT], original_colors: colors, - semantic_escape_chars: config.selection().semantic_escape_chars.clone(), + semantic_escape_chars: config.selection.semantic_escape_chars().to_owned(), cursor_style: None, - default_cursor_style: config.cursor_style(), + default_cursor_style: config.cursor.style, dynamic_title: config.dynamic_title(), tabspaces, - auto_scroll: config.scrolling().auto_scroll, + auto_scroll: config.scrolling.auto_scroll, message_buffer, should_exit: false, clipboard, @@ -912,20 +912,20 @@ impl Term { } pub fn update_config(&mut self, config: &Config) { - self.semantic_escape_chars = config.selection().semantic_escape_chars.clone(); - self.original_colors.fill_named(config.colors()); - self.original_colors.fill_cube(config.colors()); - self.original_colors.fill_gray_ramp(config.colors()); + self.semantic_escape_chars = config.selection.semantic_escape_chars().to_owned(); + self.original_colors.fill_named(&config.colors); + self.original_colors.fill_cube(&config.colors); + self.original_colors.fill_gray_ramp(&config.colors); for i in 0..color::COUNT { if !self.color_modified[i] { self.colors[i] = self.original_colors[i]; } } self.visual_bell.update_config(config); - self.default_cursor_style = config.cursor_style(); + self.default_cursor_style = config.cursor.style; self.dynamic_title = config.dynamic_title(); - self.auto_scroll = config.scrolling().auto_scroll; - self.grid.update_history(config.scrolling().history as usize, &self.cursor.template); + self.auto_scroll = config.scrolling.auto_scroll; + self.grid.update_history(config.scrolling.history() as usize, &self.cursor.template); } #[inline] @@ -1107,7 +1107,7 @@ impl Term { let alt_screen = self.mode.contains(TermMode::ALT_SCREEN); let selection = self.grid.selection.as_ref().and_then(|s| s.to_span(self, alt_screen)); - let cursor = if window_focused || !config.unfocused_hollow_cursor() { + let cursor = if window_focused || !config.cursor.unfocused_hollow() { self.cursor_style.unwrap_or(self.default_cursor_style) } else { CursorStyle::HollowBlock @@ -2285,7 +2285,7 @@ mod tests { let mut term: Term = Term::new(&config, size, MessageBuffer::new(), Clipboard::new_nop()); term.change_font_size(font_size); - let expected_font_size: Size = config.font().size() + Size::new(font_size); + let expected_font_size: Size = config.font.size + Size::new(font_size); assert_eq!(term.font_size, expected_font_size); } @@ -2336,7 +2336,7 @@ mod tests { term.change_font_size(10.0); term.reset_font_size(); - let expected_font_size: Size = config.font().size(); + let expected_font_size: Size = config.font.size; assert_eq!(term.font_size, expected_font_size); } |