diff options
author | a-kenji <aks.kenji@protonmail.com> | 2021-05-29 14:53:26 +0200 |
---|---|---|
committer | a-kenji <aks.kenji@protonmail.com> | 2021-05-30 15:07:21 +0200 |
commit | ce73b6cca0d6132a57a5a7a2321e1cec8b071720 (patch) | |
tree | 2aad7fc6a2b67d2c3957f6a4cc1b9599578651a7 | |
parent | 00bbe2b0f83cb1c4f5c121bc7c10fb5d3e523bab (diff) |
Add color theme config
* add option `theme` that allows for setting of a theme,
the default is `default`
* under `themes` the themes can be described as follows:
either:
```
themes:
default:
fg: [0,0,0]
bg: [0,0,0]
black: [0,0,0]
red: [0,0,0]
green: [0,0,0]
yellow: [0,0,0]
blue: [0,0,0]
magenta: [0,0,0]
cyan: [0,0,0]
white: [0,0,0]
orange: [0,0,0]
```
or
```
themes:
default:
fg: 0
bg: 0
black: 0
red: 0
green: 0
yellow: 0
blue: 0
magenta: 0
cyan: 0
white: 0
orange: 0
```
If the key is different from default, it needs to either be specified on
start with `options --theme [THEME]`, or in the configuration file under
theme: [THEME].
closes #390
-rw-r--r-- | zellij-client/src/lib.rs | 11 | ||||
-rw-r--r-- | zellij-server/src/lib.rs | 4 | ||||
-rw-r--r-- | zellij-server/src/route.rs | 4 | ||||
-rw-r--r-- | zellij-tile/src/data.rs | 10 | ||||
-rw-r--r-- | zellij-utils/src/input/config.rs | 19 | ||||
-rw-r--r-- | zellij-utils/src/input/mod.rs | 1 | ||||
-rw-r--r-- | zellij-utils/src/input/options.rs | 10 | ||||
-rw-r--r-- | zellij-utils/src/input/theme.rs | 94 | ||||
-rw-r--r-- | zellij-utils/src/shared.rs | 12 |
9 files changed, 145 insertions, 20 deletions
diff --git a/zellij-client/src/lib.rs b/zellij-client/src/lib.rs index 3817e7908..7ea4f81ee 100644 --- a/zellij-client/src/lib.rs +++ b/zellij-client/src/lib.rs @@ -91,7 +91,14 @@ pub fn start_client( let take_snapshot = "\u{1b}[?1049h"; let bracketed_paste = "\u{1b}[?2004h"; os_input.unset_raw_mode(0); - let palette = os_input.load_palette(); + let config_options = Options::from_cli(&config.options, opts.command.clone()); + let palette = config.themes.clone().map_or_else( + || os_input.load_palette(), + |t| { + t.theme_config(&config_options) + .unwrap_or_else(|| os_input.load_palette()) + }, + ); let _ = os_input .get_stdout_writer() .write(take_snapshot.as_bytes()) @@ -102,8 +109,6 @@ pub fn start_client( .unwrap(); std::env::set_var(&"ZELLIJ", "0"); - let config_options = Options::from_cli(&config.options, opts.command.clone()); - let full_screen_ws = os_input.get_terminal_size_using_fd(0); let client_attributes = ClientAttributes { position_and_size: full_screen_ws, diff --git a/zellij-server/src/lib.rs b/zellij-server/src/lib.rs index b40362001..8f1ad73a5 100644 --- a/zellij-server/src/lib.rs +++ b/zellij-server/src/lib.rs @@ -15,7 +15,7 @@ use std::path::PathBuf; use std::sync::{Arc, Mutex, RwLock}; use std::thread; use wasmer::Store; -use zellij_tile::data::{Event, InputMode, PluginCapabilities}; +use zellij_tile::data::{Event, InputMode,Palette, PluginCapabilities}; use crate::{ os_input_output::ServerOsApi, @@ -84,6 +84,7 @@ impl ErrorInstruction for ServerInstruction { pub(crate) struct SessionMetaData { pub senders: ThreadSenders, pub capabilities: PluginCapabilities, + pub palette: Palette, screen_thread: Option<thread::JoinHandle<()>>, pty_thread: Option<thread::JoinHandle<()>>, wasm_thread: Option<thread::JoinHandle<()>>, @@ -400,6 +401,7 @@ fn init_session( to_server: None, }, capabilities, + palette: client_attributes.palette, screen_thread: Some(screen_thread), pty_thread: Some(pty_thread), wasm_thread: Some(wasm_thread), diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs index 8dcd98ffa..baac1e9c2 100644 --- a/zellij-server/src/route.rs +++ b/zellij-server/src/route.rs @@ -18,7 +18,7 @@ use zellij_utils::{ fn route_action( action: Action, session: &SessionMetaData, - os_input: &dyn ServerOsApi, + _os_input: &dyn ServerOsApi, to_server: &SenderWithContext<ServerInstruction>, ) -> bool { let mut should_break = false; @@ -34,7 +34,7 @@ fn route_action( .unwrap(); } Action::SwitchToMode(mode) => { - let palette = os_input.load_palette(); + let palette = session.palette; // TODO: use the palette from the client and remove it from the server os api // this is left here as a stop gap measure until we shift some code around // to allow for this diff --git a/zellij-tile/src/data.rs b/zellij-tile/src/data.rs index cb4b2aa01..38b20dcdb 100644 --- a/zellij-tile/src/data.rs +++ b/zellij-tile/src/data.rs @@ -71,13 +71,13 @@ impl Default for InputMode { } #[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] -pub enum Theme { +pub enum ThemeHue { Light, Dark, } -impl Default for Theme { - fn default() -> Theme { - Theme::Dark +impl Default for ThemeHue { + fn default() -> ThemeHue { + ThemeHue::Dark } } @@ -105,7 +105,7 @@ impl Default for PaletteSource { #[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, Default)] pub struct Palette { pub source: PaletteSource, - pub theme: Theme, + pub theme_hue: ThemeHue, pub fg: PaletteColor, pub bg: PaletteColor, pub black: PaletteColor, diff --git a/zellij-utils/src/input/config.rs b/zellij-utils/src/input/config.rs index c4cf0cd72..56e333f46 100644 --- a/zellij-utils/src/input/config.rs +++ b/zellij-utils/src/input/config.rs @@ -7,6 +7,7 @@ use std::path::{Path, PathBuf}; use super::keybinds::{Keybinds, KeybindsFromYaml}; use super::options::Options; +use super::theme::ThemesFromYaml; use crate::cli::{CliArgs, Command}; use crate::setup; @@ -23,6 +24,7 @@ pub struct ConfigFromYaml { #[serde(flatten)] pub options: Option<Options>, pub keybinds: Option<KeybindsFromYaml>, + pub themes: Option<ThemesFromYaml>, } /// Main configuration. @@ -30,6 +32,7 @@ pub struct ConfigFromYaml { pub struct Config { pub keybinds: Keybinds, pub options: Options, + pub themes: Option<ThemesFromYaml>, } #[derive(Debug)] @@ -48,7 +51,13 @@ impl Default for Config { fn default() -> Self { let keybinds = Keybinds::default(); let options = Options::default(); - Config { keybinds, options } + let themes = None; + + Config { + keybinds, + options, + themes, + } } } @@ -90,7 +99,13 @@ impl Config { let config_from_yaml: ConfigFromYaml = serde_yaml::from_str(&yaml_config)?; let keybinds = Keybinds::get_default_keybinds_with_config(config_from_yaml.keybinds); let options = Options::from_yaml(config_from_yaml.options); - Ok(Config { keybinds, options }) + let themes = config_from_yaml.themes; + + Ok(Config { + keybinds, + options, + themes, + }) } /// Deserializes from given path. diff --git a/zellij-utils/src/input/mod.rs b/zellij-utils/src/input/mod.rs index 068e22bc4..93a1d2255 100644 --- a/zellij-utils/src/input/mod.rs +++ b/zellij-utils/src/input/mod.rs @@ -4,6 +4,7 @@ pub mod actions; pub mod config; pub mod keybinds; pub mod options; +pub mod theme; use termion::input::TermRead; use zellij_tile::data::{InputMode, Key, ModeInfo, Palette, PluginCapabilities}; diff --git a/zellij-utils/src/input/options.rs b/zellij-utils/src/input/options.rs index f9724c20f..c6c002b6d 100644 --- a/zellij-utils/src/input/options.rs +++ b/zellij-utils/src/input/options.rs @@ -11,6 +11,9 @@ pub struct Options { /// that is compatible with more fonts #[structopt(long)] pub simplified_ui: bool, + /// Set the default theme + #[structopt(long)] + pub theme: Option<String>, } impl Options { @@ -32,7 +35,12 @@ impl Options { self.simplified_ui }; - Options { simplified_ui } + let theme = None; + + Options { + simplified_ui, + theme, + } } pub fn from_cli(&self, other: Option<Command>) -> Options { diff --git a/zellij-utils/src/input/theme.rs b/zellij-utils/src/input/theme.rs new file mode 100644 index 000000000..35bd3d87b --- /dev/null +++ b/zellij-utils/src/input/theme.rs @@ -0,0 +1,94 @@ +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +use super::options::Options; +use zellij_tile::data::{Palette, PaletteColor}; + +/// Intermediate deserialization of themes +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] +pub struct ThemesFromYaml(HashMap<String, Theme>); + +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] +struct Theme { + #[serde(flatten)] + palette: PaletteFromYaml, +} + +/// Intermediate deserialization struct +#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, Default)] +pub struct PaletteFromYaml { + pub fg: PaletteColorFromYaml, + pub bg: PaletteColorFromYaml, + pub black: PaletteColorFromYaml, + pub red: PaletteColorFromYaml, + pub green: PaletteColorFromYaml, + pub yellow: PaletteColorFromYaml, + pub blue: PaletteColorFromYaml, + pub magenta: PaletteColorFromYaml, + pub cyan: PaletteColorFromYaml, + pub white: PaletteColorFromYaml, + pub orange: PaletteColorFromYaml, +} + +/// Intermediate deserialization enum +// This is here in order to make the untagged enum work +#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] +#[serde(untagged)] +pub enum PaletteColorFromYaml { + Rgb((u8, u8, u8)), + EightBit(u8), +} + +impl Default for PaletteColorFromYaml { + fn default() -> Self { + PaletteColorFromYaml::EightBit(0) + } +} + +impl ThemesFromYaml { + pub fn theme_config(self, opts: &Options) -> Option<Palette> { + let mut from_yaml = self; + match &opts.theme { + Some(theme) => from_yaml.from_default_theme(theme.to_owned()), + None => from_yaml.from_default_theme("default".into()), + } + } + + fn get_theme(&mut self, theme: String) -> Option<Theme> { + self.0.remove(&theme) + } + + fn from_default_theme(&mut self, theme: String) -> Option<Palette> { + self.clone() + .get_theme(theme) + .map(|t| Palette::from(t.palette)) + } +} + +impl From<PaletteFromYaml> for Palette { + fn from(yaml: PaletteFromYaml) -> Self { + Palette { + fg: yaml.fg.into(), + bg: yaml.fg.into(), + black: yaml.black.into(), + red: yaml.red.into(), + green: yaml.green.into(), + yellow: yaml.yellow.into(), + blue: yaml.blue.into(), + magenta: yaml.magenta.into(), + cyan: yaml.cyan.into(), + white: yaml.white.into(), + orange: yaml.orange.into(), + ..Palette::default() + } + } +} + +impl From<PaletteColorFromYaml> for PaletteColor { + fn from(yaml: PaletteColorFromYaml) -> Self { + match yaml { + PaletteColorFromYaml::Rgb(color) => PaletteColor::Rgb(color), + PaletteColorFromYaml::EightBit(color) => PaletteColor::EightBit(color), + } + } +} diff --git a/zellij-utils/src/shared.rs b/zellij-utils/src/shared.rs index bc8b67711..a741cc10b 100644 --- a/zellij-utils/src/shared.rs +++ b/zellij-utils/src/shared.rs @@ -8,7 +8,7 @@ use colors_transform::{Color, Rgb}; use std::os::unix::fs::PermissionsExt; use std::path::Path; use std::{fs, io}; -use zellij_tile::data::{Palette, PaletteColor, PaletteSource, Theme}; +use zellij_tile::data::{Palette, PaletteColor, PaletteSource, ThemeHue}; const UNIX_PERMISSIONS: u32 = 0o700; @@ -64,7 +64,7 @@ pub fn _hex_to_rgb(hex: &str) -> (u8, u8, u8) { pub fn default_palette() -> Palette { Palette { source: PaletteSource::Default, - theme: Theme::Dark, + theme_hue: ThemeHue::Dark, fg: PaletteColor::EightBit(colors::BRIGHT_GRAY), bg: PaletteColor::EightBit(colors::GRAY), black: PaletteColor::EightBit(colors::BLACK), @@ -80,7 +80,7 @@ pub fn default_palette() -> Palette { } // Dark magic -pub fn _detect_theme(bg: PaletteColor) -> Theme { +pub fn _detect_theme_hue(bg: PaletteColor) -> ThemeHue { match bg { PaletteColor::Rgb((r, g, b)) => { // HSP, P stands for perceived brightness @@ -89,11 +89,11 @@ pub fn _detect_theme(bg: PaletteColor) -> Theme { + 0.114 * (b as f64 * b as f64)) .sqrt(); match hsp > 127.5 { - true => Theme::Light, - false => Theme::Dark, + true => ThemeHue::Light, + false => ThemeHue::Dark, } } - _ => Theme::Dark, + _ => ThemeHue::Dark, } } |