mirror of
https://github.com/wez/wezterm.git
synced 2024-12-22 21:01:36 +03:00
allow setting selection colors with alpha values
This commit allows the following configuration: ``` wezterm -n --config 'colors = { selection_fg = "clear", selection_bg = "rgba:50% 50% 50% 50%" }' ``` which sets the selection_bg to fully transparent, and selection_bg to 50% transparent gray. When selection_fg is fully transparent we'll use the normal fg color. When selection_bg is partially (or fully!) transparent, it will be alpha blended over the current cell background color. To support this, the config file will now accept rgba colors specified as 4 whitespace delimited numeric values. If a value ends with `%` it is interpreted as a number in the range 0-100. Otherwise, it is interpreted as a number in the range 0-255. The 4 values are red, green, blue, alpha. At this time, only the selection_fg and selection_bg settings accept alpha values. refs: #1615
This commit is contained in:
parent
240026de48
commit
8cb74c62d2
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -4701,6 +4701,7 @@ name = "wezterm-color-types"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -405,7 +405,7 @@ macro_rules! pdu {
|
|||||||
/// The overall version of the codec.
|
/// The overall version of the codec.
|
||||||
/// This must be bumped when backwards incompatible changes
|
/// This must be bumped when backwards incompatible changes
|
||||||
/// are made to the types and protocol.
|
/// are made to the types and protocol.
|
||||||
pub const CODEC_VERSION: usize = 17;
|
pub const CODEC_VERSION: usize = 18;
|
||||||
|
|
||||||
// Defines the Pdu enum.
|
// Defines the Pdu enum.
|
||||||
// Each struct has an explicit identifying number.
|
// Each struct has an explicit identifying number.
|
||||||
|
@ -7,5 +7,9 @@ repository = "https://github.com/wez/wezterm"
|
|||||||
description = "Types for working with colors"
|
description = "Types for working with colors"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
use_serde = ["serde"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
|
serde = {version="1.0", features = ["derive"], optional=true}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#[cfg(feature = "use_serde")]
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
@ -209,6 +211,7 @@ impl SrgbaPixel {
|
|||||||
|
|
||||||
/// A pixel value encoded as SRGBA RGBA values in f32 format (range: 0.0-1.0)
|
/// A pixel value encoded as SRGBA RGBA values in f32 format (range: 0.0-1.0)
|
||||||
#[derive(Copy, Clone, Debug, Default, PartialEq)]
|
#[derive(Copy, Clone, Debug, Default, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "use_serde", derive(Serialize, Deserialize))]
|
||||||
pub struct SrgbaTuple(pub f32, pub f32, pub f32, pub f32);
|
pub struct SrgbaTuple(pub f32, pub f32, pub f32, pub f32);
|
||||||
|
|
||||||
impl From<(f32, f32, f32, f32)> for SrgbaTuple {
|
impl From<(f32, f32, f32, f32)> for SrgbaTuple {
|
||||||
@ -230,6 +233,11 @@ lazy_static::lazy_static! {
|
|||||||
fn build_colors() -> HashMap<String, SrgbaTuple> {
|
fn build_colors() -> HashMap<String, SrgbaTuple> {
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
let rgb_txt = include_str!("rgb.txt");
|
let rgb_txt = include_str!("rgb.txt");
|
||||||
|
|
||||||
|
map.insert("transparent".to_string(), SrgbaTuple(0., 0., 0., 0.));
|
||||||
|
map.insert("none".to_string(), SrgbaTuple(0., 0., 0., 0.));
|
||||||
|
map.insert("clear".to_string(), SrgbaTuple(0., 0., 0., 0.));
|
||||||
|
|
||||||
for line in rgb_txt.lines() {
|
for line in rgb_txt.lines() {
|
||||||
let mut fields = line.split_ascii_whitespace();
|
let mut fields = line.split_ascii_whitespace();
|
||||||
let red = fields.next().unwrap();
|
let red = fields.next().unwrap();
|
||||||
@ -289,6 +297,16 @@ impl SrgbaTuple {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_rgba_string(self) -> String {
|
||||||
|
format!(
|
||||||
|
"rgba:{} {} {} {}%",
|
||||||
|
(self.0 * 255.) as u8,
|
||||||
|
(self.1 * 255.) as u8,
|
||||||
|
(self.2 * 255.) as u8,
|
||||||
|
(self.3 * 100.) as u8
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a string of the form `rgb:RRRR/GGGG/BBBB`
|
/// Returns a string of the form `rgb:RRRR/GGGG/BBBB`
|
||||||
pub fn to_x11_16bit_rgb_string(self) -> String {
|
pub fn to_x11_16bit_rgb_string(self) -> String {
|
||||||
format!(
|
format!(
|
||||||
@ -402,6 +420,31 @@ impl FromStr for SrgbaTuple {
|
|||||||
let blue = digit!();
|
let blue = digit!();
|
||||||
|
|
||||||
Ok(Self(red, green, blue, 1.0))
|
Ok(Self(red, green, blue, 1.0))
|
||||||
|
} else if s.starts_with("rgba:") {
|
||||||
|
let fields: Vec<_> = s[5..].split_ascii_whitespace().collect();
|
||||||
|
if fields.len() == 4 {
|
||||||
|
fn field(s: &str) -> Result<f32, ()> {
|
||||||
|
if s.ends_with('%') {
|
||||||
|
let v: f32 = s[0..s.len() - 1].parse().map_err(|_| ())?;
|
||||||
|
Ok(v / 100.)
|
||||||
|
} else {
|
||||||
|
let v: f32 = s.parse().map_err(|_| ())?;
|
||||||
|
if v > 255.0 || v < 0. {
|
||||||
|
Err(())
|
||||||
|
} else {
|
||||||
|
Ok(v / 255.)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let r: f32 = field(fields[0])?;
|
||||||
|
let g: f32 = field(fields[1])?;
|
||||||
|
let b: f32 = field(fields[2])?;
|
||||||
|
let a: f32 = field(fields[3])?;
|
||||||
|
|
||||||
|
Ok(Self(r, g, b, a))
|
||||||
|
} else {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
} else if s.starts_with("hsl:") {
|
} else if s.starts_with("hsl:") {
|
||||||
let fields: Vec<_> = s[4..].split_ascii_whitespace().collect();
|
let fields: Vec<_> = s[4..].split_ascii_whitespace().collect();
|
||||||
if fields.len() == 3 {
|
if fields.len() == 3 {
|
||||||
@ -431,7 +474,7 @@ impl FromStr for SrgbaTuple {
|
|||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(())
|
Self::from_named(s).ok_or(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -470,6 +513,20 @@ impl LinearRgba {
|
|||||||
|
|
||||||
pub const TRANSPARENT: Self = Self::with_components(0., 0., 0., 0.);
|
pub const TRANSPARENT: Self = Self::with_components(0., 0., 0., 0.);
|
||||||
|
|
||||||
|
/// Returns true if this color is fully transparent
|
||||||
|
pub fn is_fully_transparent(self) -> bool {
|
||||||
|
self.3 == 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns self, except when self is transparent, in which case returns other
|
||||||
|
pub fn when_fully_transparent(self, other: Self) -> Self {
|
||||||
|
if self.is_fully_transparent() {
|
||||||
|
other
|
||||||
|
} else {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert to an SRGB u32 pixel
|
/// Convert to an SRGB u32 pixel
|
||||||
pub fn srgba_pixel(self) -> SrgbaPixel {
|
pub fn srgba_pixel(self) -> SrgbaPixel {
|
||||||
SrgbaPixel::rgba(
|
SrgbaPixel::rgba(
|
||||||
@ -501,6 +558,20 @@ mod tests {
|
|||||||
assert_eq!(foo.to_rgb_string(), "#0015ff");
|
assert_eq!(foo.to_rgb_string(), "#0015ff");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn from_rgba() {
|
||||||
|
assert_eq!(
|
||||||
|
SrgbaTuple::from_str("clear").unwrap().to_rgba_string(),
|
||||||
|
"rgba:0 0 0 0%"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
SrgbaTuple::from_str("rgba:100% 0 0 50%")
|
||||||
|
.unwrap()
|
||||||
|
.to_rgba_string(),
|
||||||
|
"rgba:255 0 0 50%"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_rgb() {
|
fn from_rgb() {
|
||||||
assert!(SrgbaTuple::from_str("").is_err());
|
assert!(SrgbaTuple::from_str("").is_err());
|
||||||
@ -524,12 +595,4 @@ mod tests {
|
|||||||
let grey = SrgbaTuple::from_str("rgb:f0f0/f0f0/f0f0").unwrap();
|
let grey = SrgbaTuple::from_str("rgb:f0f0/f0f0/f0f0").unwrap();
|
||||||
assert_eq!(grey.to_rgb_string(), "#f0f0f0");
|
assert_eq!(grey.to_rgb_string(), "#f0f0f0");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "use_serde")]
|
|
||||||
#[test]
|
|
||||||
fn roundtrip_rgbcolor() {
|
|
||||||
let data = varbincode::serialize(&SrgbaTuple::from_named("DarkGreen").unwrap()).unwrap();
|
|
||||||
eprintln!("serialized as {:?}", data);
|
|
||||||
let _decoded: SrgbaTuple = varbincode::deserialize(data.as_slice()).unwrap();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ serde = {version="1.0", features = ["rc", "derive"]}
|
|||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
smol = "1.2"
|
smol = "1.2"
|
||||||
terminfo = "0.7"
|
terminfo = "0.7"
|
||||||
termwiz = { path = "../termwiz" }
|
termwiz = { path = "../termwiz", features=["use_serde"] }
|
||||||
toml = "0.5"
|
toml = "0.5"
|
||||||
umask = { path = "../umask" }
|
umask = { path = "../umask" }
|
||||||
unicode-segmentation = "1.8"
|
unicode-segmentation = "1.8"
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use crate::lua::{format_as_escapes, FormatItem};
|
use crate::lua::{format_as_escapes, FormatItem};
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use luahelper::impl_lua_conversion;
|
use luahelper::impl_lua_conversion;
|
||||||
|
use std::str::FromStr;
|
||||||
use termwiz::cell::CellAttributes;
|
use termwiz::cell::CellAttributes;
|
||||||
pub use termwiz::color::{ColorSpec, RgbColor};
|
pub use termwiz::color::{ColorSpec, RgbColor, SrgbaTuple};
|
||||||
|
|
||||||
#[derive(Debug, Copy, Deserialize, Serialize, Clone)]
|
#[derive(Debug, Copy, Deserialize, Serialize, Clone)]
|
||||||
pub struct HsbTransform {
|
pub struct HsbTransform {
|
||||||
@ -44,6 +45,35 @@ where
|
|||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Deserialize, Serialize, Clone, Copy)]
|
||||||
|
#[serde(try_from = "String", into = "String")]
|
||||||
|
pub struct RgbaColor {
|
||||||
|
#[serde(flatten)]
|
||||||
|
color: SrgbaTuple,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<String> for RgbaColor {
|
||||||
|
fn into(self) -> String {
|
||||||
|
self.color.to_rgb_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<SrgbaTuple> for RgbaColor {
|
||||||
|
fn into(self) -> SrgbaTuple {
|
||||||
|
self.color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::TryFrom<String> for RgbaColor {
|
||||||
|
type Error = anyhow::Error;
|
||||||
|
fn try_from(s: String) -> anyhow::Result<RgbaColor> {
|
||||||
|
Ok(RgbaColor {
|
||||||
|
color: SrgbaTuple::from_str(&s)
|
||||||
|
.map_err(|_| anyhow::anyhow!("failed to parse {} as RgbaColor", &s))?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Deserialize, Serialize, Clone)]
|
#[derive(Default, Debug, Deserialize, Serialize, Clone)]
|
||||||
pub struct Palette {
|
pub struct Palette {
|
||||||
/// The text color to use when the attributes are reset to default
|
/// The text color to use when the attributes are reset to default
|
||||||
@ -55,8 +85,8 @@ pub struct Palette {
|
|||||||
pub cursor_bg: Option<RgbColor>,
|
pub cursor_bg: Option<RgbColor>,
|
||||||
pub cursor_border: Option<RgbColor>,
|
pub cursor_border: Option<RgbColor>,
|
||||||
/// The color of selected text
|
/// The color of selected text
|
||||||
pub selection_fg: Option<RgbColor>,
|
pub selection_fg: Option<RgbaColor>,
|
||||||
pub selection_bg: Option<RgbColor>,
|
pub selection_bg: Option<RgbaColor>,
|
||||||
/// A list of 8 colors corresponding to the basic ANSI palette
|
/// A list of 8 colors corresponding to the basic ANSI palette
|
||||||
pub ansi: Option<[RgbColor; 8]>,
|
pub ansi: Option<[RgbColor; 8]>,
|
||||||
/// A list of 8 colors corresponding to bright versions of the
|
/// A list of 8 colors corresponding to bright versions of the
|
||||||
@ -87,7 +117,7 @@ impl From<Palette> for wezterm_term::color::ColorPalette {
|
|||||||
macro_rules! apply_color {
|
macro_rules! apply_color {
|
||||||
($name:ident) => {
|
($name:ident) => {
|
||||||
if let Some($name) = cfg.$name {
|
if let Some($name) = cfg.$name {
|
||||||
p.$name = $name;
|
p.$name = $name.into();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::result::Result;
|
use std::result::Result;
|
||||||
pub use termwiz::color::{AnsiColor, ColorAttribute, RgbColor};
|
pub use termwiz::color::{AnsiColor, ColorAttribute, RgbColor, SrgbaTuple};
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
#[derive(Clone, PartialEq, Eq)]
|
||||||
pub struct Palette256(pub [RgbColor; 256]);
|
pub struct Palette256(pub [RgbColor; 256]);
|
||||||
@ -43,7 +43,7 @@ impl std::iter::FromIterator<RgbColor> for Palette256 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
#[cfg_attr(feature = "use_serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "use_serde", derive(Serialize, Deserialize))]
|
||||||
pub struct ColorPalette {
|
pub struct ColorPalette {
|
||||||
pub colors: Palette256,
|
pub colors: Palette256,
|
||||||
@ -52,8 +52,8 @@ pub struct ColorPalette {
|
|||||||
pub cursor_fg: RgbColor,
|
pub cursor_fg: RgbColor,
|
||||||
pub cursor_bg: RgbColor,
|
pub cursor_bg: RgbColor,
|
||||||
pub cursor_border: RgbColor,
|
pub cursor_border: RgbColor,
|
||||||
pub selection_fg: RgbColor,
|
pub selection_fg: SrgbaTuple,
|
||||||
pub selection_bg: RgbColor,
|
pub selection_bg: SrgbaTuple,
|
||||||
pub scrollbar_thumb: RgbColor,
|
pub scrollbar_thumb: RgbColor,
|
||||||
pub split: RgbColor,
|
pub split: RgbColor,
|
||||||
}
|
}
|
||||||
@ -114,8 +114,8 @@ impl ColorPalette {
|
|||||||
cursor_fg: grey_out(self.cursor_fg),
|
cursor_fg: grey_out(self.cursor_fg),
|
||||||
cursor_bg: grey_out(self.cursor_bg),
|
cursor_bg: grey_out(self.cursor_bg),
|
||||||
cursor_border: grey_out(self.cursor_border),
|
cursor_border: grey_out(self.cursor_border),
|
||||||
selection_fg: grey_out(self.selection_fg),
|
selection_fg: grey_out(self.selection_fg.into()).into(),
|
||||||
selection_bg: grey_out(self.selection_bg),
|
selection_bg: grey_out(self.selection_bg.into()).into(),
|
||||||
scrollbar_thumb: grey_out(self.scrollbar_thumb),
|
scrollbar_thumb: grey_out(self.scrollbar_thumb),
|
||||||
split: grey_out(self.split),
|
split: grey_out(self.split),
|
||||||
}
|
}
|
||||||
@ -206,8 +206,8 @@ impl ColorPalette {
|
|||||||
let cursor_border = RgbColor::new_8bpc(0x52, 0xad, 0x70);
|
let cursor_border = RgbColor::new_8bpc(0x52, 0xad, 0x70);
|
||||||
let cursor_fg = colors[AnsiColor::Black as usize];
|
let cursor_fg = colors[AnsiColor::Black as usize];
|
||||||
|
|
||||||
let selection_fg = colors[AnsiColor::Black as usize];
|
let selection_fg = colors[AnsiColor::Black as usize].into();
|
||||||
let selection_bg = RgbColor::new_8bpc(0xff, 0xfa, 0xcd);
|
let selection_bg = RgbColor::new_8bpc(0xff, 0xfa, 0xcd).into();
|
||||||
|
|
||||||
let scrollbar_thumb = RgbColor::new_8bpc(0x22, 0x22, 0x22);
|
let scrollbar_thumb = RgbColor::new_8bpc(0x22, 0x22, 0x22);
|
||||||
let split = RgbColor::new_8bpc(0x44, 0x44, 0x44);
|
let split = RgbColor::new_8bpc(0x44, 0x44, 0x44);
|
||||||
|
@ -800,13 +800,13 @@ impl<'a> Performer<'a> {
|
|||||||
ColorOrQuery::Query => {
|
ColorOrQuery::Query => {
|
||||||
let response = OperatingSystemCommand::ChangeDynamicColors(
|
let response = OperatingSystemCommand::ChangeDynamicColors(
|
||||||
which_color,
|
which_color,
|
||||||
vec![ColorOrQuery::Color(self.palette().$name)],
|
vec![ColorOrQuery::Color(self.palette().$name.into())],
|
||||||
);
|
);
|
||||||
log::trace!("Color Query response {:?}", response);
|
log::trace!("Color Query response {:?}", response);
|
||||||
write!(self.writer, "{}", response).ok();
|
write!(self.writer, "{}", response).ok();
|
||||||
self.writer.flush().ok();
|
self.writer.flush().ok();
|
||||||
}
|
}
|
||||||
ColorOrQuery::Color(c) => self.palette_mut().$name = c,
|
ColorOrQuery::Color(c) => self.palette_mut().$name = c.into(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ wezterm-color-types = { path = "../color-types" }
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
widgets = ["cassowary", "fnv"]
|
widgets = ["cassowary", "fnv"]
|
||||||
use_serde = ["serde"]
|
use_serde = ["serde", "wezterm-color-types/use_serde"]
|
||||||
use_image = ["image"]
|
use_image = ["image"]
|
||||||
docs = ["widgets", "use_serde"]
|
docs = ["widgets", "use_serde"]
|
||||||
|
|
||||||
|
@ -60,6 +60,12 @@ pub struct RgbColor {
|
|||||||
bits: u32,
|
bits: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Into<SrgbaTuple> for RgbColor {
|
||||||
|
fn into(self) -> SrgbaTuple {
|
||||||
|
self.to_tuple_rgba()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl RgbColor {
|
impl RgbColor {
|
||||||
/// Construct a color from discrete red, green, blue values
|
/// Construct a color from discrete red, green, blue values
|
||||||
/// in the range 0-255.
|
/// in the range 0-255.
|
||||||
|
@ -1276,8 +1276,8 @@ impl super::TermWindow {
|
|||||||
let selrange = self.selection(pos.pane.pane_id()).range.clone();
|
let selrange = self.selection(pos.pane.pane_id()).range.clone();
|
||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let selection_fg = rgbcolor_to_window_color(palette.selection_fg);
|
let selection_fg = palette.selection_fg.to_linear();
|
||||||
let selection_bg = rgbcolor_to_window_color(palette.selection_bg);
|
let selection_bg = palette.selection_bg.to_linear();
|
||||||
let cursor_fg = rgbcolor_to_window_color(palette.cursor_fg);
|
let cursor_fg = rgbcolor_to_window_color(palette.cursor_fg);
|
||||||
let cursor_bg = rgbcolor_to_window_color(palette.cursor_bg);
|
let cursor_bg = rgbcolor_to_window_color(palette.cursor_bg);
|
||||||
for (line_idx, line) in lines.iter().enumerate() {
|
for (line_idx, line) in lines.iter().enumerate() {
|
||||||
@ -2495,9 +2495,11 @@ impl super::TermWindow {
|
|||||||
visibility,
|
visibility,
|
||||||
) {
|
) {
|
||||||
// Selected text overrides colors
|
// Selected text overrides colors
|
||||||
(true, _, _, CursorVisibility::Hidden) => {
|
(true, _, _, CursorVisibility::Hidden) => (
|
||||||
(params.selection_fg, params.selection_bg, params.cursor_bg)
|
params.selection_fg.when_fully_transparent(params.fg_color),
|
||||||
}
|
params.selection_bg,
|
||||||
|
params.cursor_bg,
|
||||||
|
),
|
||||||
// block Cursor cell overrides colors
|
// block Cursor cell overrides colors
|
||||||
(
|
(
|
||||||
_,
|
_,
|
||||||
|
Loading…
Reference in New Issue
Block a user