Skip to content

Commit

Permalink
feat(config): new theme definition spec (#3242)
Browse files Browse the repository at this point in the history
* Implement initial structs from spec

* kdl configuration unmarshalling

* typo text styling

* remove is_selected toggle

* incorporate new status bar ui into theming

* improve test coverage of config behavior

* tab bar correction

* correct also compact bar

* remove spacing between table columns

* refactor table styling

* use text_unselected.emphasis_1 for keygroup sep

* fix tab bar more text

* repair field flattening for theme

* remove extra styling KDL node

* update tests

* updated selected text conversion

* padding for header bar

* minor corrections for existing themes

* background handling

* compact bar corrections

* properly handle opaque method to activate background

* update newer plugins to use styling struct

* correct omission of selected state

* fix: bold typeface for text elements

* fix: fg -> white for list_unselected conversion

* fix: emphasis and opacity handling for nested_list

* correct stylings in the session-manager

* fix emphases translation for table component

* correct emphasis for run instructions

* correct frame_highlight translation for old themes

* provide missing implementation of frame_highlight

* fencepost emphasis color names

* Set a pseudo-None for frame_unselected in old theme conversion

* correct alternating bg for simplified-ui

* update snapshots

* fix inner text padding and errorneous snapshots

* suppress warning about deprecated usage of palette

* remove unused import

* feat(plugins): API to change floating pane coordinates (#3958)

* basic functionality through the cli

* added to plugin api

* add display area and viewport size to TabInfo

* fix tests and add new one

* some cleanups

* refactor: extract pane_id parsing logic

* style(fmt): rustfmt

* docs(changelog): floating pane coordinate chagne API

* fix(tiled-panes): opening panes from the cli (#3963)

* feat(plugins): add `PastedText` Event (#3962)

* working with text paste

* handle utf8 conversion error

* feat(plugins): add PastedText Event

* docs(changelog): plugins pasted text event

* black for table opaque background

* properly apply opacity to table

* correct padding for explicit width ribbons

* feat(plugins): Allow opening panes near plugin (#3966)

* added command + terminal variants

* added editor variant

* style(fmt): rustfmt

* docs(changelog): plugin apis to open panes near plugin

* feat(plugins): send info about $EDITOR and $SHELL (#3971)

* feat(plugins): send info about $EDITOR and $SHELL

* fix(e2e): snapshot update

* docs(changelog): plugin editor and shell info

* fix(floating-panes): when changing coordinates, if a pane is not floating - make it floating (#3972)

* fix(panes): when changing floating pane coordinates, if the pane is not floating, float it

* style(fmt): rustfmt

* docs(changelog): floating pane coordinate fix

* fix(break-pane): strip logical position when inserting pane to new tab (#3973)

* docs(changelog): logical position fix

* Optional frame_unselected theme

* fixture with correct width to account for arrow padding

* update snapshot and rustfmt

---------

Co-authored-by: Aram Drevekenin <[email protected]>
  • Loading branch information
DeaconDesperado and imsnif authored Feb 7, 2025
1 parent 834f1e6 commit 26b99ea
Show file tree
Hide file tree
Showing 59 changed files with 5,080 additions and 1,228 deletions.
94 changes: 42 additions & 52 deletions default-plugins/compact-bar/src/line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn populate_tabs_in_tab_line(
tabs_after_active: &mut Vec<LinePart>,
tabs_to_render: &mut Vec<LinePart>,
cols: usize,
palette: Palette,
palette: Styling,
capabilities: PluginCapabilities,
) {
let mut middle_size = get_current_title_len(tabs_to_render);
Expand Down Expand Up @@ -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 {
Expand All @@ -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_0;
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 {
Expand All @@ -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 {
Expand All @@ -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_0;
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 {
Expand All @@ -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<LinePart> {
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_3;
let normal_mode_color = palette.text_unselected.emphasis_2;
let other_modes_color = palette.text_unselected.emphasis_0;

let prefix_styled_text = style!(text_color, bg_color).bold().paint(prefix_text);
let mut parts = vec![LinePart {
Expand All @@ -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 {
Expand Down Expand Up @@ -253,7 +245,7 @@ pub fn tab_line(
mut all_tabs: Vec<LinePart>,
active_tab_index: usize,
cols: usize,
palette: Palette,
palette: Styling,
capabilities: PluginCapabilities,
hide_session_name: bool,
mode: InputMode,
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -323,39 +316,36 @@ fn swap_layout_status(
swap_layout_name: &Option<String>,
is_swap_layout_damaged: bool,
input_mode: InputMode,
palette: &Palette,
palette: &Styling,
separator: &str,
) -> Option<LinePart> {
match swap_layout_name {
Some(swap_layout_name) => {
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!(
Expand Down
5 changes: 1 addition & 4 deletions default-plugins/compact-bar/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
35 changes: 19 additions & 16 deletions default-plugins/compact-bar/src/tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ANSIString>, usize) {
fn cursors(focused_clients: &[ClientId], colors: MultiplayerColors) -> (Vec<ANSIString>, 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;
}
Expand All @@ -21,37 +21,40 @@ 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 separator_fill_color = palette.text_unselected.background;
let left_separator = style!(separator_fill_color, background_color).paint(separator);
let mut tab_text_len = text.width() + (separator_width * 2) + 2; // + 2 for padding

let tab_styled_text = style!(foreground_color, background_color)
.bold()
.paint(format!(" {} ", text));

let right_separator = style!(background_color, foreground_color).paint(separator);
let right_separator = style!(background_color, separator_fill_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)
Expand Down Expand Up @@ -85,7 +88,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);
Expand Down
4 changes: 2 additions & 2 deletions default-plugins/configuration/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ struct State {
ui_size: usize,
current_screen: Screen,
latest_mode_info: Option<ModeInfo>,
colors: Palette,
colors: Styling,
}

impl Default for State {
Expand All @@ -82,7 +82,7 @@ impl Default for State {
ui_size: UI_SIZE,
current_screen: Screen::default(),
latest_mode_info: None,
colors: Palette::default(),
colors: Palette::default().into(),
}
}
}
Expand Down
7 changes: 2 additions & 5 deletions default-plugins/configuration/src/ui_components.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
use crate::{Screen, WIDTH_BREAKPOINTS};
use zellij_tile::prelude::*;

pub fn top_tab_menu(cols: usize, current_screen: &Screen, colors: &Palette) {
let background = match colors.theme_hue {
ThemeHue::Dark => colors.black,
ThemeHue::Light => colors.white,
};
pub fn top_tab_menu(cols: usize, current_screen: &Screen, colors: &Styling) {
let background = colors.text_unselected.background;
let bg_color = match background {
PaletteColor::Rgb((r, g, b)) => format!("\u{1b}[48;2;{};{};{}m\u{1b}[0K", r, g, b),
PaletteColor::EightBit(color) => format!("\u{1b}[48;5;{}m\u{1b}[0K", color),
Expand Down
13 changes: 5 additions & 8 deletions default-plugins/plugin-manager/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub struct NewPluginScreen {
selected_config_index: Option<usize>,
request_ids: Vec<String>,
load_in_background: bool,
colors: Palette,
colors: Styling,
}

impl Default for NewPluginScreen {
Expand All @@ -50,13 +50,13 @@ impl Default for NewPluginScreen {
selected_config_index: None,
request_ids: vec![],
load_in_background: false,
colors: Palette::default(),
colors: Palette::default().into(),
}
}
}

impl NewPluginScreen {
pub fn new(colors: Palette) -> Self {
pub fn new(colors: Styling) -> Self {
Self {
colors,
..Default::default()
Expand Down Expand Up @@ -261,10 +261,7 @@ impl NewPluginScreen {
None,
None,
);
let background = match self.colors.theme_hue {
ThemeHue::Dark => self.colors.black,
ThemeHue::Light => self.colors.white,
};
let background = self.colors.text_unselected.background;
let bg_color = match background {
PaletteColor::Rgb((r, g, b)) => format!("\u{1b}[48;2;{};{};{}m\u{1b}[0K", r, g, b),
PaletteColor::EightBit(color) => format!("\u{1b}[48;5;{}m\u{1b}[0K", color),
Expand Down Expand Up @@ -496,7 +493,7 @@ struct State {
plugin_id_to_tab_position: HashMap<u32, usize>,
search_term: String,
new_plugin_screen: Option<NewPluginScreen>,
colors: Palette,
colors: Styling,
}

register_plugin!(State);
Expand Down
5 changes: 1 addition & 4 deletions default-plugins/session-manager/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,7 @@ impl ZellijPlugin for State {
fn render(&mut self, rows: usize, cols: usize) {
let (x, y, width, height) = self.main_menu_size(rows, cols);

let background = match self.colors.palette.theme_hue {
ThemeHue::Dark => self.colors.palette.black,
ThemeHue::Light => self.colors.palette.white,
};
let background = self.colors.palette.text_unselected.background;

if self.is_welcome_screen {
render_banner(x, 0, rows.saturating_sub(height), width);
Expand Down
Loading

0 comments on commit 26b99ea

Please sign in to comment.