From 8b49ef6cb2530bce721ea67142ad7a3ac41916bb Mon Sep 17 00:00:00 2001 From: sxyazi Date: Thu, 12 Oct 2023 09:21:31 +0800 Subject: [PATCH] .. --- app/src/help/bindings.rs | 12 +-- app/src/help/layout.rs | 5 +- app/src/input/input.rs | 8 +- app/src/select/select.rs | 10 +-- app/src/tasks/layout.rs | 6 +- app/src/which/layout.rs | 5 +- app/src/which/side.rs | 8 +- config/preset/theme.toml | 173 +++++++++++++++++++++++------------- config/src/theme/help.rs | 12 +++ config/src/theme/input.rs | 11 +++ config/src/theme/manager.rs | 33 +++++++ config/src/theme/mod.rs | 14 +++ config/src/theme/select.rs | 10 +++ config/src/theme/tasks.rs | 10 +++ config/src/theme/theme.rs | 153 ++++++------------------------- config/src/theme/which.rs | 25 ++++++ 16 files changed, 279 insertions(+), 216 deletions(-) create mode 100644 config/src/theme/help.rs create mode 100644 config/src/theme/input.rs create mode 100644 config/src/theme/manager.rs create mode 100644 config/src/theme/select.rs create mode 100644 config/src/theme/tasks.rs create mode 100644 config/src/theme/which.rs diff --git a/app/src/help/bindings.rs b/app/src/help/bindings.rs index 2a0f4fa78..b69958e46 100644 --- a/app/src/help/bindings.rs +++ b/app/src/help/bindings.rs @@ -1,8 +1,8 @@ +use core::Ctx; + use config::THEME; use ratatui::{layout::{self, Constraint}, prelude::{Buffer, Direction, Rect}, widgets::{List, ListItem, Widget}}; -use crate::context::Ctx; - pub(super) struct Bindings<'a> { cx: &'a Ctx, } @@ -21,13 +21,13 @@ impl Widget for Bindings<'_> { // Key let col1 = bindings .iter() - .map(|c| ListItem::new(c.on()).style(THEME.help.key.get())) + .map(|c| ListItem::new(c.on()).style(THEME.help.key.into())) .collect::>(); // Execution let col2 = bindings .iter() - .map(|c| ListItem::new(c.exec()).style(THEME.help.exec.get())) + .map(|c| ListItem::new(c.exec()).style(THEME.help.exec.into())) .collect::>(); // Description @@ -35,7 +35,7 @@ impl Widget for Bindings<'_> { .iter() .map(|c| { ListItem::new(if let Some(ref desc) = c.desc { desc } else { "-" }) - .style(THEME.help.desc.get()) + .style(THEME.help.desc.into()) }) .collect::>(); @@ -47,7 +47,7 @@ impl Widget for Bindings<'_> { let cursor = self.cx.help.rel_cursor() as u16; buf.set_style( Rect { x: area.x, y: area.y + cursor, width: area.width, height: 1 }, - THEME.help.curr.get(), + THEME.help.curr.into(), ); List::new(col1).render(chunks[0], buf); diff --git a/app/src/help/layout.rs b/app/src/help/layout.rs index f0f32cfdc..dc1d34bd6 100644 --- a/app/src/help/layout.rs +++ b/app/src/help/layout.rs @@ -1,8 +1,9 @@ +use core::Ctx; + use config::THEME; use ratatui::{buffer::Buffer, layout::{self, Rect}, prelude::{Constraint, Direction}, widgets::{Clear, Paragraph, Widget}}; use super::Bindings; -use crate::Ctx; pub(crate) struct Layout<'a> { cx: &'a Ctx, @@ -23,7 +24,7 @@ impl<'a> Widget for Layout<'a> { let help = &self.cx.help; Paragraph::new(help.keyword().unwrap_or_else(|| format!("{}.help", help.layer()))) - .style(THEME.help.btm.get()) + .style(THEME.help.btm.into()) .render(chunks[1], buf); Bindings::new(self.cx).render(chunks[0], buf); diff --git a/app/src/input/input.rs b/app/src/input/input.rs index 36d9e1ba2..8dc4bcb24 100644 --- a/app/src/input/input.rs +++ b/app/src/input/input.rs @@ -33,14 +33,14 @@ impl<'a> Widget for Input<'a> { Block::new() .borders(Borders::ALL) .border_type(BorderType::Rounded) - .border_style(THEME.input.border.get()) + .border_style(THEME.input.border.into()) .title({ let mut line = Line::from(input.title()); - line.patch_style(THEME.input.title.get()); + line.patch_style(THEME.input.title.into()); line }), ) - .style(THEME.input.text.get()) + .style(THEME.input.text.into()) .render(area, buf); if let Some(Range { start, end }) = input.selected() { @@ -49,7 +49,7 @@ impl<'a> Widget for Input<'a> { buf.set_style( Rect { x, y, width: (end - start).min(win.width - x), height: 1.min(win.height - y) }, - THEME.input.visual.get(), + THEME.input.visual.into(), ) } diff --git a/app/src/select/select.rs b/app/src/select/select.rs index 5d7a7c91a..f0b9a0dca 100644 --- a/app/src/select/select.rs +++ b/app/src/select/select.rs @@ -1,8 +1,8 @@ +use core::Ctx; + use config::THEME; use ratatui::{buffer::Buffer, layout::Rect, widgets::{Block, BorderType, Borders, Clear, List, ListItem, Widget}}; -use crate::Ctx; - pub(crate) struct Select<'a> { cx: &'a Ctx, } @@ -22,10 +22,10 @@ impl<'a> Widget for Select<'a> { .enumerate() .map(|(i, v)| { if i != select.rel_cursor() { - return ListItem::new(format!(" {v}")).style(THEME.opener.inactive.get()); + return ListItem::new(format!(" {v}")).style(THEME.select.inactive.into()); } - ListItem::new(format!(" {v}")).style(THEME.opener.active.get()) + ListItem::new(format!(" {v}")).style(THEME.select.active.into()) }) .collect::>(); @@ -36,7 +36,7 @@ impl<'a> Widget for Select<'a> { .title(select.title()) .borders(Borders::ALL) .border_type(BorderType::Rounded) - .border_style(THEME.opener.border.get()), + .border_style(THEME.select.border.into()), ) .render(area, buf); } diff --git a/app/src/tasks/layout.rs b/app/src/tasks/layout.rs index 71cf93d92..0416c184c 100644 --- a/app/src/tasks/layout.rs +++ b/app/src/tasks/layout.rs @@ -50,7 +50,7 @@ impl<'a> Widget for Layout<'a> { let block = Block::new() .title({ let mut line = Line::from("Tasks".to_string()); - line.patch_style(THEME.tasks.title.get()); + line.patch_style(THEME.tasks.title.into()); line }) .title_alignment(Alignment::Center) @@ -58,7 +58,7 @@ impl<'a> Widget for Layout<'a> { // Maybe also add these border type in to the later theme system .borders(Borders::ALL) .border_type(BorderType::Rounded) - .border_style(THEME.tasks.border.get()); + .border_style(THEME.tasks.border.into()); block.clone().render(area, buf); let tasks = &self.cx.tasks; @@ -69,7 +69,7 @@ impl<'a> Widget for Layout<'a> { .map(|(i, v)| { let mut item = ListItem::new(v.name.clone()); if i == tasks.cursor { - item = item.style(THEME.tasks.items.get()); + item = item.style(THEME.tasks.items.into()); } item }) diff --git a/app/src/which/layout.rs b/app/src/which/layout.rs index ccc79b371..9f4f66f43 100644 --- a/app/src/which/layout.rs +++ b/app/src/which/layout.rs @@ -1,8 +1,9 @@ +use core::Ctx; + use config::THEME; use ratatui::{layout, prelude::{Buffer, Constraint, Direction, Rect}, widgets::{Block, Clear, Widget}}; use super::Side; -use crate::Ctx; pub(crate) struct Which<'a> { cx: &'a Ctx, @@ -41,7 +42,7 @@ impl Widget for Which<'_> { .split(area); Clear.render(area, buf); - Block::new().style(THEME.which.block.get()).render(area, buf); + Block::new().style(THEME.which.block.into()).render(area, buf); Side::new(which.times, cands.0).render(chunks[0], buf); Side::new(which.times, cands.1).render(chunks[1], buf); Side::new(which.times, cands.2).render(chunks[2], buf); diff --git a/app/src/which/side.rs b/app/src/which/side.rs index 404c68b47..4b11eed5c 100644 --- a/app/src/which/side.rs +++ b/app/src/which/side.rs @@ -21,19 +21,19 @@ impl Widget for Side<'_> { // Keys let keys = c.on[self.times..].iter().map(ToString::to_string).collect::>(); spans.push(Span::raw(" ".repeat(10usize.saturating_sub(keys.join("").len())))); - spans.push(Span::styled(keys[0].clone(), THEME.which.key.get())); + spans.push(Span::styled(keys[0].clone(), THEME.which.key.into())); spans.extend( - keys.iter().skip(1).map(|k| Span::styled(k.to_string(), THEME.which.extend.get())), + keys.iter().skip(1).map(|k| Span::styled(k.to_string(), THEME.which.extend.into())), ); // Separator spans.push(Span::styled( THEME.which.separator.separator.to_string(), - Style::new().fg(*THEME.which.separator.color), + Style::new().fg(THEME.which.separator.color.into()), )); // Exec, - spans.push(Span::styled(c.desc_or_exec(), THEME.which.desc.get())); + spans.push(Span::styled(c.desc_or_exec(), THEME.which.desc.into())); ListItem::new(Line::from(spans)) }) diff --git a/config/preset/theme.toml b/config/preset/theme.toml index e38f0a5c4..3375e8a99 100644 --- a/config/preset/theme.toml +++ b/config/preset/theme.toml @@ -1,94 +1,82 @@ -# 00FFFF is for blue? -[tab] -active = { fg = "Black", bg = "Blue" } -inactive = { fg = "White", bg = "DarkGrey" } -header = { fg = "Cyan" } -max_width = 1 +# vim:fileencoding=utf-8:foldmethod=marker + +# : Status {{{ [status] -primary = { normal = "Blue", select = "LightMagenta", unset = "Yellow" } -secondary = { normal = "Black", select = "Black", unset = "Black" } -tertiary = { normal = "Grey", select = "Grey", unset = "Grey" } -body = { normal = "DarkGrey", select = "DarkGrey", unset = "DarkGrey" } -emphasis = { normal = "White", select = "White", unset = "White" } -info = { normal = "Cyan", select = "Cyan", unset = "Cyan" } -success = { normal = "Green", select = "Green", unset = "Green" } -warning = { normal = "Yellow", select = "Yellow", unset = "Yellow" } -danger = { normal = "Red", select = "Red", unset = "Red" } +plain = { fg = "#FFFFFF" } +fancy = { bg = "#45475D" } separator = { opening = "", closing = "" } -[which] -block = { bg = "Black" } -key = { fg = "LightCyan" } -extend = { fg = "DarkGray" } -desc = { fg = "Magenta" } -separator = { separator = " -> ", color = "DarkGray" } - -# Interactive opener style -[opener] -border = { fg = "Blue" } -active = { fg = "Magenta" } -inactive = { fg = "White" } +# Mode +mode_normal = { fg = "#181827", bg = "#7DB5FF", bold = true } +mode_select = { fg = "#1E1E30", bg = "#D2A4FE", bold = true } +mode_unset = { fg = "#1E1E30", bg = "#FFAF80", bold = true } -[find] -arrow = { fg = "LightYellow", italic = true } +# Progress +progress_label = { fg = "#FFFFFF", bold = true } +progress_normal = { fg = "#FFA577", bg = "#484D66" } +progress_error = { fg = "#FF84A9", bg = "#484D66" } -[progress] -gauge = { fg = "Yellow", bg = "Black" } -label = { fg = "LightWhite", bold = true } +# Permissions +permissions_t = { fg = "#97DC8D" } +permissions_r = { fg = "#F3D398" } +permissions_w = { fg = "#FA7F94" } +permissions_x = { fg = "#7AD9E5" } +permissions_s = { fg = "#6D738F" } -[tasks] -border = { fg = "Blue" } -title = { fg = "White" } -items = { underline = true } +# : }}} -# Color is largely different from original -[input] -border = { fg = "Blue" } -title = { fg = "White" } -text = { fg = "White" } -visual = { fg = "DarkGray" } -[selection] -hovered = { fg = "Black", bg = "Blue" } +# : Manager {{{ + +[tabs] +active = { fg = "#1E2031", bg = "#80AEFA" } +inactive = { fg = "#C8D3F8", bg = "#484D66" } +header = { fg = "#00FFFF" } +max_width = 1 + +[files] +hovered = { fg = "#1E2031", bg = "#80AEFA" } [marker] -selecting = { fg = "Green", bg = "Green" } -selected = { fg = "Yellow", bg = "Yellow" } +selected = { fg = "#97DC8D", bg = "#97DC8D" } +copied = { fg = "#F3D398", bg = "#F3D398" } +cut = { fg = "#FF84A9", bg = "#FF84A9" } + +[find] +# arrow = { fg = "LightYellow", italic = true } [preview] hovered = { underline = true } syntect_theme = "~/.config/bat/themes/Catppuccin-macchiato.tmTheme" -[help] -key = { fg = "Yellow" } -exec = { fg = "Cyan" } -desc = { fg = "White" } -curr = { bg = "Black", bold = true } -btm = { fg = "Black", bg = "White" } +# : }}} + + +# : File-specific styles {{{ [filetype] rules = [ # Images - { mime = "image/*", fg = "Cyan" }, + { mime = "image/*", fg = "#7AD9E5" }, # Videos - { mime = "video/*", fg = "Yellow" }, - { mime = "audio/*", fg = "Yellow" }, + { mime = "video/*", fg = "#F3D398" }, + { mime = "audio/*", fg = "#F3D398" }, # Archives - { mime = "application/zip", fg = "LightMagenta" }, - { mime = "application/gzip", fg = "LightMagenta" }, - { mime = "application/x-tar", fg = "LightMagenta" }, - { mime = "application/x-bzip", fg = "LightMagenta" }, - { mime = "application/x-bzip2", fg = "LightMagenta" }, - { mime = "application/x-7z-compressed", fg = "LightMagenta" }, - { mime = "application/x-rar", fg = "LightMagenta" }, + { mime = "application/zip", fg = "#CD9EFC" }, + { mime = "application/gzip", fg = "#CD9EFC" }, + { mime = "application/x-tar", fg = "#CD9EFC" }, + { mime = "application/x-bzip", fg = "#CD9EFC" }, + { mime = "application/x-bzip2", fg = "#CD9EFC" }, + { mime = "application/x-7z-compressed", fg = "#CD9EFC" }, + { mime = "application/x-rar", fg = "#CD9EFC" }, # Fallback - { name = "*", fg = "White" }, - { name = "*/", fg = "Blue" } + { name = "*", fg = "#C8D3F8" }, + { name = "*/", fg = "#80AEFA" } ] [icons] @@ -185,3 +173,60 @@ rules = [ # Default "*" = "" "*/" = "" + +# : }}} + + +# : Input {{{ + +[input] +border = { fg = "blue" } +title = { fg = "white" } +value = { fg = "white" } +selected = { fg = "darkGray" } + +# : }}} + + +# : Select {{{ + +[select] +border = { fg = "blue" } +active = { fg = "magenta" } +inactive = { fg = "white" } + +# : }}} + + +# : Tasks {{{ + +[tasks] +border = { fg = "blue" } +title = { fg = "white" } +hovered = { underline = true } + +# : }}} + + +# : Which {{{ + +[which] +# block = { bg = "Black" } +# key = { fg = "LightCyan" } +# extend = { fg = "DarkGray" } +# desc = { fg = "Magenta" } +# separator = { separator = " -> ", color = "DarkGray" } + +# : }}} + + +# : Help {{{ + +[help] +# key = { fg = "#E5E510" } +# exec = { fg = "#11A8CD" } +# desc = { fg = "#E5E5E5" } +# curr = { bg = "#666666", bold = true } +# btm = { fg = "#666666", bg = "#E5E5E5" } + +# : }}} diff --git a/config/src/theme/help.rs b/config/src/theme/help.rs new file mode 100644 index 000000000..199297ced --- /dev/null +++ b/config/src/theme/help.rs @@ -0,0 +1,12 @@ +use serde::{Deserialize, Serialize}; + +use super::Style; + +#[derive(Deserialize, Serialize)] +pub struct Help { + pub key: Style, + pub exec: Style, + pub desc: Style, + pub curr: Style, + pub btm: Style, +} diff --git a/config/src/theme/input.rs b/config/src/theme/input.rs new file mode 100644 index 000000000..e252e2fee --- /dev/null +++ b/config/src/theme/input.rs @@ -0,0 +1,11 @@ +use serde::{Deserialize, Serialize}; + +use super::Style; + +#[derive(Deserialize, Serialize)] +pub struct Input { + pub border: Style, + pub title: Style, + pub value: Style, + pub selected: Style, +} diff --git a/config/src/theme/manager.rs b/config/src/theme/manager.rs new file mode 100644 index 000000000..51d2b2af9 --- /dev/null +++ b/config/src/theme/manager.rs @@ -0,0 +1,33 @@ +use std::path::PathBuf; + +use serde::{Deserialize, Serialize}; +use validator::Validate; + +use super::Style; + +#[derive(Deserialize, Serialize, Validate)] +pub struct Tabs { + pub active: Style, + pub inactive: Style, + pub header: Style, + #[validate(range(min = 1, message = "Must be greater than 0"))] + pub max_width: u8, +} + +#[derive(Deserialize, Serialize)] +pub struct Files { + pub hovered: Style, +} + +#[derive(Deserialize, Serialize)] +pub struct Marker { + pub selected: Style, + pub copied: Style, + pub cut: Style, +} + +#[derive(Deserialize, Serialize)] +pub struct Preview { + pub hovered: Style, + pub syntect_theme: PathBuf, +} diff --git a/config/src/theme/mod.rs b/config/src/theme/mod.rs index ed9aa3dfa..2e2a69671 100644 --- a/config/src/theme/mod.rs +++ b/config/src/theme/mod.rs @@ -1,11 +1,25 @@ mod color; mod filetype; +mod help; mod icon; +mod input; +mod manager; +mod select; +mod status; mod style; +mod tasks; mod theme; +mod which; pub use color::*; pub use filetype::*; +pub use help::*; pub use icon::*; +pub use input::*; +pub use manager::*; +pub use select::*; +pub use status::*; pub use style::*; +pub use tasks::*; pub use theme::*; +pub use which::*; diff --git a/config/src/theme/select.rs b/config/src/theme/select.rs new file mode 100644 index 000000000..856f239e5 --- /dev/null +++ b/config/src/theme/select.rs @@ -0,0 +1,10 @@ +use serde::{Deserialize, Serialize}; + +use super::Style; + +#[derive(Deserialize, Serialize)] +pub struct Select { + pub border: Style, + pub active: Style, + pub inactive: Style, +} diff --git a/config/src/theme/tasks.rs b/config/src/theme/tasks.rs new file mode 100644 index 000000000..96198e798 --- /dev/null +++ b/config/src/theme/tasks.rs @@ -0,0 +1,10 @@ +use serde::{Deserialize, Serialize}; + +use super::Style; + +#[derive(Deserialize, Serialize)] +pub struct Tasks { + pub border: Style, + pub title: Style, + pub hovered: Style, +} diff --git a/config/src/theme/theme.rs b/config/src/theme/theme.rs index aafbae369..ce912ff6b 100644 --- a/config/src/theme/theme.rs +++ b/config/src/theme/theme.rs @@ -1,147 +1,48 @@ -use std::path::PathBuf; - -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use shared::expand_path; use validator::Validate; -use super::{Color, ColorGroup, Filetype, Icon, Style}; +use super::{Files, Filetype, Help, Icon, Input, Marker, Preview, Select, Status, Tabs, Tasks, Which}; use crate::{validation::check_validation, MERGED_THEME}; -#[derive(Deserialize, Validate)] -pub struct Tab { - pub active: Style, - pub inactive: Style, - pub header: Style, - #[validate(range(min = 1, message = "Must be greater than 0"))] - pub max_width: u8, -} - -#[derive(Deserialize)] -pub struct Status { - pub primary: ColorGroup, - pub secondary: ColorGroup, - pub tertiary: ColorGroup, - pub body: ColorGroup, - pub emphasis: ColorGroup, - pub info: ColorGroup, - pub success: ColorGroup, - pub warning: ColorGroup, - pub danger: ColorGroup, - pub separator: StatusSeparator, -} - -#[derive(Deserialize)] -pub struct StatusSeparator { - pub opening: String, - pub closing: String, -} - -#[derive(Deserialize)] -pub struct Progress { - pub gauge: Style, - pub label: Style, -} - -#[derive(Deserialize)] -pub struct Tasks { - pub border: Style, - pub title: Style, - pub items: Style, -} - -#[derive(Deserialize)] -pub struct Input { - pub border: Style, - pub title: Style, - pub text: Style, - pub visual: Style, -} - -#[derive(Deserialize)] -pub struct Which { - pub block: Style, - pub key: Style, - pub separator: WhichSeparator, - pub extend: Style, - pub desc: Style, -} - -#[derive(Deserialize)] -pub struct WhichItem { - pub key: Color, - pub extend: Color, - pub description: Color, -} +#[derive(Deserialize, Serialize)] +pub struct Theme { + // Status + pub status: Status, -#[derive(Deserialize)] -pub struct WhichSeparator { - pub separator: String, - pub color: Color, -} + // Manager + pub tabs: Tabs, + pub files: Files, + pub marker: Marker, + pub preview: Preview, -#[derive(Deserialize)] -pub struct Opener { - pub border: Style, - pub active: Style, - pub inactive: Style, -} + // File-specific styles + #[serde(rename = "filetype", deserialize_with = "Filetype::deserialize", skip_serializing)] + pub filetypes: Vec, + #[serde(deserialize_with = "Icon::deserialize", skip_serializing)] + pub icons: Vec, -#[derive(Deserialize)] -pub struct Find { - pub arrow: Style, -} + // Input + pub input: Input, -#[derive(Deserialize)] -pub struct Selection { - pub hovered: Style, -} + // Select + pub select: Select, -#[derive(Deserialize)] -pub struct Marker { - pub selecting: Style, - pub selected: Style, -} - -#[derive(Deserialize)] -pub struct Preview { - pub hovered: Style, - pub syntect_theme: PathBuf, -} + // Tasks + pub tasks: Tasks, -#[derive(Deserialize)] -pub struct Help { - pub key: Style, - pub exec: Style, - pub desc: Style, - pub curr: Style, - pub btm: Style, -} + // Which + pub which: Which, -#[derive(Deserialize)] -pub struct Theme { - pub tab: Tab, - pub status: Status, - pub progress: Progress, - pub tasks: Tasks, - pub input: Input, - pub which: Which, - pub opener: Opener, - pub find: Find, - pub selection: Selection, - pub marker: Marker, - pub preview: Preview, - pub help: Help, - #[serde(rename = "filetype", deserialize_with = "Filetype::deserialize")] - pub filetypes: Vec, - #[serde(deserialize_with = "Icon::deserialize")] - pub icons: Vec, + // Help + pub help: Help, } impl Default for Theme { fn default() -> Self { let mut theme: Self = toml::from_str(&MERGED_THEME).unwrap(); - check_validation(theme.tab.validate()); + check_validation(theme.tabs.validate()); theme.preview.syntect_theme = expand_path(&theme.preview.syntect_theme); diff --git a/config/src/theme/which.rs b/config/src/theme/which.rs new file mode 100644 index 000000000..fc274fb38 --- /dev/null +++ b/config/src/theme/which.rs @@ -0,0 +1,25 @@ +use serde::{Deserialize, Serialize}; + +use super::{Color, Style}; + +#[derive(Deserialize, Serialize)] +pub struct Which { + pub block: Style, + pub key: Style, + pub separator: WhichSeparator, + pub extend: Style, + pub desc: Style, +} + +#[derive(Deserialize, Serialize)] +pub struct WhichItem { + pub key: Color, + pub extend: Color, + pub description: Color, +} + +#[derive(Deserialize, Serialize)] +pub struct WhichSeparator { + pub separator: String, + pub color: Color, +}