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
This commit is contained in:
parent
00bbe2b0f8
commit
ce73b6cca0
9 changed files with 145 additions and 20 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
94
zellij-utils/src/input/theme.rs
Normal file
94
zellij-utils/src/input/theme.rs
Normal file
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue