diff --git a/default-plugins/compact-bar/src/line.rs b/default-plugins/compact-bar/src/line.rs index fa5fd3e932..5e531772d4 100644 --- a/default-plugins/compact-bar/src/line.rs +++ b/default-plugins/compact-bar/src/line.rs @@ -16,7 +16,7 @@ fn populate_tabs_in_tab_line( tabs_after_active: &mut Vec, tabs_to_render: &mut Vec, cols: usize, - palette: Palette, + palette: Styling, capabilities: PluginCapabilities, ) { let mut middle_size = get_current_title_len(tabs_to_render); @@ -107,7 +107,7 @@ fn populate_tabs_in_tab_line( fn left_more_message( tab_count_to_the_left: usize, - palette: Palette, + palette: Styling, separator: &str, tab_index: usize, ) -> LinePart { @@ -122,13 +122,14 @@ fn left_more_message( // 238 // chars length plus separator length on both sides let more_text_len = more_text.width() + 2 * separator.width(); - let (text_color, sep_color) = match palette.theme_hue { - ThemeHue::Dark => (palette.white, palette.black), - ThemeHue::Light => (palette.black, palette.white), - }; - let left_separator = style!(sep_color, palette.orange).paint(separator); - let more_styled_text = style!(text_color, palette.orange).bold().paint(more_text); - let right_separator = style!(palette.orange, sep_color).paint(separator); + let (text_color, sep_color) = ( + palette.ribbon_unselected.base, + palette.text_unselected.background, + ); + let plus_ribbon_bg = palette.text_selected.emphasis_1; + let left_separator = style!(sep_color, plus_ribbon_bg).paint(separator); + let more_styled_text = style!(text_color, plus_ribbon_bg).bold().paint(more_text); + let right_separator = style!(plus_ribbon_bg, sep_color).paint(separator); let more_styled_text = ANSIStrings(&[left_separator, more_styled_text, right_separator]).to_string(); LinePart { @@ -140,7 +141,7 @@ fn left_more_message( fn right_more_message( tab_count_to_the_right: usize, - palette: Palette, + palette: Styling, separator: &str, tab_index: usize, ) -> LinePart { @@ -154,13 +155,15 @@ fn right_more_message( }; // chars length plus separator length on both sides let more_text_len = more_text.width() + 2 * separator.width(); - let (text_color, sep_color) = match palette.theme_hue { - ThemeHue::Dark => (palette.white, palette.black), - ThemeHue::Light => (palette.black, palette.white), - }; - let left_separator = style!(sep_color, palette.orange).paint(separator); - let more_styled_text = style!(text_color, palette.orange).bold().paint(more_text); - let right_separator = style!(palette.orange, sep_color).paint(separator); + + let (text_color, sep_color) = ( + palette.ribbon_unselected.base, + palette.text_unselected.background, + ); + let plus_ribbon_bg = palette.text_selected.emphasis_1; + let left_separator = style!(sep_color, plus_ribbon_bg).paint(separator); + let more_styled_text = style!(text_color, plus_ribbon_bg).bold().paint(more_text); + let right_separator = style!(plus_ribbon_bg, sep_color).paint(separator); let more_styled_text = ANSIStrings(&[left_separator, more_styled_text, right_separator]).to_string(); LinePart { @@ -173,24 +176,17 @@ fn right_more_message( fn tab_line_prefix( session_name: Option<&str>, mode: InputMode, - palette: Palette, + palette: Styling, cols: usize, ) -> Vec { let prefix_text = " Zellij ".to_string(); let prefix_text_len = prefix_text.chars().count(); - let text_color = match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }; - let bg_color = match palette.theme_hue { - ThemeHue::Dark => palette.black, - ThemeHue::Light => palette.white, - }; - - let locked_mode_color = palette.magenta; - let normal_mode_color = palette.green; - let other_modes_color = palette.orange; + let text_color = palette.text_unselected.base; + let bg_color = palette.text_unselected.background; + let locked_mode_color = palette.text_unselected.emphasis_4; + let normal_mode_color = palette.text_unselected.emphasis_3; + let other_modes_color = palette.text_unselected.emphasis_1; let prefix_styled_text = style!(text_color, bg_color).bold().paint(prefix_text); let mut parts = vec![LinePart { @@ -201,10 +197,6 @@ fn tab_line_prefix( if let Some(name) = session_name { let name_part = format!("({})", name); let name_part_len = name_part.width(); - let text_color = match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }; let name_part_styled_text = style!(text_color, bg_color).bold().paint(name_part); if cols.saturating_sub(prefix_text_len) >= name_part_len { parts.push(LinePart { @@ -253,7 +245,7 @@ pub fn tab_line( mut all_tabs: Vec, active_tab_index: usize, cols: usize, - palette: Palette, + palette: Styling, capabilities: PluginCapabilities, hide_session_name: bool, mode: InputMode, @@ -293,6 +285,7 @@ pub fn tab_line( let current_title_len = get_current_title_len(&prefix); if current_title_len < cols { let mut remaining_space = cols - current_title_len; + let remaining_bg = palette.text_unselected.background; if let Some(swap_layout_status) = swap_layout_status( remaining_space, active_swap_layout_name, @@ -304,7 +297,7 @@ pub fn tab_line( remaining_space -= swap_layout_status.len; let mut buffer = String::new(); for _ in 0..remaining_space { - buffer.push_str(&style!(palette.black, palette.black).paint(" ").to_string()); + buffer.push_str(&style!(remaining_bg, remaining_bg).paint(" ").to_string()); } prefix.push(LinePart { part: buffer, @@ -323,7 +316,7 @@ fn swap_layout_status( swap_layout_name: &Option, is_swap_layout_damaged: bool, input_mode: InputMode, - palette: &Palette, + palette: &Styling, separator: &str, ) -> Option { match swap_layout_name { @@ -331,31 +324,28 @@ fn swap_layout_status( let mut swap_layout_name = format!(" {} ", swap_layout_name); swap_layout_name.make_ascii_uppercase(); let swap_layout_name_len = swap_layout_name.len() + 3; + let bg = palette.text_unselected.background; + let fg = palette.ribbon_unselected.background; + let green = palette.ribbon_selected.background; let (prefix_separator, swap_layout_name, suffix_separator) = if input_mode == InputMode::Locked { ( - style!(palette.black, palette.fg).paint(separator), - style!(palette.black, palette.fg) - .italic() - .paint(&swap_layout_name), - style!(palette.fg, palette.black).paint(separator), + style!(bg, fg).paint(separator), + style!(bg, fg).italic().paint(&swap_layout_name), + style!(fg, bg).paint(separator), ) } else if is_swap_layout_damaged { ( - style!(palette.black, palette.fg).paint(separator), - style!(palette.black, palette.fg) - .bold() - .paint(&swap_layout_name), - style!(palette.fg, palette.black).paint(separator), + style!(bg, fg).paint(separator), + style!(bg, fg).bold().paint(&swap_layout_name), + style!(fg, bg).paint(separator), ) } else { ( - style!(palette.black, palette.green).paint(separator), - style!(palette.black, palette.green) - .bold() - .paint(&swap_layout_name), - style!(palette.green, palette.black).paint(separator), + style!(bg, green).paint(separator), + style!(bg, green).bold().paint(&swap_layout_name), + style!(green, bg).paint(separator), ) }; let swap_layout_indicator = format!( diff --git a/default-plugins/compact-bar/src/main.rs b/default-plugins/compact-bar/src/main.rs index a7a19bd019..567dc187ed 100644 --- a/default-plugins/compact-bar/src/main.rs +++ b/default-plugins/compact-bar/src/main.rs @@ -131,10 +131,7 @@ impl ZellijPlugin for State { .tab_line .iter() .fold(String::new(), |output, part| output + &part.part); - let background = match self.mode_info.style.colors.theme_hue { - ThemeHue::Dark => self.mode_info.style.colors.black, - ThemeHue::Light => self.mode_info.style.colors.white, - }; + let background = self.mode_info.style.colors.text_unselected.background; match background { PaletteColor::Rgb((r, g, b)) => { print!("{}\u{1b}[48;2;{};{};{}m\u{1b}[0K", output, r, g, b); diff --git a/default-plugins/compact-bar/src/tab.rs b/default-plugins/compact-bar/src/tab.rs index 1aa13d4c33..e586bd676f 100644 --- a/default-plugins/compact-bar/src/tab.rs +++ b/default-plugins/compact-bar/src/tab.rs @@ -4,12 +4,12 @@ use unicode_width::UnicodeWidthStr; use zellij_tile::prelude::*; use zellij_tile_utils::style; -fn cursors(focused_clients: &[ClientId], palette: Palette) -> (Vec, usize) { +fn cursors(focused_clients: &[ClientId], colors: MultiplayerColors) -> (Vec, usize) { // cursor section, text length let mut len = 0; let mut cursors = vec![]; for client_id in focused_clients.iter() { - if let Some(color) = client_id_to_colors(*client_id, palette) { + if let Some(color) = client_id_to_colors(*client_id, colors) { cursors.push(style!(color.1, color.0).paint(" ")); len += 1; } @@ -21,26 +21,27 @@ pub fn render_tab( text: String, tab: &TabInfo, is_alternate_tab: bool, - palette: Palette, + palette: Styling, separator: &str, ) -> LinePart { let focused_clients = tab.other_focused_clients.as_slice(); let separator_width = separator.width(); - let alternate_tab_color = match palette.theme_hue { - // TODO: only do this if we don't have the arrow capabilities - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, + let alternate_tab_color = if is_alternate_tab { + palette.ribbon_unselected.emphasis_1 + } else { + palette.ribbon_unselected.background }; let background_color = if tab.active { - palette.green + palette.ribbon_selected.background } else if is_alternate_tab { alternate_tab_color } else { - palette.fg + palette.ribbon_unselected.background }; - let foreground_color = match palette.theme_hue { - ThemeHue::Dark => palette.black, - ThemeHue::Light => palette.white, + let foreground_color = if tab.active { + palette.ribbon_selected.base + } else { + palette.ribbon_unselected.base }; let left_separator = style!(foreground_color, background_color).paint(separator); let mut tab_text_len = text.width() + (separator_width * 2) + 2; // + 2 for padding @@ -51,7 +52,8 @@ pub fn render_tab( let right_separator = style!(background_color, foreground_color).paint(separator); let tab_styled_text = if !focused_clients.is_empty() { - let (cursor_section, extra_length) = cursors(focused_clients, palette); + let (cursor_section, extra_length) = + cursors(focused_clients, palette.multiplayer_user_colors); tab_text_len += extra_length; let mut s = String::new(); let cursor_beginning = style!(foreground_color, background_color) @@ -85,7 +87,7 @@ pub fn tab_style( mut tabname: String, tab: &TabInfo, mut is_alternate_tab: bool, - palette: Palette, + palette: Styling, capabilities: PluginCapabilities, ) -> LinePart { let separator = tab_separator(capabilities); diff --git a/default-plugins/session-manager/src/ui/components.rs b/default-plugins/session-manager/src/ui/components.rs index 5c265f5426..075d326300 100644 --- a/default-plugins/session-manager/src/ui/components.rs +++ b/default-plugins/session-manager/src/ui/components.rs @@ -83,9 +83,14 @@ impl ListItem { let mut remaining_cols = max_cols; for span in session_name { span.render( - indices - .clone() - .map(|i| (SpanStyle::ForegroundBold(self.colors.palette.magenta), i)), + indices.clone().map(|i| { + ( + SpanStyle::ForegroundBold( + self.colors.palette.text_unselected.emphasis_4, + ), + i, + ) + }), &mut line_to_render, &mut remaining_cols, ); @@ -102,9 +107,14 @@ impl ListItem { let mut remaining_cols = max_cols; for span in tab_name { span.render( - indices - .clone() - .map(|i| (SpanStyle::ForegroundBold(self.colors.palette.magenta), i)), + indices.clone().map(|i| { + ( + SpanStyle::ForegroundBold( + self.colors.palette.text_unselected.emphasis_4, + ), + i, + ) + }), &mut line_to_render, &mut remaining_cols, ); @@ -116,9 +126,14 @@ impl ListItem { let mut remaining_cols = max_cols; for span in pane_name { span.render( - indices - .clone() - .map(|i| (SpanStyle::ForegroundBold(self.colors.palette.magenta), i)), + indices.clone().map(|i| { + ( + SpanStyle::ForegroundBold( + self.colors.palette.text_unselected.emphasis_4, + ), + i, + ) + }), &mut line_to_render, &mut remaining_cols, ); @@ -297,11 +312,11 @@ impl LineToRender { pub fn make_selected_as_search(&mut self, add_arrows: bool) { self.is_selected = true; let arrows = if add_arrows { - self.colors.magenta(" <↓↑> ") + self.colors.shortcuts(" <↓↑> ") } else { " ".to_owned() }; - match self.colors.palette.bg { + match self.colors.palette.list_selected.background { PaletteColor::EightBit(byte) => { self.line = format!( "\u{1b}[48;5;{byte}m\u{1b}[K\u{1b}[48;5;{byte}m{arrows}{}", @@ -319,11 +334,11 @@ impl LineToRender { pub fn make_selected(&mut self, add_arrows: bool) { self.is_selected = true; let arrows = if add_arrows { - self.colors.magenta("<←↓↑→>") + self.colors.shortcuts("<←↓↑→>") } else { " ".to_owned() }; - match self.colors.palette.bg { + match self.colors.palette.list_selected.background { PaletteColor::EightBit(byte) => { self.line = format!( "\u{1b}[48;5;{byte}m\u{1b}[K\u{1b}[48;5;{byte}m{arrows}{}", @@ -343,7 +358,7 @@ impl LineToRender { let more = if self.truncated_result_count > 0 { self.colors - .red(&format!(" [+{}]", self.truncated_result_count)) + .exit_code_error(&format!(" [+{}]", self.truncated_result_count)) } else { String::new() }; @@ -368,12 +383,12 @@ pub fn build_session_ui_line(session_ui_info: &SessionUiInfo, colors: Colors) -> .iter() .fold(0, |acc, tab| acc + tab.panes.len()); let tab_count = format!("{}", tab_count_text); - let tab_count_styled = colors.cyan(&tab_count); + let tab_count_styled = colors.tab_count(&tab_count); let total_pane_count = format!("{}", total_pane_count_text); - let total_pane_count_styled = colors.green(&total_pane_count); + let total_pane_count_styled = colors.pane_count_search_prompt(&total_pane_count); let session_name = &session_ui_info.name; let connected_users = format!("{}", session_ui_info.connected_users); - let connected_users_styled = colors.orange(&connected_users); + let connected_users_styled = colors.connected_users(&connected_users); let session_bullet_span = UiSpan::UiSpanTelescope(UiSpanTelescope::new(vec![StringAndLength::new( format!(" > "), @@ -381,7 +396,7 @@ pub fn build_session_ui_line(session_ui_info: &SessionUiInfo, colors: Colors) -> )])); let session_name_span = UiSpan::TruncatableUiSpan(TruncatableUiSpan::new( session_name.clone(), - SpanStyle::ForegroundBold(colors.palette.orange), + SpanStyle::ForegroundBold(colors.palette.exit_code_success.base), )); let tab_and_pane_count = UiSpan::UiSpanTelescope(UiSpanTelescope::new(vec![ StringAndLength::new( @@ -409,9 +424,9 @@ pub fn build_session_ui_line(session_ui_info: &SessionUiInfo, colors: Colors) -> ui_spans.push(connected_users_count); if session_ui_info.is_current_session { let current_session_indication = UiSpan::UiSpanTelescope(UiSpanTelescope::new(vec![ - StringAndLength::new(colors.orange(&format!(" ")), 18), - StringAndLength::new(colors.orange(&format!(" ")), 10), - StringAndLength::new(colors.orange(&format!(" ")), 4), + StringAndLength::new(colors.connected_users(&format!(" ")), 18), + StringAndLength::new(colors.connected_users(&format!(" ")), 10), + StringAndLength::new(colors.connected_users(&format!(" ")), 4), ])); ui_spans.push(current_session_indication); } @@ -423,7 +438,7 @@ pub fn build_tab_ui_line(tab_ui_info: &TabUiInfo, colors: Colors) -> Vec let tab_name = &tab_ui_info.name; let pane_count_text = tab_ui_info.panes.len(); let pane_count = format!("{}", pane_count_text); - let pane_count_styled = colors.green(&pane_count); + let pane_count_styled = colors.pane_count_search_prompt(&pane_count); let tab_bullet_span = UiSpan::UiSpanTelescope(UiSpanTelescope::new(vec![StringAndLength::new( format!(" - "), @@ -431,7 +446,7 @@ pub fn build_tab_ui_line(tab_ui_info: &TabUiInfo, colors: Colors) -> Vec )])); let tab_name_span = UiSpan::TruncatableUiSpan(TruncatableUiSpan::new( tab_name.clone(), - SpanStyle::ForegroundBold(colors.palette.cyan), + SpanStyle::ForegroundBold(colors.palette.text_unselected.emphasis_2), )); let connected_users_count_span = UiSpan::UiSpanTelescope(UiSpanTelescope::new(vec![ StringAndLength::new( @@ -455,9 +470,9 @@ pub fn build_pane_ui_line(pane_ui_info: &PaneUiInfo, colors: Colors) -> Vec= folder_prompt.width() @@ -581,8 +596,8 @@ fn render_new_session_folder_prompt( print!( "\u{1b}[m{}{} {} ({} {}, {} {})", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green(folder_prompt), - colors.orange(&new_session_folder), + colors.session_name(folder_prompt), + colors.pane_count_search_prompt(&new_session_folder), change_folder_shortcut, to_change, reset_folder_shortcut, @@ -600,8 +615,8 @@ fn render_new_session_folder_prompt( print!( "\u{1b}[m{}{} {} ({} {}, {} {})", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green(short_folder_prompt), - colors.orange(&new_session_folder), + colors.session_name(short_folder_prompt), + colors.pane_count_search_prompt(&new_session_folder), change_folder_shortcut, to_change, reset_folder_shortcut, @@ -617,8 +632,8 @@ fn render_new_session_folder_prompt( print!( "\u{1b}[m{}{} {} ({}/{})", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green(short_folder_prompt), - colors.orange(&new_session_folder), + colors.session_name(short_folder_prompt), + colors.pane_count_search_prompt(&new_session_folder), change_folder_shortcut, reset_folder_shortcut, ); @@ -635,8 +650,8 @@ fn render_new_session_folder_prompt( print!( "\u{1b}[m{}{} {} ({}/{})", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green(short_folder_prompt), - colors.orange(&truncated_path), + colors.session_name(short_folder_prompt), + colors.pane_count_search_prompt(&truncated_path), change_folder_shortcut, reset_folder_shortcut, ); @@ -646,7 +661,7 @@ fn render_new_session_folder_prompt( let folder_prompt = "New session folder:"; let short_folder_prompt = "Folder:"; let change_folder_shortcut_text = ""; - let change_folder_shortcut = colors.magenta(change_folder_shortcut_text); + let change_folder_shortcut = colors.shortcuts(change_folder_shortcut_text); let to_set = "to set"; if max_cols @@ -655,7 +670,7 @@ fn render_new_session_folder_prompt( print!( "\u{1b}[m{}{} ({} {})", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green(folder_prompt), + colors.session_name(folder_prompt), change_folder_shortcut, to_set, ); @@ -668,7 +683,7 @@ fn render_new_session_folder_prompt( print!( "\u{1b}[m{}{} ({} {})", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green(short_folder_prompt), + colors.session_name(short_folder_prompt), change_folder_shortcut, to_set, ); @@ -676,7 +691,7 @@ fn render_new_session_folder_prompt( print!( "\u{1b}[m{}{} {}", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green(short_folder_prompt), + colors.session_name(short_folder_prompt), change_folder_shortcut, ); } @@ -692,7 +707,7 @@ pub fn render_new_session_block( x: usize, y: usize, ) { - let enter = colors.magenta(""); + let enter = colors.shortcuts(""); if new_session_info.entering_new_session_name() { let prompt = "New session name:"; let long_instruction = "when done, blank for random"; @@ -703,8 +718,8 @@ pub fn render_new_session_block( println!( "\u{1b}[m{}{} {}_ ({} {})", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green(prompt), - colors.orange(&new_session_name), + colors.session_name(prompt), + colors.pane_count_search_prompt(&new_session_name), enter, long_instruction, ); @@ -729,8 +744,8 @@ pub fn render_new_session_block( println!( "\u{1b}[m{}{} {}_ {}", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green(prompt), - colors.orange(&new_session_name), + colors.session_name(prompt), + colors.pane_count_search_prompt(&new_session_name), enter, ); } @@ -742,23 +757,23 @@ pub fn render_new_session_block( }; let prompt = "New session name:"; let long_instruction = "to correct"; - let esc = colors.magenta(""); + let esc = colors.shortcuts(""); if max_cols_of_new_session_block > prompt.width() + long_instruction.width() + new_session_name.width() + 15 { println!( "\u{1b}[m{}{}: {} ({} to correct)", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green("New session name"), - colors.orange(new_session_name), + colors.session_name("New session name"), + colors.pane_count_search_prompt(new_session_name), esc, ); } else { println!( "\u{1b}[m{}{}: {} {}", format!("\u{1b}[{};{}H", y + 1, x + 1), - colors.green("New session name"), - colors.orange(new_session_name), + colors.session_name("New session name"), + colors.pane_count_search_prompt(new_session_name), esc, ); } @@ -892,13 +907,13 @@ pub fn render_controls_line( } }, ActiveScreen::AttachToSession => { - let rename = colors.magenta(""); + let rename = colors.shortcuts(""); let rename_text = colors.bold("Rename"); - let disconnect = colors.magenta(""); + let disconnect = colors.shortcuts(""); let disconnect_text = colors.bold("Disconnect others"); - let kill = colors.magenta(""); + let kill = colors.shortcuts(""); let kill_text = colors.bold("Kill"); - let kill_all = colors.magenta(""); + let kill_all = colors.shortcuts(""); let kill_all_text = colors.bold("Kill all"); if max_cols > 90 { @@ -910,13 +925,13 @@ pub fn render_controls_line( } }, ActiveScreen::ResurrectSession => { - let arrows = colors.magenta("<↓↑>"); + let arrows = colors.shortcuts("<↓↑>"); let navigate = colors.bold("Navigate"); - let enter = colors.magenta(""); + let enter = colors.shortcuts(""); let select = colors.bold("Resurrect"); - let del = colors.magenta(""); + let del = colors.shortcuts(""); let del_text = colors.bold("Delete"); - let del_all = colors.magenta(""); + let del_all = colors.shortcuts(""); let del_all_text = colors.bold("Delete all"); if max_cols > 83 { @@ -932,10 +947,10 @@ pub fn render_controls_line( #[derive(Debug, Default, Clone, Copy)] pub struct Colors { - pub palette: Palette, + pub palette: Styling, } impl Colors { - pub fn new(palette: Palette) -> Self { + pub fn new(palette: Styling) -> Self { Colors { palette } } pub fn bold(&self, text: &str) -> String { @@ -952,24 +967,29 @@ impl Colors { }, } } - pub fn orange(&self, text: &str) -> String { - self.color(&self.palette.orange, text) + + pub fn session_name(&self, text: &str) -> String { + self.color(&self.palette.exit_code_success.emphasis_1, text) + } + + pub fn connected_users(&self, text: &str) -> String { + self.color(&self.palette.text_unselected.emphasis_3, text) } - pub fn green(&self, text: &str) -> String { - self.color(&self.palette.green, text) + pub fn pane_count_search_prompt(&self, text: &str) -> String { + self.color(&self.palette.text_unselected.emphasis_3, text) } - pub fn red(&self, text: &str) -> String { - self.color(&self.palette.red, text) + pub fn exit_code_error(&self, text: &str) -> String { + self.color(&self.palette.exit_code_error.base, text) } - pub fn cyan(&self, text: &str) -> String { - self.color(&self.palette.cyan, text) + pub fn tab_count(&self, text: &str) -> String { + self.color(&self.palette.text_unselected.emphasis_2, text) } - pub fn magenta(&self, text: &str) -> String { - self.color(&self.palette.magenta, text) + pub fn shortcuts(&self, text: &str) -> String { + self.color(&self.palette.text_unselected.emphasis_4, text) } } diff --git a/default-plugins/status-bar/src/first_line.rs b/default-plugins/status-bar/src/first_line.rs index ee9b9478d4..2a28a24b1e 100644 --- a/default-plugins/status-bar/src/first_line.rs +++ b/default-plugins/status-bar/src/first_line.rs @@ -345,14 +345,17 @@ fn key_indicators( line_part } -fn swap_layout_keycode(mode_info: &ModeInfo, palette: &Palette) -> LinePart { +fn swap_layout_keycode(mode_info: &ModeInfo) -> LinePart { let mode_keybinds = mode_info.get_mode_keybinds(); let prev_next_keys = action_key_group( &mode_keybinds, &[&[Action::PreviousSwapLayout], &[Action::NextSwapLayout]], ); - let prev_next_keys_indicator = - style_key_with_modifier(&prev_next_keys, palette, Some(palette.black)); + let prev_next_keys_indicator = style_key_with_modifier( + &prev_next_keys, + &mode_info.style.colors, + Some(mode_info.style.colors.text_unselected.background), + ); let keycode = ANSIStrings(&prev_next_keys_indicator); let len = unstyled_len(&keycode); let part = keycode.to_string(); @@ -365,14 +368,13 @@ fn swap_layout_status( is_swap_layout_damaged: bool, mode_info: &ModeInfo, colored_elements: ColoredElements, - palette: &Palette, separator: &str, ) -> Option { match swap_layout_name { Some(swap_layout_name) => { let mut swap_layout_name = format!(" {} ", swap_layout_name); swap_layout_name.make_ascii_uppercase(); - let keycode = swap_layout_keycode(mode_info, palette); + let keycode = swap_layout_keycode(mode_info); let swap_layout_name_len = swap_layout_name.len() + 3; // 2 for the arrow separators, one for the screen end buffer // macro_rules! style_swap_layout_indicator { @@ -702,7 +704,6 @@ pub fn first_line( tab_info.is_swap_layout_dirty, help, colored_elements, - &help.style.colors, separator, ) { remaining_space -= swap_layout_status.len; @@ -731,7 +732,7 @@ mod tests { use super::*; fn colored_elements() -> ColoredElements { - let palette = Palette::default(); + let palette = Styling::default(); color_elements(palette, false) } diff --git a/default-plugins/status-bar/src/main.rs b/default-plugins/status-bar/src/main.rs index 7db9b09d97..a885b1126b 100644 --- a/default-plugins/status-bar/src/main.rs +++ b/default-plugins/status-bar/src/main.rs @@ -87,96 +87,105 @@ pub struct SegmentStyle { // we need different colors from palette for the default theme // plus here we can add new sources in the future, like Theme // that can be defined in the config perhaps -fn color_elements(palette: Palette, different_color_alternates: bool) -> ColoredElements { - let background = match palette.theme_hue { - ThemeHue::Dark => palette.black, - ThemeHue::Light => palette.white, - }; - let foreground = match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }; +fn color_elements(palette: Styling, different_color_alternates: bool) -> ColoredElements { + let background = palette.text_unselected.background; + let foreground = palette.text_unselected.base; let alternate_background_color = if different_color_alternates { - match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - } + palette.ribbon_unselected.base } else { - palette.fg + palette.ribbon_unselected.background }; - match palette.source { - PaletteSource::Default => ColoredElements { - selected: SegmentStyle { - prefix_separator: style!(background, palette.green), - char_left_separator: style!(background, palette.green).bold(), - char_shortcut: style!(palette.red, palette.green).bold(), - char_right_separator: style!(background, palette.green).bold(), - styled_text: style!(background, palette.green).bold(), - suffix_separator: style!(palette.green, background).bold(), - }, - unselected: SegmentStyle { - prefix_separator: style!(background, palette.fg), - char_left_separator: style!(background, palette.fg).bold(), - char_shortcut: style!(palette.red, palette.fg).bold(), - char_right_separator: style!(background, palette.fg).bold(), - styled_text: style!(background, palette.fg).bold(), - suffix_separator: style!(palette.fg, background), - }, - unselected_alternate: SegmentStyle { - prefix_separator: style!(background, alternate_background_color), - char_left_separator: style!(background, alternate_background_color).bold(), - char_shortcut: style!(palette.red, alternate_background_color).bold(), - char_right_separator: style!(background, alternate_background_color).bold(), - styled_text: style!(background, alternate_background_color).bold(), - suffix_separator: style!(alternate_background_color, background), - }, - disabled: SegmentStyle { - prefix_separator: style!(background, palette.fg), - char_left_separator: style!(background, palette.fg).dimmed().italic(), - char_shortcut: style!(background, palette.fg).dimmed().italic(), - char_right_separator: style!(background, palette.fg).dimmed().italic(), - styled_text: style!(background, palette.fg).dimmed().italic(), - suffix_separator: style!(palette.fg, background), - }, - superkey_prefix: style!(foreground, background).bold(), - superkey_suffix_separator: style!(background, background), + ColoredElements { + selected: SegmentStyle { + prefix_separator: style!(background, palette.ribbon_selected.background), + char_left_separator: style!( + palette.ribbon_selected.base, + palette.ribbon_selected.background + ) + .bold(), + char_shortcut: style!( + palette.ribbon_selected.emphasis_1, + palette.ribbon_selected.background + ) + .bold(), + char_right_separator: style!( + palette.ribbon_selected.base, + palette.ribbon_selected.background + ) + .bold(), + styled_text: style!( + palette.ribbon_selected.base, + palette.ribbon_selected.background + ) + .bold(), + suffix_separator: style!(palette.ribbon_selected.background, background).bold(), }, - PaletteSource::Xresources => ColoredElements { - selected: SegmentStyle { - prefix_separator: style!(background, palette.green), - char_left_separator: style!(palette.fg, palette.green).bold(), - char_shortcut: style!(palette.red, palette.green).bold(), - char_right_separator: style!(palette.fg, palette.green).bold(), - styled_text: style!(background, palette.green).bold(), - suffix_separator: style!(palette.green, background).bold(), - }, - unselected: SegmentStyle { - prefix_separator: style!(background, palette.fg), - char_left_separator: style!(background, palette.fg).bold(), - char_shortcut: style!(palette.red, palette.fg).bold(), - char_right_separator: style!(background, palette.fg).bold(), - styled_text: style!(background, palette.fg).bold(), - suffix_separator: style!(palette.fg, background), - }, - unselected_alternate: SegmentStyle { - prefix_separator: style!(background, alternate_background_color), - char_left_separator: style!(background, alternate_background_color).bold(), - char_shortcut: style!(palette.red, alternate_background_color).bold(), - char_right_separator: style!(background, alternate_background_color).bold(), - styled_text: style!(background, alternate_background_color).bold(), - suffix_separator: style!(alternate_background_color, background), - }, - disabled: SegmentStyle { - prefix_separator: style!(background, palette.fg), - char_left_separator: style!(background, palette.fg).dimmed(), - char_shortcut: style!(background, palette.fg).dimmed(), - char_right_separator: style!(background, palette.fg).dimmed(), - styled_text: style!(background, palette.fg).dimmed(), - suffix_separator: style!(palette.fg, background), - }, - superkey_prefix: style!(background, palette.fg).bold(), - superkey_suffix_separator: style!(palette.fg, background), + unselected: SegmentStyle { + prefix_separator: style!(background, palette.ribbon_unselected.background), + char_left_separator: style!( + palette.ribbon_unselected.base, + palette.ribbon_unselected.background + ) + .bold(), + char_shortcut: style!( + palette.ribbon_unselected.emphasis_1, + palette.ribbon_unselected.background + ) + .bold(), + char_right_separator: style!( + palette.ribbon_unselected.base, + palette.ribbon_unselected.background + ) + .bold(), + styled_text: style!( + palette.ribbon_unselected.base, + palette.ribbon_unselected.background + ) + .bold(), + suffix_separator: style!(palette.ribbon_unselected.background, background).bold(), + }, + unselected_alternate: SegmentStyle { + prefix_separator: style!(background, alternate_background_color), + char_left_separator: style!(background, alternate_background_color).bold(), + char_shortcut: style!( + palette.ribbon_unselected.emphasis_1, + alternate_background_color + ) + .bold(), + char_right_separator: style!(background, alternate_background_color).bold(), + styled_text: style!(palette.ribbon_unselected.base, alternate_background_color).bold(), + suffix_separator: style!(alternate_background_color, background).bold(), }, + disabled: SegmentStyle { + prefix_separator: style!(background, palette.ribbon_unselected.background), + char_left_separator: style!( + palette.ribbon_unselected.base, + palette.ribbon_unselected.background + ) + .dimmed() + .italic(), + char_shortcut: style!( + palette.ribbon_unselected.base, + palette.ribbon_unselected.background + ) + .dimmed() + .italic(), + char_right_separator: style!( + palette.ribbon_unselected.base, + palette.ribbon_unselected.background + ) + .dimmed() + .italic(), + styled_text: style!( + palette.ribbon_unselected.base, + palette.ribbon_unselected.background + ) + .dimmed() + .italic(), + suffix_separator: style!(palette.ribbon_unselected.background, background), + }, + superkey_prefix: style!(foreground, background).bold(), + superkey_suffix_separator: style!(background, background), } } @@ -268,15 +277,12 @@ impl ZellijPlugin for State { return; } + //TODO: Switch to UI components here let active_tab = self.tabs.iter().find(|t| t.active); let first_line = first_line(&self.mode_info, active_tab, cols, separator); let second_line = self.second_line(cols); - let background = match self.mode_info.style.colors.theme_hue { - ThemeHue::Dark => self.mode_info.style.colors.black, - ThemeHue::Light => self.mode_info.style.colors.white, - }; - + let background = self.mode_info.style.colors.text_unselected.background; // [48;5;238m is white background, [0K is so that it fills the rest of the line // [m is background reset, [0K is so that it clears the rest of the line match background { @@ -425,19 +431,16 @@ pub fn action_key_group( /// type. pub fn style_key_with_modifier( keyvec: &[KeyWithModifier], - palette: &Palette, + palette: &Styling, background: Option, ) -> Vec> { if keyvec.is_empty() { return vec![]; } - let text_color = palette_match!(match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }); - let green_color = palette_match!(palette.green); - let orange_color = palette_match!(palette.orange); + let text_color = palette_match!(palette.text_unselected.base); + let green_color = palette_match!(palette.text_unselected.emphasis_3); + let orange_color = palette_match!(palette.text_unselected.emphasis_1); let mut ret = vec![]; let common_modifiers = get_common_modifiers(keyvec.iter().collect()); @@ -699,7 +702,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Char('b')), KeyWithModifier::new(BareKey::Char('c')), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -715,7 +718,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Char('k')), KeyWithModifier::new(BareKey::Char('l')), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -731,7 +734,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Up), KeyWithModifier::new(BareKey::Right), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -745,7 +748,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Left), KeyWithModifier::new(BareKey::Right), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -759,7 +762,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Down), KeyWithModifier::new(BareKey::Up), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -775,7 +778,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Char('c')).with_ctrl_modifier(), KeyWithModifier::new(BareKey::Char('d')).with_ctrl_modifier(), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -791,7 +794,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Char('c')).with_alt_modifier(), KeyWithModifier::new(BareKey::Char('d')).with_alt_modifier(), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -807,7 +810,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Up).with_alt_modifier(), KeyWithModifier::new(BareKey::Right).with_alt_modifier(), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -822,7 +825,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Char('b')).with_ctrl_modifier(), KeyWithModifier::new(BareKey::Char('c')), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -845,7 +848,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Tab), KeyWithModifier::new(BareKey::Esc), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -863,7 +866,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Char(' ')).with_ctrl_modifier(), KeyWithModifier::new(BareKey::Tab).with_ctrl_modifier(), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); @@ -878,7 +881,7 @@ pub mod tests { KeyWithModifier::new(BareKey::Char(' ')).with_alt_modifier(), KeyWithModifier::new(BareKey::Tab).with_alt_modifier(), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = style_key_with_modifier(&keyvec, &palette, None); let ret = unstyle(&ANSIStrings(&ret)); diff --git a/default-plugins/status-bar/src/one_line_ui.rs b/default-plugins/status-bar/src/one_line_ui.rs index 87b1e2fd26..80b17512ba 100644 --- a/default-plugins/status-bar/src/one_line_ui.rs +++ b/default-plugins/status-bar/src/one_line_ui.rs @@ -1055,8 +1055,8 @@ fn add_keygroup_separator(help: &ModeInfo, max_len: usize) -> Option { let mut ret = LinePart::default(); - let separator_color = palette_match!(palette.orange); - let bg_color = palette_match!(palette.black); + let separator_color = palette_match!(palette.ribbon_selected.emphasis_2); + let bg_color = palette_match!(palette.ribbon_selected.base); let mut bits: Vec = vec![]; let mode_help_text = match help.mode { InputMode::RenamePane => Some("RENAMING PANE"), diff --git a/default-plugins/status-bar/src/second_line.rs b/default-plugins/status-bar/src/second_line.rs index 63730aa4eb..ae58657b4c 100644 --- a/default-plugins/status-bar/src/second_line.rs +++ b/default-plugins/status-bar/src/second_line.rs @@ -17,16 +17,13 @@ fn full_length_shortcut( is_first_shortcut: bool, key: Vec, action: &str, - palette: Palette, + palette: Styling, ) -> LinePart { if key.is_empty() { return LinePart::default(); } - let text_color = palette_match!(match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }); + let text_color = palette_match!(palette.text_unselected.base); let separator = if is_first_shortcut { " " } else { " / " }; let mut bits: Vec = vec![Style::new().fg(text_color).paint(separator)]; @@ -45,13 +42,10 @@ fn full_length_shortcut( } } -fn locked_interface_indication(palette: Palette) -> LinePart { +fn locked_interface_indication(palette: Styling) -> LinePart { let locked_text = " -- INTERFACE LOCKED -- "; let locked_text_len = locked_text.chars().count(); - let text_color = palette_match!(match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }); + let text_color = palette_match!(palette.text_unselected.base); let locked_styled_text = Style::new().fg(text_color).bold().paint(locked_text); LinePart { part: locked_styled_text.to_string(), @@ -354,8 +348,8 @@ pub fn keybinds(help: &ModeInfo, tip_name: &str, max_width: usize) -> LinePart { best_effort_shortcut_list(help, tip_body.short, max_width) } -pub fn text_copied_hint(palette: &Palette, copy_destination: CopyDestination) -> LinePart { - let green_color = palette_match!(palette.green); +pub fn text_copied_hint(palette: &Styling, copy_destination: CopyDestination) -> LinePart { + let green_color = palette_match!(palette.text_unselected.emphasis_3); let hint = match copy_destination { CopyDestination::Command => "Text piped to external command", #[cfg(not(target_os = "macos"))] @@ -370,22 +364,19 @@ pub fn text_copied_hint(palette: &Palette, copy_destination: CopyDestination) -> } } -pub fn system_clipboard_error(palette: &Palette) -> LinePart { +pub fn system_clipboard_error(palette: &Styling) -> LinePart { let hint = " Error using the system clipboard."; - let red_color = palette_match!(palette.red); + let red_color = palette_match!(palette.text_unselected.emphasis_4); LinePart { part: Style::new().fg(red_color).bold().paint(hint).to_string(), len: hint.len(), } } -pub fn fullscreen_panes_to_hide(palette: &Palette, panes_to_hide: usize) -> LinePart { - let text_color = palette_match!(match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }); - let green_color = palette_match!(palette.green); - let orange_color = palette_match!(palette.orange); +pub fn fullscreen_panes_to_hide(palette: &Styling, panes_to_hide: usize) -> LinePart { + let text_color = palette_match!(palette.text_unselected.base); + let green_color = palette_match!(palette.text_unselected.emphasis_3); + let orange_color = palette_match!(palette.text_unselected.emphasis_1); let shortcut_left_separator = Style::new().fg(text_color).bold().paint(" ("); let shortcut_right_separator = Style::new().fg(text_color).bold().paint("): "); let fullscreen = "FULLSCREEN"; @@ -414,18 +405,9 @@ pub fn fullscreen_panes_to_hide(palette: &Palette, panes_to_hide: usize) -> Line pub fn floating_panes_are_visible(mode_info: &ModeInfo) -> LinePart { let palette = mode_info.style.colors; let km = &mode_info.get_mode_keybinds(); - let white_color = match palette.white { - PaletteColor::Rgb((r, g, b)) => RGB(r, g, b), - PaletteColor::EightBit(color) => Fixed(color), - }; - let green_color = match palette.green { - PaletteColor::Rgb((r, g, b)) => RGB(r, g, b), - PaletteColor::EightBit(color) => Fixed(color), - }; - let orange_color = match palette.orange { - PaletteColor::Rgb((r, g, b)) => RGB(r, g, b), - PaletteColor::EightBit(color) => Fixed(color), - }; + let white_color = palette_match!(palette.text_unselected.base); + let green_color = palette_match!(palette.text_unselected.emphasis_3); + let orange_color = palette_match!(palette.text_unselected.emphasis_1); let shortcut_left_separator = Style::new().fg(white_color).bold().paint(" ("); let shortcut_right_separator = Style::new().fg(white_color).bold().paint("): "); let floating_panes = "FLOATING PANES VISIBLE"; @@ -477,13 +459,10 @@ pub fn floating_panes_are_visible(mode_info: &ModeInfo) -> LinePart { } } -pub fn locked_fullscreen_panes_to_hide(palette: &Palette, panes_to_hide: usize) -> LinePart { - let text_color = palette_match!(match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }); - let green_color = palette_match!(palette.green); - let orange_color = palette_match!(palette.orange); +pub fn locked_fullscreen_panes_to_hide(palette: &Styling, panes_to_hide: usize) -> LinePart { + let text_color = palette_match!(palette.text_unselected.base); + let green_color = palette_match!(palette.text_unselected.emphasis_3); + let orange_color = palette_match!(palette.text_unselected.emphasis_1); let locked_text = " -- INTERFACE LOCKED -- "; let shortcut_left_separator = Style::new().fg(text_color).bold().paint(" ("); let shortcut_right_separator = Style::new().fg(text_color).bold().paint("): "); @@ -512,15 +491,9 @@ pub fn locked_fullscreen_panes_to_hide(palette: &Palette, panes_to_hide: usize) } } -pub fn locked_floating_panes_are_visible(palette: &Palette) -> LinePart { - let white_color = match palette.white { - PaletteColor::Rgb((r, g, b)) => RGB(r, g, b), - PaletteColor::EightBit(color) => Fixed(color), - }; - let orange_color = match palette.orange { - PaletteColor::Rgb((r, g, b)) => RGB(r, g, b), - PaletteColor::EightBit(color) => Fixed(color), - }; +pub fn locked_floating_panes_are_visible(palette: &Styling) -> LinePart { + let white_color = palette_match!(palette.text_unselected.base); + let orange_color = palette_match!(palette.text_unselected.emphasis_1); let shortcut_left_separator = Style::new().fg(white_color).bold().paint(" ("); let shortcut_right_separator = Style::new().fg(white_color).bold().paint(")"); let locked_text = " -- INTERFACE LOCKED -- "; @@ -566,7 +539,7 @@ mod tests { #[test] fn full_length_shortcut_with_key() { let keyvec = vec![KeyWithModifier::new(BareKey::Char('a'))]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(false, keyvec, "Foobar", palette); let ret = unstyle(ret); @@ -577,7 +550,7 @@ mod tests { #[test] fn full_length_shortcut_with_key_first_element() { let keyvec = vec![KeyWithModifier::new(BareKey::Char('a'))]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(true, keyvec, "Foobar", palette); let ret = unstyle(ret); @@ -589,7 +562,7 @@ mod tests { // When there is no binding, we print no shortcut either fn full_length_shortcut_without_key() { let keyvec = vec![]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(false, keyvec, "Foobar", palette); let ret = unstyle(ret); @@ -600,7 +573,7 @@ mod tests { #[test] fn full_length_shortcut_with_key_unprintable_1() { let keyvec = vec![KeyWithModifier::new(BareKey::Enter)]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(false, keyvec, "Foobar", palette); let ret = unstyle(ret); @@ -611,7 +584,7 @@ mod tests { #[test] fn full_length_shortcut_with_key_unprintable_2() { let keyvec = vec![KeyWithModifier::new(BareKey::Backspace)]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(false, keyvec, "Foobar", palette); let ret = unstyle(ret); @@ -622,7 +595,7 @@ mod tests { #[test] fn full_length_shortcut_with_ctrl_key() { let keyvec = vec![KeyWithModifier::new(BareKey::Char('a')).with_ctrl_modifier()]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(false, keyvec, "Foobar", palette); let ret = unstyle(ret); @@ -633,7 +606,7 @@ mod tests { #[test] fn full_length_shortcut_with_alt_key() { let keyvec = vec![KeyWithModifier::new(BareKey::Char('a')).with_alt_modifier()]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(false, keyvec, "Foobar", palette); let ret = unstyle(ret); @@ -648,7 +621,7 @@ mod tests { KeyWithModifier::new(BareKey::Char('b')), KeyWithModifier::new(BareKey::Char('c')), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(false, keyvec, "Foobar", palette); let ret = unstyle(ret); @@ -663,7 +636,7 @@ mod tests { KeyWithModifier::new(BareKey::Char('b')).with_ctrl_modifier(), KeyWithModifier::new(BareKey::Enter), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(false, keyvec, "Foobar", palette); let ret = unstyle(ret); @@ -678,7 +651,7 @@ mod tests { KeyWithModifier::new(BareKey::Char('b')).with_ctrl_modifier(), KeyWithModifier::new(BareKey::Char('c')).with_ctrl_modifier(), ]; - let palette = get_palette(); + let palette = Styling::default(); let ret = full_length_shortcut(false, keyvec, "Foobar", palette); let ret = unstyle(ret); diff --git a/default-plugins/status-bar/src/tip/data/compact_layout.rs b/default-plugins/status-bar/src/tip/data/compact_layout.rs index 77dec8a60f..f7ee7335a3 100644 --- a/default-plugins/status-bar/src/tip/data/compact_layout.rs +++ b/default-plugins/status-bar/src/tip/data/compact_layout.rs @@ -25,7 +25,7 @@ macro_rules! strings { pub fn compact_layout_full(help: &ModeInfo) -> LinePart { // Tip: UI taking up too much space? Start Zellij with // zellij -l compact or remove pane frames with Ctrl +

+ - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_1); let mut bits = vec![ Style::new().paint(" Tip: "), @@ -43,7 +43,7 @@ pub fn compact_layout_full(help: &ModeInfo) -> LinePart { pub fn compact_layout_medium(help: &ModeInfo) -> LinePart { // Tip: To save screen space, start Zellij with // zellij -l compact or remove pane frames with Ctrl +

+ - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_1); let mut bits = vec![ Style::new().paint(" Tip: "), @@ -61,7 +61,7 @@ pub fn compact_layout_medium(help: &ModeInfo) -> LinePart { pub fn compact_layout_short(help: &ModeInfo) -> LinePart { // Save screen space, start Zellij with // zellij -l compact or remove pane frames with Ctrl +

+ - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_1); let mut bits = vec![ Style::new().paint(" Save screen space, start with: "), diff --git a/default-plugins/status-bar/src/tip/data/edit_scrollbuffer.rs b/default-plugins/status-bar/src/tip/data/edit_scrollbuffer.rs index ebd944b779..a8c18ad65e 100644 --- a/default-plugins/status-bar/src/tip/data/edit_scrollbuffer.rs +++ b/default-plugins/status-bar/src/tip/data/edit_scrollbuffer.rs @@ -24,7 +24,7 @@ macro_rules! strings { pub fn edit_scrollbuffer_full(help: &ModeInfo) -> LinePart { // Tip: Search through the scrollbuffer using your default $EDITOR with // Ctrl + + - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_1); let mut bits = vec![ Style::new().paint(" Tip: "), @@ -39,7 +39,7 @@ pub fn edit_scrollbuffer_full(help: &ModeInfo) -> LinePart { pub fn edit_scrollbuffer_medium(help: &ModeInfo) -> LinePart { // Tip: Search the scrollbuffer using your $EDITOR with // Ctrl + + - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_1); let mut bits = vec![ Style::new().paint(" Tip: "), @@ -54,7 +54,7 @@ pub fn edit_scrollbuffer_medium(help: &ModeInfo) -> LinePart { pub fn edit_scrollbuffer_short(help: &ModeInfo) -> LinePart { // Search using $EDITOR with // Ctrl + + - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_1); let mut bits = vec![ Style::new().paint(" Search using "), diff --git a/default-plugins/status-bar/src/tip/data/move_tabs.rs b/default-plugins/status-bar/src/tip/data/move_tabs.rs index 6ad119e49c..690686a1e4 100644 --- a/default-plugins/status-bar/src/tip/data/move_tabs.rs +++ b/default-plugins/status-bar/src/tip/data/move_tabs.rs @@ -25,7 +25,7 @@ macro_rules! strings { pub fn move_tabs_full(help: &ModeInfo) -> LinePart { // Tip: Wrong order of tabs? You can move them to left and right with: // Alt + i (left) and Alt + o (right) - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_3); let bits = vec![ Style::new().paint(" Tip: "), @@ -41,7 +41,7 @@ pub fn move_tabs_full(help: &ModeInfo) -> LinePart { pub fn move_tabs_medium(help: &ModeInfo) -> LinePart { // Tip: You can move tabs to left and right with: // Alt + i (left) and Alt + o (right) - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_3); let bits = vec![ Style::new().paint(" Tip: "), @@ -56,7 +56,7 @@ pub fn move_tabs_medium(help: &ModeInfo) -> LinePart { pub fn move_tabs_short(help: &ModeInfo) -> LinePart { // Move tabs with: Alt + i (left) and Alt + o (right) - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_3); let bits = vec![ Style::new().paint(" Move tabs with: "), diff --git a/default-plugins/status-bar/src/tip/data/send_mouse_click_to_terminal.rs b/default-plugins/status-bar/src/tip/data/send_mouse_click_to_terminal.rs index 7daabeb6dd..69c9057f7a 100644 --- a/default-plugins/status-bar/src/tip/data/send_mouse_click_to_terminal.rs +++ b/default-plugins/status-bar/src/tip/data/send_mouse_click_to_terminal.rs @@ -23,8 +23,8 @@ macro_rules! strings { pub fn mouse_click_to_terminal_full(help: &ModeInfo) -> LinePart { // Tip: SHIFT + bypasses Zellij and sends the mouse click directly to the terminal - let green_color = palette_match!(help.style.colors.green); - let orange_color = palette_match!(help.style.colors.orange); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_3); + let orange_color = palette_match!(help.style.colors.text_unselected.emphasis_1); strings!(&[ Style::new().paint(" Tip: "), @@ -37,8 +37,8 @@ pub fn mouse_click_to_terminal_full(help: &ModeInfo) -> LinePart { pub fn mouse_click_to_terminal_medium(help: &ModeInfo) -> LinePart { // Tip: SHIFT + sends the click directly to the terminal - let green_color = palette_match!(help.style.colors.green); - let orange_color = palette_match!(help.style.colors.orange); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_3); + let orange_color = palette_match!(help.style.colors.text_unselected.emphasis_1); strings!(&[ Style::new().paint(" Tip: "), Style::new().fg(orange_color).bold().paint("Shift"), @@ -50,8 +50,8 @@ pub fn mouse_click_to_terminal_medium(help: &ModeInfo) -> LinePart { pub fn mouse_click_to_terminal_short(help: &ModeInfo) -> LinePart { // Tip: SHIFT + => sends click to terminal. - let green_color = palette_match!(help.style.colors.green); - let orange_color = palette_match!(help.style.colors.orange); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_3); + let orange_color = palette_match!(help.style.colors.text_unselected.emphasis_1); strings!(&[ Style::new().paint(" Tip: "), diff --git a/default-plugins/status-bar/src/tip/data/use_mouse.rs b/default-plugins/status-bar/src/tip/data/use_mouse.rs index 4bbfbf948d..da4fa57bba 100644 --- a/default-plugins/status-bar/src/tip/data/use_mouse.rs +++ b/default-plugins/status-bar/src/tip/data/use_mouse.rs @@ -24,7 +24,7 @@ macro_rules! strings { pub fn use_mouse_full(help: &ModeInfo) -> LinePart { // Tip: Use the mouse to switch pane focus, scroll through the pane // scrollbuffer, switch or scroll through tabs - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_3); strings!(&[ Style::new().paint(" Tip: "), @@ -36,7 +36,7 @@ pub fn use_mouse_full(help: &ModeInfo) -> LinePart { pub fn use_mouse_medium(help: &ModeInfo) -> LinePart { // Tip: Use the mouse to switch panes/tabs or scroll through the pane // scrollbuffer - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_3); strings!(&[ Style::new().paint(" Tip: "), @@ -47,7 +47,7 @@ pub fn use_mouse_medium(help: &ModeInfo) -> LinePart { pub fn use_mouse_short(help: &ModeInfo) -> LinePart { // Tip: Use the mouse to switch panes/tabs or scroll - let green_color = palette_match!(help.style.colors.green); + let green_color = palette_match!(help.style.colors.text_unselected.emphasis_3); strings!(&[ Style::new().fg(green_color).bold().paint(" Use the mouse"), diff --git a/default-plugins/status-bar/src/tip/data/zellij_setup_check.rs b/default-plugins/status-bar/src/tip/data/zellij_setup_check.rs index 3dd7b6d853..62eb0ad205 100644 --- a/default-plugins/status-bar/src/tip/data/zellij_setup_check.rs +++ b/default-plugins/status-bar/src/tip/data/zellij_setup_check.rs @@ -23,7 +23,7 @@ macro_rules! strings { pub fn zellij_setup_check_full(help: &ModeInfo) -> LinePart { // Tip: Having issues with Zellij? Try running "zellij setup --check" - let orange_color = palette_match!(help.style.colors.orange); + let orange_color = palette_match!(help.style.colors.text_unselected.emphasis_1); strings!(&[ Style::new().paint(" Tip: "), @@ -37,7 +37,7 @@ pub fn zellij_setup_check_full(help: &ModeInfo) -> LinePart { pub fn zellij_setup_check_medium(help: &ModeInfo) -> LinePart { // Tip: Run "zellij setup --check" to find issues - let orange_color = palette_match!(help.style.colors.orange); + let orange_color = palette_match!(help.style.colors.text_unselected.emphasis_1); strings!(&[ Style::new().paint(" Tip: "), @@ -52,7 +52,7 @@ pub fn zellij_setup_check_medium(help: &ModeInfo) -> LinePart { pub fn zellij_setup_check_short(help: &ModeInfo) -> LinePart { // Run "zellij setup --check" to find issues - let orange_color = palette_match!(help.style.colors.orange); + let orange_color = palette_match!(help.style.colors.text_unselected.emphasis_1); strings!(&[ Style::new().paint(" Run "), diff --git a/default-plugins/tab-bar/src/line.rs b/default-plugins/tab-bar/src/line.rs index 349981f4d8..65c732f8b8 100644 --- a/default-plugins/tab-bar/src/line.rs +++ b/default-plugins/tab-bar/src/line.rs @@ -21,7 +21,7 @@ fn populate_tabs_in_tab_line( tabs_after_active: &mut Vec, tabs_to_render: &mut Vec, cols: usize, - palette: Palette, + palette: Styling, capabilities: PluginCapabilities, ) { let mut middle_size = get_current_title_len(tabs_to_render); @@ -113,7 +113,7 @@ fn populate_tabs_in_tab_line( fn left_more_message( tab_count_to_the_left: usize, - palette: Palette, + palette: Styling, separator: &str, tab_index: usize, ) -> LinePart { @@ -128,13 +128,15 @@ fn left_more_message( // 238 // chars length plus separator length on both sides let more_text_len = more_text.width() + 2 * separator.width(); - let (text_color, sep_color) = match palette.theme_hue { - ThemeHue::Dark => (palette.white, palette.black), - ThemeHue::Light => (palette.black, palette.white), - }; - let left_separator = style!(sep_color, palette.orange).paint(separator); - let more_styled_text = style!(text_color, palette.orange).bold().paint(more_text); - let right_separator = style!(palette.orange, sep_color).paint(separator); + let (text_color, sep_color) = ( + palette.text_unselected.base, + palette.text_unselected.background, + ); + let left_separator = style!(sep_color, palette.ribbon_unselected.background).paint(separator); + let more_styled_text = style!(text_color, palette.ribbon_unselected.background) + .bold() + .paint(more_text); + let right_separator = style!(palette.ribbon_unselected.background, sep_color).paint(separator); let more_styled_text = ANSIStrings(&[left_separator, more_styled_text, right_separator]).to_string(); LinePart { @@ -146,7 +148,7 @@ fn left_more_message( fn right_more_message( tab_count_to_the_right: usize, - palette: Palette, + palette: Styling, separator: &str, tab_index: usize, ) -> LinePart { @@ -160,13 +162,15 @@ fn right_more_message( }; // chars length plus separator length on both sides let more_text_len = more_text.width() + 2 * separator.width(); - let (text_color, sep_color) = match palette.theme_hue { - ThemeHue::Dark => (palette.white, palette.black), - ThemeHue::Light => (palette.black, palette.white), - }; - let left_separator = style!(sep_color, palette.orange).paint(separator); - let more_styled_text = style!(text_color, palette.orange).bold().paint(more_text); - let right_separator = style!(palette.orange, sep_color).paint(separator); + let (text_color, sep_color) = ( + palette.text_unselected.base, + palette.text_unselected.background, + ); + let left_separator = style!(sep_color, palette.ribbon_unselected.background).paint(separator); + let more_styled_text = style!(text_color, palette.ribbon_unselected.background) + .bold() + .paint(more_text); + let right_separator = style!(palette.ribbon_unselected.background, sep_color).paint(separator); let more_styled_text = ANSIStrings(&[left_separator, more_styled_text, right_separator]).to_string(); LinePart { @@ -176,18 +180,12 @@ fn right_more_message( } } -fn tab_line_prefix(session_name: Option<&str>, palette: Palette, cols: usize) -> Vec { +fn tab_line_prefix(session_name: Option<&str>, palette: Styling, cols: usize) -> Vec { let prefix_text = " Zellij ".to_string(); let prefix_text_len = prefix_text.chars().count(); - let text_color = match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }; - let bg_color = match palette.theme_hue { - ThemeHue::Dark => palette.black, - ThemeHue::Light => palette.white, - }; + let text_color = palette.text_unselected.base; + let bg_color = palette.text_unselected.background; let prefix_styled_text = style!(text_color, bg_color).bold().paint(prefix_text); let mut parts = vec![LinePart { part: prefix_styled_text.to_string(), @@ -197,10 +195,7 @@ fn tab_line_prefix(session_name: Option<&str>, palette: Palette, cols: usize) -> if let Some(name) = session_name { let name_part = format!("({}) ", name); let name_part_len = name_part.width(); - let text_color = match palette.theme_hue { - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, - }; + let text_color = palette.text_unselected.base; let name_part_styled_text = style!(text_color, bg_color).bold().paint(name_part); if cols.saturating_sub(prefix_text_len) >= name_part_len { parts.push(LinePart { @@ -226,7 +221,7 @@ pub fn tab_line( mut all_tabs: Vec, active_tab_index: usize, cols: usize, - palette: Palette, + palette: Styling, capabilities: PluginCapabilities, hide_session_name: bool, tab_info: Option<&TabInfo>, diff --git a/default-plugins/tab-bar/src/main.rs b/default-plugins/tab-bar/src/main.rs index 8230467d1a..dbd507a4dd 100644 --- a/default-plugins/tab-bar/src/main.rs +++ b/default-plugins/tab-bar/src/main.rs @@ -142,10 +142,7 @@ impl ZellijPlugin for State { .iter() .fold(String::new(), |output, part| output + &part.part); - let background = match self.mode_info.style.colors.theme_hue { - ThemeHue::Dark => self.mode_info.style.colors.black, - ThemeHue::Light => self.mode_info.style.colors.white, - }; + let background = self.mode_info.style.colors.text_unselected.background; match background { PaletteColor::Rgb((r, g, b)) => { print!("{}\u{1b}[48;2;{};{};{}m\u{1b}[0K", output, r, g, b); diff --git a/default-plugins/tab-bar/src/tab.rs b/default-plugins/tab-bar/src/tab.rs index 5044ac8722..6395460067 100644 --- a/default-plugins/tab-bar/src/tab.rs +++ b/default-plugins/tab-bar/src/tab.rs @@ -4,12 +4,12 @@ use unicode_width::UnicodeWidthStr; use zellij_tile::prelude::*; use zellij_tile_utils::style; -fn cursors(focused_clients: &[ClientId], palette: Palette) -> (Vec, usize) { +fn cursors(focused_clients: &[ClientId], palette: Styling) -> (Vec, usize) { // cursor section, text length let mut len = 0; let mut cursors = vec![]; for client_id in focused_clients.iter() { - if let Some(color) = client_id_to_colors(*client_id, palette) { + if let Some(color) = client_id_to_colors(*client_id, palette.multiplayer_user_colors) { cursors.push(style!(color.1, color.0).paint(" ")); len += 1; } @@ -21,26 +21,28 @@ pub fn render_tab( text: String, tab: &TabInfo, is_alternate_tab: bool, - palette: Palette, + palette: Styling, separator: &str, ) -> LinePart { let focused_clients = tab.other_focused_clients.as_slice(); let separator_width = separator.width(); - let alternate_tab_color = match palette.theme_hue { - // TODO: only do this if we don't have the arrow capabilities - ThemeHue::Dark => palette.white, - ThemeHue::Light => palette.black, + + let alternate_tab_color = if is_alternate_tab { + palette.text_unselected.background + } else { + palette.ribbon_unselected.background }; let background_color = if tab.active { - palette.green + palette.ribbon_selected.background } else if is_alternate_tab { alternate_tab_color } else { - palette.fg + palette.ribbon_unselected.background }; - let foreground_color = match palette.theme_hue { - ThemeHue::Dark => palette.black, - ThemeHue::Light => palette.white, + let foreground_color = if tab.active { + palette.ribbon_selected.base + } else { + palette.ribbon_unselected.base }; let left_separator = style!(foreground_color, background_color).paint(separator); let mut tab_text_len = text.width() + (separator_width * 2) + 2; // +2 for padding @@ -84,7 +86,7 @@ pub fn tab_style( mut tabname: String, tab: &TabInfo, mut is_alternate_tab: bool, - palette: Palette, + palette: Styling, capabilities: PluginCapabilities, ) -> LinePart { let separator = tab_separator(capabilities); diff --git a/zellij-client/src/lib.rs b/zellij-client/src/lib.rs index 422e205283..ce85d3e400 100644 --- a/zellij-client/src/lib.rs +++ b/zellij-client/src/lib.rs @@ -206,15 +206,15 @@ pub fn start_client( envs::set_zellij("0".to_string()); config.env.set_vars(); - let palette = config + let styling = config .theme_config(&config_options) - .unwrap_or_else(|| os_input.load_palette()); + .unwrap_or_else(|| os_input.load_palette().into()); let full_screen_ws = os_input.get_terminal_size_using_fd(0); let client_attributes = ClientAttributes { size: full_screen_ws, style: Style { - colors: palette, + colors: styling, rounded_corners: config.ui.pane_frames.rounded_corners, hide_session_name: config.ui.pane_frames.hide_session_name, }, @@ -574,7 +574,7 @@ pub fn start_server_detached( let palette = config .theme_config(&config_options) - .unwrap_or_else(|| os_input.load_palette()); + .unwrap_or_else(|| os_input.load_palette().into()); let client_attributes = ClientAttributes { size: Size { rows: 50, cols: 50 }, // just so size is not 0, it doesn't matter because we diff --git a/zellij-server/src/panes/grid.rs b/zellij-server/src/panes/grid.rs index c22cb4808c..0686a9c177 100644 --- a/zellij-server/src/panes/grid.rs +++ b/zellij-server/src/panes/grid.rs @@ -1085,14 +1085,19 @@ impl Grid { .selection .contains_row(character_chunk.y.saturating_sub(content_y)) { - let background_color = match style.colors.bg { + let background_color = match style.colors.text_selected.background { PaletteColor::Rgb(rgb) => AnsiCode::RgbCode(rgb), PaletteColor::EightBit(col) => AnsiCode::ColorIndex(col), }; + let foreground_color = match style.colors.text_selected.base { + PaletteColor::Rgb(rgb) => AnsiCode::RgbCode(rgb), + PaletteColor::EightBit(col) => AnsiCode::ColorIndex(col), + }; + character_chunk.add_selection_and_colors( self.selection, background_color, - None, + Some(foreground_color), content_x, content_y, ); @@ -1101,9 +1106,15 @@ impl Grid { if res.contains_row(character_chunk.y.saturating_sub(content_y)) { let (select_background_palette, select_foreground_palette) = if Some(res) == self.search_results.active.as_ref() { - (style.colors.orange, style.colors.black) + ( + style.colors.text_unselected.emphasis_1, + style.colors.text_unselected.background, + ) } else { - (style.colors.green, style.colors.black) + ( + style.colors.text_unselected.emphasis_3, + style.colors.text_unselected.background, + ) }; let background_color = match select_background_palette { PaletteColor::Rgb(rgb) => AnsiCode::RgbCode(rgb), diff --git a/zellij-server/src/panes/plugin_pane.rs b/zellij-server/src/panes/plugin_pane.rs index f7ad387114..d60701d4cb 100644 --- a/zellij-server/src/panes/plugin_pane.rs +++ b/zellij-server/src/panes/plugin_pane.rs @@ -617,7 +617,7 @@ impl Pane for PluginPane { .unwrap(); } fn add_red_pane_frame_color_override(&mut self, error_text: Option) { - self.pane_frame_color_override = Some((self.style.colors.red, error_text)); + self.pane_frame_color_override = Some((self.style.colors.exit_code_error.base, error_text)); } fn clear_pane_frame_color_override(&mut self) { self.pane_frame_color_override = None; @@ -696,10 +696,10 @@ impl PluginPane { } } fn display_request_permission_message(&self, plugin_permission: &PluginPermission) -> String { - let bold_white = style!(self.style.colors.white).bold(); - let cyan = style!(self.style.colors.cyan).bold(); - let orange = style!(self.style.colors.orange).bold(); - let green = style!(self.style.colors.green).bold(); + let bold_white = style!(self.style.colors.text_unselected.base).bold(); + let cyan = style!(self.style.colors.text_unselected.emphasis_2).bold(); + let orange = style!(self.style.colors.text_unselected.emphasis_1).bold(); + let green = style!(self.style.colors.text_unselected.emphasis_3).bold(); let mut messages = String::new(); let permissions: BTreeSet = diff --git a/zellij-server/src/panes/terminal_character.rs b/zellij-server/src/panes/terminal_character.rs index 3bdc6559fd..444ab550c1 100644 --- a/zellij-server/src/panes/terminal_character.rs +++ b/zellij-server/src/panes/terminal_character.rs @@ -5,6 +5,7 @@ use std::rc::Rc; use unicode_width::UnicodeWidthChar; use unicode_width::UnicodeWidthStr; +use zellij_utils::data::StyleDeclaration; use zellij_utils::input::command::RunCommand; use zellij_utils::{ data::{PaletteColor, Style}, @@ -762,6 +763,14 @@ impl Display for CharacterStyles { } } +impl From for CharacterStyles { + fn from(declaration: StyleDeclaration) -> Self { + RESET_STYLES + .foreground(Some(declaration.base.into())) + .background(Some(declaration.background.into())) + } +} + #[derive(Clone, Copy, Debug, PartialEq)] pub enum LinkAnchor { Start(u16), @@ -977,7 +986,9 @@ pub fn render_first_run_banner( Some(run_command) => { let bold_text = RESET_STYLES.bold(Some(AnsiCode::On)); let command_color_text = RESET_STYLES - .foreground(Some(AnsiCode::from(style.colors.green))) + .foreground(Some(AnsiCode::from( + style.colors.text_unselected.emphasis_3, + ))) .bold(Some(AnsiCode::On)); let waiting_to_run_text = "Waiting to run: "; let command_text = run_command.to_string(); @@ -1002,7 +1013,9 @@ pub fn render_first_run_banner( let ctrl_c_bare_text = "Ctrl-c"; let controls_bare_text_fourth_part = "> exit"; let controls_color = RESET_STYLES - .foreground(Some(AnsiCode::from(style.colors.orange))) + .foreground(Some(AnsiCode::from( + style.colors.text_unselected.emphasis_1, + ))) .bold(Some(AnsiCode::On)); let controls_line_length = controls_bare_text_first_part.len() + enter_bare_text.len() @@ -1054,7 +1067,9 @@ pub fn render_first_run_banner( let ctrl_c_bare_text = "Ctrl-c"; let controls_bare_text_fourth_part = "> exit"; let controls_color = RESET_STYLES - .foreground(Some(AnsiCode::from(style.colors.orange))) + .foreground(Some(AnsiCode::from( + style.colors.text_unselected.emphasis_1, + ))) .bold(Some(AnsiCode::On)); let controls_line_length = controls_bare_text_first_part.len() + enter_bare_text.len() diff --git a/zellij-server/src/panes/terminal_pane.rs b/zellij-server/src/panes/terminal_pane.rs index 4df0552129..c162078ba8 100644 --- a/zellij-server/src/panes/terminal_pane.rs +++ b/zellij-server/src/panes/terminal_pane.rs @@ -714,7 +714,7 @@ impl Pane for TerminalPane { self.set_should_render(true); } fn add_red_pane_frame_color_override(&mut self, error_text: Option) { - self.pane_frame_color_override = Some((self.style.colors.red, error_text)); + self.pane_frame_color_override = Some((self.style.colors.exit_code_error.base, error_text)); } fn clear_pane_frame_color_override(&mut self) { self.pane_frame_color_override = None; diff --git a/zellij-server/src/ui/components/mod.rs b/zellij-server/src/ui/components/mod.rs index 8fcfcc143f..43d628e3fd 100644 --- a/zellij-server/src/ui/components/mod.rs +++ b/zellij-server/src/ui/components/mod.rs @@ -10,7 +10,7 @@ use zellij_utils::{data::Style, lazy_static::lazy_static, regex::Regex, vte}; use component_coordinates::{is_too_high, is_too_wide, Coordinates}; use nested_list::{nested_list, parse_nested_list_items}; -use ribbon::{emphasis_variants_for_ribbon, emphasis_variants_for_selected_ribbon, ribbon}; +use ribbon::ribbon; use table::table; use text::{parse_text, parse_text_params, stringify_text, text, Text}; @@ -87,7 +87,6 @@ impl<'a> UiComponentParser<'a> { columns, rows, stringified_params, - Some(self.style.colors.green), &self.style, component_coordinates, ); diff --git a/zellij-server/src/ui/components/nested_list.rs b/zellij-server/src/ui/components/nested_list.rs index 9b60d57421..e1625312f3 100644 --- a/zellij-server/src/ui/components/nested_list.rs +++ b/zellij-server/src/ui/components/nested_list.rs @@ -1,7 +1,7 @@ use super::{ is_too_high, parse_indices, parse_selected, parse_text, stringify_text, Coordinates, Text, }; -use crate::panes::terminal_character::{AnsiCode, RESET_STYLES}; +use crate::panes::terminal_character::{AnsiCode, CharacterStyles, RESET_STYLES}; use zellij_utils::data::Style; use unicode_width::UnicodeWidthChar; @@ -26,9 +26,10 @@ pub fn nested_list( if is_too_high(line_index + 1, &coordinates) { break; } - let mut reset_styles_for_item = RESET_STYLES; - if line_item.text.selected { - reset_styles_for_item.background = None; + let style_declaration = if line_item.text.selected { + style.colors.list_selected + } else { + style.colors.list_unselected }; let padding = line_item.indentation_level * 2 + 1; let bulletin = if line_item.indentation_level % 2 == 0 { @@ -36,13 +37,13 @@ pub fn nested_list( } else { "- " }; - let text_style = reset_styles_for_item.bold(Some(AnsiCode::On)); + let text_style = CharacterStyles::from(style_declaration); let (mut text, text_width) = stringify_text( &line_item.text, Some(padding + bulletin.len()), &coordinates, - style, - text_style, + &style_declaration, + text_style.bold(Some(AnsiCode::On)), ); text = pad_line(text, max_width, padding, text_width); let go_to_row_instruction = coordinates @@ -55,23 +56,14 @@ pub fn nested_list( "".to_owned() } }); - if line_item.text.selected { - let selected_background = RESET_STYLES.background(Some(style.colors.bg.into())); - stringified.push_str(&format!( - "{}{}{}{:padding$}{bulletin}{}{text}{}", - go_to_row_instruction, - selected_background, - reset_styles_for_item, - " ", - text_style, - RESET_STYLES - )); - } else { - stringified.push_str(&format!( - "{}{}{:padding$}{bulletin}{}{text}{}", - go_to_row_instruction, reset_styles_for_item, " ", text_style, RESET_STYLES - )); - } + stringified.push_str(&format!( + "{}{}{:padding$}{bulletin}{}{text}{}", + go_to_row_instruction, + text_style, + " ", + text_style.bold(Some(AnsiCode::On)), + RESET_STYLES + )); } stringified.as_bytes().to_vec() } diff --git a/zellij-server/src/ui/components/ribbon.rs b/zellij-server/src/ui/components/ribbon.rs index 7f0f781592..b1b9901ce8 100644 --- a/zellij-server/src/ui/components/ribbon.rs +++ b/zellij-server/src/ui/components/ribbon.rs @@ -1,6 +1,5 @@ -use super::{is_too_wide, Coordinates, Text}; +use super::{text::stringify_text, Coordinates, Text}; use crate::panes::terminal_character::{AnsiCode, CharacterStyles, RESET_STYLES}; -use unicode_width::UnicodeWidthChar; use zellij_utils::data::{PaletteColor, Style}; static ARROW_SEPARATOR: &str = ""; @@ -12,21 +11,24 @@ pub fn ribbon( component_coordinates: Option, ) -> Vec { let colors = style.colors; - let (first_arrow_styles, text_style, last_arrow_styles) = if content.selected { - ( - character_style(colors.black, colors.green), - character_style(colors.black, colors.green), - character_style(colors.green, colors.black), - ) + let background = colors.text_unselected.background; + let declaration = if content.selected { + colors.ribbon_selected } else { - ( - character_style(colors.black, colors.fg), - character_style(colors.black, colors.fg), - character_style(colors.fg, colors.black), - ) + colors.ribbon_unselected }; - let (text, _text_width) = - stringify_ribbon_text(&content, &component_coordinates, style, text_style); + let (first_arrow_styles, text_style, last_arrow_styles) = ( + character_style(background, declaration.background), + character_style(declaration.base, declaration.background), + character_style(declaration.background, background), + ); + let (text, _text_width) = stringify_text( + &content, + None, + &component_coordinates, + &declaration, + text_style, + ); let mut stringified = component_coordinates .map(|c| c.to_string()) .unwrap_or_else(|| String::new()); @@ -45,68 +47,6 @@ pub fn ribbon( stringified.as_bytes().to_vec() } -pub fn emphasis_variants_for_ribbon(style: &Style) -> [PaletteColor; 4] { - [ - style.colors.red, - style.colors.white, - style.colors.blue, - style.colors.magenta, - ] -} - -pub fn emphasis_variants_for_selected_ribbon(style: &Style) -> [PaletteColor; 4] { - [ - style.colors.red, - style.colors.orange, - style.colors.magenta, - style.colors.blue, - ] -} - -fn stringify_ribbon_text( - text: &Text, - coordinates: &Option, - style: &Style, - text_style: CharacterStyles, -) -> (String, usize) { - let mut stringified = String::new(); - let mut text_width = 0; - for (i, character) in text.text.chars().enumerate() { - let character_width = character.width().unwrap_or(0); - if is_too_wide(character_width, text_width, &coordinates) { - break; - } - if !text.indices.is_empty() { - let character_with_styling = - color_ribbon_index_character(character, i, &text, style, text_style); - stringified.push_str(&character_with_styling); - } else { - stringified.push(character); - } - text_width += character_width; - } - (stringified, text_width) -} - -fn color_ribbon_index_character( - character: char, - index: usize, - text: &Text, - style: &Style, - base_style: CharacterStyles, -) -> String { - let character_style = if text.selected { - text.style_of_index_for_selected_ribbon(index, style) - .map(|foreground_style| base_style.foreground(Some(foreground_style.into()))) - .unwrap_or(base_style) - } else { - text.style_of_index_for_ribbon(index, style) - .map(|foreground_style| base_style.foreground(Some(foreground_style.into()))) - .unwrap_or(base_style) - }; - format!("{}{}{}", character_style, character, base_style) -} - fn character_style(foreground: PaletteColor, background: PaletteColor) -> CharacterStyles { RESET_STYLES .foreground(Some(foreground.into())) diff --git a/zellij-server/src/ui/components/table.rs b/zellij-server/src/ui/components/table.rs index 4842f93e74..c8a3c1a4e1 100644 --- a/zellij-server/src/ui/components/table.rs +++ b/zellij-server/src/ui/components/table.rs @@ -1,16 +1,15 @@ use super::{is_too_high, is_too_wide, stringify_text, Coordinates, Text}; -use crate::panes::terminal_character::{AnsiCode, RESET_STYLES}; -use std::collections::BTreeMap; -use zellij_utils::{ - data::{PaletteColor, Style}, - shared::ansi_len, +use crate::panes::{ + terminal_character::{AnsiCode, RESET_STYLES}, + CharacterStyles, }; +use std::collections::BTreeMap; +use zellij_utils::{data::Style, shared::ansi_len}; pub fn table( columns: usize, _rows: usize, contents: Vec, - title_color: Option, style: &Style, coordinates: Option, ) -> Vec { @@ -18,30 +17,30 @@ pub fn table( // we first arrange the data by columns so that we can pad them by the widest one let stringified_columns = stringify_table_columns(contents, columns); let stringified_rows = stringify_table_rows(stringified_columns, &coordinates); - let title_styles = RESET_STYLES - .foreground(title_color.map(|t| t.into())) - .bold(Some(AnsiCode::On)); - let cell_styles = RESET_STYLES.bold(Some(AnsiCode::On)); for (row_index, (_, row)) in stringified_rows.into_iter().enumerate() { let is_title_row = row_index == 0; if is_too_high(row_index + 1, &coordinates) { break; } for cell in row { - let mut reset_styles_for_item = RESET_STYLES; - let mut text_style = if is_title_row { - title_styles + let reset_styles_for_item = RESET_STYLES; + let declaration = if is_title_row { + style.colors.table_title } else { - cell_styles + if cell.selected { + style.colors.table_cell_selected + } else { + style.colors.table_cell_unselected + } }; - if cell.selected { - reset_styles_for_item.background = None; - text_style = text_style.background(Some(style.colors.bg.into())); - } // here we intentionally don't pass our coordinates even if we have them, because // these cells have already been padded and truncated - let (text, _text_width) = stringify_text(&cell, None, &None, style, text_style); - stringified.push_str(&format!("{}{}{} ", text_style, text, reset_styles_for_item)); + let text_styles = CharacterStyles::from(declaration).bold(Some(AnsiCode::On)); + let (text, _text_width) = stringify_text(&cell, None, &None, &declaration, text_styles); + stringified.push_str(&format!( + "{}{}{} ", + text_styles, text, reset_styles_for_item + )); } let next_row_instruction = coordinates .as_ref() diff --git a/zellij-server/src/ui/components/text.rs b/zellij-server/src/ui/components/text.rs index cb94eebe02..df82482f86 100644 --- a/zellij-server/src/ui/components/text.rs +++ b/zellij-server/src/ui/components/text.rs @@ -1,10 +1,7 @@ -use super::{ - emphasis_variants_for_ribbon, emphasis_variants_for_selected_ribbon, is_too_wide, - parse_indices, parse_selected, Coordinates, -}; -use crate::panes::terminal_character::{AnsiCode, CharacterStyles, RESET_STYLES}; +use super::{is_too_wide, parse_indices, parse_selected, Coordinates}; +use crate::panes::terminal_character::CharacterStyles; use zellij_utils::{ - data::{PaletteColor, Style}, + data::{PaletteColor, Style, StyleDeclaration}, shared::ansi_len, }; @@ -12,17 +9,26 @@ use unicode_width::UnicodeWidthChar; use zellij_utils::errors::prelude::*; pub fn text(content: Text, style: &Style, component_coordinates: Option) -> Vec { - let mut text_style = RESET_STYLES.bold(Some(AnsiCode::On)); - if content.selected { - text_style = text_style.background(Some(style.colors.bg.into())); - } - let (text, _text_width) = - stringify_text(&content, None, &component_coordinates, style, text_style); + let declaration = if content.selected { + style.colors.text_selected + } else { + style.colors.text_unselected + }; + let base_text_style = CharacterStyles::from(declaration); + let (text, _text_width) = stringify_text( + &content, + None, + &component_coordinates, + &declaration, + base_text_style, + ); match component_coordinates { - Some(component_coordinates) => format!("{}{}{}", component_coordinates, text_style, text) - .as_bytes() - .to_vec(), - None => format!("{}{}", text_style, text).as_bytes().to_vec(), + Some(component_coordinates) => { + format!("{}{}{}", component_coordinates, base_text_style, text) + .as_bytes() + .to_vec() + }, + None => format!("{}{}", base_text_style, text).as_bytes().to_vec(), } } @@ -30,8 +36,8 @@ pub fn stringify_text( text: &Text, left_padding: Option, coordinates: &Option, - style: &Style, - text_style: CharacterStyles, + style: &StyleDeclaration, + base_text_style: CharacterStyles, ) -> (String, usize) { let mut text_width = 0; let mut stringified = String::new(); @@ -47,7 +53,7 @@ pub fn stringify_text( text_width += character_width; if !text.indices.is_empty() { let character_with_styling = - color_index_character(character, i, &text, style, text_style); + color_index_character(character, i, &text, style, base_text_style); stringified.push_str(&character_with_styling); } else { stringified.push(character); @@ -60,25 +66,16 @@ pub fn color_index_character( character: char, index: usize, text: &Text, - style: &Style, + declaration: &StyleDeclaration, base_text_style: CharacterStyles, ) -> String { let character_style = text - .style_of_index(index, style) + .style_of_index(index, declaration) .map(|foreground_style| base_text_style.foreground(Some(foreground_style.into()))) .unwrap_or(base_text_style); format!("{}{}{}", character_style, character, base_text_style) } -pub fn emphasis_variants(style: &Style) -> [PaletteColor; 4] { - [ - style.colors.orange, - style.colors.cyan, - style.colors.green, - style.colors.magenta, - ] -} - pub fn parse_text_params<'a>(params_iter: impl Iterator) -> Vec { params_iter .flat_map(|mut stringified| { @@ -107,38 +104,14 @@ impl Text { self.text.push(' '); } } - pub fn style_of_index(&self, index: usize, style: &Style) -> Option { - let index_variant_styles = emphasis_variants(style); - for i in (0..=3).rev() { - // we do this in reverse to give precedence to the last applied - // style - if let Some(indices) = self.indices.get(i) { - if indices.contains(&index) { - return Some(index_variant_styles[i]); - } - } - } - None - } - pub fn style_of_index_for_ribbon(&self, index: usize, style: &Style) -> Option { - let index_variant_styles = emphasis_variants_for_ribbon(style); - for i in (0..=3).rev() { - // we do this in reverse to give precedence to the last applied - // style - if let Some(indices) = self.indices.get(i) { - if indices.contains(&index) { - return Some(index_variant_styles[i]); - } - } - } - None - } - pub fn style_of_index_for_selected_ribbon( - &self, - index: usize, - style: &Style, - ) -> Option { - let index_variant_styles = emphasis_variants_for_selected_ribbon(style); + + pub fn style_of_index(&self, index: usize, style: &StyleDeclaration) -> Option { + let index_variant_styles = [ + style.emphasis_1, + style.emphasis_2, + style.emphasis_3, + style.emphasis_4, + ]; for i in (0..=3).rev() { // we do this in reverse to give precedence to the last applied // style diff --git a/zellij-server/src/ui/loading_indication.rs b/zellij-server/src/ui/loading_indication.rs index 1c77d03983..a9c55bf9ff 100644 --- a/zellij-server/src/ui/loading_indication.rs +++ b/zellij-server/src/ui/loading_indication.rs @@ -1,7 +1,7 @@ use std::fmt::{Display, Error, Formatter}; use zellij_utils::{ - data::{Palette, PaletteColor}, + data::{PaletteColor, Styling}, errors::prelude::*, }; @@ -24,7 +24,7 @@ pub struct LoadingIndication { error: Option, animation_offset: usize, plugin_name: String, - terminal_emulator_colors: Option, + terminal_emulator_colors: Option, override_previous_error: bool, } @@ -39,7 +39,7 @@ impl LoadingIndication { pub fn set_name(&mut self, plugin_name: String) { self.plugin_name = plugin_name; } - pub fn with_colors(mut self, terminal_emulator_colors: Palette) -> Self { + pub fn with_colors(mut self, terminal_emulator_colors: Styling) -> Self { self.terminal_emulator_colors = Some(terminal_emulator_colors); self } @@ -142,19 +142,27 @@ macro_rules! style { impl Display for LoadingIndication { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { let cyan = match self.terminal_emulator_colors { - Some(terminal_emulator_colors) => style!(terminal_emulator_colors.cyan).bold(), + Some(terminal_emulator_colors) => { + style!(terminal_emulator_colors.exit_code_success.emphasis_1).bold() + }, None => ansi_term::Style::new(), }; let green = match self.terminal_emulator_colors { - Some(terminal_emulator_colors) => style!(terminal_emulator_colors.green).bold(), + Some(terminal_emulator_colors) => { + style!(terminal_emulator_colors.exit_code_success.base).bold() + }, None => ansi_term::Style::new(), }; let yellow = match self.terminal_emulator_colors { - Some(terminal_emulator_colors) => style!(terminal_emulator_colors.yellow).bold(), + Some(terminal_emulator_colors) => { + style!(terminal_emulator_colors.exit_code_error.emphasis_1).bold() + }, None => ansi_term::Style::new(), }; let red = match self.terminal_emulator_colors { - Some(terminal_emulator_colors) => style!(terminal_emulator_colors.red).bold(), + Some(terminal_emulator_colors) => { + style!(terminal_emulator_colors.exit_code_error.base).bold() + }, None => ansi_term::Style::new(), }; let bold = ansi_term::Style::new().bold().italic(); diff --git a/zellij-server/src/ui/pane_boundaries_frame.rs b/zellij-server/src/ui/pane_boundaries_frame.rs index 57cff1ce42..3e9509e2db 100644 --- a/zellij-server/src/ui/pane_boundaries_frame.rs +++ b/zellij-server/src/ui/pane_boundaries_frame.rs @@ -117,7 +117,7 @@ impl PaneFrame { self.color = Some(color); } fn client_cursor(&self, client_id: ClientId) -> Vec { - let color = client_id_to_colors(client_id, self.style.colors); + let color = client_id_to_colors(client_id, self.style.colors.multiplayer_user_colors); background_color(" ", color.map(|c| c.0)) } fn get_corner(&self, corner: &'static str) -> &'static str { @@ -773,9 +773,9 @@ impl PaneFrame { let exited_text = "EXIT CODE: "; let exit_code_text = format!("{}", exit_code); let exit_code_color = if exit_code == 0 { - self.style.colors.green + self.style.colors.exit_code_success.base } else { - self.style.colors.red + self.style.colors.exit_code_error.base }; let right_bracket = " ] "; first_part.append(&mut foreground_color(left_bracket, self.color)); @@ -801,7 +801,7 @@ impl PaneFrame { first_part.append(&mut foreground_color(left_bracket, self.color)); first_part.append(&mut foreground_color( exited_text, - Some(self.style.colors.red), + Some(self.style.colors.exit_code_error.base), )); first_part.append(&mut foreground_color(right_bracket, self.color)); ( @@ -836,7 +836,7 @@ impl PaneFrame { second_part.append(&mut foreground_color(left_enter_bracket, self.color)); second_part.append(&mut foreground_color( enter_text, - Some(self.style.colors.orange), + Some(self.style.colors.text_unselected.emphasis_4), )); second_part.append(&mut foreground_color(right_enter_bracket, self.color)); second_part.append(&mut foreground_color(enter_tip, self.color)); @@ -844,7 +844,7 @@ impl PaneFrame { second_part.append(&mut foreground_color(left_esc_bracket, self.color)); second_part.append(&mut foreground_color( esc_text, - Some(self.style.colors.orange), + Some(self.style.colors.text_unselected.emphasis_4), )); second_part.append(&mut foreground_color(right_esc_bracket, self.color)); second_part.append(&mut foreground_color(esc_tip, self.color)); @@ -852,7 +852,7 @@ impl PaneFrame { second_part.append(&mut foreground_color(left_break_bracket, self.color)); second_part.append(&mut foreground_color( break_text, - Some(self.style.colors.orange), + Some(self.style.colors.text_unselected.emphasis_4), )); second_part.append(&mut foreground_color(right_break_bracket, self.color)); second_part.append(&mut foreground_color(break_tip, self.color)); diff --git a/zellij-server/src/ui/pane_contents_and_ui.rs b/zellij-server/src/ui/pane_contents_and_ui.rs index 72f0b80499..6918884f61 100644 --- a/zellij-server/src/ui/pane_contents_and_ui.rs +++ b/zellij-server/src/ui/pane_contents_and_ui.rs @@ -5,9 +5,7 @@ use crate::ui::boundaries::Boundaries; use crate::ui::pane_boundaries_frame::FrameParams; use crate::ClientId; use std::collections::HashMap; -use zellij_utils::data::{ - client_id_to_colors, single_client_color, InputMode, PaletteColor, Style, -}; +use zellij_utils::data::{client_id_to_colors, InputMode, PaletteColor, Style}; use zellij_utils::errors::prelude::*; pub struct PaneContentsAndUi<'a> { pane: &'a mut Box, @@ -135,7 +133,10 @@ impl<'a> PaneContentsAndUi<'a> { .with_context(|| { format!("failed to render fake cursor if needed for client {client_id}") })?; - if let Some(colors) = client_id_to_colors(*fake_cursor_client_id, self.style.colors) { + if let Some(colors) = client_id_to_colors( + *fake_cursor_client_id, + self.style.colors.multiplayer_user_colors, + ) { if let Some(vte_output) = self.pane.render_fake_cursor(colors.0, colors.1) { self.output.add_post_vte_instruction_to_client( client_id, @@ -259,14 +260,16 @@ impl<'a> PaneContentsAndUi<'a> { match mode { InputMode::Normal | InputMode::Locked => { if session_is_mirrored || !self.multiple_users_exist_in_session { - let colors = single_client_color(self.style.colors); // mirrored sessions only have one focused color - Some(colors.0) + Some(self.style.colors.frame_selected.base) } else { - let colors = client_id_to_colors(client_id, self.style.colors); + let colors = client_id_to_colors( + client_id, + self.style.colors.multiplayer_user_colors, + ); colors.map(|colors| colors.0) } }, - _ => Some(self.style.colors.orange), + _ => Some(self.style.colors.frame_highlight.base), } } else { None diff --git a/zellij-utils/assets/prost/api.style.rs b/zellij-utils/assets/prost/api.style.rs index cd768c3908..62080a5f97 100644 --- a/zellij-utils/assets/prost/api.style.rs +++ b/zellij-utils/assets/prost/api.style.rs @@ -1,12 +1,15 @@ #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Style { + #[deprecated] #[prost(message, optional, tag = "1")] pub palette: ::core::option::Option, #[prost(bool, tag = "2")] pub rounded_corners: bool, #[prost(bool, tag = "3")] pub hide_session_name: bool, + #[prost(message, optional, tag = "4")] + pub styling: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -77,6 +80,40 @@ pub struct RgbColorPayload { #[prost(uint32, tag = "3")] pub blue: u32, } +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Styling { + #[prost(message, repeated, tag = "1")] + pub text_unselected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "2")] + pub text_selected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "3")] + pub ribbon_unselected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "4")] + pub ribbon_selected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "5")] + pub table_title: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "6")] + pub table_cell_unselected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "7")] + pub table_cell_selected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "8")] + pub list_unselected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "9")] + pub list_selected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "10")] + pub frame_unselected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "11")] + pub frame_selected: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "12")] + pub frame_highlight: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "13")] + pub exit_code_success: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "14")] + pub exit_code_error: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "15")] + pub multiplayer_user_colors: ::prost::alloc::vec::Vec, +} #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum ColorType { diff --git a/zellij-utils/src/data.rs b/zellij-utils/src/data.rs index 54c056e359..f2da5819f0 100644 --- a/zellij-utils/src/data.rs +++ b/zellij-utils/src/data.rs @@ -2,6 +2,7 @@ use crate::input::actions::Action; use crate::input::config::ConversionError; use crate::input::keybinds::Keybinds; use crate::input::layout::SplitSize; +use crate::shared::colors as default_colors; use clap::ArgEnum; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; @@ -22,20 +23,21 @@ pub type ClientId = u16; // TODO: merge with crate type? pub fn client_id_to_colors( client_id: ClientId, - colors: Palette, + colors: MultiplayerColors, ) -> Option<(PaletteColor, PaletteColor)> { // (primary color, secondary color) + let black = PaletteColor::EightBit(default_colors::BLACK); match client_id { - 1 => Some((colors.magenta, colors.black)), - 2 => Some((colors.blue, colors.black)), - 3 => Some((colors.purple, colors.black)), - 4 => Some((colors.yellow, colors.black)), - 5 => Some((colors.cyan, colors.black)), - 6 => Some((colors.gold, colors.black)), - 7 => Some((colors.red, colors.black)), - 8 => Some((colors.silver, colors.black)), - 9 => Some((colors.pink, colors.black)), - 10 => Some((colors.brown, colors.black)), + 1 => Some((colors.player_1, black)), + 2 => Some((colors.player_2, black)), + 3 => Some((colors.player_3, black)), + 4 => Some((colors.player_4, black)), + 5 => Some((colors.player_5, black)), + 6 => Some((colors.player_6, black)), + 7 => Some((colors.player_7, black)), + 8 => Some((colors.player_8, black)), + 9 => Some((colors.player_9, black)), + 10 => Some((colors.player_10, black)), _ => None, } } @@ -1129,11 +1131,348 @@ pub struct Palette { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default, Serialize, Deserialize)] pub struct Style { - pub colors: Palette, + pub colors: Styling, pub rounded_corners: bool, pub hide_session_name: bool, } +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] +pub struct Styling { + pub text_unselected: StyleDeclaration, + pub text_selected: StyleDeclaration, + pub ribbon_unselected: StyleDeclaration, + pub ribbon_selected: StyleDeclaration, + pub table_title: StyleDeclaration, + pub table_cell_unselected: StyleDeclaration, + pub table_cell_selected: StyleDeclaration, + pub list_unselected: StyleDeclaration, + pub list_selected: StyleDeclaration, + pub frame_unselected: StyleDeclaration, + pub frame_selected: StyleDeclaration, + pub frame_highlight: StyleDeclaration, + pub exit_code_success: StyleDeclaration, + pub exit_code_error: StyleDeclaration, + pub multiplayer_user_colors: MultiplayerColors, +} + +#[derive(Debug, Copy, Default, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] +pub struct StyleDeclaration { + pub base: PaletteColor, + pub background: PaletteColor, + pub emphasis_1: PaletteColor, + pub emphasis_2: PaletteColor, + pub emphasis_3: PaletteColor, + pub emphasis_4: PaletteColor, +} + +#[derive(Debug, Copy, Default, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] +pub struct MultiplayerColors { + pub player_1: PaletteColor, + pub player_2: PaletteColor, + pub player_3: PaletteColor, + pub player_4: PaletteColor, + pub player_5: PaletteColor, + pub player_6: PaletteColor, + pub player_7: PaletteColor, + pub player_8: PaletteColor, + pub player_9: PaletteColor, + pub player_10: PaletteColor, +} + +pub const DEFAULT_STYLES: Styling = Styling { + text_unselected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::BRIGHT_GRAY), + emphasis_1: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_2: PaletteColor::EightBit(default_colors::CYAN), + emphasis_3: PaletteColor::EightBit(default_colors::GREEN), + emphasis_4: PaletteColor::EightBit(default_colors::MAGENTA), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + text_selected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::BRIGHT_GRAY), + emphasis_1: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_2: PaletteColor::EightBit(default_colors::CYAN), + emphasis_3: PaletteColor::EightBit(default_colors::GREEN), + emphasis_4: PaletteColor::EightBit(default_colors::MAGENTA), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + ribbon_unselected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::BLACK), + emphasis_1: PaletteColor::EightBit(default_colors::RED), + emphasis_2: PaletteColor::EightBit(default_colors::WHITE), + emphasis_3: PaletteColor::EightBit(default_colors::BLUE), + emphasis_4: PaletteColor::EightBit(default_colors::MAGENTA), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + ribbon_selected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::BLACK), + emphasis_1: PaletteColor::EightBit(default_colors::RED), + emphasis_2: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_3: PaletteColor::EightBit(default_colors::MAGENTA), + emphasis_4: PaletteColor::EightBit(default_colors::BLUE), + background: PaletteColor::EightBit(default_colors::GREEN), + }, + exit_code_success: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::GREEN), + emphasis_1: PaletteColor::EightBit(default_colors::CYAN), + emphasis_2: PaletteColor::EightBit(default_colors::BLACK), + emphasis_3: PaletteColor::EightBit(default_colors::MAGENTA), + emphasis_4: PaletteColor::EightBit(default_colors::BLUE), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + exit_code_error: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::RED), + emphasis_1: PaletteColor::EightBit(default_colors::YELLOW), + emphasis_2: PaletteColor::EightBit(default_colors::GOLD), + emphasis_3: PaletteColor::EightBit(default_colors::SILVER), + emphasis_4: PaletteColor::EightBit(default_colors::PURPLE), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + frame_unselected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_1: PaletteColor::EightBit(default_colors::PINK), + emphasis_2: PaletteColor::EightBit(default_colors::GRAY), + emphasis_3: PaletteColor::EightBit(default_colors::BROWN), + emphasis_4: PaletteColor::EightBit(default_colors::BLACK), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + frame_selected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::GREEN), + emphasis_1: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_2: PaletteColor::EightBit(default_colors::CYAN), + emphasis_3: PaletteColor::EightBit(default_colors::MAGENTA), + emphasis_4: PaletteColor::EightBit(default_colors::BROWN), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + frame_highlight: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::GREEN), + emphasis_1: PaletteColor::EightBit(default_colors::GREEN), + emphasis_2: PaletteColor::EightBit(default_colors::GREEN), + emphasis_3: PaletteColor::EightBit(default_colors::GREEN), + emphasis_4: PaletteColor::EightBit(default_colors::GREEN), + background: PaletteColor::EightBit(default_colors::GREEN), + }, + table_title: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::GREEN), + emphasis_1: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_2: PaletteColor::EightBit(default_colors::CYAN), + emphasis_3: PaletteColor::EightBit(default_colors::GREEN), + emphasis_4: PaletteColor::EightBit(default_colors::MAGENTA), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + table_cell_unselected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::BRIGHT_GRAY), + emphasis_1: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_2: PaletteColor::EightBit(default_colors::CYAN), + emphasis_3: PaletteColor::EightBit(default_colors::GREEN), + emphasis_4: PaletteColor::EightBit(default_colors::MAGENTA), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + table_cell_selected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::GREEN), + emphasis_1: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_2: PaletteColor::EightBit(default_colors::CYAN), + emphasis_3: PaletteColor::EightBit(default_colors::RED), + emphasis_4: PaletteColor::EightBit(default_colors::MAGENTA), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + list_unselected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::BRIGHT_GRAY), + emphasis_1: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_2: PaletteColor::EightBit(default_colors::CYAN), + emphasis_3: PaletteColor::EightBit(default_colors::GREEN), + emphasis_4: PaletteColor::EightBit(default_colors::MAGENTA), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + list_selected: StyleDeclaration { + base: PaletteColor::EightBit(default_colors::GREEN), + emphasis_1: PaletteColor::EightBit(default_colors::ORANGE), + emphasis_2: PaletteColor::EightBit(default_colors::CYAN), + emphasis_3: PaletteColor::EightBit(default_colors::RED), + emphasis_4: PaletteColor::EightBit(default_colors::MAGENTA), + background: PaletteColor::EightBit(default_colors::GRAY), + }, + multiplayer_user_colors: MultiplayerColors { + player_1: PaletteColor::EightBit(default_colors::MAGENTA), + player_2: PaletteColor::EightBit(default_colors::BLUE), + player_3: PaletteColor::EightBit(default_colors::PURPLE), + player_4: PaletteColor::EightBit(default_colors::YELLOW), + player_5: PaletteColor::EightBit(default_colors::CYAN), + player_6: PaletteColor::EightBit(default_colors::GOLD), + player_7: PaletteColor::EightBit(default_colors::RED), + player_8: PaletteColor::EightBit(default_colors::SILVER), + player_9: PaletteColor::EightBit(default_colors::PINK), + player_10: PaletteColor::EightBit(default_colors::BROWN), + }, +}; + +impl Default for Styling { + fn default() -> Self { + DEFAULT_STYLES + } +} + +impl From for Palette { + fn from(styling: Styling) -> Self { + Palette { + theme_hue: ThemeHue::Dark, + source: PaletteSource::Default, + fg: styling.ribbon_unselected.background, + bg: styling.text_unselected.background, + red: styling.exit_code_error.base, + green: styling.text_unselected.emphasis_3, + yellow: styling.exit_code_error.emphasis_1, + blue: styling.ribbon_unselected.emphasis_3, + magenta: styling.text_unselected.emphasis_4, + orange: styling.text_unselected.emphasis_1, + cyan: styling.text_unselected.emphasis_2, + black: styling.ribbon_unselected.base, + white: styling.ribbon_unselected.emphasis_2, + gray: styling.list_unselected.background, + purple: styling.multiplayer_user_colors.player_3, + gold: styling.multiplayer_user_colors.player_6, + silver: styling.multiplayer_user_colors.player_8, + pink: styling.multiplayer_user_colors.player_9, + brown: styling.multiplayer_user_colors.player_10, + } + } +} + +impl From for Styling { + fn from(palette: Palette) -> Self { + let (fg, bg) = match palette.theme_hue { + ThemeHue::Light => (palette.black, palette.white), + ThemeHue::Dark => (palette.white, palette.black), + }; + Styling { + text_unselected: StyleDeclaration { + base: fg, + emphasis_1: palette.orange, + emphasis_2: palette.cyan, + emphasis_3: palette.green, + emphasis_4: palette.magenta, + background: bg, + }, + text_selected: StyleDeclaration { + base: fg, + emphasis_1: palette.orange, + emphasis_2: palette.cyan, + emphasis_3: palette.green, + emphasis_4: palette.magenta, + background: palette.bg, + }, + ribbon_unselected: StyleDeclaration { + base: palette.black, + emphasis_1: palette.red, + emphasis_2: palette.white, + emphasis_3: palette.blue, + emphasis_4: palette.magenta, + background: palette.fg, + }, + ribbon_selected: StyleDeclaration { + base: palette.black, + emphasis_1: palette.red, + emphasis_2: palette.orange, + emphasis_3: palette.magenta, + emphasis_4: palette.blue, + background: palette.green, + }, + exit_code_success: StyleDeclaration { + base: palette.green, + emphasis_1: palette.cyan, + emphasis_2: palette.black, + emphasis_3: palette.magenta, + emphasis_4: palette.blue, + background: Default::default(), + }, + exit_code_error: StyleDeclaration { + base: palette.red, + emphasis_1: palette.yellow, + emphasis_2: palette.gold, + emphasis_3: palette.silver, + emphasis_4: palette.purple, + background: Default::default(), + }, + frame_unselected: StyleDeclaration { + base: palette.orange, + emphasis_1: palette.pink, + emphasis_2: palette.gray, + emphasis_3: palette.brown, + emphasis_4: palette.black, + background: Default::default(), + }, + frame_selected: StyleDeclaration { + base: palette.green, + emphasis_1: palette.orange, + emphasis_2: palette.cyan, + emphasis_3: palette.magenta, + emphasis_4: palette.brown, + background: Default::default(), + }, + frame_highlight: StyleDeclaration { + base: palette.green, + emphasis_1: palette.green, + emphasis_2: palette.green, + emphasis_3: palette.green, + emphasis_4: palette.green, + background: Default::default(), + }, + table_title: StyleDeclaration { + base: palette.green, + emphasis_1: palette.orange, + emphasis_2: palette.cyan, + emphasis_3: palette.red, + emphasis_4: palette.magenta, + background: palette.gray, + }, + table_cell_unselected: StyleDeclaration { + base: palette.fg, + emphasis_1: palette.orange, + emphasis_2: palette.cyan, + emphasis_3: palette.green, + emphasis_4: palette.magenta, + background: palette.bg, + }, + table_cell_selected: StyleDeclaration { + base: palette.green, + emphasis_1: palette.orange, + emphasis_2: palette.cyan, + emphasis_3: palette.red, + emphasis_4: palette.magenta, + background: palette.bg, + }, + list_unselected: StyleDeclaration { + base: palette.fg, + emphasis_1: palette.orange, + emphasis_2: palette.cyan, + emphasis_3: palette.green, + emphasis_4: palette.magenta, + background: palette.bg, + }, + list_selected: StyleDeclaration { + base: palette.green, + emphasis_1: palette.orange, + emphasis_2: palette.cyan, + emphasis_3: palette.red, + emphasis_4: palette.magenta, + background: palette.bg, + }, + multiplayer_user_colors: MultiplayerColors { + player_1: palette.magenta, + player_2: palette.blue, + player_3: palette.purple, + player_4: palette.yellow, + player_5: palette.cyan, + player_6: palette.gold, + player_7: palette.red, + player_8: palette.silver, + player_9: palette.pink, + player_10: palette.brown, + }, + } + } +} + // FIXME: Poor devs hashtable since HashTable can't derive `Default`... pub type KeybindsVec = Vec<(InputMode, Vec<(KeyWithModifier, Vec)>)>; diff --git a/zellij-utils/src/input/config.rs b/zellij-utils/src/input/config.rs index 56c6f338af..e53a4a9be1 100644 --- a/zellij-utils/src/input/config.rs +++ b/zellij-utils/src/input/config.rs @@ -1,4 +1,4 @@ -use crate::data::Palette; +use crate::data::Styling; use miette::{Diagnostic, LabeledSpan, NamedSource, SourceCode}; use std::fs::File; use std::io::{self, Read}; @@ -162,7 +162,7 @@ impl TryFrom<&CliArgs> for Config { } impl Config { - pub fn theme_config(&self, opts: &Options) -> Option { + pub fn theme_config(&self, opts: &Options) -> Option { match &opts.theme { Some(theme_name) => self.themes.get_theme(theme_name).map(|theme| theme.palette), None => self.themes.get_theme("default").map(|theme| theme.palette), @@ -238,7 +238,7 @@ impl Config { #[cfg(test)] mod config_test { use super::*; - use crate::data::{InputMode, Palette, PaletteColor, PluginTag}; + use crate::data::{InputMode, Palette, PaletteColor, PluginTag, StyleDeclaration, Styling}; use crate::input::layout::{RunPlugin, RunPluginLocation}; use crate::input::options::{Clipboard, OnForceClose}; use crate::input::plugins::{PluginConfig, PluginType}; @@ -462,7 +462,8 @@ mod config_test { black: PaletteColor::Rgb((0, 0, 0)), white: PaletteColor::Rgb((255, 255, 255)), ..Default::default() - }, + } + .into(), }, ); let expected_themes = Themes::from_data(expected_themes); @@ -519,7 +520,8 @@ mod config_test { black: PaletteColor::Rgb((0, 0, 0)), white: PaletteColor::Rgb((255, 255, 255)), ..Default::default() - }, + } + .into(), }, ); expected_themes.insert( @@ -538,7 +540,8 @@ mod config_test { white: PaletteColor::Rgb((229, 233, 240)), orange: PaletteColor::Rgb((208, 135, 112)), ..Default::default() - }, + } + .into(), }, ); let expected_themes = Themes::from_data(expected_themes); @@ -582,13 +585,316 @@ mod config_test { black: PaletteColor::EightBit(1), white: PaletteColor::EightBit(255), ..Default::default() - }, + } + .into(), }, ); let expected_themes = Themes::from_data(expected_themes); assert_eq!(config.themes, expected_themes, "Theme defined in config"); } + #[test] + fn can_define_style_for_theme_with_hex() { + let config_contents = r##" + themes { + named_theme { + styling { + text_unselected { + base "#DCD7BA" + emphasis_1 "#DCD7CD" + emphasis_2 "#DCD8DD" + emphasis_3 "#DCD899" + emphasis_4 "#ACD7CD" + background "#1F1F28" + } + text_selected { + base "#16161D" + emphasis_1 "#16161D" + emphasis_2 "#16161D" + emphasis_3 "#16161D" + emphasis_4 "#16161D" + background "#9CABCA" + } + ribbon_unselected { + base "#DCD7BA" + emphasis_1 "#7FB4CA" + emphasis_2 "#A3D4D5" + emphasis_3 "#7AA89F" + emphasis_4 "#DCD819" + background "#252535" + } + ribbon_selected { + base "#16161D" + emphasis_1 "#181820" + emphasis_2 "#1A1A22" + emphasis_3 "#2A2A37" + emphasis_4 "#363646" + background "#76946A" + } + table_title { + base "#DCD7BA" + emphasis_1 "#7FB4CA" + emphasis_2 "#A3D4D5" + emphasis_3 "#7AA89F" + emphasis_4 "#DCD819" + background "#252535" + } + table_cell_unselected { + base "#DCD7BA" + emphasis_1 "#DCD7CD" + emphasis_2 "#DCD8DD" + emphasis_3 "#DCD899" + emphasis_4 "#ACD7CD" + background "#1F1F28" + } + table_cell_selected { + base "#16161D" + emphasis_1 "#181820" + emphasis_2 "#1A1A22" + emphasis_3 "#2A2A37" + emphasis_4 "#363646" + background "#76946A" + } + list_unselected { + base "#DCD7BA" + emphasis_1 "#DCD7CD" + emphasis_2 "#DCD8DD" + emphasis_3 "#DCD899" + emphasis_4 "#ACD7CD" + background "#1F1F28" + } + list_selected { + base "#16161D" + emphasis_1 "#181820" + emphasis_2 "#1A1A22" + emphasis_3 "#2A2A37" + emphasis_4 "#363646" + background "#76946A" + } + frame_unselected { + base "#DCD8DD" + emphasis_1 "#7FB4CA" + emphasis_2 "#A3D4D5" + emphasis_3 "#7AA89F" + emphasis_4 "#DCD819" + } + frame_selected { + base "#76946A" + emphasis_1 "#C34043" + emphasis_2 "#C8C093" + emphasis_3 "#ACD7CD" + emphasis_4 "#DCD819" + } + exit_code_success { + base "#76946A" + emphasis_1 "#76946A" + emphasis_2 "#76946A" + emphasis_3 "#76946A" + emphasis_4 "#76946A" + } + exit_code_error { + base "#C34043" + emphasis_1 "#C34043" + emphasis_2 "#C34043" + emphasis_3 "#C34043" + emphasis_4 "#C34043" + } + } + } + } + "##; + + let config = Config::from_kdl(config_contents, None).unwrap(); + let mut expected_themes = HashMap::new(); + expected_themes.insert( + "named_theme".into(), + Theme { + palette: Styling { + text_unselected: StyleDeclaration { + base: PaletteColor::Rgb((220, 215, 186)), + emphasis_1: PaletteColor::Rgb((220, 215, 205)), + emphasis_2: PaletteColor::Rgb((220, 216, 221)), + emphasis_3: PaletteColor::Rgb((220, 216, 153)), + emphasis_4: PaletteColor::Rgb((172, 215, 205)), + background: PaletteColor::Rgb((31, 31, 40)), + }, + text_selected: StyleDeclaration { + base: PaletteColor::Rgb((22, 22, 29)), + emphasis_1: PaletteColor::Rgb((22, 22, 29)), + emphasis_2: PaletteColor::Rgb((22, 22, 29)), + emphasis_3: PaletteColor::Rgb((22, 22, 29)), + emphasis_4: PaletteColor::Rgb((22, 22, 29)), + background: PaletteColor::Rgb((156, 171, 202)), + }, + ribbon_unselected: StyleDeclaration { + base: PaletteColor::Rgb((220, 215, 186)), + emphasis_1: PaletteColor::Rgb((127, 180, 202)), + emphasis_2: PaletteColor::Rgb((163, 212, 213)), + emphasis_3: PaletteColor::Rgb((122, 168, 159)), + emphasis_4: PaletteColor::Rgb((220, 216, 25)), + background: PaletteColor::Rgb((37, 37, 53)), + }, + ribbon_selected: StyleDeclaration { + base: PaletteColor::Rgb((22, 22, 29)), + emphasis_1: PaletteColor::Rgb((24, 24, 32)), + emphasis_2: PaletteColor::Rgb((26, 26, 34)), + emphasis_3: PaletteColor::Rgb((42, 42, 55)), + emphasis_4: PaletteColor::Rgb((54, 54, 70)), + background: PaletteColor::Rgb((118, 148, 106)), + }, + table_title: StyleDeclaration { + base: PaletteColor::Rgb((220, 215, 186)), + emphasis_1: PaletteColor::Rgb((127, 180, 202)), + emphasis_2: PaletteColor::Rgb((163, 212, 213)), + emphasis_3: PaletteColor::Rgb((122, 168, 159)), + emphasis_4: PaletteColor::Rgb((220, 216, 25)), + background: PaletteColor::Rgb((37, 37, 53)), + }, + table_cell_unselected: StyleDeclaration { + base: PaletteColor::Rgb((220, 215, 186)), + emphasis_1: PaletteColor::Rgb((220, 215, 205)), + emphasis_2: PaletteColor::Rgb((220, 216, 221)), + emphasis_3: PaletteColor::Rgb((220, 216, 153)), + emphasis_4: PaletteColor::Rgb((172, 215, 205)), + background: PaletteColor::Rgb((31, 31, 40)), + }, + table_cell_selected: StyleDeclaration { + base: PaletteColor::Rgb((22, 22, 29)), + emphasis_1: PaletteColor::Rgb((24, 24, 32)), + emphasis_2: PaletteColor::Rgb((26, 26, 34)), + emphasis_3: PaletteColor::Rgb((42, 42, 55)), + emphasis_4: PaletteColor::Rgb((54, 54, 70)), + background: PaletteColor::Rgb((118, 148, 106)), + }, + list_unselected: StyleDeclaration { + base: PaletteColor::Rgb((220, 215, 186)), + emphasis_1: PaletteColor::Rgb((220, 215, 205)), + emphasis_2: PaletteColor::Rgb((220, 216, 221)), + emphasis_3: PaletteColor::Rgb((220, 216, 153)), + emphasis_4: PaletteColor::Rgb((172, 215, 205)), + background: PaletteColor::Rgb((31, 31, 40)), + }, + list_selected: StyleDeclaration { + base: PaletteColor::Rgb((22, 22, 29)), + emphasis_1: PaletteColor::Rgb((24, 24, 32)), + emphasis_2: PaletteColor::Rgb((26, 26, 34)), + emphasis_3: PaletteColor::Rgb((42, 42, 55)), + emphasis_4: PaletteColor::Rgb((54, 54, 70)), + background: PaletteColor::Rgb((118, 148, 106)), + }, + frame_unselected: StyleDeclaration { + base: PaletteColor::Rgb((220, 216, 221)), + emphasis_1: PaletteColor::Rgb((127, 180, 202)), + emphasis_2: PaletteColor::Rgb((163, 212, 213)), + emphasis_3: PaletteColor::Rgb((122, 168, 159)), + emphasis_4: PaletteColor::Rgb((220, 216, 25)), + ..Default::default() + }, + frame_selected: StyleDeclaration { + base: PaletteColor::Rgb((118, 148, 106)), + emphasis_1: PaletteColor::Rgb((195, 64, 67)), + emphasis_2: PaletteColor::Rgb((200, 192, 147)), + emphasis_3: PaletteColor::Rgb((172, 215, 205)), + emphasis_4: PaletteColor::Rgb((220, 216, 25)), + ..Default::default() + }, + exit_code_success: StyleDeclaration { + base: PaletteColor::Rgb((118, 148, 106)), + emphasis_1: PaletteColor::Rgb((118, 148, 106)), + emphasis_2: PaletteColor::Rgb((118, 148, 106)), + emphasis_3: PaletteColor::Rgb((118, 148, 106)), + emphasis_4: PaletteColor::Rgb((118, 148, 106)), + ..Default::default() + }, + exit_code_error: StyleDeclaration { + base: PaletteColor::Rgb((195, 64, 67)), + emphasis_1: PaletteColor::Rgb((195, 64, 67)), + emphasis_2: PaletteColor::Rgb((195, 64, 67)), + emphasis_3: PaletteColor::Rgb((195, 64, 67)), + emphasis_4: PaletteColor::Rgb((195, 64, 67)), + ..Default::default() + }, + ..Default::default() + }, + }, + ); + let expected_themes = Themes::from_data(expected_themes); + assert_eq!(config.themes, expected_themes, "Theme defined in config") + } + + #[test] + fn omitting_required_style_errors() { + let config_contents = r##" + themes { + named_theme { + styling { + text_unselected { + base "#DCD7BA" + emphasis_2 "#DCD8DD" + emphasis_3 "#DCD899" + emphasis_4 "#ACD7CD" + background "#1F1F28" + } + } + } + } + "##; + + let config = Config::from_kdl(config_contents, None); + assert!(config.is_err()); + if let Err(ConfigError::KdlError(KdlError { + error_message, + src: _, + offset: _, + len: _, + help_message: _, + })) = config + { + assert_eq!(error_message, "Missing theme color: emphasis_1") + } + } + + #[test] + fn partial_declaration_of_styles_defaults_omitted() { + let config_contents = r##" + themes { + named_theme { + styling { + text_unselected { + base "#DCD7BA" + emphasis_1 "#DCD7CD" + emphasis_2 "#DCD8DD" + emphasis_3 "#DCD899" + emphasis_4 "#ACD7CD" + background "#1F1F28" + } + } + } + } + "##; + + let config = Config::from_kdl(config_contents, None).unwrap(); + let mut expected_themes = HashMap::new(); + expected_themes.insert( + "named_theme".into(), + Theme { + palette: Styling { + text_unselected: StyleDeclaration { + base: PaletteColor::Rgb((220, 215, 186)), + emphasis_1: PaletteColor::Rgb((220, 215, 205)), + emphasis_2: PaletteColor::Rgb((220, 216, 221)), + emphasis_3: PaletteColor::Rgb((220, 216, 153)), + emphasis_4: PaletteColor::Rgb((172, 215, 205)), + background: PaletteColor::Rgb((31, 31, 40)), + }, + ..Default::default() + }, + }, + ); + let expected_themes = Themes::from_data(expected_themes); + assert_eq!(config.themes, expected_themes, "Theme defined in config") + } + #[test] fn can_define_plugin_configuration_in_configfile() { let config_contents = r#" diff --git a/zellij-utils/src/input/theme.rs b/zellij-utils/src/input/theme.rs index bf0edf232c..6e65628664 100644 --- a/zellij-utils/src/input/theme.rs +++ b/zellij-utils/src/input/theme.rs @@ -7,7 +7,7 @@ use std::{ fmt, }; -use crate::data::Palette; +use crate::data::Styling; #[derive(Debug, Default, Clone, Copy, PartialEq, Deserialize, Serialize)] pub struct UiConfig { @@ -72,7 +72,7 @@ impl Themes { #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] pub struct Theme { #[serde(flatten)] - pub palette: Palette, + pub palette: Styling, } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__theme__theme_test__dracula_theme_from_file.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__theme__theme_test__dracula_theme_from_file.snap index 315c6d50eb..3ed9288d48 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__theme__theme_test__dracula_theme_from_file.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__theme__theme_test__dracula_theme_from_file.snap @@ -4,104 +4,623 @@ expression: "format!(\"{:#?}\", theme)" --- { "dracula": Theme { - palette: Palette { - source: Default, - theme_hue: Dark, - fg: Rgb( - ( - 248, - 248, - 242, - ), - ), - bg: Rgb( - ( - 40, - 42, - 54, - ), - ), - black: Rgb( - ( - 0, - 0, - 0, - ), - ), - red: Rgb( - ( - 255, - 85, - 85, - ), - ), - green: Rgb( - ( - 80, - 250, - 123, - ), - ), - yellow: Rgb( - ( - 241, - 250, - 140, - ), - ), - blue: Rgb( - ( - 98, - 114, - 164, - ), - ), - magenta: Rgb( - ( - 255, - 121, - 198, - ), - ), - cyan: Rgb( - ( - 139, - 233, - 253, - ), - ), - white: Rgb( - ( - 255, - 255, - 255, - ), - ), - orange: Rgb( - ( - 255, - 184, - 108, - ), - ), - gray: EightBit( - 0, - ), - purple: EightBit( - 0, - ), - gold: EightBit( - 0, - ), - silver: EightBit( - 0, - ), - pink: EightBit( - 0, - ), - brown: EightBit( - 0, - ), + palette: Styling { + text_unselected: StyleDeclaration { + base: Rgb( + ( + 255, + 255, + 255, + ), + ), + background: Rgb( + ( + 0, + 0, + 0, + ), + ), + emphasis_1: Rgb( + ( + 255, + 184, + 108, + ), + ), + emphasis_2: Rgb( + ( + 139, + 233, + 253, + ), + ), + emphasis_3: Rgb( + ( + 80, + 250, + 123, + ), + ), + emphasis_4: Rgb( + ( + 255, + 121, + 198, + ), + ), + }, + text_selected: StyleDeclaration { + base: Rgb( + ( + 255, + 255, + 255, + ), + ), + background: Rgb( + ( + 40, + 42, + 54, + ), + ), + emphasis_1: Rgb( + ( + 255, + 184, + 108, + ), + ), + emphasis_2: Rgb( + ( + 139, + 233, + 253, + ), + ), + emphasis_3: Rgb( + ( + 80, + 250, + 123, + ), + ), + emphasis_4: Rgb( + ( + 255, + 121, + 198, + ), + ), + }, + ribbon_unselected: StyleDeclaration { + base: Rgb( + ( + 0, + 0, + 0, + ), + ), + background: Rgb( + ( + 248, + 248, + 242, + ), + ), + emphasis_1: Rgb( + ( + 255, + 85, + 85, + ), + ), + emphasis_2: Rgb( + ( + 255, + 255, + 255, + ), + ), + emphasis_3: Rgb( + ( + 98, + 114, + 164, + ), + ), + emphasis_4: Rgb( + ( + 255, + 121, + 198, + ), + ), + }, + ribbon_selected: StyleDeclaration { + base: Rgb( + ( + 0, + 0, + 0, + ), + ), + background: Rgb( + ( + 80, + 250, + 123, + ), + ), + emphasis_1: Rgb( + ( + 255, + 85, + 85, + ), + ), + emphasis_2: Rgb( + ( + 255, + 184, + 108, + ), + ), + emphasis_3: Rgb( + ( + 255, + 121, + 198, + ), + ), + emphasis_4: Rgb( + ( + 98, + 114, + 164, + ), + ), + }, + table_title: StyleDeclaration { + base: Rgb( + ( + 80, + 250, + 123, + ), + ), + background: EightBit( + 0, + ), + emphasis_1: Rgb( + ( + 255, + 184, + 108, + ), + ), + emphasis_2: Rgb( + ( + 139, + 233, + 253, + ), + ), + emphasis_3: Rgb( + ( + 255, + 85, + 85, + ), + ), + emphasis_4: Rgb( + ( + 255, + 121, + 198, + ), + ), + }, + table_cell_unselected: StyleDeclaration { + base: Rgb( + ( + 248, + 248, + 242, + ), + ), + background: Rgb( + ( + 40, + 42, + 54, + ), + ), + emphasis_1: Rgb( + ( + 255, + 184, + 108, + ), + ), + emphasis_2: Rgb( + ( + 139, + 233, + 253, + ), + ), + emphasis_3: Rgb( + ( + 80, + 250, + 123, + ), + ), + emphasis_4: Rgb( + ( + 255, + 121, + 198, + ), + ), + }, + table_cell_selected: StyleDeclaration { + base: Rgb( + ( + 80, + 250, + 123, + ), + ), + background: Rgb( + ( + 40, + 42, + 54, + ), + ), + emphasis_1: Rgb( + ( + 255, + 184, + 108, + ), + ), + emphasis_2: Rgb( + ( + 139, + 233, + 253, + ), + ), + emphasis_3: Rgb( + ( + 255, + 85, + 85, + ), + ), + emphasis_4: Rgb( + ( + 255, + 121, + 198, + ), + ), + }, + list_unselected: StyleDeclaration { + base: Rgb( + ( + 248, + 248, + 242, + ), + ), + background: Rgb( + ( + 40, + 42, + 54, + ), + ), + emphasis_1: Rgb( + ( + 255, + 184, + 108, + ), + ), + emphasis_2: Rgb( + ( + 139, + 233, + 253, + ), + ), + emphasis_3: Rgb( + ( + 80, + 250, + 123, + ), + ), + emphasis_4: Rgb( + ( + 255, + 121, + 198, + ), + ), + }, + list_selected: StyleDeclaration { + base: Rgb( + ( + 80, + 250, + 123, + ), + ), + background: Rgb( + ( + 40, + 42, + 54, + ), + ), + emphasis_1: Rgb( + ( + 255, + 184, + 108, + ), + ), + emphasis_2: Rgb( + ( + 139, + 233, + 253, + ), + ), + emphasis_3: Rgb( + ( + 255, + 85, + 85, + ), + ), + emphasis_4: Rgb( + ( + 255, + 121, + 198, + ), + ), + }, + frame_unselected: StyleDeclaration { + base: Rgb( + ( + 255, + 184, + 108, + ), + ), + background: EightBit( + 0, + ), + emphasis_1: EightBit( + 0, + ), + emphasis_2: EightBit( + 0, + ), + emphasis_3: EightBit( + 0, + ), + emphasis_4: Rgb( + ( + 0, + 0, + 0, + ), + ), + }, + frame_selected: StyleDeclaration { + base: Rgb( + ( + 80, + 250, + 123, + ), + ), + background: EightBit( + 0, + ), + emphasis_1: Rgb( + ( + 255, + 184, + 108, + ), + ), + emphasis_2: Rgb( + ( + 139, + 233, + 253, + ), + ), + emphasis_3: Rgb( + ( + 255, + 121, + 198, + ), + ), + emphasis_4: EightBit( + 0, + ), + }, + frame_highlight: StyleDeclaration { + base: Rgb( + ( + 80, + 250, + 123, + ), + ), + background: EightBit( + 0, + ), + emphasis_1: Rgb( + ( + 80, + 250, + 123, + ), + ), + emphasis_2: Rgb( + ( + 80, + 250, + 123, + ), + ), + emphasis_3: Rgb( + ( + 80, + 250, + 123, + ), + ), + emphasis_4: Rgb( + ( + 80, + 250, + 123, + ), + ), + }, + exit_code_success: StyleDeclaration { + base: Rgb( + ( + 80, + 250, + 123, + ), + ), + background: EightBit( + 0, + ), + emphasis_1: Rgb( + ( + 139, + 233, + 253, + ), + ), + emphasis_2: Rgb( + ( + 0, + 0, + 0, + ), + ), + emphasis_3: Rgb( + ( + 255, + 121, + 198, + ), + ), + emphasis_4: Rgb( + ( + 98, + 114, + 164, + ), + ), + }, + exit_code_error: StyleDeclaration { + base: Rgb( + ( + 255, + 85, + 85, + ), + ), + background: EightBit( + 0, + ), + emphasis_1: Rgb( + ( + 241, + 250, + 140, + ), + ), + emphasis_2: EightBit( + 0, + ), + emphasis_3: EightBit( + 0, + ), + emphasis_4: EightBit( + 0, + ), + }, + multiplayer_user_colors: MultiplayerColors { + player_1: Rgb( + ( + 255, + 121, + 198, + ), + ), + player_2: Rgb( + ( + 98, + 114, + 164, + ), + ), + player_3: EightBit( + 0, + ), + player_4: Rgb( + ( + 241, + 250, + 140, + ), + ), + player_5: Rgb( + ( + 139, + 233, + 253, + ), + ), + player_6: EightBit( + 0, + ), + player_7: Rgb( + ( + 255, + 85, + 85, + ), + ), + player_8: EightBit( + 0, + ), + player_9: EightBit( + 0, + ), + player_10: EightBit( + 0, + ), + }, }, }, } diff --git a/zellij-utils/src/kdl/mod.rs b/zellij-utils/src/kdl/mod.rs index a69b6b0276..474fd2b85f 100644 --- a/zellij-utils/src/kdl/mod.rs +++ b/zellij-utils/src/kdl/mod.rs @@ -1,7 +1,8 @@ mod kdl_layout_parser; use crate::data::{ - Direction, FloatingPaneCoordinates, InputMode, KeyWithModifier, LayoutInfo, Palette, - PaletteColor, PaneInfo, PaneManifest, PermissionType, Resize, SessionInfo, TabInfo, + Direction, FloatingPaneCoordinates, InputMode, KeyWithModifier, LayoutInfo, MultiplayerColors, + Palette, PaletteColor, PaneInfo, PaneManifest, PermissionType, Resize, SessionInfo, + StyleDeclaration, Styling, TabInfo, DEFAULT_STYLES, }; use crate::envs::EnvironmentVariables; use crate::home::{find_default_config_dir, get_layout_dir}; @@ -1429,6 +1430,20 @@ macro_rules! kdl_child_with_name { }}; } +#[macro_export] +macro_rules! kdl_child_with_name_or_error { + ( $kdl_node:expr, $name:expr) => {{ + $kdl_node + .children() + .and_then(|children| children.nodes().iter().find(|c| c.name().value() == $name)) + .ok_or(ConfigError::new_kdl_error( + format!("Missing node {}", $name).into(), + $kdl_node.span().offset(), + $kdl_node.span().len(), + )) + }}; +} + #[macro_export] macro_rules! kdl_get_string_property_or_child_value_with_error { ( $kdl_node:expr, $name:expr ) => { @@ -1976,25 +1991,172 @@ impl UiConfig { } impl Themes { + fn style_declaration_from_node( + style_node: &KdlNode, + style_descriptor: &str, + default: StyleDeclaration, + ) -> Result { + let descriptor_node = kdl_child_with_name!(style_node, style_descriptor); + + match descriptor_node { + Some(descriptor) => { + let colors = kdl_children_or_error!( + descriptor, + format!("Missing colors for {}", style_descriptor) + ); + Ok(StyleDeclaration { + base: PaletteColor::try_from(("base", colors))?, + background: PaletteColor::try_from(("background", colors)).unwrap_or_default(), + emphasis_1: PaletteColor::try_from(("emphasis_1", colors))?, + emphasis_2: PaletteColor::try_from(("emphasis_2", colors))?, + emphasis_3: PaletteColor::try_from(("emphasis_3", colors))?, + emphasis_4: PaletteColor::try_from(("emphasis_4", colors))?, + }) + }, + None => Ok(default), + } + } + + fn multiplayer_colors(style_node: &KdlNode) -> Result { + let descriptor_node = kdl_child_with_name!(style_node, "multiplayer_user_colors"); + match descriptor_node { + Some(descriptor) => { + let colors = kdl_children_or_error!( + descriptor, + format!("Missing colors for {}", "multiplayer_user_colors") + ); + Ok(MultiplayerColors { + player_1: PaletteColor::try_from(("player_1", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_1), + player_2: PaletteColor::try_from(("player_2", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_2), + player_3: PaletteColor::try_from(("player_3", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_3), + player_4: PaletteColor::try_from(("player_4", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_4), + player_5: PaletteColor::try_from(("player_5", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_5), + player_6: PaletteColor::try_from(("player_6", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_6), + player_7: PaletteColor::try_from(("player_7", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_7), + player_8: PaletteColor::try_from(("player_8", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_8), + player_9: PaletteColor::try_from(("player_9", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_9), + player_10: PaletteColor::try_from(("player_10", colors)) + .unwrap_or(DEFAULT_STYLES.multiplayer_user_colors.player_10), + }) + }, + None => Ok(DEFAULT_STYLES.multiplayer_user_colors), + } + } + pub fn from_kdl(themes_from_kdl: &KdlNode) -> Result { let mut themes: HashMap = HashMap::new(); for theme_config in kdl_children_nodes_or_error!(themes_from_kdl, "no themes found") { let theme_name = kdl_name!(theme_config); let theme_colors = kdl_children_or_error!(theme_config, "empty theme"); - let theme = Theme { - palette: Palette { - fg: PaletteColor::try_from(("fg", theme_colors))?, - bg: PaletteColor::try_from(("bg", theme_colors))?, - red: PaletteColor::try_from(("red", theme_colors))?, - green: PaletteColor::try_from(("green", theme_colors))?, - yellow: PaletteColor::try_from(("yellow", theme_colors))?, - blue: PaletteColor::try_from(("blue", theme_colors))?, - magenta: PaletteColor::try_from(("magenta", theme_colors))?, - orange: PaletteColor::try_from(("orange", theme_colors))?, - cyan: PaletteColor::try_from(("cyan", theme_colors))?, - black: PaletteColor::try_from(("black", theme_colors))?, - white: PaletteColor::try_from(("white", theme_colors))?, - ..Default::default() + let styling = kdl_child_with_name!(theme_config, "styling"); + let theme = match styling { + // Newer theme definition with named styles + Some(style) => { + let s = Styling { + text_unselected: Themes::style_declaration_from_node( + style, + "text_unselected", + DEFAULT_STYLES.text_unselected, + )?, + text_selected: Themes::style_declaration_from_node( + style, + "text_selected", + DEFAULT_STYLES.text_selected, + )?, + ribbon_unselected: Themes::style_declaration_from_node( + style, + "ribbon_unselected", + DEFAULT_STYLES.ribbon_unselected, + )?, + ribbon_selected: Themes::style_declaration_from_node( + style, + "ribbon_selected", + DEFAULT_STYLES.ribbon_selected, + )?, + table_title: Themes::style_declaration_from_node( + style, + "table_title", + DEFAULT_STYLES.table_title, + )?, + table_cell_unselected: Themes::style_declaration_from_node( + style, + "table_cell_unselected", + DEFAULT_STYLES.table_cell_unselected, + )?, + table_cell_selected: Themes::style_declaration_from_node( + style, + "table_cell_selected", + DEFAULT_STYLES.table_cell_selected, + )?, + list_unselected: Themes::style_declaration_from_node( + style, + "list_unselected", + DEFAULT_STYLES.list_unselected, + )?, + list_selected: Themes::style_declaration_from_node( + style, + "list_selected", + DEFAULT_STYLES.list_selected, + )?, + frame_unselected: Themes::style_declaration_from_node( + style, + "frame_unselected", + DEFAULT_STYLES.frame_unselected, + )?, + frame_selected: Themes::style_declaration_from_node( + style, + "frame_selected", + DEFAULT_STYLES.frame_selected, + )?, + frame_highlight: Themes::style_declaration_from_node( + style, + "frame_highlight", + DEFAULT_STYLES.frame_highlight, + )?, + exit_code_success: Themes::style_declaration_from_node( + style, + "exit_code_success", + DEFAULT_STYLES.exit_code_success, + )?, + exit_code_error: Themes::style_declaration_from_node( + style, + "exit_code_error", + DEFAULT_STYLES.exit_code_error, + )?, + multiplayer_user_colors: Themes::multiplayer_colors(style) + .unwrap_or_default(), + }; + + Theme { palette: s } + }, + // Older palette based theme definition + None => { + let palette = Palette { + fg: PaletteColor::try_from(("fg", theme_colors))?, + bg: PaletteColor::try_from(("bg", theme_colors))?, + red: PaletteColor::try_from(("red", theme_colors))?, + green: PaletteColor::try_from(("green", theme_colors))?, + yellow: PaletteColor::try_from(("yellow", theme_colors))?, + blue: PaletteColor::try_from(("blue", theme_colors))?, + magenta: PaletteColor::try_from(("magenta", theme_colors))?, + orange: PaletteColor::try_from(("orange", theme_colors))?, + cyan: PaletteColor::try_from(("cyan", theme_colors))?, + black: PaletteColor::try_from(("black", theme_colors))?, + white: PaletteColor::try_from(("white", theme_colors))?, + ..Default::default() + }; + Theme { + palette: palette.into(), + } }, }; themes.insert(theme_name.into(), theme); diff --git a/zellij-utils/src/plugin_api/event.rs b/zellij-utils/src/plugin_api/event.rs index 1e793e66cf..6ff6180f17 100644 --- a/zellij-utils/src/plugin_api/event.rs +++ b/zellij-utils/src/plugin_api/event.rs @@ -1114,7 +1114,9 @@ fn serialize_mode_update_event_with_non_default_values() { silver: PaletteColor::EightBit(2), pink: PaletteColor::EightBit(2), brown: PaletteColor::Rgb((222, 221, 220)), - }, + } + .into(), + // TODO: replace default rounded_corners: true, hide_session_name: false, }, diff --git a/zellij-utils/src/plugin_api/style.proto b/zellij-utils/src/plugin_api/style.proto index f4f3b75889..cfea362e52 100644 --- a/zellij-utils/src/plugin_api/style.proto +++ b/zellij-utils/src/plugin_api/style.proto @@ -3,9 +3,10 @@ syntax = "proto3"; package api.style; message Style { - Palette palette = 1; + Palette palette = 1 [deprecated = true]; bool rounded_corners = 2; bool hide_session_name = 3; + Styling styling = 4; } message Palette { @@ -52,3 +53,21 @@ enum ThemeHue { Dark = 0; Light = 1; } + +message Styling { + repeated Color text_unselected = 1; + repeated Color text_selected = 2; + repeated Color ribbon_unselected = 3; + repeated Color ribbon_selected =4; + repeated Color table_title = 5; + repeated Color table_cell_unselected = 6; + repeated Color table_cell_selected = 7; + repeated Color list_unselected = 8; + repeated Color list_selected = 9; + repeated Color frame_unselected = 10; + repeated Color frame_selected = 11; + repeated Color frame_highlight = 12; + repeated Color exit_code_success = 13; + repeated Color exit_code_error = 14; + repeated Color multiplayer_user_colors = 15; +} diff --git a/zellij-utils/src/plugin_api/style.rs b/zellij-utils/src/plugin_api/style.rs index 1e3ba677f6..2b30ec15f2 100644 --- a/zellij-utils/src/plugin_api/style.rs +++ b/zellij-utils/src/plugin_api/style.rs @@ -1,9 +1,11 @@ use super::generated_api::api::style::{ color::Payload as ProtobufColorPayload, Color as ProtobufColor, ColorType as ProtobufColorType, Palette as ProtobufPalette, RgbColorPayload as ProtobufRgbColorPayload, Style as ProtobufStyle, - ThemeHue as ProtobufThemeHue, + Styling as ProtobufStyling, ThemeHue as ProtobufThemeHue, +}; +use crate::data::{ + MultiplayerColors, Palette, PaletteColor, Style, StyleDeclaration, Styling, ThemeHue, }; -use crate::data::{Palette, PaletteColor, Style, ThemeHue}; use crate::errors::prelude::*; use std::convert::TryFrom; @@ -11,11 +13,12 @@ use std::convert::TryFrom; impl TryFrom for Style { type Error = &'static str; fn try_from(protobuf_style: ProtobufStyle) -> Result { + let s = protobuf_style + .styling + .ok_or("malformed style payload")? + .try_into()?; Ok(Style { - colors: protobuf_style - .palette - .ok_or("malformed style payload")? - .try_into()?, + colors: s, rounded_corners: protobuf_style.rounded_corners, hide_session_name: protobuf_style.hide_session_name, }) @@ -25,10 +28,156 @@ impl TryFrom for Style { impl TryFrom