diff options
Diffstat (limited to 'alacritty_terminal')
-rw-r--r-- | alacritty_terminal/Cargo.toml | 4 | ||||
-rw-r--r-- | alacritty_terminal/src/config/bell.rs | 72 | ||||
-rw-r--r-- | alacritty_terminal/src/config/colors.rs | 237 | ||||
-rw-r--r-- | alacritty_terminal/src/config/mod.rs | 224 | ||||
-rw-r--r-- | alacritty_terminal/src/config/scrolling.rs | 78 | ||||
-rw-r--r-- | alacritty_terminal/src/event_loop.rs | 2 | ||||
-rw-r--r-- | alacritty_terminal/src/selection.rs | 14 | ||||
-rw-r--r-- | alacritty_terminal/src/term/color.rs | 52 | ||||
-rw-r--r-- | alacritty_terminal/src/term/mod.rs | 27 |
9 files changed, 212 insertions, 498 deletions
diff --git a/alacritty_terminal/Cargo.toml b/alacritty_terminal/Cargo.toml index 64404e64..9bdccf7b 100644 --- a/alacritty_terminal/Cargo.toml +++ b/alacritty_terminal/Cargo.toml @@ -8,6 +8,10 @@ readme = "../README.md" homepage = "https://github.com/alacritty/alacritty" edition = "2018" +[dependencies.alacritty_config_derive] +path = "../alacritty_config_derive" +version = "0.1.0" + [dependencies] libc = "0.2" bitflags = "1" diff --git a/alacritty_terminal/src/config/bell.rs b/alacritty_terminal/src/config/bell.rs index 97010f31..825a7b1f 100644 --- a/alacritty_terminal/src/config/bell.rs +++ b/alacritty_terminal/src/config/bell.rs @@ -1,95 +1,45 @@ use std::time::Duration; -use log::error; -use serde::{Deserialize, Deserializer}; -use serde_yaml::Value; +use alacritty_config_derive::ConfigDeserialize; -use crate::config::{failure_default, Program, LOG_TARGET_CONFIG}; +use crate::config::Program; use crate::term::color::Rgb; -const DEFAULT_BELL_COLOR: Rgb = Rgb { r: 255, g: 255, b: 255 }; - -#[serde(default)] -#[derive(Deserialize, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] pub struct BellConfig { /// Visual bell animation function. - #[serde(deserialize_with = "failure_default")] pub animation: BellAnimation, - /// Visual bell duration in milliseconds. - #[serde(deserialize_with = "failure_default")] - duration: u16, + /// Command to run on bell. + pub command: Option<Program>, /// Visual bell flash color. - #[serde(deserialize_with = "deserialize_bell_color")] pub color: Rgb, - /// Command to run on bell. - #[serde(deserialize_with = "deserialize_bell_command")] - pub command: Option<Program>, + /// Visual bell duration in milliseconds. + duration: u16, } impl Default for BellConfig { fn default() -> Self { Self { + color: Rgb { r: 255, g: 255, b: 255 }, animation: Default::default(), - duration: Default::default(), command: Default::default(), - color: DEFAULT_BELL_COLOR, + duration: Default::default(), } } } impl BellConfig { - /// Visual bell duration in milliseconds. - #[inline] pub fn duration(&self) -> Duration { - Duration::from_millis(u64::from(self.duration)) - } -} - -fn deserialize_bell_color<'a, D>(deserializer: D) -> Result<Rgb, D::Error> -where - D: Deserializer<'a>, -{ - let value = Value::deserialize(deserializer)?; - match Rgb::deserialize(value) { - Ok(value) => Ok(value), - Err(err) => { - error!( - target: LOG_TARGET_CONFIG, - "Problem with config: {}, using default color value {}", err, DEFAULT_BELL_COLOR - ); - - Ok(DEFAULT_BELL_COLOR) - }, - } -} - -fn deserialize_bell_command<'a, D>(deserializer: D) -> Result<Option<Program>, D::Error> -where - D: Deserializer<'a>, -{ - // Deserialize to generic value. - let val = Value::deserialize(deserializer)?; - - // Accept `None` to disable the bell command. - if val.as_str().filter(|v| v.to_lowercase() == "none").is_some() { - return Ok(None); - } - - match Program::deserialize(val) { - Ok(command) => Ok(Some(command)), - Err(err) => { - error!(target: LOG_TARGET_CONFIG, "Problem with config: {}; ignoring field", err); - Ok(None) - }, + Duration::from_millis(self.duration as u64) } } /// `VisualBellAnimations` are modeled after a subset of CSS transitions and Robert /// Penner's Easing Functions. -#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq)] +#[derive(ConfigDeserialize, Clone, Copy, Debug, PartialEq, Eq)] pub enum BellAnimation { // CSS animation. Ease, diff --git a/alacritty_terminal/src/config/colors.rs b/alacritty_terminal/src/config/colors.rs index a292fde4..df52f19f 100644 --- a/alacritty_terminal/src/config/colors.rs +++ b/alacritty_terminal/src/config/colors.rs @@ -1,42 +1,24 @@ -use log::error; +use serde::de::Error as SerdeError; use serde::{Deserialize, Deserializer}; -use serde_yaml::Value; -use crate::config::{failure_default, LOG_TARGET_CONFIG}; +use alacritty_config_derive::ConfigDeserialize; + use crate::term::color::{CellRgb, Rgb}; -#[serde(default)] -#[derive(Deserialize, Clone, Debug, Default, PartialEq, Eq)] +#[derive(ConfigDeserialize, Clone, Debug, Default, PartialEq, Eq)] pub struct Colors { - #[serde(deserialize_with = "failure_default")] pub primary: PrimaryColors, - #[serde(deserialize_with = "failure_default")] - pub cursor: CursorColors, - #[serde(deserialize_with = "failure_default")] - pub vi_mode_cursor: CursorColors, - #[serde(deserialize_with = "failure_default")] + pub cursor: InvertedCellColors, + pub vi_mode_cursor: InvertedCellColors, pub selection: InvertedCellColors, - #[serde(deserialize_with = "failure_default")] - normal: NormalColors, - #[serde(deserialize_with = "failure_default")] - bright: BrightColors, - #[serde(deserialize_with = "failure_default")] - pub dim: Option<AnsiColors>, - #[serde(deserialize_with = "failure_default")] + pub normal: NormalColors, + pub bright: BrightColors, + pub dim: Option<DimColors>, pub indexed_colors: Vec<IndexedColor>, - #[serde(deserialize_with = "failure_default")] pub search: SearchColors, } impl Colors { - pub fn normal(&self) -> &AnsiColors { - &self.normal.0 - } - - pub fn bright(&self) -> &AnsiColors { - &self.bright.0 - } - pub fn search_bar_foreground(&self) -> Rgb { self.search.bar.foreground.unwrap_or(self.primary.background) } @@ -46,158 +28,88 @@ impl Colors { } } -#[derive(Deserialize, Copy, Clone, Debug, PartialEq, Eq)] -struct DefaultForegroundCellRgb(CellRgb); - -impl Default for DefaultForegroundCellRgb { - fn default() -> Self { - Self(CellRgb::CellForeground) - } -} - -#[derive(Deserialize, Copy, Clone, Debug, PartialEq, Eq)] -struct DefaultBackgroundCellRgb(CellRgb); - -impl Default for DefaultBackgroundCellRgb { - fn default() -> Self { - Self(CellRgb::CellBackground) - } -} - -#[serde(default)] -#[derive(Deserialize, Clone, Default, Debug, PartialEq, Eq)] +#[derive(Deserialize, Copy, Clone, Default, Debug, PartialEq, Eq)] pub struct IndexedColor { - #[serde(deserialize_with = "deserialize_color_index")] - pub index: u8, - #[serde(deserialize_with = "failure_default")] pub color: Rgb, -} -fn deserialize_color_index<'a, D>(deserializer: D) -> Result<u8, D::Error> -where - D: Deserializer<'a>, -{ - let value = Value::deserialize(deserializer)?; - match u8::deserialize(value) { - Ok(index) => { - if index < 16 { - error!( - target: LOG_TARGET_CONFIG, - "Problem with config: indexed_color's index is {}, but a value bigger than 15 \ - was expected; ignoring setting", - index - ); - - // Return value out of range to ignore this color. - Ok(0) - } else { - Ok(index) - } - }, - Err(err) => { - error!(target: LOG_TARGET_CONFIG, "Problem with config: {}; ignoring setting", err); + index: ColorIndex, +} - // Return value out of range to ignore this color. - Ok(0) - }, +impl IndexedColor { + #[inline] + pub fn index(&self) -> u8 { + self.index.0 } } -#[serde(default)] -#[derive(Deserialize, Debug, Copy, Clone, Default, PartialEq, Eq)] -pub struct CursorColors { - #[serde(deserialize_with = "failure_default")] - text: DefaultBackgroundCellRgb, - #[serde(deserialize_with = "failure_default")] - cursor: DefaultForegroundCellRgb, -} +#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)] +struct ColorIndex(u8); -impl CursorColors { - pub fn text(self) -> CellRgb { - self.text.0 - } +impl<'de> Deserialize<'de> for ColorIndex { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + let index = u8::deserialize(deserializer)?; - pub fn cursor(self) -> CellRgb { - self.cursor.0 + if index < 16 { + Err(SerdeError::custom( + "Config error: indexed_color's index is {}, but a value bigger than 15 was \ + expected; ignoring setting", + )) + } else { + Ok(Self(index)) + } } } -#[serde(default)] -#[derive(Deserialize, Debug, Copy, Clone, Default, PartialEq, Eq)] +#[derive(ConfigDeserialize, Debug, Copy, Clone, PartialEq, Eq)] pub struct InvertedCellColors { - #[serde(deserialize_with = "failure_default", alias = "text")] - foreground: DefaultBackgroundCellRgb, - #[serde(deserialize_with = "failure_default")] - background: DefaultForegroundCellRgb, + #[config(alias = "text")] + pub foreground: CellRgb, + #[config(alias = "cursor")] + pub background: CellRgb, } -impl InvertedCellColors { - pub fn foreground(self) -> CellRgb { - self.foreground.0 - } - - pub fn background(self) -> CellRgb { - self.background.0 +impl Default for InvertedCellColors { + fn default() -> Self { + Self { foreground: CellRgb::CellBackground, background: CellRgb::CellForeground } } } -#[serde(default)] -#[derive(Deserialize, Debug, Copy, Clone, Default, PartialEq, Eq)] +#[derive(ConfigDeserialize, Debug, Copy, Clone, Default, PartialEq, Eq)] pub struct SearchColors { - #[serde(deserialize_with = "failure_default")] - pub matches: MatchColors, - #[serde(deserialize_with = "failure_default")] pub focused_match: InvertedCellColors, - #[serde(deserialize_with = "failure_default")] + pub matches: MatchColors, bar: BarColors, } -#[serde(default)] -#[derive(Deserialize, Debug, Copy, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Debug, Copy, Clone, PartialEq, Eq)] pub struct MatchColors { - #[serde(deserialize_with = "failure_default")] pub foreground: CellRgb, - #[serde(deserialize_with = "deserialize_match_background")] pub background: CellRgb, } impl Default for MatchColors { fn default() -> Self { - Self { foreground: CellRgb::default(), background: default_match_background() } + Self { + background: CellRgb::Rgb(Rgb { r: 0xff, g: 0xff, b: 0xff }), + foreground: CellRgb::Rgb(Rgb { r: 0x00, g: 0x00, b: 0x00 }), + } } } -fn deserialize_match_background<'a, D>(deserializer: D) -> Result<CellRgb, D::Error> -where - D: Deserializer<'a>, -{ - let value = Value::deserialize(deserializer)?; - Ok(CellRgb::deserialize(value).unwrap_or_else(|_| default_match_background())) -} - -fn default_match_background() -> CellRgb { - CellRgb::Rgb(Rgb { r: 0xff, g: 0xff, b: 0xff }) -} - -#[serde(default)] -#[derive(Deserialize, Debug, Copy, Clone, Default, PartialEq, Eq)] +#[derive(ConfigDeserialize, Debug, Copy, Clone, Default, PartialEq, Eq)] pub struct BarColors { - #[serde(deserialize_with = "failure_default")] foreground: Option<Rgb>, - #[serde(deserialize_with = "failure_default")] background: Option<Rgb>, } -#[serde(default)] -#[derive(Deserialize, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] pub struct PrimaryColors { - #[serde(deserialize_with = "failure_default")] - pub background: Rgb, - #[serde(deserialize_with = "failure_default")] pub foreground: Rgb, - #[serde(deserialize_with = "failure_default")] + pub background: Rgb, pub bright_foreground: Option<Rgb>, - #[serde(deserialize_with = "failure_default")] pub dim_foreground: Option<Rgb>, } @@ -212,33 +124,21 @@ impl Default for PrimaryColors { } } -/// The 8-colors sections of config. -#[derive(Deserialize, Clone, Debug, PartialEq, Eq)] -pub struct AnsiColors { - #[serde(deserialize_with = "failure_default")] +#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] +pub struct NormalColors { pub black: Rgb, - #[serde(deserialize_with = "failure_default")] pub red: Rgb, - #[serde(deserialize_with = "failure_default")] pub green: Rgb, - #[serde(deserialize_with = "failure_default")] pub yellow: Rgb, - #[serde(deserialize_with = "failure_default")] pub blue: Rgb, - #[serde(deserialize_with = "failure_default")] pub magenta: Rgb, - #[serde(deserialize_with = "failure_default")] pub cyan: Rgb, - #[serde(deserialize_with = "failure_default")] pub white: Rgb, } -#[derive(Deserialize, Clone, Debug, PartialEq, Eq)] -struct NormalColors(AnsiColors); - impl Default for NormalColors { fn default() -> Self { - NormalColors(AnsiColors { + NormalColors { black: Rgb { r: 0x1d, g: 0x1f, b: 0x21 }, red: Rgb { r: 0xcc, g: 0x66, b: 0x66 }, green: Rgb { r: 0xb5, g: 0xbd, b: 0x68 }, @@ -247,16 +147,25 @@ impl Default for NormalColors { magenta: Rgb { r: 0xb2, g: 0x94, b: 0xbb }, cyan: Rgb { r: 0x8a, g: 0xbe, b: 0xb7 }, white: Rgb { r: 0xc5, g: 0xc8, b: 0xc6 }, - }) + } } } -#[derive(Deserialize, Clone, Debug, PartialEq, Eq)] -struct BrightColors(AnsiColors); +#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] +pub struct BrightColors { + pub black: Rgb, + pub red: Rgb, + pub green: Rgb, + pub yellow: Rgb, + pub blue: Rgb, + pub magenta: Rgb, + pub cyan: Rgb, + pub white: Rgb, +} impl Default for BrightColors { fn default() -> Self { - BrightColors(AnsiColors { + BrightColors { black: Rgb { r: 0x66, g: 0x66, b: 0x66 }, red: Rgb { r: 0xd5, g: 0x4e, b: 0x53 }, green: Rgb { r: 0xb9, g: 0xca, b: 0x4a }, @@ -265,6 +174,18 @@ impl Default for BrightColors { magenta: Rgb { r: 0xc3, g: 0x97, b: 0xd8 }, cyan: Rgb { r: 0x70, g: 0xc0, b: 0xb1 }, white: Rgb { r: 0xea, g: 0xea, b: 0xea }, - }) + } } } + +#[derive(Deserialize, Clone, Debug, PartialEq, Eq)] +pub struct DimColors { + pub black: Rgb, + pub red: Rgb, + pub green: Rgb, + pub yellow: Rgb, + pub blue: Rgb, + pub magenta: Rgb, + pub cyan: Rgb, + pub white: Rgb, +} diff --git a/alacritty_terminal/src/config/mod.rs b/alacritty_terminal/src/config/mod.rs index f3221920..cbe56057 100644 --- a/alacritty_terminal/src/config/mod.rs +++ b/alacritty_terminal/src/config/mod.rs @@ -1,11 +1,10 @@ use std::cmp::max; use std::collections::HashMap; -use std::fmt::Display; use std::path::PathBuf; -use log::error; -use serde::{Deserialize, Deserializer}; -use serde_yaml::Value; +use serde::Deserialize; + +use alacritty_config_derive::ConfigDeserialize; mod bell; mod colors; @@ -17,132 +16,103 @@ pub use crate::config::bell::{BellAnimation, BellConfig}; pub use crate::config::colors::Colors; pub use crate::config::scrolling::Scrolling; -pub const LOG_TARGET_CONFIG: &str = "alacritty_config"; -const DEFAULT_CURSOR_THICKNESS: f32 = 0.15; -const MAX_SCROLLBACK_LINES: u32 = 100_000; +pub const LOG_TARGET_CONFIG: &str = "alacritty_config_derive"; const MIN_BLINK_INTERVAL: u64 = 10; pub type MockConfig = Config<HashMap<String, serde_yaml::Value>>; /// Top-level config type. -#[derive(Debug, PartialEq, Default, Deserialize)] +#[derive(ConfigDeserialize, Debug, PartialEq, Default)] pub struct Config<T> { /// TERM env variable. - #[serde(default, deserialize_with = "failure_default")] pub env: HashMap<String, String>, /// Should draw bold text with brighter colors instead of bold font. - #[serde(default, deserialize_with = "failure_default")] - draw_bold_text_with_bright_colors: bool, + pub draw_bold_text_with_bright_colors: bool, - #[serde(default, deserialize_with = "failure_default")] pub colors: Colors, - #[serde(default, deserialize_with = "failure_default")] pub selection: Selection, /// Path to a shell program to run on startup. - #[serde(default, deserialize_with = "failure_default")] pub shell: Option<Program>, - /// Bell configuration. - #[serde(default, deserialize_with = "failure_default")] - bell: BellConfig, - /// How much scrolling history to keep. - #[serde(default, deserialize_with = "failure_default")] pub scrolling: Scrolling, /// Cursor configuration. - #[serde(default, deserialize_with = "failure_default")] pub cursor: Cursor, /// Shell startup directory. - #[serde(default, deserialize_with = "option_explicit_none")] pub working_directory: Option<PathBuf>, /// Additional configuration options not directly required by the terminal. - #[serde(flatten)] + #[config(flatten)] pub ui_config: T, /// Remain open after child process exits. - #[serde(skip)] + #[config(skip)] pub hold: bool, - // TODO: DEPRECATED + /// Bell configuration. + bell: BellConfig, + #[cfg(windows)] - #[serde(default, deserialize_with = "failure_default")] + #[config(deprecated = "recompile with winpty feature or remove this setting")] pub winpty_backend: bool, - // TODO: DEPRECATED - #[serde(default, deserialize_with = "failure_default")] + #[config(deprecated = "use `bell` instead")] pub visual_bell: Option<BellConfig>, - - // TODO: REMOVED - #[serde(default, deserialize_with = "failure_default")] - pub tabspaces: Option<usize>, } impl<T> Config<T> { #[inline] - pub fn draw_bold_text_with_bright_colors(&self) -> bool { - self.draw_bold_text_with_bright_colors - } - - #[inline] pub fn bell(&self) -> &BellConfig { self.visual_bell.as_ref().unwrap_or(&self.bell) } } -#[serde(default)] -#[derive(Deserialize, Default, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] pub struct Selection { - #[serde(deserialize_with = "failure_default")] - semantic_escape_chars: EscapeChars, - #[serde(deserialize_with = "failure_default")] + pub semantic_escape_chars: String, pub save_to_clipboard: bool, } -impl Selection { - pub fn semantic_escape_chars(&self) -> &str { - &self.semantic_escape_chars.0 - } -} - -#[derive(Deserialize, Clone, Debug, PartialEq, Eq)] -struct EscapeChars(String); - -impl Default for EscapeChars { +impl Default for Selection { fn default() -> Self { - EscapeChars(String::from(",│`|:\"' ()[]{}<>\t")) + Self { + semantic_escape_chars: String::from(",│`|:\"' ()[]{}<>\t"), + save_to_clipboard: Default::default(), + } } } -#[serde(default)] -#[derive(Deserialize, Copy, Clone, Debug, PartialEq)] +#[derive(ConfigDeserialize, Copy, Clone, Debug, PartialEq)] pub struct Cursor { - #[serde(deserialize_with = "failure_default")] pub style: ConfigCursorStyle, - #[serde(deserialize_with = "option_explicit_none")] pub vi_mode_style: Option<ConfigCursorStyle>, - #[serde(deserialize_with = "failure_default")] - blink_interval: BlinkInterval, - #[serde(deserialize_with = "deserialize_cursor_thickness")] + pub unfocused_hollow: bool, + thickness: Percentage, - #[serde(deserialize_with = "failure_default")] - unfocused_hollow: DefaultTrueBool, + blink_interval: u64, } -impl Cursor { - #[inline] - pub fn unfocused_hollow(self) -> bool { - self.unfocused_hollow.0 +impl Default for Cursor { + fn default() -> Self { + Self { + thickness: Percentage(0.15), + unfocused_hollow: true, + blink_interval: 750, + style: Default::default(), + vi_mode_style: Default::default(), + } } +} +impl Cursor { #[inline] - pub fn thickness(self) -> f64 { - self.thickness.0 as f64 + pub fn thickness(self) -> f32 { + self.thickness.as_f32() } #[inline] @@ -157,48 +127,7 @@ impl Cursor { #[inline] pub fn blink_interval(self) -> u64 { - max(self.blink_interval.0, MIN_BLINK_INTERVAL) - } -} - -impl Default for Cursor { - fn default() -> Self { - Self { - style: Default::default(), - vi_mode_style: Default::default(), - thickness: Percentage::new(DEFAULT_CURSOR_THICKNESS), - unfocused_hollow: Default::default(), - blink_interval: Default::default(), - } - } -} - -#[derive(Deserialize, Copy, Clone, Debug, PartialEq)] -struct BlinkInterval(u64); - -impl Default for BlinkInterval { - fn default() -> Self { - BlinkInterval(750) - } -} - -fn deserialize_cursor_thickness<'a, D>(deserializer: D) -> Result<Percentage, D::Error> -where - D: Deserializer<'a>, -{ - let value = Value::deserialize(deserializer)?; - match Percentage::deserialize(value) { - Ok(value) => Ok(value), - Err(err) => { - error!( - target: LOG_TARGET_CONFIG, - "Problem with config: {}, using default thickness value {}", - err, - DEFAULT_CURSOR_THICKNESS - ); - - Ok(Percentage::new(DEFAULT_CURSOR_THICKNESS)) - }, + max(self.blink_interval, MIN_BLINK_INTERVAL) } } @@ -206,17 +135,12 @@ where #[derive(Deserialize, Debug, Copy, Clone, PartialEq, Eq)] pub enum ConfigCursorStyle { Shape(CursorShape), - WithBlinking { - #[serde(default, deserialize_with = "failure_default")] - shape: CursorShape, - #[serde(default, deserialize_with = "failure_default")] - blinking: CursorBlinking, - }, + WithBlinking { shape: CursorShape, blinking: CursorBlinking }, } impl Default for ConfigCursorStyle { fn default() -> Self { - Self::WithBlinking { shape: CursorShape::default(), blinking: CursorBlinking::default() } + Self::Shape(CursorShape::default()) } } @@ -241,7 +165,7 @@ impl From<ConfigCursorStyle> for CursorStyle { } } -#[derive(Deserialize, Debug, Copy, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Debug, Copy, Clone, PartialEq, Eq)] pub enum CursorBlinking { Never, Off, @@ -275,11 +199,7 @@ impl Into<bool> for CursorBlinking { #[derive(Deserialize, Debug, Clone, PartialEq, Eq)] pub enum Program { Just(String), - WithArgs { - program: String, - #[serde(default, deserialize_with = "failure_default")] - args: Vec<String>, - }, + WithArgs { program: String, args: Vec<String> }, } impl Program { @@ -299,9 +219,15 @@ impl Program { } /// Wrapper around f32 that represents a percentage value between 0.0 and 1.0. -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Deserialize, Clone, Copy, Debug, PartialEq)] pub struct Percentage(f32); +impl Default for Percentage { + fn default() -> Self { + Percentage(1.0) + } +} + impl Percentage { pub fn new(value: f32) -> Self { Percentage(if value < 0.0 { @@ -317,55 +243,3 @@ impl Percentage { self.0 } } - -impl Default for Percentage { - fn default() -> Self { - Percentage(1.0) - } -} - -impl<'a> Deserialize<'a> for Percentage { - fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> - where - D: Deserializer<'a>, - { - Ok(Percentage::new(f32::deserialize(deserializer)?)) - } -} - -#[derive(Deserialize, Copy, Clone, Debug, PartialEq, Eq)] -struct DefaultTrueBool(bool); - -impl Default for DefaultTrueBool { - fn default() -> Self { - DefaultTrueBool(true) - } -} - -fn fallback_default<T, E>(err: E) -> T -where - T: Default, - E: Display, -{ - error!(target: LOG_TARGET_CONFIG, "Problem with config: {}; using default value", err); - T::default() -} - -pub fn failure_default<'a, D, T>(deserializer: D) -> Result<T, D::Error> -where - D: Deserializer<'a>, - T: Deserialize<'a> + Default, -{ - Ok(T::deserialize(Value::deserialize(deserializer)?).unwrap_or_else(fallback_default)) -} - -pub fn option_explicit_none<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error> -where - D: Deserializer<'de>, - T: Deserialize<'de> + Default, -{ - Ok(match Value::deserialize(deserializer)? { - Value::String(ref value) if value.to_lowercase() == "none" => None, - value => Some(T::deserialize(value).unwrap_or_else(fallback_default)), - }) -} diff --git a/alacritty_terminal/src/config/scrolling.rs b/alacritty_terminal/src/config/scrolling.rs index 136e9389..159b0f44 100644 --- a/alacritty_terminal/src/config/scrolling.rs +++ b/alacritty_terminal/src/config/scrolling.rs @@ -1,24 +1,23 @@ -use log::error; +use serde::de::Error as SerdeError; use serde::{Deserialize, Deserializer}; -use crate::config::{failure_default, LOG_TARGET_CONFIG, MAX_SCROLLBACK_LINES}; +use alacritty_config_derive::ConfigDeserialize; + +/// Maximum scrollback amount configurable. +const MAX_SCROLLBACK_LINES: u32 = 100_000; /// Struct for scrolling related settings. -#[serde(default)] -#[derive(Deserialize, Copy, Clone, Default, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Copy, Clone, Debug, PartialEq, Eq)] pub struct Scrolling { - #[serde(deserialize_with = "failure_default")] - history: ScrollingHistory, - #[serde(deserialize_with = "failure_default")] - multiplier: ScrollingMultiplier, + pub multiplier: u8, - // TODO: REMOVED - #[serde(deserialize_with = "failure_default")] - pub auto_scroll: Option<bool>, + history: ScrollingHistory, +} - // TODO: DEPRECATED - #[serde(deserialize_with = "failure_default")] - faux_multiplier: Option<ScrollingMultiplier>, +impl Default for Scrolling { + fn default() -> Self { + Self { multiplier: 3, history: Default::default() } + } } impl Scrolling { @@ -26,29 +25,12 @@ impl Scrolling { self.history.0 } - pub fn multiplier(self) -> u8 { - self.multiplier.0 - } - - pub fn faux_multiplier(self) -> Option<u8> { - self.faux_multiplier.map(|sm| sm.0) - } - // Update the history size, used in ref tests. pub fn set_history(&mut self, history: u32) { self.history = ScrollingHistory(history); } } -#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize)] -struct ScrollingMultiplier(u8); - -impl Default for ScrollingMultiplier { - fn default() -> Self { - Self(3) - } -} - #[derive(Copy, Clone, Debug, PartialEq, Eq)] struct ScrollingHistory(u32); @@ -59,33 +41,19 @@ impl Default for ScrollingHistory { } impl<'de> Deserialize<'de> for ScrollingHistory { - fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error> + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>, { - let value = serde_yaml::Value::deserialize(deserializer)?; - match u32::deserialize(value) { - Ok(lines) => { - if lines > MAX_SCROLLBACK_LINES { - error!( - target: LOG_TARGET_CONFIG, - "Problem with config: scrollback size is {}, but expected a maximum of \ - {}; using {1} instead", - lines, - MAX_SCROLLBACK_LINES, - ); - Ok(ScrollingHistory(MAX_SCROLLBACK_LINES)) - } else { - Ok(ScrollingHistory(lines)) - } - }, - Err(err) => { - error!( - target: LOG_TARGET_CONFIG, - "Problem with config: {}; using default value", err - ); - Ok(Default::default()) - }, + let lines = u32::deserialize(deserializer)?; + + if lines > MAX_SCROLLBACK_LINES { + Err(SerdeError::custom(format!( + "exceeded maximum scrolling history ({}/{})", + lines, MAX_SCROLLBACK_LINES + ))) + } else { + Ok(Self(lines)) } } } diff --git a/alacritty_terminal/src/event_loop.rs b/alacritty_terminal/src/event_loop.rs index f3d4d353..2fe3f64e 100644 --- a/alacritty_terminal/src/event_loop.rs +++ b/alacritty_terminal/src/event_loop.rs @@ -22,7 +22,7 @@ use crate::thread; use crate::tty; /// Max bytes to read from the PTY. -const MAX_READ: usize = 0x10_000; +const MAX_READ: usize = u16::max_value() as usize; /// Messages that may be sent to the `EventLoop`. #[derive(Debug)] diff --git a/alacritty_terminal/src/selection.rs b/alacritty_terminal/src/selection.rs index da44feac..9c3fa598 100644 --- a/alacritty_terminal/src/selection.rs +++ b/alacritty_terminal/src/selection.rs @@ -255,8 +255,8 @@ impl Selection { match self.ty { SelectionType::Simple => self.range_simple(start, end, num_cols), SelectionType::Block => self.range_block(start, end), - SelectionType::Semantic => Self::range_semantic(term, start.point, end.point), - SelectionType::Lines => Self::range_lines(term, start.point, end.point), + SelectionType::Semantic => Some(Self::range_semantic(term, start.point, end.point)), + SelectionType::Lines => Some(Self::range_lines(term, start.point, end.point)), } } @@ -294,7 +294,7 @@ impl Selection { term: &Term<T>, mut start: Point<usize>, mut end: Point<usize>, - ) -> Option<SelectionRange> { + ) -> SelectionRange { if start == end { if let Some(matching) = term.bracket_search(start) { if (matching.line == start.line && matching.col < start.col) @@ -305,25 +305,25 @@ impl Selection { end = matching; } - return Some(SelectionRange { start, end, is_block: false }); + return SelectionRange { start, end, is_block: false }; } } start = term.semantic_search_left(start); end = term.semantic_search_right(end); - Some(SelectionRange { start, end, is_block: false }) + SelectionRange { start, end, is_block: false } } fn range_lines<T>( term: &Term<T>, mut start: Point<usize>, mut end: Point<usize>, - ) -> Option<SelectionRange> { + ) -> SelectionRange { start = term.line_search_left(start); end = term.line_search_right(end); - Some(SelectionRange { start, end, is_block: false }) + SelectionRange { start, end, is_block: false } } fn range_simple( diff --git a/alacritty_terminal/src/term/color.rs b/alacritty_terminal/src/term/color.rs index 8626cda5..88af6de6 100644 --- a/alacritty_terminal/src/term/color.rs +++ b/alacritty_terminal/src/term/color.rs @@ -257,24 +257,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); @@ -299,14 +299,14 @@ impl List { }, None => { trace!("Deriving dim colors from normal colors"); - self[ansi::NamedColor::DimBlack] = colors.normal().black * DIM_FACTOR; - self[ansi::NamedColor::DimRed] = colors.normal().red * DIM_FACTOR; - self[ansi::NamedColor::DimGreen] = colors.normal().green * DIM_FACTOR; - self[ansi::NamedColor::DimYellow] = colors.normal().yellow * DIM_FACTOR; - self[ansi::NamedColor::DimBlue] = colors.normal().blue * DIM_FACTOR; - self[ansi::NamedColor::DimMagenta] = colors.normal().magenta * DIM_FACTOR; - self[ansi::NamedColor::DimCyan] = colors.normal().cyan * DIM_FACTOR; - self[ansi::NamedColor::DimWhite] = colors.normal().white * DIM_FACTOR; + self[ansi::NamedColor::DimBlack] = colors.normal.black * DIM_FACTOR; + self[ansi::NamedColor::DimRed] = colors.normal.red * DIM_FACTOR; + self[ansi::NamedColor::DimGreen] = colors.normal.green * DIM_FACTOR; + self[ansi::NamedColor::DimYellow] = colors.normal.yellow * DIM_FACTOR; + self[ansi::NamedColor::DimBlue] = colors.normal.blue * DIM_FACTOR; + self[ansi::NamedColor::DimMagenta] = colors.normal.magenta * DIM_FACTOR; + self[ansi::NamedColor::DimCyan] = colors.normal.cyan * DIM_FACTOR; + self[ansi::NamedColor::DimWhite] = colors.normal.white * DIM_FACTOR; }, } } @@ -319,7 +319,7 @@ impl List { for b in 0..6 { // Override colors 16..232 with the config (if present). if let Some(indexed_color) = - colors.indexed_colors.iter().find(|ic| ic.index == index as u8) + colors.indexed_colors.iter().find(|ic| ic.index() == index as u8) { self[index] = indexed_color.color; } else { @@ -346,7 +346,7 @@ impl List { // Override colors 232..256 with the config (if present). if let Some(indexed_color) = - colors.indexed_colors.iter().find(|ic| ic.index == color_index) + colors.indexed_colors.iter().find(|ic| ic.index() == color_index) { self[index] = indexed_color.color; index += 1; diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs index 154a24a2..64493bd9 100644 --- a/alacritty_terminal/src/term/mod.rs +++ b/alacritty_terminal/src/term/mod.rs @@ -157,7 +157,7 @@ impl<'a, C> Iterator for RenderableCellsIter<'a, C> { if self.cursor.rendered { return self.next_cursor_cell(); } else { - return self.next_cursor(); + return Some(self.next_cursor()); } } else { // Handle non-cursor cells. @@ -213,7 +213,7 @@ impl<'a, C> RenderableCellsIter<'a, C> { } /// Get the next renderable cell as the cursor. - fn next_cursor(&mut self) -> Option<RenderableCell> { + fn next_cursor(&mut self) -> RenderableCell { // Handle cursor. self.cursor.rendered = true; @@ -236,7 +236,7 @@ impl<'a, C> RenderableCellsIter<'a, C> { cell.fg = self.cursor.cursor_color.color(cell.fg, cell.bg); } - Some(cell) + cell } /// Check selection state of a cell. @@ -323,8 +323,8 @@ impl RenderableCell { let mut is_match = false; if iter.is_selected(point) { - let config_bg = iter.config.colors.selection.background(); - let selected_fg = iter.config.colors.selection.foreground().color(fg_rgb, bg_rgb); + let config_bg = iter.config.colors.selection.background; + let selected_fg = iter.config.colors.selection.foreground.color(fg_rgb, bg_rgb); bg_rgb = config_bg.color(fg_rgb, bg_rgb); fg_rgb = selected_fg; @@ -377,7 +377,7 @@ impl RenderableCell { _ => rgb, }, Color::Named(ansi) => { - match (config.draw_bold_text_with_bright_colors(), flags & Flags::DIM_BOLD) { + match (config.draw_bold_text_with_bright_colors, flags & Flags::DIM_BOLD) { // If no bright foreground is set, treat it like the BOLD flag doesn't exist. (_, Flags::DIM_BOLD) if ansi == NamedColor::Foreground @@ -395,7 +395,7 @@ impl RenderableCell { }, Color::Indexed(idx) => { let idx = match ( - config.draw_bold_text_with_bright_colors(), + config.draw_bold_text_with_bright_colors, flags & Flags::DIM_BOLD, idx, ) { @@ -851,7 +851,7 @@ impl<T> Term<T> { colors, color_modified: [false; color::COUNT], original_colors: colors, - semantic_escape_chars: config.selection.semantic_escape_chars().to_owned(), + semantic_escape_chars: config.selection.semantic_escape_chars.to_owned(), cursor_style: None, default_cursor_style: config.cursor.style(), vi_mode_cursor_style: config.cursor.vi_mode_style(), @@ -870,7 +870,7 @@ impl<T> Term<T> { where T: EventListener, { - self.semantic_escape_chars = config.selection.semantic_escape_chars().to_owned(); + 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); @@ -880,9 +880,6 @@ impl<T> Term<T> { } } self.visual_bell.update_config(config); - if let Some(0) = config.scrolling.faux_multiplier() { - self.mode.remove(TermMode::ALTERNATE_SCROLL); - } self.default_cursor_style = config.cursor.style(); self.vi_mode_cursor_style = config.cursor.vi_mode_style(); @@ -1418,7 +1415,7 @@ impl<T> Term<T> { let cursor_shape = if hidden { point.line = Line(0); CursorShape::Hidden - } else if !self.is_focused && config.cursor.unfocused_hollow() { + } else if !self.is_focused && config.cursor.unfocused_hollow { CursorShape::HollowBlock } else { let cursor_style = self.cursor_style.unwrap_or(self.default_cursor_style); @@ -1435,9 +1432,9 @@ impl<T> Term<T> { let cursor_color = if self.color_modified[NamedColor::Cursor as usize] { CellRgb::Rgb(self.colors[NamedColor::Cursor]) } else { - color.cursor() + color.background }; - let text_color = color.text(); + let text_color = color.foreground; // Expand across wide cell when inside wide char or spacer. let buffer_point = self.visible_to_buffer(point); |