aboutsummaryrefslogtreecommitdiffstats
path: root/zellij-utils/src/input
diff options
context:
space:
mode:
authoruser <user@clank>2026-08-08 21:06:40 +0200
committeruser <user@clank>2026-08-08 21:06:40 +0200
commit97b744a57e3ba53169781a9357d8dc86b15d387e (patch)
tree258562cbe750017fc08180e3d92a96c12689a47d /zellij-utils/src/input
parentsl0p: uniform pane gap + aspect-corrected horizontal gap (diff)
downloadsl0ppij-97b744a57e3ba53169781a9357d8dc86b15d387e.tar.gz
sl0ppij-97b744a57e3ba53169781a9357d8dc86b15d387e.tar.xz
sl0ppij-97b744a57e3ba53169781a9357d8dc86b15d387e.zip
sl0p: CSS-style 1/2/4-value shorthand for inner padding
`padding` now accepts: padding 1 -> all four sides padding 1 2 -> up/down = 1, left/right = 2 padding 1 2 3 4 -> up=1 down=2 left=3 right=4 NOTE the 4-value order is UP DOWN LEFT RIGHT as requested, deliberately NOT CSS's clockwise top-right-bottom-left. Documented on PanePadding and at the parser, since the similarity to CSS invites the wrong assumption. 3 or 5 values are rejected with a message naming the accepted forms, rather than being silently reinterpreted. Negative values clamp to 0. ASPECT: only the 1-value form is aspect-corrected (left/right multiplied by gap_aspect) so `padding 1` looks square on a non-square cell grid. The 2- and 4-value forms are literal: specifying axes separately means the caller is already controlling horizontal size, and silently doubling it would surprise. Style now carries a PanePadding {top,bottom,left,right} instead of an x/y pair, which also collapses the reconfigure plumbing back to a single field rather than growing another parameter per side. to_kdl always emits the explicit 4-value form: emitting the 1-value form would re-apply gap_aspect on the next read and silently double the padding on every config round-trip. Baselines held: zellij-utils 435/5, zellij-server 1421/30.
Diffstat (limited to 'zellij-utils/src/input')
-rw-r--r--zellij-utils/src/input/config.rs45
-rw-r--r--zellij-utils/src/input/theme.rs12
2 files changed, 51 insertions, 6 deletions
diff --git a/zellij-utils/src/input/config.rs b/zellij-utils/src/input/config.rs
index be08adb9..db86de54 100644
--- a/zellij-utils/src/input/config.rs
+++ b/zellij-utils/src/input/config.rs
@@ -1393,6 +1393,51 @@ mod config_test {
}
#[test]
+ fn pane_padding_accepts_1_2_and_4_value_shorthand() {
+ let parse = |padding: &str| {
+ let contents = format!(
+ "ui {{\n pane_frames {{\n padding {}\n }}\n}}",
+ padding
+ );
+ Config::from_kdl(&contents, None).map(|c| c.ui.pane_frames.padding)
+ };
+
+ // 1 value: all sides, and left/right are aspect-corrected (x2 default)
+ // so that `padding 1` reads as square on a non-square cell grid
+ let p = parse("1").unwrap();
+ assert_eq!((p.top, p.bottom), (1, 1), "1-value: vertical");
+ assert_eq!((p.left, p.right), (2, 2), "1-value: horizontal is aspect-corrected");
+
+ // 2 values: up/down then left/right, taken LITERALLY (no aspect scaling -
+ // the caller is already controlling the horizontal size)
+ let p = parse("1 2").unwrap();
+ assert_eq!((p.top, p.bottom, p.left, p.right), (1, 1, 2, 2), "2-value");
+
+ // 4 values: up down left right (NOT css clockwise order)
+ let p = parse("1 2 3 4").unwrap();
+ assert_eq!((p.top, p.bottom, p.left, p.right), (1, 2, 3, 4), "4-value");
+
+ // 3 and 5 are rejected rather than silently reinterpreted
+ assert!(parse("1 2 3").is_err(), "3 values must be rejected");
+ assert!(parse("1 2 3 4 5").is_err(), "5 values must be rejected");
+
+ // negatives clamp to 0 instead of wrapping to a huge usize
+ let p = parse("-4").unwrap();
+ assert!(p.is_zero(), "negative padding must clamp to zero, got {:?}", p);
+ }
+
+ #[test]
+ fn pane_padding_aspect_is_configurable() {
+ let contents = "ui {\n pane_frames {\n gap_aspect 1\n padding 1\n }\n}";
+ let p = Config::from_kdl(contents, None).unwrap().ui.pane_frames.padding;
+ assert_eq!(
+ (p.top, p.left),
+ (1, 1),
+ "gap_aspect 1 disables horizontal correction"
+ );
+ }
+
+ #[test]
fn can_define_ui_configuration_in_configfile() {
let config_contents = r#"
ui {
diff --git a/zellij-utils/src/input/theme.rs b/zellij-utils/src/input/theme.rs
index f4f2ec80..f1e0adf1 100644
--- a/zellij-utils/src/input/theme.rs
+++ b/zellij-utils/src/input/theme.rs
@@ -30,8 +30,9 @@ pub struct FrameConfig {
/// outer gap between panes, expressed in ROWS (see Style::pane_gap_y).
/// Columns are scaled by `gap_aspect` so the gap looks square.
pub gap: usize,
- /// inner padding between a pane's frame and its content, in ROWS
- pub padding: usize,
+ /// inner padding between a pane's frame and its content, per side.
+ /// Already resolved at parse time (including any aspect correction).
+ pub padding: crate::data::PanePadding,
/// Columns per row. Terminal cells are roughly twice as tall as they are
/// wide, so 1 row of gap needs ~2 columns to look like the same distance.
/// 0 is treated as 1 (no correction).
@@ -49,7 +50,7 @@ impl Default for FrameConfig {
hide_session_name: false,
title_alignment: Default::default(),
gap: 0,
- padding: 0,
+ padding: Default::default(),
gap_aspect: 2,
}
}
@@ -63,9 +64,8 @@ impl FrameConfig {
pub fn resolved_gap(&self) -> (usize, usize) {
(self.gap * self.aspect(), self.gap)
}
- /// (columns, rows) of inner padding
- pub fn resolved_padding(&self) -> (usize, usize) {
- (self.padding * self.aspect(), self.padding)
+ pub fn resolved_padding(&self) -> crate::data::PanePadding {
+ self.padding
}
}