diff options
| author | Daniel Jankowski <daniel.jankowski@rub.de> | 2024-05-25 16:19:48 +0200 |
|---|---|---|
| committer | Daniel Jankowski <daniel.jankowski@rub.de> | 2024-05-25 16:19:48 +0200 |
| commit | 63b13dd6f0e73d9ccba0614ccc2fbda1708c5577 (patch) | |
| tree | 0483ab6deb224ea91110286ab13a3c7a07a7687c /src | |
| parent | feat(frames): show frames when renaming pane or searching (diff) | |
| download | sl0pstatus-63b13dd6f0e73d9ccba0614ccc2fbda1708c5577.tar.gz sl0pstatus-63b13dd6f0e73d9ccba0614ccc2fbda1708c5577.tar.xz sl0pstatus-63b13dd6f0e73d9ccba0614ccc2fbda1708c5577.zip | |
feat: implement format precedence to hide overflown parts
Fixes #58
Diffstat (limited to 'src')
| -rw-r--r-- | src/config.rs | 84 |
1 files changed, 83 insertions, 1 deletions
diff --git a/src/config.rs b/src/config.rs index ae00e45..a58007c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,6 @@ -use std::{collections::BTreeMap, sync::Arc}; +use std::{collections::BTreeMap, str::FromStr, sync::Arc}; +use itertools::Itertools; use regex::Regex; use zellij_tile::prelude::*; @@ -24,6 +25,26 @@ pub struct ZellijState { pub cache_mask: u8, } +#[derive(Clone, Debug, Ord, Eq, PartialEq, PartialOrd, Copy)] +pub enum Part { + Left, + Center, + Right, +} + +impl FromStr for Part { + fn from_str(part: &str) -> Result<Self> { + match part { + "l" => Ok(Part::Left), + "c" => Ok(Part::Center), + "r" => Ok(Part::Right), + _ => anyhow::bail!("Invalid part: {}", part), + } + } + + type Err = anyhow::Error; +} + pub enum UpdateEventMask { Always = 0b10000000, Mode = 0b00000001, @@ -57,6 +78,7 @@ pub struct ModuleConfig { pub format_space: FormattedPart, pub hide_frame_for_single_pane: bool, pub border: BorderConfig, + pub format_precedence: Vec<Part>, } impl ModuleConfig { @@ -86,6 +108,14 @@ impl ModuleConfig { None => "", }; + let format_precedence = match config.get("format_precedence") { + Some(conf) => conf + .chars() + .map(|c| Part::from_str(&c.to_string()).expect("Invalid part")) + .collect(), + None => vec![Part::Left, Part::Center, Part::Right], + }; + let border_config = match parse_border_config(config.clone()) { Some(bc) => bc, None => BorderConfig::default(), @@ -101,6 +131,7 @@ impl ModuleConfig { format_space: FormattedPart::from_format_string(format_space_config), hide_frame_for_single_pane, border: border_config, + format_precedence, } } @@ -275,6 +306,9 @@ impl ModuleConfig { ) }); + let (output_left, output_center, output_right) = + self.trim_output(&output_left, &output_center, &output_right, state.cols); + if self.border.enabled { let mut border_top = "".to_owned(); if self.border.enabled && self.border.position == BorderPosition::Top { @@ -328,6 +362,54 @@ impl ModuleConfig { ) } + fn trim_output( + &self, + output_left: &str, + output_center: &str, + output_right: &str, + cols: usize, + ) -> (String, String, String) { + let center_pos = (cols as f32 / 2.0).floor() as usize; + + let mut output = BTreeMap::from([ + (Part::Left, output_left.to_owned()), + (Part::Center, output_center.to_owned()), + (Part::Right, output_right.to_owned()), + ]); + + let combinations = [ + (self.format_precedence[2], self.format_precedence[1]), + (self.format_precedence[1], self.format_precedence[0]), + (self.format_precedence[2], self.format_precedence[0]), + ]; + + for win in combinations.iter() { + let (a, b) = win; + + let part_a = output.get(a).unwrap(); + let part_b = output.get(b).unwrap(); + + let a_count = console::measure_text_width(part_a); + let b_count = console::measure_text_width(part_b); + + let overlap = match (a, b) { + (Part::Left, Part::Right) => a_count + b_count > cols, + (Part::Right, Part::Left) => a_count + b_count > cols, + (Part::Left, Part::Center) => a_count > center_pos - (b_count / 2), + (Part::Center, Part::Left) => b_count > center_pos - (a_count / 2), + (Part::Right, Part::Center) => a_count > center_pos - (b_count / 2), + (Part::Center, Part::Right) => b_count > center_pos - (a_count / 2), + _ => false, + }; + + if overlap { + output.insert(*a, "".to_owned()); + } + } + + output.values().cloned().collect_tuple().unwrap() + } + #[tracing::instrument(skip_all)] fn get_spacer_left(&self, output_left: &str, output_center: &str, cols: usize) -> String { let text_count = console::measure_text_width(output_left) |
