aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel Jankowski <daniel.jankowski@rub.de>2024-05-25 16:19:48 +0200
committerDaniel Jankowski <daniel.jankowski@rub.de>2024-05-25 16:19:48 +0200
commit63b13dd6f0e73d9ccba0614ccc2fbda1708c5577 (patch)
tree0483ab6deb224ea91110286ab13a3c7a07a7687c /src
parentfeat(frames): show frames when renaming pane or searching (diff)
downloadsl0pstatus-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.rs84
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)