2018-02-07 18:51:04 +03:00
|
|
|
//! Configuration for the gui portion of the terminal
|
|
|
|
|
|
|
|
use failure::Error;
|
|
|
|
use std;
|
|
|
|
use std::fs;
|
|
|
|
use std::io::prelude::*;
|
|
|
|
use toml;
|
|
|
|
|
2018-02-07 20:23:24 +03:00
|
|
|
use term;
|
2018-02-10 19:36:34 +03:00
|
|
|
use term::color::RgbColor;
|
2018-02-07 18:51:04 +03:00
|
|
|
|
2018-02-07 20:23:24 +03:00
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
2018-02-07 18:51:04 +03:00
|
|
|
pub struct Config {
|
|
|
|
/// The font size, measured in points
|
|
|
|
#[serde(default = "default_font_size")]
|
|
|
|
pub font_size: f64,
|
|
|
|
|
|
|
|
/// The DPI to assume
|
|
|
|
#[serde(default = "default_dpi")]
|
|
|
|
pub dpi: f64,
|
|
|
|
|
2018-02-07 20:23:24 +03:00
|
|
|
/// The baseline font to use
|
2018-02-07 18:51:04 +03:00
|
|
|
#[serde(default)]
|
|
|
|
pub font: TextStyle,
|
2018-02-07 20:23:24 +03:00
|
|
|
|
|
|
|
/// An optional set of style rules to select the font based
|
|
|
|
/// on the cell attributes
|
2018-02-08 02:42:12 +03:00
|
|
|
#[serde(default)]
|
2018-02-07 20:23:24 +03:00
|
|
|
pub font_rules: Vec<StyleRule>,
|
2018-02-10 19:16:20 +03:00
|
|
|
|
|
|
|
/// The color palette
|
|
|
|
pub colors: Option<Palette>,
|
2018-02-10 20:43:54 +03:00
|
|
|
|
|
|
|
/// How many lines of scrollback you want to retain
|
|
|
|
pub scrollback_lines: Option<usize>,
|
2018-02-07 18:51:04 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
fn default_font_size() -> f64 {
|
|
|
|
10.0
|
|
|
|
}
|
|
|
|
|
|
|
|
fn default_dpi() -> f64 {
|
|
|
|
96.0
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for Config {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
|
|
|
font_size: default_font_size(),
|
|
|
|
dpi: default_dpi(),
|
|
|
|
font: TextStyle::default(),
|
2018-02-07 20:23:24 +03:00
|
|
|
font_rules: Vec::new(),
|
2018-02-10 19:16:20 +03:00
|
|
|
colors: None,
|
2018-02-10 20:43:54 +03:00
|
|
|
scrollback_lines: None,
|
2018-02-07 18:51:04 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Represents textual styling.
|
2018-02-07 20:23:24 +03:00
|
|
|
#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Hash)]
|
2018-02-07 18:51:04 +03:00
|
|
|
pub struct TextStyle {
|
|
|
|
/// A font config pattern to parse to locate the font.
|
|
|
|
/// Note that the dpi and current font_size for the terminal
|
|
|
|
/// will be set on the parsed result.
|
|
|
|
pub fontconfig_pattern: String,
|
2018-02-10 19:36:34 +03:00
|
|
|
|
|
|
|
/// If set, when rendering text that is set to the default
|
|
|
|
/// foreground color, use this color instead. This is most
|
|
|
|
/// useful in a `[[font_rules]]` section to implement changing
|
|
|
|
/// the text color for eg: bold text.
|
|
|
|
pub foreground: Option<RgbColor>,
|
2018-02-07 18:51:04 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for TextStyle {
|
|
|
|
fn default() -> Self {
|
2018-02-10 19:36:34 +03:00
|
|
|
Self {
|
|
|
|
fontconfig_pattern: "monospace".into(),
|
|
|
|
foreground: None,
|
|
|
|
}
|
2018-02-07 18:51:04 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-07 20:23:24 +03:00
|
|
|
/// Defines a rule that can be used to select a TextStyle given
|
|
|
|
/// an input CellAttributes value. The logic that applies the
|
|
|
|
/// matching can be found in src/font/mod.rs. The concept is that
|
|
|
|
/// the user can specify something like this:
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// [[font_rules]]
|
|
|
|
/// italic = true
|
|
|
|
/// font = { fontconfig_pattern = "Operator Mono SSm Lig:style=Italic" }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// The above is translated as: "if the CellAttributes have the italic bit
|
|
|
|
/// set, then use the italic style of font rather than the default", and
|
|
|
|
/// stop processing further font rules.
|
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
|
|
pub struct StyleRule {
|
|
|
|
/// If present, this rule matches when CellAttributes::intensity holds
|
|
|
|
/// a value that matches this rule. Valid values are "Bold", "Normal",
|
|
|
|
/// "Half".
|
|
|
|
pub intensity: Option<term::Intensity>,
|
|
|
|
/// If present, this rule matches when CellAttributes::underline holds
|
|
|
|
/// a value that matches this rule. Valid values are "None", "Single",
|
|
|
|
/// "Double".
|
|
|
|
pub underline: Option<term::Underline>,
|
|
|
|
/// If present, this rule matches when CellAttributes::italic holds
|
|
|
|
/// a value that matches this rule.
|
|
|
|
pub italic: Option<bool>,
|
|
|
|
/// If present, this rule matches when CellAttributes::blink holds
|
|
|
|
/// a value that matches this rule.
|
|
|
|
pub blink: Option<bool>,
|
|
|
|
/// If present, this rule matches when CellAttributes::reverse holds
|
|
|
|
/// a value that matches this rule.
|
|
|
|
pub reverse: Option<bool>,
|
|
|
|
/// If present, this rule matches when CellAttributes::strikethrough holds
|
|
|
|
/// a value that matches this rule.
|
|
|
|
pub strikethrough: Option<bool>,
|
|
|
|
/// If present, this rule matches when CellAttributes::invisible holds
|
|
|
|
/// a value that matches this rule.
|
|
|
|
pub invisible: Option<bool>,
|
|
|
|
|
|
|
|
/// When this rule matches, `font` specifies the styling to be used.
|
|
|
|
pub font: TextStyle,
|
|
|
|
}
|
|
|
|
|
2018-02-07 18:51:04 +03:00
|
|
|
impl Config {
|
|
|
|
pub fn load() -> Result<Self, Error> {
|
2018-02-21 09:08:19 +03:00
|
|
|
let home = std::env::home_dir().ok_or_else(|| format_err!("can't find home dir"))?;
|
2018-02-07 18:51:04 +03:00
|
|
|
|
|
|
|
let paths = [
|
|
|
|
home.join(".config").join("wezterm").join("wezterm.toml"),
|
|
|
|
home.join(".wezterm.toml"),
|
|
|
|
];
|
|
|
|
|
|
|
|
for p in paths.iter() {
|
|
|
|
let mut file = match fs::File::open(p) {
|
|
|
|
Ok(file) => file,
|
2018-02-21 09:08:19 +03:00
|
|
|
Err(err) => match err.kind() {
|
|
|
|
std::io::ErrorKind::NotFound => continue,
|
|
|
|
_ => bail!("Error opening {}: {:?}", p.display(), err),
|
|
|
|
},
|
2018-02-07 18:51:04 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
let mut s = String::new();
|
|
|
|
file.read_to_string(&mut s)?;
|
|
|
|
|
2018-02-21 09:08:19 +03:00
|
|
|
return toml::from_str(&s)
|
|
|
|
.map_err(|e| format_err!("Error parsing TOML from {}: {:?}", p.display(), e));
|
2018-02-07 18:51:04 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(Self::default())
|
|
|
|
}
|
|
|
|
}
|
2018-02-10 19:16:20 +03:00
|
|
|
|
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
|
|
pub struct Palette {
|
|
|
|
/// The text color to use when the attributes are reset to default
|
2018-02-10 19:36:34 +03:00
|
|
|
pub foreground: Option<RgbColor>,
|
2018-02-10 19:16:20 +03:00
|
|
|
/// The background color to use when the attributes are reset to default
|
2018-02-10 19:36:34 +03:00
|
|
|
pub background: Option<RgbColor>,
|
2018-02-10 19:16:20 +03:00
|
|
|
/// The color of the cursor
|
2018-02-10 19:36:34 +03:00
|
|
|
pub cursor: Option<RgbColor>,
|
2018-02-10 19:16:20 +03:00
|
|
|
/// A list of 8 colors corresponding to the basic ANSI palette
|
2018-02-10 19:36:34 +03:00
|
|
|
pub ansi: Option<[RgbColor; 8]>,
|
2018-02-10 19:16:20 +03:00
|
|
|
/// A list of 8 colors corresponding to bright versions of the
|
|
|
|
/// ANSI palette
|
2018-02-10 19:36:34 +03:00
|
|
|
pub brights: Option<[RgbColor; 8]>,
|
2018-02-10 19:16:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|