diff options
| author | user <user@clank> | 2026-08-11 16:33:46 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-11 16:33:46 +0200 |
| commit | 4e001669f5a9dcc883f58bf0c3710c7460ae93cc (patch) | |
| tree | 116fae3213fd781ea62b15c05256831f2ec9843e /zellij-utils | |
| parent | sl0p: click the picker's indicator row to expand a capped stack (diff) | |
| download | sl0ppij-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')
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: {}, |
