Skip to content

Commit 6881d32

Browse files
committed
Pane(feat[select]): add direction, last, zoom, mark, and input-toggle flags
why: select-pane has rich flag support for directional navigation, pane marking, and input control that was not exposed in the Python API. what: - Add direction (-D/-U/-L/-R), last (-l), keep_zoom (-Z), mark (-m), clear_mark (-M), disable_input (-d), enable_input (-e) parameters - Reuse existing ResizeAdjustmentDirection enum for direction flags - Skip deprecated -P (style) and -g (show style) flags - Add tests for direction, last pane, mark/clear, and input toggle
1 parent cf661bf commit 6881d32

2 files changed

Lines changed: 156 additions & 2 deletions

File tree

src/libtmux/pane.py

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -653,9 +653,42 @@ def kill(
653653
additional scoped window info.
654654
"""
655655

656-
def select(self) -> Pane:
656+
def select(
657+
self,
658+
*,
659+
direction: ResizeAdjustmentDirection | None = None,
660+
last: bool | None = None,
661+
keep_zoom: bool | None = None,
662+
mark: bool | None = None,
663+
clear_mark: bool | None = None,
664+
disable_input: bool | None = None,
665+
enable_input: bool | None = None,
666+
) -> Pane:
657667
"""Select pane.
658668
669+
Parameters
670+
----------
671+
direction : ResizeAdjustmentDirection, optional
672+
Select the pane in the given direction (``-U``, ``-D``, ``-L``,
673+
``-R``).
674+
last : bool, optional
675+
Select the last (previously selected) pane (``-l`` flag).
676+
keep_zoom : bool, optional
677+
Keep the window zoomed if it was zoomed (``-Z`` flag).
678+
mark : bool, optional
679+
Set the marked pane (``-m`` flag).
680+
clear_mark : bool, optional
681+
Clear the marked pane (``-M`` flag).
682+
disable_input : bool, optional
683+
Disable input to the pane (``-d`` flag).
684+
enable_input : bool, optional
685+
Enable input to the pane (``-e`` flag).
686+
687+
Returns
688+
-------
689+
:class:`Pane`
690+
Self, for method chaining.
691+
659692
Examples
660693
--------
661694
>>> pane = window.active_pane
@@ -677,7 +710,30 @@ def select(self) -> Pane:
677710
>>> new_pane.pane_active == '1'
678711
True
679712
"""
680-
proc = self.cmd("select-pane")
713+
tmux_args: tuple[str, ...] = ()
714+
715+
if direction is not None:
716+
tmux_args += (RESIZE_ADJUSTMENT_DIRECTION_FLAG_MAP[direction],)
717+
718+
if last:
719+
tmux_args += ("-l",)
720+
721+
if keep_zoom:
722+
tmux_args += ("-Z",)
723+
724+
if mark:
725+
tmux_args += ("-m",)
726+
727+
if clear_mark:
728+
tmux_args += ("-M",)
729+
730+
if disable_input:
731+
tmux_args += ("-d",)
732+
733+
if enable_input:
734+
tmux_args += ("-e",)
735+
736+
proc = self.cmd("select-pane", *tmux_args)
681737

682738
if proc.stderr:
683739
raise exc.LibTmuxException(proc.stderr)

tests/test_pane.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,3 +544,101 @@ def test_send_keys_flags(
544544
# Give a brief moment then verify absence
545545
contents = "\n".join(pane.capture_pane())
546546
assert not_expected_in_capture not in contents
547+
548+
549+
def test_select_pane_direction(session: Session) -> None:
550+
"""Test Pane.select() with direction flags."""
551+
window = session.new_window(window_name="test_select_dir")
552+
window.resize(height=40, width=80)
553+
pane_top = window.active_pane
554+
assert pane_top is not None
555+
pane_bottom = pane_top.split(direction=PaneDirection.Below)
556+
557+
# Top pane should be active (it was active before split with -d default)
558+
pane_bottom.select()
559+
pane_bottom.refresh()
560+
assert pane_bottom.pane_active == "1"
561+
562+
# Select up → should go to top pane
563+
pane_bottom.select(direction=ResizeAdjustmentDirection.Up)
564+
pane_top.refresh()
565+
assert pane_top.pane_active == "1"
566+
567+
# Select down → should go back to bottom
568+
pane_top.select(direction=ResizeAdjustmentDirection.Down)
569+
pane_bottom.refresh()
570+
assert pane_bottom.pane_active == "1"
571+
572+
573+
def test_select_pane_last(session: Session) -> None:
574+
"""Test Pane.select() with last flag."""
575+
window = session.new_window(window_name="test_select_last")
576+
pane1 = window.active_pane
577+
assert pane1 is not None
578+
pane2 = pane1.split()
579+
580+
# pane2 is now active (attach=True by default... wait, default is False)
581+
# After split, pane2 is NOT active since attach=False by default
582+
# Select pane2 explicitly
583+
pane2.select()
584+
pane2.refresh()
585+
assert pane2.pane_active == "1"
586+
587+
# Now select pane1
588+
pane1.select()
589+
pane1.refresh()
590+
assert pane1.pane_active == "1"
591+
592+
# Use -l to go back to last (pane2)
593+
pane1.select(last=True)
594+
pane2.refresh()
595+
assert pane2.pane_active == "1"
596+
597+
598+
def test_select_pane_mark(session: Session) -> None:
599+
"""Test Pane.select() with mark/clear_mark flags."""
600+
window = session.new_window(window_name="test_select_mark")
601+
pane = window.active_pane
602+
assert pane is not None
603+
604+
# Mark the pane — verify no error
605+
pane.select(mark=True)
606+
607+
# Clear the mark — verify no error
608+
pane.select(clear_mark=True)
609+
610+
611+
def test_select_pane_disable_enable_input(session: Session) -> None:
612+
"""Test Pane.select() with disable/enable input flags."""
613+
env = shutil.which("env")
614+
assert env is not None
615+
616+
window = session.new_window(
617+
window_name="test_input_toggle",
618+
window_shell=f"{env} PS1='$ ' sh",
619+
)
620+
pane = window.active_pane
621+
assert pane is not None
622+
623+
retry_until(lambda: "$" in "\n".join(pane.capture_pane()), 2, raises=True)
624+
625+
# Disable input
626+
pane.select(disable_input=True)
627+
628+
# Send keys — they should not appear since input is disabled
629+
pane.send_keys("echo disabled_test", enter=False)
630+
631+
# Verify "disabled_test" does NOT appear
632+
contents = "\n".join(pane.capture_pane())
633+
assert "disabled_test" not in contents
634+
635+
# Re-enable input
636+
pane.select(enable_input=True)
637+
638+
# Now send keys — they should appear
639+
pane.send_keys("echo enabled_ok", enter=True)
640+
retry_until(
641+
lambda: "enabled_ok" in "\n".join(pane.capture_pane()),
642+
3,
643+
raises=True,
644+
)

0 commit comments

Comments
 (0)