From 63bfe9c5e495481da97c7c566a727216de75c8a7 Mon Sep 17 00:00:00 2001 From: Jae-Heon Ji <32578710+jaeheonji@users.noreply.github.com> Date: Mon, 6 Mar 2023 23:36:12 +0900 Subject: feat: add self-provided themes (#2224) * chore: move themes to default assets * feat: add self-provided themes * fix: embed themes into binary --- zellij-utils/Cargo.toml | 1 + zellij-utils/assets/themes/catppuccin.kdl | 60 ++++++++++++++++++++++++ zellij-utils/assets/themes/dracula.kdl | 17 +++++++ zellij-utils/assets/themes/everforest-dark.kdl | 15 ++++++ zellij-utils/assets/themes/everforest-light.kdl | 15 ++++++ zellij-utils/assets/themes/gruvbox.kdl | 29 ++++++++++++ zellij-utils/assets/themes/kanagawa.kdl | 15 ++++++ zellij-utils/assets/themes/molokai-dark.kdl | 16 +++++++ zellij-utils/assets/themes/nord.kdl | 15 ++++++ zellij-utils/assets/themes/one-half-dark.kdl | 16 +++++++ zellij-utils/assets/themes/pencil.kdl | 15 ++++++ zellij-utils/assets/themes/solarized-dark.kdl | 16 +++++++ zellij-utils/assets/themes/solarized-light.kdl | 16 +++++++ zellij-utils/assets/themes/tokyo-night-dark.kdl | 15 ++++++ zellij-utils/assets/themes/tokyo-night-light.kdl | 16 +++++++ zellij-utils/assets/themes/tokyo-night-storm.kdl | 16 +++++++ zellij-utils/assets/themes/tokyo-night.kdl | 16 +++++++ zellij-utils/src/consts.rs | 2 + zellij-utils/src/kdl/mod.rs | 30 +++++++++--- zellij-utils/src/setup.rs | 47 +++++++++++-------- 20 files changed, 363 insertions(+), 25 deletions(-) create mode 100644 zellij-utils/assets/themes/catppuccin.kdl create mode 100644 zellij-utils/assets/themes/dracula.kdl create mode 100644 zellij-utils/assets/themes/everforest-dark.kdl create mode 100644 zellij-utils/assets/themes/everforest-light.kdl create mode 100644 zellij-utils/assets/themes/gruvbox.kdl create mode 100644 zellij-utils/assets/themes/kanagawa.kdl create mode 100644 zellij-utils/assets/themes/molokai-dark.kdl create mode 100644 zellij-utils/assets/themes/nord.kdl create mode 100644 zellij-utils/assets/themes/one-half-dark.kdl create mode 100644 zellij-utils/assets/themes/pencil.kdl create mode 100644 zellij-utils/assets/themes/solarized-dark.kdl create mode 100644 zellij-utils/assets/themes/solarized-light.kdl create mode 100644 zellij-utils/assets/themes/tokyo-night-dark.kdl create mode 100644 zellij-utils/assets/themes/tokyo-night-light.kdl create mode 100644 zellij-utils/assets/themes/tokyo-night-storm.kdl create mode 100644 zellij-utils/assets/themes/tokyo-night.kdl (limited to 'zellij-utils') diff --git a/zellij-utils/Cargo.toml b/zellij-utils/Cargo.toml index 766031866..0af9d7c78 100644 --- a/zellij-utils/Cargo.toml +++ b/zellij-utils/Cargo.toml @@ -38,6 +38,7 @@ miette = { version = "3.3.0", features = ["fancy"] } regex = "1.5.5" tempfile = "3.2.0" kdl = { version = "4.5.0", features = ["span"] } +include_dir = "0.7.3" #[cfg(not(target_family = "wasm"))] [target.'cfg(not(target_family = "wasm"))'.dependencies] diff --git a/zellij-utils/assets/themes/catppuccin.kdl b/zellij-utils/assets/themes/catppuccin.kdl new file mode 100644 index 000000000..b8e70bbb6 --- /dev/null +++ b/zellij-utils/assets/themes/catppuccin.kdl @@ -0,0 +1,60 @@ +// Catppuccin Theme: +// https://github.com/catppuccin/catppuccin + +themes { + catppuccin-latte { + bg "#acb0be" // Surface2 + fg "#acb0be" // Surface2 + red "#d20f39" + green "#40a02b" + blue "#1e66f5" + yellow "#df8e1d" + magenta "#ea76cb" // Pink + orange "#fe640b" // Peach + cyan "#04a5e5" // Sky + black "#dce0e8" // Crust + white "#4c4f69" // Text + } + + catppuccin-frappe { + bg "#626880" // Surface2 + fg "#c6d0f5" + red "#e78284" + green "#a6d189" + blue "#8caaee" + yellow "#e5c890" + magenta "#f4b8e4" // Pink + orange "#ef9f76" // Peach + cyan "#99d1db" // Sky + black "#292c3c" // Mantle + white "#c6d0f5" + } + + catppuccin-macchiato { + bg "#5b6078" // Surface2 + fg "#cad3f5" + red "#ed8796" + green "#a6da95" + blue "#8aadf4" + yellow "#eed49f" + magenta "#f5bde6" // Pink + orange "#f5a97f" // Peach + cyan "#91d7e3" // Sky + black "#1e2030" // Mantle + white "#cad3f5" + } + + catppuccin-mocha { + bg "#585b70" // Surface2 + fg "#cdd6f4" + red "#f38ba8" + green "#a6e3a1" + blue "#89b4fa" + yellow "#f9e2af" + magenta "#f5c2e7" // Pink + orange "#fab387" // Peach + cyan "#89dceb" // Sky + black "#181825" // Mantle + white "#cdd6f4" + } +} diff --git a/zellij-utils/assets/themes/dracula.kdl b/zellij-utils/assets/themes/dracula.kdl new file mode 100644 index 000000000..26f20504e --- /dev/null +++ b/zellij-utils/assets/themes/dracula.kdl @@ -0,0 +1,17 @@ +// From https://github.com/dracula/zellij + +themes { + dracula { + fg 248 248 242 + bg 40 42 54 + black 0 0 0 + red 255 85 85 + green 80 250 123 + yellow 241 250 140 + blue 98 114 164 + magenta 255 121 198 + cyan 139 233 253 + white 255 255 255 + orange 255 184 108 + } +} diff --git a/zellij-utils/assets/themes/everforest-dark.kdl b/zellij-utils/assets/themes/everforest-dark.kdl new file mode 100644 index 000000000..00f996fec --- /dev/null +++ b/zellij-utils/assets/themes/everforest-dark.kdl @@ -0,0 +1,15 @@ +themes { + everforest-dark { + bg "#2b3339" + fg "#d3c6aa" + black "#4b565c" + red "#e67e80" + green "#a7c080" + yellow "#dbbc7f" + blue "#7fbbb3" + magenta "#d699b6" + cyan "#83c092" + white "#d3c6aa" + orange "#FF9E64" + } +} diff --git a/zellij-utils/assets/themes/everforest-light.kdl b/zellij-utils/assets/themes/everforest-light.kdl new file mode 100644 index 000000000..0bfb9d8f6 --- /dev/null +++ b/zellij-utils/assets/themes/everforest-light.kdl @@ -0,0 +1,15 @@ +themes { + everforest-light { + bg "#fff9e8" + fg "#5c6a72" + black "#5c6a72" + red "#f85552" + green "#8da101" + yellow "#dfa000" + blue "#3a94c5" + magenta "#df69ba" + cyan "#35a77c" + white "#dfddc8" + orange "#FF9E64" + } +} diff --git a/zellij-utils/assets/themes/gruvbox.kdl b/zellij-utils/assets/themes/gruvbox.kdl new file mode 100644 index 000000000..2c7ca0c8f --- /dev/null +++ b/zellij-utils/assets/themes/gruvbox.kdl @@ -0,0 +1,29 @@ +themes { + gruvbox-light { + fg 60 56 54 + bg 251 82 75 + black 40 40 40 + red 205 75 69 + green 152 151 26 + yellow 215 153 33 + blue 69 133 136 + magenta 177 98 134 + cyan 104 157 106 + white 213 196 161 + orange 214 93 14 + } + gruvbox-dark { + fg 213 196 161 + bg 40 40 40 + black 60 56 54 + red 204 36 29 + green 152 151 26 + yellow 215 153 33 + blue 69 133 136 + magenta 177 98 134 + cyan 104 157 106 + white 251 241 199 + orange 214 93 14 + } +} + diff --git a/zellij-utils/assets/themes/kanagawa.kdl b/zellij-utils/assets/themes/kanagawa.kdl new file mode 100644 index 000000000..f0b575555 --- /dev/null +++ b/zellij-utils/assets/themes/kanagawa.kdl @@ -0,0 +1,15 @@ +themes { + kanagawa { + fg "#DCD7BA" + bg "#1F1F28" + red "#C34043" + green "#76946A" + yellow "#FF9E3B" + blue "#7E9CD8" + magenta "#957FB8" + orange "#FFA066" + cyan "#7FB4CA" + black "#16161D" + white "#DCD7BA" + } +} diff --git a/zellij-utils/assets/themes/molokai-dark.kdl b/zellij-utils/assets/themes/molokai-dark.kdl new file mode 100644 index 000000000..6fd96f9af --- /dev/null +++ b/zellij-utils/assets/themes/molokai-dark.kdl @@ -0,0 +1,16 @@ +themes { + molokai-dark { + fg 248 248 240 + bg 27 29 30 + black 0 0 0 + red 255 0 0 + green 0 140 0 + yellow 255 255 0 + blue 102 217 239 + magenta 174 129 255 + cyan 0 255 255 + white 255 255 255 + orange 253 151 31 + } +} + diff --git a/zellij-utils/assets/themes/nord.kdl b/zellij-utils/assets/themes/nord.kdl new file mode 100644 index 000000000..a56a9bfb3 --- /dev/null +++ b/zellij-utils/assets/themes/nord.kdl @@ -0,0 +1,15 @@ +themes { + nord { + fg 216 222 233 // #D8DEE9 + bg 46 52 64 // #2E3440 + black 59 66 82 // #3B4252 + red 191 97 106 // #BF616A + green 163 190 140 // #A3BE8C + yellow 235 203 139 // #EBCB8B + blue 129 161 193 // #81A1C1 + magenta 180 142 173 // #B48EAD + cyan 136 192 208 // #88C0D0 + white 229 233 240 // #E5E9F0 + orange 208 135 112 // #D08770 + } +} diff --git a/zellij-utils/assets/themes/one-half-dark.kdl b/zellij-utils/assets/themes/one-half-dark.kdl new file mode 100644 index 000000000..ade1874bf --- /dev/null +++ b/zellij-utils/assets/themes/one-half-dark.kdl @@ -0,0 +1,16 @@ +themes { + one-half-dark { + fg 220 223 228 + bg 40 44 52 + black 27 29 35 + red 227 63 76 + green 152 195 121 + yellow 229 192 123 + blue 97 175 239 + magenta 198 120 221 + cyan 86 182 194 + white 233 225 254 + orange 216 133 76 + } +} + diff --git a/zellij-utils/assets/themes/pencil.kdl b/zellij-utils/assets/themes/pencil.kdl new file mode 100644 index 000000000..166368349 --- /dev/null +++ b/zellij-utils/assets/themes/pencil.kdl @@ -0,0 +1,15 @@ +themes { + pencil-light { + fg "#005F87" + bg "#f1f1f1" + black "#f1f1f1" + red "#B6D6FD" + green "#10A778" + yellow "#A89C14" + blue "#008EC4" + magenta "#B6D6FD" + cyan "#20A5BA" + white "#424242" + orange "#D75F5F" + } +} diff --git a/zellij-utils/assets/themes/solarized-dark.kdl b/zellij-utils/assets/themes/solarized-dark.kdl new file mode 100644 index 000000000..20482f5c3 --- /dev/null +++ b/zellij-utils/assets/themes/solarized-dark.kdl @@ -0,0 +1,16 @@ +themes { + solarized-dark { + fg 253 246 227 + bg 0 43 54 + black 7 54 66 + red 220 50 47 + green 133 153 0 + yellow 181 137 0 + blue 38 139 210 + magenta 211 54 130 + cyan 42 161 152 + white 238 232 213 + orange 203 75 22 + } +} + diff --git a/zellij-utils/assets/themes/solarized-light.kdl b/zellij-utils/assets/themes/solarized-light.kdl new file mode 100644 index 000000000..93bac49b7 --- /dev/null +++ b/zellij-utils/assets/themes/solarized-light.kdl @@ -0,0 +1,16 @@ +themes { + solarized-light { + fg 101 123 131 + bg 253 246 227 + black 7 54 66 + red 220 50 47 + green 133 153 0 + yellow 181 137 0 + blue 38 139 210 + magenta 211 54 130 + cyan 42 161 152 + white 238 232 213 + orange 203 75 22 + } +} + diff --git a/zellij-utils/assets/themes/tokyo-night-dark.kdl b/zellij-utils/assets/themes/tokyo-night-dark.kdl new file mode 100644 index 000000000..6813a3360 --- /dev/null +++ b/zellij-utils/assets/themes/tokyo-night-dark.kdl @@ -0,0 +1,15 @@ +themes { + tokyo-night-dark { + fg 169 177 214 + bg 26 27 38 + black 56 62 90 + red 249 51 87 + green 158 206 106 + yellow 224 175 104 + blue 122 162 247 + magenta 187 154 247 + cyan 42 195 222 + white 192 202 245 + orange 255 158 100 + } +} diff --git a/zellij-utils/assets/themes/tokyo-night-light.kdl b/zellij-utils/assets/themes/tokyo-night-light.kdl new file mode 100644 index 000000000..3ac5fb767 --- /dev/null +++ b/zellij-utils/assets/themes/tokyo-night-light.kdl @@ -0,0 +1,16 @@ +themes { + tokyo-night-light { + fg 52 59 88 + bg 213 214 219 + black 15 15 20 + red 186 75 96 + green 72 94 48 + yellow 143 94 21 + blue 52 84 138 + magenta 90 74 120 + cyan 15 75 110 + white 130 137 172 + orange 150 80 39 + } +} + diff --git a/zellij-utils/assets/themes/tokyo-night-storm.kdl b/zellij-utils/assets/themes/tokyo-night-storm.kdl new file mode 100644 index 000000000..e727ef72f --- /dev/null +++ b/zellij-utils/assets/themes/tokyo-night-storm.kdl @@ -0,0 +1,16 @@ +themes { + tokyo-night-storm { + fg 169 177 214 + bg 36 40 59 + black 56 62 90 + red 249 51 87 + green 158 206 106 + yellow 224 175 104 + blue 122 162 247 + magenta 187 154 247 + cyan 42 195 222 + white 192 202 245 + orange 255 158 100 + } +} + diff --git a/zellij-utils/assets/themes/tokyo-night.kdl b/zellij-utils/assets/themes/tokyo-night.kdl new file mode 100644 index 000000000..4ea1a8104 --- /dev/null +++ b/zellij-utils/assets/themes/tokyo-night.kdl @@ -0,0 +1,16 @@ +themes { + tokyo-night { + fg 169 177 214 + bg 26 27 38 + black 56 62 90 + red 249 51 87 + green 158 206 106 + yellow 224 175 104 + blue 122 162 247 + magenta 187 154 247 + cyan 42 195 222 + white 192 202 245 + orange 255 158 100 + } +} + diff --git a/zellij-utils/src/consts.rs b/zellij-utils/src/consts.rs index 5709db891..7599a5ae0 100644 --- a/zellij-utils/src/consts.rs +++ b/zellij-utils/src/consts.rs @@ -1,6 +1,7 @@ //! Zellij program-wide constants. use directories_next::ProjectDirs; +use include_dir::{include_dir, Dir}; use lazy_static::lazy_static; use once_cell::sync::OnceCell; use std::path::PathBuf; @@ -15,6 +16,7 @@ pub static DEBUG_MODE: OnceCell = OnceCell::new(); pub const SYSTEM_DEFAULT_CONFIG_DIR: &str = "/etc/zellij"; pub const SYSTEM_DEFAULT_DATA_DIR_PREFIX: &str = system_default_data_dir(); +pub static ZELLIJ_THEMES_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/assets/themes"); const fn system_default_data_dir() -> &'static str { if let Some(data_dir) = std::option_env!("PREFIX") { diff --git a/zellij-utils/src/kdl/mod.rs b/zellij-utils/src/kdl/mod.rs index 64fe0bac4..6d2c5958d 100644 --- a/zellij-utils/src/kdl/mod.rs +++ b/zellij-utils/src/kdl/mod.rs @@ -1734,12 +1734,8 @@ impl Themes { Ok(themes) } - pub fn from_path(path_to_theme_file: PathBuf) -> Result { - // String is the theme name - let mut file = File::open(path_to_theme_file.clone())?; - let mut kdl_config = String::new(); - file.read_to_string(&mut kdl_config)?; - let kdl_config: KdlDocument = kdl_config.parse()?; + pub fn from_string(raw_string: String) -> Result { + let kdl_config: KdlDocument = raw_string.parse()?; let kdl_themes = kdl_config.get("themes").ok_or(ConfigError::new_kdl_error( "No theme node found in file".into(), kdl_config.span().offset(), @@ -1748,4 +1744,26 @@ impl Themes { let all_themes_in_file = Themes::from_kdl(kdl_themes)?; Ok(all_themes_in_file) } + + pub fn from_path(path_to_theme_file: PathBuf) -> Result { + // String is the theme name + let mut file = File::open(path_to_theme_file.clone())?; + let mut kdl_config = String::new(); + file.read_to_string(&mut kdl_config)?; + Themes::from_string(kdl_config) + } + + pub fn from_dir(path_to_theme_dir: PathBuf) -> Result { + let mut themes = Themes::default(); + for entry in std::fs::read_dir(path_to_theme_dir)? { + let entry = entry?; + let path = entry.path(); + if let Some(extension) = path.extension() { + if extension == "kdl" { + themes = themes.merge(Themes::from_path(path)?); + } + } + } + Ok(themes) + } } diff --git a/zellij-utils/src/setup.rs b/zellij-utils/src/setup.rs index 0086c6a99..2466083da 100644 --- a/zellij-utils/src/setup.rs +++ b/zellij-utils/src/setup.rs @@ -1,5 +1,6 @@ #[cfg(not(target_family = "wasm"))] use crate::consts::ASSET_MAP; +use crate::consts::ZELLIJ_THEMES_DIR; use crate::input::theme::Themes; use crate::{ cli::{CliArgs, Command}, @@ -51,6 +52,22 @@ fn default_config_dirs() -> Vec> { ] } +#[cfg(not(test))] +fn get_default_themes() -> Result { + let mut themes = Themes::default(); + for entry in ZELLIJ_THEMES_DIR.files() { + if let Some(entry) = entry.contents_utf8() { + themes = themes.merge(Themes::from_string(entry.to_string())?); + } + } + Ok(themes) +} + +#[cfg(test)] +fn get_default_themes() -> Result { + Ok(Themes::default()) +} + /// Looks for an existing dir, uses that, else returns a /// dir matching the config spec. pub fn get_default_data_dir() -> PathBuf { @@ -87,6 +104,7 @@ pub fn get_layout_dir(config_dir: Option) -> Option { pub fn get_theme_dir(config_dir: Option) -> Option { config_dir.map(|dir| dir.join("themes")) } + pub fn dump_asset(asset: &[u8]) -> std::io::Result<()> { std::io::stdout().write_all(asset)?; Ok(()) @@ -310,25 +328,13 @@ impl Setup { None => config.options.clone(), }; - if let Some(theme_dir) = config_options - .theme_dir - .clone() - .or_else(|| get_theme_dir(cli_args.config_dir.clone().or_else(find_default_config_dir))) - { - if theme_dir.is_dir() { - for entry in (theme_dir.read_dir()?).flatten() { - if let Some(extension) = entry.path().extension() { - if extension == "kdl" { - match Themes::from_path(entry.path()) { - Ok(themes) => config.themes = config.themes.merge(themes), - Err(e) => { - log::error!("error loading theme file: {:?}", e); - }, - } - } - } - } - } + config.themes = config.themes.merge(get_default_themes()?); + + let user_theme_dir = config_options.theme_dir.clone().or_else(|| { + get_theme_dir(cli_args.config_dir.clone().or_else(find_default_config_dir)) + }); + if let Some(user_dir) = user_theme_dir { + config.themes = config.themes.merge(Themes::from_dir(user_dir)?); } if let Some(Command::Setup(ref setup)) = &cli_args.command { @@ -514,6 +520,7 @@ impl Setup { Ok(()) } + fn generate_completion(shell: &str) { let shell: Shell = match shell.to_lowercase().parse() { Ok(shell) => shell, @@ -564,6 +571,7 @@ impl Setup { _ => {}, } } + fn parse_layout_and_override_config( cli_config_options: Option<&Options>, config: Config, @@ -593,6 +601,7 @@ impl Setup { // that needs to take precedence Layout::from_path_or_default(chosen_layout.as_ref(), layout_dir.clone(), config) } + fn handle_setup_commands(cli_args: &CliArgs) { if let Some(Command::Setup(ref setup)) = &cli_args.command { setup.from_cli().map_or_else( -- cgit v1.2.3