summaryrefslogtreecommitdiff
path: root/alacritty_terminal/src/term
diff options
context:
space:
mode:
authorAnhad Singh <62820092+Andy-Python-Programmer@users.noreply.github.com>2023-05-24 06:35:58 +1000
committerGitHub <noreply@github.com>2023-05-23 20:35:58 +0000
commitcb7ad5b7e6893787c2006cc8cb09fbbc4711c0f7 (patch)
treee8c5315bb620e6d4e1564dfd6825303b498a3d6d /alacritty_terminal/src/term
parentf0379f2da751e81ba05bbf65ecb5e59590f39be4 (diff)
downloadalacritty-cb7ad5b7e6893787c2006cc8cb09fbbc4711c0f7.tar.gz
alacritty-cb7ad5b7e6893787c2006cc8cb09fbbc4711c0f7.zip
Switch to VTE's built-in ansi feature
Co-authored-by: Christian Duerr <contact@christianduerr.com>
Diffstat (limited to 'alacritty_terminal/src/term')
-rw-r--r--alacritty_terminal/src/term/cell.rs13
-rw-r--r--alacritty_terminal/src/term/color.rs104
-rw-r--r--alacritty_terminal/src/term/mod.rs76
3 files changed, 86 insertions, 107 deletions
diff --git a/alacritty_terminal/src/term/cell.rs b/alacritty_terminal/src/term/cell.rs
index 5253ede1..ddf6a745 100644
--- a/alacritty_terminal/src/term/cell.rs
+++ b/alacritty_terminal/src/term/cell.rs
@@ -3,6 +3,7 @@ use std::sync::Arc;
use bitflags::bitflags;
use serde::{Deserialize, Serialize};
+use vte::ansi::Hyperlink as VteHyperlink;
use crate::ansi::{Color, NamedColor};
use crate::grid::{self, GridCell};
@@ -57,6 +58,18 @@ impl Hyperlink {
}
}
+impl From<VteHyperlink> for Hyperlink {
+ fn from(value: VteHyperlink) -> Self {
+ Self::new(value.id, value.uri)
+ }
+}
+
+impl From<Hyperlink> for VteHyperlink {
+ fn from(val: Hyperlink) -> Self {
+ VteHyperlink { id: Some(val.id().to_owned()), uri: val.uri().to_owned() }
+ }
+}
+
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash)]
struct HyperlinkInner {
/// Identifier for the given hyperlink.
diff --git a/alacritty_terminal/src/term/color.rs b/alacritty_terminal/src/term/color.rs
index 8f193b39..b4bdba3a 100644
--- a/alacritty_terminal/src/term/color.rs
+++ b/alacritty_terminal/src/term/color.rs
@@ -1,89 +1,62 @@
use std::fmt::{self, Display, Formatter};
-use std::ops::{Add, Index, IndexMut, Mul};
+use std::ops::{Add, Deref, Index, IndexMut, Mul};
use std::str::FromStr;
-use log::trace;
use serde::de::{Error as _, Visitor};
use serde::{Deserialize, Deserializer, Serialize};
use serde_yaml::Value;
use alacritty_config_derive::SerdeReplace;
+use vte::ansi::Rgb as VteRgb;
+
use crate::ansi::NamedColor;
/// Number of terminal colors.
pub const COUNT: usize = 269;
#[derive(SerdeReplace, Debug, Eq, PartialEq, Copy, Clone, Default, Serialize)]
-pub struct Rgb {
- pub r: u8,
- pub g: u8,
- pub b: u8,
-}
+pub struct Rgb(VteRgb);
impl Rgb {
- /// Implementation of W3C's luminance
- /// [algorithm](https://www.w3.org/TR/WCAG20/#relativeluminancedef)
- fn luminance(self) -> f64 {
- let channel_luminance = |channel| {
- let channel = channel as f64 / 255.;
- if channel <= 0.03928 {
- channel / 12.92
- } else {
- f64::powf((channel + 0.055) / 1.055, 2.4)
- }
- };
-
- let r_luminance = channel_luminance(self.r);
- let g_luminance = channel_luminance(self.g);
- let b_luminance = channel_luminance(self.b);
+ #[inline]
+ pub const fn new(r: u8, g: u8, b: u8) -> Self {
+ Self(VteRgb { r, g, b })
+ }
- 0.2126 * r_luminance + 0.7152 * g_luminance + 0.0722 * b_luminance
+ #[inline]
+ pub fn as_tuple(self) -> (u8, u8, u8) {
+ (self.0.r, self.0.g, self.0.b)
}
+}
- /// Implementation of [W3C's contrast algorithm].
- ///
- /// [W3C's contrast algorithm]: https://www.w3.org/TR/WCAG20/#contrast-ratiodef
- pub fn contrast(self, other: Rgb) -> f64 {
- let self_luminance = self.luminance();
- let other_luminance = other.luminance();
+impl From<VteRgb> for Rgb {
+ fn from(value: VteRgb) -> Self {
+ Self(value)
+ }
+}
- let (darker, lighter) = if self_luminance > other_luminance {
- (other_luminance, self_luminance)
- } else {
- (self_luminance, other_luminance)
- };
+impl Deref for Rgb {
+ type Target = VteRgb;
- (lighter + 0.05) / (darker + 0.05)
+ fn deref(&self) -> &Self::Target {
+ &self.0
}
}
-// A multiply function for Rgb, as the default dim is just *2/3.
impl Mul<f32> for Rgb {
type Output = Rgb;
- fn mul(self, rhs: f32) -> Rgb {
- let result = Rgb {
- r: (f32::from(self.r) * rhs).clamp(0.0, 255.0) as u8,
- g: (f32::from(self.g) * rhs).clamp(0.0, 255.0) as u8,
- b: (f32::from(self.b) * rhs).clamp(0.0, 255.0) as u8,
- };
-
- trace!("Scaling RGB by {} from {:?} to {:?}", rhs, self, result);
-
- result
+ fn mul(self, rhs: f32) -> Self::Output {
+ Rgb(self.0 * rhs)
}
}
impl Add<Rgb> for Rgb {
type Output = Rgb;
- fn add(self, rhs: Rgb) -> Rgb {
- Rgb {
- r: self.r.saturating_add(rhs.r),
- g: self.g.saturating_add(rhs.g),
- b: self.b.saturating_add(rhs.b),
- }
+ fn add(self, rhs: Rgb) -> Self::Output {
+ Rgb(self.0 + rhs.0)
}
}
@@ -130,7 +103,7 @@ impl<'de> Deserialize<'de> for Rgb {
// Attempt to deserialize from struct form.
if let Ok(RgbDerivedDeser { r, g, b }) = RgbDerivedDeser::deserialize(value.clone()) {
- return Ok(Rgb { r, g, b });
+ return Ok(Rgb::new(r, g, b));
}
// Deserialize from hex notation (either 0xff00ff or #ff00ff).
@@ -163,7 +136,7 @@ impl FromStr for Rgb {
let g = (color & 0xff) as u8;
color >>= 8;
let r = color as u8;
- Ok(Rgb { r, g, b })
+ Ok(Rgb::new(r, g, b))
},
Err(_) => Err(()),
}
@@ -283,26 +256,3 @@ impl IndexMut<NamedColor> for Colors {
&mut self.0[index as usize]
}
}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn contrast() {
- let rgb1 = Rgb { r: 0xff, g: 0xff, b: 0xff };
- let rgb2 = Rgb { r: 0x00, g: 0x00, b: 0x00 };
- assert!((rgb1.contrast(rgb2) - 21.).abs() < f64::EPSILON);
-
- let rgb1 = Rgb { r: 0xff, g: 0xff, b: 0xff };
- assert!((rgb1.contrast(rgb1) - 1.).abs() < f64::EPSILON);
-
- let rgb1 = Rgb { r: 0xff, g: 0x00, b: 0xff };
- let rgb2 = Rgb { r: 0x00, g: 0xff, b: 0x00 };
- assert!((rgb1.contrast(rgb2) - 2.285_543_608_124_253_3).abs() < f64::EPSILON);
-
- let rgb1 = Rgb { r: 0x12, g: 0x34, b: 0x56 };
- let rgb2 = Rgb { r: 0xfe, g: 0xdc, b: 0xba };
- assert!((rgb1.contrast(rgb2) - 9.786_558_997_257_74).abs() < f64::EPSILON);
- }
-}
diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs
index bdfd6c9b..7c4abb57 100644
--- a/alacritty_terminal/src/term/mod.rs
+++ b/alacritty_terminal/src/term/mod.rs
@@ -7,6 +7,7 @@ use std::{cmp, mem, ptr, slice, str};
use bitflags::bitflags;
use log::{debug, trace};
use unicode_width::UnicodeWidthChar;
+use vte::ansi::{Hyperlink as VteHyperlink, Rgb as VteRgb};
use crate::ansi::{
self, Attr, CharsetIndex, Color, CursorShape, CursorStyle, Handler, NamedColor, StandardCharset,
@@ -16,8 +17,8 @@ use crate::event::{Event, EventListener};
use crate::grid::{Dimensions, Grid, GridIterator, Scroll};
use crate::index::{self, Boundary, Column, Direction, Line, Point, Side};
use crate::selection::{Selection, SelectionRange, SelectionType};
-use crate::term::cell::{Cell, Flags, Hyperlink, LineLength};
-use crate::term::color::{Colors, Rgb};
+use crate::term::cell::{Cell, Flags, LineLength};
+use crate::term::color::Colors;
use crate::vi_mode::{ViModeCursor, ViMotion};
pub mod cell;
@@ -1069,7 +1070,10 @@ impl<T: EventListener> Handler for Term<T> {
}
#[inline]
- fn goto(&mut self, line: Line, col: Column) {
+ fn goto(&mut self, line: i32, col: usize) {
+ let line = Line(line);
+ let col = Column(col);
+
trace!("Going to: line={}, col={}", line, col);
let (y_offset, max_y) = if self.mode.contains(TermMode::ORIGIN) {
(self.scroll_region.start, self.scroll_region.end - 1)
@@ -1085,15 +1089,15 @@ impl<T: EventListener> Handler for Term<T> {
}
#[inline]
- fn goto_line(&mut self, line: Line) {
+ fn goto_line(&mut self, line: i32) {
trace!("Going to line: {}", line);
- self.goto(line, self.grid.cursor.point.column)
+ self.goto(line, self.grid.cursor.point.column.0)
}
#[inline]
- fn goto_col(&mut self, col: Column) {
+ fn goto_col(&mut self, col: usize) {
trace!("Going to column: {}", col);
- self.goto(self.grid.cursor.point.line, col)
+ self.goto(self.grid.cursor.point.line.0, col)
}
#[inline]
@@ -1127,17 +1131,23 @@ impl<T: EventListener> Handler for Term<T> {
#[inline]
fn move_up(&mut self, lines: usize) {
trace!("Moving up: {}", lines);
- self.goto(self.grid.cursor.point.line - lines, self.grid.cursor.point.column)
+
+ let line = self.grid.cursor.point.line - lines;
+ let column = self.grid.cursor.point.column;
+ self.goto(line.0, column.0)
}
#[inline]
fn move_down(&mut self, lines: usize) {
trace!("Moving down: {}", lines);
- self.goto(self.grid.cursor.point.line + lines, self.grid.cursor.point.column)
+
+ let line = self.grid.cursor.point.line + lines;
+ let column = self.grid.cursor.point.column;
+ self.goto(line.0, column.0)
}
#[inline]
- fn move_forward(&mut self, cols: Column) {
+ fn move_forward(&mut self, cols: usize) {
trace!("Moving forward: {}", cols);
let last_column = cmp::min(self.grid.cursor.point.column + cols, self.last_column());
@@ -1149,9 +1159,9 @@ impl<T: EventListener> Handler for Term<T> {
}
#[inline]
- fn move_backward(&mut self, cols: Column) {
+ fn move_backward(&mut self, cols: usize) {
trace!("Moving backward: {}", cols);
- let column = self.grid.cursor.point.column.saturating_sub(cols.0);
+ let column = self.grid.cursor.point.column.saturating_sub(cols);
let cursor_line = self.grid.cursor.point.line.0 as usize;
self.damage.damage_line(cursor_line, column, self.grid.cursor.point.column.0);
@@ -1198,13 +1208,17 @@ impl<T: EventListener> Handler for Term<T> {
#[inline]
fn move_down_and_cr(&mut self, lines: usize) {
trace!("Moving down and cr: {}", lines);
- self.goto(self.grid.cursor.point.line + lines, Column(0))
+
+ let line = self.grid.cursor.point.line + lines;
+ self.goto(line.0, 0)
}
#[inline]
fn move_up_and_cr(&mut self, lines: usize) {
trace!("Moving up and cr: {}", lines);
- self.goto(self.grid.cursor.point.line - lines, Column(0))
+
+ let line = self.grid.cursor.point.line - lines;
+ self.goto(line.0, 0)
}
/// Insert tab at cursor position.
@@ -1362,7 +1376,7 @@ impl<T: EventListener> Handler for Term<T> {
}
#[inline]
- fn erase_chars(&mut self, count: Column) {
+ fn erase_chars(&mut self, count: usize) {
let cursor = &self.grid.cursor;
trace!("Erasing chars: count={}, col={}", count, cursor.point.column);
@@ -1479,9 +1493,11 @@ impl<T: EventListener> Handler for Term<T> {
/// Set the indexed color value.
#[inline]
- fn set_color(&mut self, index: usize, color: Rgb) {
+ fn set_color(&mut self, index: usize, color: VteRgb) {
trace!("Setting color[{}] = {:?}", index, color);
+ let color = color.into();
+
// Damage terminal if the color changed and it's not the cursor.
if index != NamedColor::Cursor as usize && self.colors[index] != Some(color) {
self.mark_fully_damaged();
@@ -1679,9 +1695,9 @@ impl<T: EventListener> Handler for Term<T> {
}
#[inline]
- fn set_hyperlink(&mut self, hyperlink: Option<Hyperlink>) {
+ fn set_hyperlink(&mut self, hyperlink: Option<VteHyperlink>) {
trace!("Setting hyperlink: {:?}", hyperlink);
- self.grid.cursor.template.set_hyperlink(hyperlink);
+ self.grid.cursor.template.set_hyperlink(hyperlink.map(|e| e.into()));
}
/// Set a terminal attribute.
@@ -1858,7 +1874,7 @@ impl<T: EventListener> Handler for Term<T> {
let screen_lines = Line(self.screen_lines() as i32);
self.scroll_region.start = cmp::min(start, screen_lines);
self.scroll_region.end = cmp::min(end, screen_lines);
- self.goto(Line(0), Column(0));
+ self.goto(0, 0);
}
#[inline]
@@ -2756,7 +2772,7 @@ mod tests {
// Reset terminal for partial damage tests since it's initialized as fully damaged.
term.reset_damage();
- term.goto(Line(1), Column(1));
+ term.goto(1, 1);
// NOTE While we can use `[Term::damage]` to access terminal damage information, in the
// following tests we will be accessing `term.damage.lines` directly to avoid adding extra
@@ -2766,13 +2782,13 @@ mod tests {
assert_eq!(term.damage.lines[1], LineDamageBounds { line: 1, left: 1, right: 1 });
term.damage.reset(num_cols);
- term.move_forward(Column(3));
+ term.move_forward(3);
assert_eq!(term.damage.lines[1], LineDamageBounds { line: 1, left: 1, right: 4 });
term.damage.reset(num_cols);
- term.move_backward(Column(8));
+ term.move_backward(8);
assert_eq!(term.damage.lines[1], LineDamageBounds { line: 1, left: 0, right: 4 });
- term.goto(Line(5), Column(5));
+ term.goto(5, 5);
term.damage.reset(num_cols);
term.backspace();
@@ -2795,7 +2811,7 @@ mod tests {
term.wrapline();
assert_eq!(term.damage.lines[6], LineDamageBounds { line: 6, left: 3, right: 3 });
assert_eq!(term.damage.lines[7], LineDamageBounds { line: 7, left: 0, right: 0 });
- term.move_forward(Column(3));
+ term.move_forward(3);
term.move_up(1);
term.damage.reset(num_cols);
@@ -2808,20 +2824,20 @@ mod tests {
assert_eq!(term.damage.lines[7], LineDamageBounds { line: 7, left: 0, right: 3 });
term.damage.reset(num_cols);
- term.erase_chars(Column(5));
+ term.erase_chars(5);
assert_eq!(term.damage.lines[7], LineDamageBounds { line: 7, left: 0, right: 5 });
term.damage.reset(num_cols);
term.delete_chars(3);
let right = term.columns() - 1;
assert_eq!(term.damage.lines[7], LineDamageBounds { line: 7, left: 0, right });
- term.move_forward(Column(term.columns()));
+ term.move_forward(term.columns());
term.damage.reset(num_cols);
term.move_backward_tabs(1);
assert_eq!(term.damage.lines[7], LineDamageBounds { line: 7, left: 8, right });
term.save_cursor_position();
- term.goto(Line(1), Column(1));
+ term.goto(1, 1);
term.damage.reset(num_cols);
term.restore_cursor_position();
@@ -2896,12 +2912,12 @@ mod tests {
term.reset_damage();
let color_index = 257;
- term.set_color(color_index, Rgb::default());
+ term.set_color(color_index, VteRgb::default());
assert!(term.damage.is_fully_damaged);
term.reset_damage();
// Setting the same color once again shouldn't trigger full damage.
- term.set_color(color_index, Rgb::default());
+ term.set_color(color_index, VteRgb::default());
assert!(!term.damage.is_fully_damaged);
term.reset_color(color_index);
@@ -2909,7 +2925,7 @@ mod tests {
term.reset_damage();
// We shouldn't trigger fully damage when cursor gets update.
- term.set_color(NamedColor::Cursor as usize, Rgb::default());
+ term.set_color(NamedColor::Cursor as usize, VteRgb::default());
assert!(!term.damage.is_fully_damaged);
// However requesting terminal damage should mark terminal as fully damaged in `Insert`