aboutsummaryrefslogtreecommitdiffstats
path: root/zellij-utils
diff options
context:
space:
mode:
authoruser <user@clank>2026-08-11 16:33:46 +0200
committeruser <user@clank>2026-08-11 16:33:46 +0200
commit4e001669f5a9dcc883f58bf0c3710c7460ae93cc (patch)
tree116fae3213fd781ea62b15c05256831f2ec9843e /zellij-utils
parentsl0p: click the picker's indicator row to expand a capped stack (diff)
downloadsl0ppij-4e001669f5a9dcc883f58bf0c3710c7460ae93cc.tar.gz
sl0ppij-4e001669f5a9dcc883f58bf0c3710c7460ae93cc.tar.xz
sl0ppij-4e001669f5a9dcc883f58bf0c3710c7460ae93cc.zip
sl0p: optionally render the stacked-pane picker as a grid
`stack_list_layout "grid"` packs picker entries several per row, which turns stack_list_max_rows from a count into a space budget: eight panes in a wide terminal now fit on one row instead of spending three and hiding five. The entry renderer already drew each entry as a single chunk at its own x/y, sized by its geom and centring its own label, so a grid needed no rendering changes at all -- only the loop assigning every entry the same x and the full width. Column count is derived from the widest label rather than configured, so it adapts to the titles; one column is the floor and reproduces the previous full-width rows byte for byte. The row -> member mapping now has a column axis, and it had already caused one wrong-pane bug when two consumers disagreed. So the layout is computed once, by one function, into explicit cells; the renderer, the reserved-row budget and the mouse hit-test all read those same cells rather than each doing their own arithmetic. Windowing is by row, so a grid scrolls a whole row at a time and degrades to the old per-member window when there is one column. Cells are separated by a two-column gap: without it the focused entry's "> " marker sits flush against the previous cell and reads as belonging to it.
Diffstat (limited to 'zellij-utils')
-rw-r--r--zellij-utils/src/input/config.rs1
-rw-r--r--zellij-utils/src/input/theme.rs5
-rw-r--r--zellij-utils/src/kdl/mod.rs19
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap1
8 files changed, 30 insertions, 0 deletions
diff --git a/zellij-utils/src/input/config.rs b/zellij-utils/src/input/config.rs
index d64e4598..4cb315ca 100644
--- a/zellij-utils/src/input/config.rs
+++ b/zellij-utils/src/input/config.rs
@@ -1497,6 +1497,7 @@ mod config_test {
responsive_min_cols: 0,
responsive_layout: String::from("stacked"),
stack_list_max_rows: 0,
+ stack_list_grid: false,
},
};
assert_eq!(config.ui, expected_ui_config, "Ui config defined in config");
diff --git a/zellij-utils/src/input/theme.rs b/zellij-utils/src/input/theme.rs
index 7cd89d41..412aaae2 100644
--- a/zellij-utils/src/input/theme.rs
+++ b/zellij-utils/src/input/theme.rs
@@ -52,6 +52,9 @@ pub struct FrameConfig {
/// windows around the focused entry and reports the rest as "+N". 0 = show
/// every member, however many rows that takes.
pub stack_list_max_rows: usize,
+ /// Pack picker entries into a grid instead of one per row. The row cap then
+ /// becomes a space budget rather than a count.
+ pub stack_list_grid: bool,
}
/// Hand-written rather than derived: `gap_aspect` must default to 2 to match
@@ -72,6 +75,7 @@ impl Default for FrameConfig {
responsive_min_cols: 0,
responsive_layout: String::from("stacked"),
stack_list_max_rows: 0,
+ stack_list_grid: false,
}
}
}
@@ -103,6 +107,7 @@ impl FrameConfig {
merged.responsive_min_cols = other.responsive_min_cols;
merged.responsive_layout = other.responsive_layout.clone();
merged.stack_list_max_rows = other.stack_list_max_rows;
+ merged.stack_list_grid = other.stack_list_grid;
merged
}
}
diff --git a/zellij-utils/src/kdl/mod.rs b/zellij-utils/src/kdl/mod.rs
index 425e9157..dda62c87 100644
--- a/zellij-utils/src/kdl/mod.rs
+++ b/zellij-utils/src/kdl/mod.rs
@@ -5614,6 +5614,24 @@ impl UiConfig {
kdl_children_property_first_arg_as_i64!(pane_frames, "stack_list_max_rows")
.unwrap_or(0)
.max(0) as usize;
+ let stack_list_grid =
+ match kdl_children_property_first_arg_as_string!(pane_frames, "stack_list_layout") {
+ Some(raw) => match raw.trim().to_lowercase().as_str() {
+ "grid" => true,
+ "rows" => false,
+ _ => {
+ return Err(ConfigError::new_kdl_error(
+ format!(
+ "Unknown stack_list_layout: \"{}\". Valid values are: \"rows\", \"grid\"",
+ raw
+ ),
+ pane_frames.span().offset(),
+ pane_frames.span().len(),
+ ))
+ },
+ },
+ None => false,
+ };
let frame_config = FrameConfig {
rounded_corners,
hide_session_name,
@@ -5626,6 +5644,7 @@ impl UiConfig {
responsive_min_cols,
responsive_layout,
stack_list_max_rows,
+ stack_list_grid,
};
ui_config.pane_frames = frame_config;
}
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap
index 3ca65d74..c2c29be5 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap
@@ -6244,6 +6244,7 @@ Config {
responsive_min_cols: 0,
responsive_layout: "stacked",
stack_list_max_rows: 0,
+ stack_list_grid: false,
},
},
env: {},
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap
index 21e4e851..bc58ffff 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap
@@ -6244,6 +6244,7 @@ Config {
responsive_min_cols: 0,
responsive_layout: "stacked",
stack_list_max_rows: 0,
+ stack_list_grid: false,
},
},
env: {
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap
index 67da72dc..75cbc50e 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap
@@ -306,6 +306,7 @@ Config {
responsive_min_cols: 0,
responsive_layout: "stacked",
stack_list_max_rows: 0,
+ stack_list_grid: false,
},
},
env: {},
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap
index d04d9547..d04f6e93 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap
@@ -8015,6 +8015,7 @@ Config {
responsive_min_cols: 0,
responsive_layout: "stacked",
stack_list_max_rows: 0,
+ stack_list_grid: false,
},
},
env: {},
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap
index a3b5b5ac..966fed4e 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap
@@ -6244,6 +6244,7 @@ Config {
responsive_min_cols: 0,
responsive_layout: "stacked",
stack_list_max_rows: 0,
+ stack_list_grid: false,
},
},
env: {},