aboutsummaryrefslogtreecommitdiff
path: root/alacritty_terminal/src/term
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty_terminal/src/term')
-rw-r--r--alacritty_terminal/src/term/color.rs147
-rw-r--r--alacritty_terminal/src/term/mod.rs56
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);
}