Skip to content

Commit 680ac34

Browse files
committed
Pane(feat[split]): add percentage parameter for split-window
why: split-window supports -p for percentage-based sizing which is more intuitive than the absolute cell count provided by the existing size parameter. what: - Add percentage (-p) parameter to Pane.split(), mutually exclusive with size - Validate that size and percentage are not both specified - Add tests for percentage split and mutual exclusion
1 parent 8c4ca4d commit 680ac34

2 files changed

Lines changed: 40 additions & 1 deletion

File tree

src/libtmux/pane.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,7 @@ def split(
876876
zoom: bool | None = None,
877877
shell: str | None = None,
878878
size: str | int | None = None,
879+
percentage: int | None = None,
879880
environment: dict[str, str] | None = None,
880881
) -> Pane:
881882
"""Split window and return :class:`Pane`, by default beneath current pane.
@@ -903,7 +904,12 @@ def split(
903904
is useful for long-running processes where the closing of the
904905
window upon completion is desired.
905906
size: int, optional
906-
Cell/row or percentage to occupy with respect to current window.
907+
Cell/row count to occupy with respect to current window.
908+
percentage: int, optional
909+
Percentage (0-100) of the window to occupy (``-p`` flag).
910+
Mutually exclusive with *size*.
911+
912+
.. versionadded:: 0.45
907913
environment: dict, optional
908914
Environmental variables for new pane. Passthrough to ``-e``.
909915
@@ -969,9 +975,16 @@ def split(
969975
else:
970976
tmux_args += tuple(PANE_DIRECTION_FLAG_MAP[PaneDirection.Below])
971977

978+
if size is not None and percentage is not None:
979+
msg = "Cannot specify both size and percentage"
980+
raise ValueError(msg)
981+
972982
if size is not None:
973983
tmux_args += (f"-l{size}",)
974984

985+
if percentage is not None:
986+
tmux_args += (f"-p{percentage}",)
987+
975988
if full_window_split:
976989
tmux_args += ("-f",)
977990

tests/test_pane.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,3 +712,29 @@ def test_display_message_flags(
712712
assert result is not None
713713
output = "\n".join(result)
714714
assert expected_in_output in output
715+
716+
717+
def test_split_percentage(session: Session) -> None:
718+
"""Test Pane.split() with percentage parameter."""
719+
window = session.new_window(window_name="test_split_pct")
720+
window.resize(height=40, width=80)
721+
pane = window.active_pane
722+
assert pane is not None
723+
724+
new_pane = pane.split(percentage=25)
725+
assert new_pane in window.panes
726+
assert len(window.panes) == 2
727+
728+
# The new pane should be roughly 25% of the window height
729+
new_pane.refresh()
730+
assert new_pane.pane_height is not None
731+
assert int(new_pane.pane_height) <= 15 # ~25% of 40
732+
733+
734+
def test_split_percentage_size_mutual_exclusion(session: Session) -> None:
735+
"""Test that size and percentage are mutually exclusive."""
736+
window = session.new_window(window_name="test_split_mutex")
737+
pane = window.active_pane
738+
assert pane is not None
739+
with pytest.raises(ValueError, match="Cannot specify both"):
740+
pane.split(size=10, percentage=50)

0 commit comments

Comments
 (0)