Skip to content

Commit c92cea7

Browse files
committed
Session(feat[detach_client]): add detach_client() wrapping tmux detach-client
why: detach-client is needed for programmatically disconnecting clients from sessions, useful for session management and automation. what: - Add Session.detach_client() with target_client (-t) and all_clients (-a) - Use -s for session targeting since -t targets clients in detach-client - Test uses ControlMode context manager to create a real client, then verifies list-clients count drops after detach
1 parent 8ca960d commit c92cea7

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

src/libtmux/session.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,43 @@ def cmd(
245245
Commands (tmux-like)
246246
"""
247247

248+
def detach_client(
249+
self,
250+
*,
251+
target_client: str | None = None,
252+
all_clients: bool | None = None,
253+
) -> None:
254+
"""Detach clients from this session via ``$ tmux detach-client``.
255+
256+
Parameters
257+
----------
258+
target_client : str, optional
259+
Target client to detach (``-t`` flag). If omitted, detaches
260+
the most recently active client.
261+
all_clients : bool, optional
262+
Detach all clients attached to this session (``-a`` flag).
263+
264+
Examples
265+
--------
266+
>>> with control_mode() as ctl:
267+
... session.detach_client()
268+
"""
269+
tmux_args: tuple[str, ...] = ()
270+
271+
if all_clients:
272+
tmux_args += ("-a",)
273+
274+
if target_client is not None:
275+
tmux_args += ("-t", target_client)
276+
277+
# Use -s for session targeting (not -t, which targets clients)
278+
tmux_args += ("-s", str(self.session_id))
279+
280+
proc = self.server.cmd("detach-client", *tmux_args)
281+
282+
if proc.stderr:
283+
raise exc.LibTmuxException(proc.stderr)
284+
248285
def last_window(self) -> Window:
249286
"""Select the last (previously selected) window.
250287

tests/test_session.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,20 @@ def patched_cmd(cmd_name: str, *args: t.Any, **kwargs: t.Any) -> tmux_cmd:
576576
test_session.attach()
577577

578578

579+
def test_detach_client(
580+
control_mode: t.Callable[..., t.Any],
581+
session: Session,
582+
server: Server,
583+
) -> None:
584+
"""Test Session.detach_client() detaches the control-mode client."""
585+
with control_mode():
586+
before = len(server.list_clients())
587+
assert before > 0
588+
session.detach_client()
589+
after = len(server.list_clients())
590+
assert after == before - 1
591+
592+
579593
def test_last_window(session: Session) -> None:
580594
"""Test Session.last_window() selects previous window."""
581595
w1 = session.new_window(window_name="last_a", attach=True)

0 commit comments

Comments
 (0)