summaryrefslogtreecommitdiff
path: root/alacritty_terminal
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty_terminal')
-rw-r--r--alacritty_terminal/Cargo.toml4
-rw-r--r--alacritty_terminal/src/config/bell.rs72
-rw-r--r--alacritty_terminal/src/config/colors.rs237
-rw-r--r--alacritty_terminal/src/config/mod.rs224
-rw-r--r--alacritty_terminal/src/config/scrolling.rs78
-rw-r--r--alacritty_terminal/src/event_loop.rs2
-rw-r--r--alacritty_terminal/src/selection.rs14
-rw-r--r--alacritty_terminal/src/term/color.rs52
-rw-r--r--alacritty_terminal/src/term/mod.rs27
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);