mirror of
https://github.com/wez/wezterm.git
synced 2024-11-22 22:42:48 +03:00
Allow configuring colors
This commit is contained in:
parent
4ce67c7f9a
commit
3075e47c89
15
README.md
15
README.md
@ -98,3 +98,18 @@ font = { fontconfig_pattern = "Operator Mono SSm Lig Light" }
|
||||
|
||||
The default configuration will attempt to use whichever font is returned from
|
||||
fontconfig when `monospace` is requested.
|
||||
|
||||
### Colors
|
||||
|
||||
You can configure colors with a section like this. In addition to specifying
|
||||
SVG/CSS3 color names, you can use `#RRGGBB` to specify a color code using the
|
||||
usualy hex notation; eg: `#000000` is equivalent to `black`:
|
||||
|
||||
```
|
||||
[colors]
|
||||
foreground = "silver"
|
||||
background = "black"
|
||||
cursor = "springgreen"
|
||||
ansi = ["black", "maroon", "green", "olive", "navy", "purple", "teal", "silver"]
|
||||
brights = ["grey", "red", "lime", "yellow", "blue", "fuchsia", "aqua", "white"]
|
||||
```
|
||||
|
@ -27,6 +27,9 @@ pub struct Config {
|
||||
/// on the cell attributes
|
||||
#[serde(default)]
|
||||
pub font_rules: Vec<StyleRule>,
|
||||
|
||||
/// The color palette
|
||||
pub colors: Option<Palette>,
|
||||
}
|
||||
|
||||
fn default_font_size() -> f64 {
|
||||
@ -44,6 +47,7 @@ impl Default for Config {
|
||||
dpi: default_dpi(),
|
||||
font: TextStyle::default(),
|
||||
font_rules: Vec::new(),
|
||||
colors: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -147,3 +151,44 @@ impl Config {
|
||||
Ok(Self::default())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
pub struct Palette {
|
||||
/// The text color to use when the attributes are reset to default
|
||||
pub foreground: Option<term::color::RgbColor>,
|
||||
/// The background color to use when the attributes are reset to default
|
||||
pub background: Option<term::color::RgbColor>,
|
||||
/// The color of the cursor
|
||||
pub cursor: Option<term::color::RgbColor>,
|
||||
/// A list of 8 colors corresponding to the basic ANSI palette
|
||||
pub ansi: Option<[term::color::RgbColor; 8]>,
|
||||
/// A list of 8 colors corresponding to bright versions of the
|
||||
/// ANSI palette
|
||||
pub brights: Option<[term::color::RgbColor; 8]>,
|
||||
}
|
||||
|
||||
impl From<Palette> for term::color::ColorPalette {
|
||||
fn from(cfg: Palette) -> term::color::ColorPalette {
|
||||
let mut p = term::color::ColorPalette::default();
|
||||
if let Some(foreground) = cfg.foreground {
|
||||
p.foreground = foreground;
|
||||
}
|
||||
if let Some(background) = cfg.background {
|
||||
p.background = background;
|
||||
}
|
||||
if let Some(cursor) = cfg.cursor {
|
||||
p.cursor = cursor;
|
||||
}
|
||||
if let Some(ansi) = cfg.ansi {
|
||||
for (idx, col) in ansi.iter().enumerate() {
|
||||
p.colors[idx] = *col;
|
||||
}
|
||||
}
|
||||
if let Some(brights) = cfg.brights {
|
||||
for (idx, col) in brights.iter().enumerate() {
|
||||
p.colors[idx + 8] = *col;
|
||||
}
|
||||
}
|
||||
p
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ fn run() -> Result<(), Error> {
|
||||
// First step is to figure out the font metrics so that we know how
|
||||
// big things are going to be.
|
||||
|
||||
let fontconfig = FontConfiguration::new(config);
|
||||
let fontconfig = FontConfiguration::new(config.clone());
|
||||
let font = fontconfig.default_font()?;
|
||||
|
||||
// we always load the cell_height for font 0,
|
||||
@ -132,6 +132,9 @@ fn run() -> Result<(), Error> {
|
||||
master,
|
||||
child,
|
||||
fontconfig,
|
||||
config.colors.map(|p| p.into()).unwrap_or_else(
|
||||
term::color::ColorPalette::default,
|
||||
),
|
||||
)?;
|
||||
|
||||
window.show();
|
||||
|
@ -197,6 +197,7 @@ impl<'a> TerminalWindow<'a> {
|
||||
pty: MasterPty,
|
||||
process: Child,
|
||||
fonts: FontConfiguration,
|
||||
palette: term::color::ColorPalette,
|
||||
) -> Result<TerminalWindow, Error> {
|
||||
let (cell_height, cell_width, descender) = {
|
||||
// Urgh, this is a bit repeaty, but we need to satisfy the borrow checker
|
||||
@ -237,7 +238,7 @@ impl<'a> TerminalWindow<'a> {
|
||||
terminal,
|
||||
process,
|
||||
glyph_cache: RefCell::new(HashMap::new()),
|
||||
palette: term::color::ColorPalette::default(),
|
||||
palette,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ version = "0.1.0"
|
||||
[dependencies]
|
||||
bitflags = "1.0.1"
|
||||
failure = "0.1.1"
|
||||
palette = "0.2.1"
|
||||
serde = "1.0.27"
|
||||
serde_derive = "1.0.27"
|
||||
unicode-segmentation = "1.2.0"
|
||||
|
@ -1,5 +1,8 @@
|
||||
//! Colors for attributes
|
||||
|
||||
use palette;
|
||||
use serde::{self, Deserialize, Deserializer};
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
@ -31,7 +34,62 @@ pub struct RgbColor {
|
||||
pub blue: u8,
|
||||
}
|
||||
|
||||
impl RgbColor {}
|
||||
impl RgbColor {
|
||||
/// Construct a color from discrete red, green, blue values
|
||||
/// in the range 0-255.
|
||||
pub fn new(red: u8, green: u8, blue: u8) -> Self {
|
||||
Self { red, green, blue }
|
||||
}
|
||||
|
||||
/// Construct a color from an SVG/CSS3 color name. The name
|
||||
/// must be lower case. Returns None if the supplied name is
|
||||
/// not recognized.
|
||||
/// The list of names can be found here:
|
||||
/// https://ogeon.github.io/docs/palette/master/palette/named/index.html
|
||||
pub fn from_named(name: &str) -> Option<RgbColor> {
|
||||
palette::named::from_str(name).map(|(r, g, b)| Self::new(r, g, b))
|
||||
}
|
||||
|
||||
/// Construct a color from a string of the form `#RRGGBB` where
|
||||
/// R, G and B are all hex digits.
|
||||
pub fn from_rgb_str(s: &str) -> Option<RgbColor> {
|
||||
if s.as_bytes()[0] == b'#' && s.len() == 7 {
|
||||
let mut chars = s.chars().skip(1);
|
||||
|
||||
macro_rules! digit {
|
||||
() => {
|
||||
{
|
||||
let hi = match chars.next().unwrap().to_digit(16) {
|
||||
Some(v) => (v as u8) << 4,
|
||||
None => return None
|
||||
};
|
||||
let lo = match chars.next().unwrap().to_digit(16) {
|
||||
Some(v) => v as u8,
|
||||
None => return None
|
||||
};
|
||||
hi | lo
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(Self::new(digit!(), digit!(), digit!()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for RgbColor {
|
||||
fn deserialize<D>(deserializer: D) -> Result<RgbColor, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
RgbColor::from_rgb_str(&s)
|
||||
.or_else(|| RgbColor::from_named(&s))
|
||||
.ok_or(format!("unknown color name: {}", s))
|
||||
.map_err(serde::de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
pub enum ColorAttribute {
|
||||
@ -43,10 +101,10 @@ pub enum ColorAttribute {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ColorPalette {
|
||||
colors: [RgbColor; 256],
|
||||
foreground: RgbColor,
|
||||
background: RgbColor,
|
||||
cursor: RgbColor,
|
||||
pub colors: [RgbColor; 256],
|
||||
pub foreground: RgbColor,
|
||||
pub background: RgbColor,
|
||||
pub cursor: RgbColor,
|
||||
}
|
||||
|
||||
impl ColorPalette {
|
||||
@ -131,21 +189,13 @@ impl Default for ColorPalette {
|
||||
|
||||
for idx in 0..24 {
|
||||
let grey = GREYS[idx];
|
||||
colors[232 + idx] = RgbColor {
|
||||
red: grey,
|
||||
green: grey,
|
||||
blue: grey,
|
||||
};
|
||||
colors[232 + idx] = RgbColor::new(grey, grey, grey);
|
||||
}
|
||||
|
||||
let foreground = colors[249]; // Grey70
|
||||
let background = colors[AnsiColor::Black as usize];
|
||||
|
||||
let cursor = RgbColor {
|
||||
red: 0x52,
|
||||
green: 0xad,
|
||||
blue: 0x70,
|
||||
};
|
||||
let cursor = RgbColor::new(0x52, 0xad, 0x70);
|
||||
|
||||
ColorPalette {
|
||||
colors,
|
||||
|
@ -6,6 +6,7 @@
|
||||
extern crate failure;
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
extern crate palette;
|
||||
extern crate unicode_width;
|
||||
extern crate unicode_segmentation;
|
||||
extern crate serde;
|
||||
|
Loading…
Reference in New Issue
Block a user