Skip to content

Commit 5ba2e3d

Browse files
committed
docs(session,window): Add comprehensive docstrings for async methods
Enhance Session and Window async method docstrings to first-class documentation standard: Session.anew_window(): - Expand all 8 parameter descriptions with detailed explanations - Add 7 comprehensive narrative examples covering: - Basic window creation - Custom working directory - Environment variables - Concurrent window creation - Window shell commands - Window index positioning - Direction-based positioning (tmux 3.2+) - Document tmux command equivalents - Include version change notes - Add See Also section with cross-references Session.arename_session(): - Add detailed parameter and return value documentation - Include 3 narrative examples: - Basic session rename - Rename with verification - Chaining operations - Document BSD system tmux 2.7 warning behavior - Add cross-references to related methods Window.akill(): - Expand all_except parameter documentation - Add 4 comprehensive examples: - Kill single window - Kill all windows except one - Concurrent window cleanup - Cleanup pattern with try/finally - Document behavior after killing - Add See Also section All docstrings now match the quality and depth of sync method documentation, following NumPy docstring conventions with narrative code blocks for async examples.
1 parent 5f3c870 commit 5ba2e3d

File tree

2 files changed

+291
-26
lines changed

2 files changed

+291
-26
lines changed

src/libtmux/session.py

Lines changed: 208 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -295,19 +295,71 @@ async def acmd(
295295
async def arename_session(self, new_name: str) -> Session:
296296
"""Rename session asynchronously and return session object.
297297
298+
This is the async version of :meth:`rename_session`. It uses ``await self.acmd()``
299+
for non-blocking session renaming, making it suitable for async applications.
300+
301+
Equivalent to::
302+
303+
$ tmux rename-session <new_name>
304+
298305
Parameters
299306
----------
300307
new_name : str
301-
new session name
308+
New name for the session. Must not contain periods (.) or colons (:).
309+
310+
Returns
311+
-------
312+
:class:`Session`
313+
Returns self (the session object) with updated name
302314
303315
Raises
304316
------
305317
:exc:`exc.BadSessionName`
318+
If new_name contains invalid characters (periods or colons)
319+
:exc:`exc.LibTmuxException`
320+
If tmux command execution fails
321+
322+
See Also
323+
--------
324+
:meth:`rename_session` : Synchronous version of this method
325+
:meth:`Session.session_name` : Property to get current session name
326+
327+
Notes
328+
-----
329+
This method is non-blocking and suitable for use in async applications.
330+
The session object is automatically refreshed after renaming to ensure
331+
the session_name property reflects the new name.
332+
333+
On tmux 2.7 with BSD systems, a "no current client" warning may be
334+
raised but is safely ignored as it's a known issue fixed in later versions.
335+
336+
.. versionadded:: 0.48.0
337+
338+
Added async session renaming support.
306339
307340
Examples
308341
--------
309-
>>> await session.arename_session("new_name")
310-
Session($1 new_name)
342+
Basic session rename::
343+
344+
# Rename the session
345+
session = await session.arename_session("new_name")
346+
# session.session_name == "new_name"
347+
348+
Rename and verify::
349+
350+
old_name = session.session_name
351+
await session.arename_session("production")
352+
353+
# Verify the rename
354+
assert session.session_name == "production"
355+
assert session.server.has_session("production")
356+
assert not session.server.has_session(old_name)
357+
358+
Chaining operations::
359+
360+
# arename_session returns self, allowing chaining
361+
session = await session.arename_session("new_name")
362+
window = await session.anew_window(window_name="main")
311363
"""
312364
session_check_name(new_name)
313365

@@ -343,39 +395,178 @@ async def anew_window(
343395
) -> Window:
344396
"""Create new window asynchronously, returns new :class:`Window`.
345397
398+
This is the async version of :meth:`new_window`. It uses ``await self.acmd()``
399+
for non-blocking window creation, making it suitable for async applications
400+
and enabling concurrent window creation.
401+
346402
By default, this will make the window active. For the new window
347403
to be created and not set to current, pass in ``attach=False``.
348404
405+
Equivalent to::
406+
407+
$ tmux new-window -n <window_name>
408+
349409
Parameters
350410
----------
351411
window_name : str, optional
352-
start_directory : str, optional
353-
working directory in which the new window is created.
412+
Name for the new window. If not provided, tmux will auto-name
413+
based on the shell command running in the window.
414+
415+
start_directory : str or PathLike, optional
416+
Working directory in which the new window is created. All panes
417+
in the window will default to this directory.
418+
419+
Supports pathlib.Path objects and tilde expansion (``~/``).
420+
421+
Equivalent to::
422+
423+
$ tmux new-window -c <start_directory>
424+
354425
attach : bool, optional
355-
make new window the current window after creating it, default True.
356-
window_index : str
357-
create the new window at the given index position. Default is empty
358-
string which will create the window in the next available position.
426+
Make the new window the current (active) window after creating it.
427+
Default is False, meaning the window is created in the background.
428+
429+
When False (default)::
430+
431+
$ tmux new-window -d
432+
433+
window_index : str, optional
434+
Create the new window at the given index position. Default is empty
435+
string which creates the window in the next available position.
436+
437+
Use to control window ordering or create windows at specific indices.
438+
359439
window_shell : str, optional
360-
execute a command on starting the window. The window will close
361-
when the command exits.
440+
Shell command to execute when starting the window. The window will
441+
automatically close when the command exits.
442+
443+
.. warning::
444+
445+
When this command exits, the window will close. This feature is
446+
useful for long-running processes where automatic cleanup is desired.
447+
448+
environment : dict[str, str], optional
449+
Dictionary of environment variables to set in the new window.
450+
Each key-value pair will be set as an environment variable.
451+
452+
.. note::
453+
454+
Requires tmux 3.0+. On older versions, this parameter is ignored
455+
with a warning.
362456
363457
direction : WindowDirection, optional
364-
Insert window before or after target window (tmux 3.2+).
458+
Insert the new window before or after the target window.
459+
Values: "before" or "after".
460+
461+
.. note::
462+
463+
Requires tmux 3.2+. On older versions, this parameter is ignored
464+
with a warning.
365465
366466
target_window : str, optional
367-
Used by :meth:`Window.new_window` to specify the target window.
467+
Target window identifier for positioning the new window when using
468+
the direction parameter.
469+
470+
.. note::
471+
472+
Requires tmux 3.2+. On older versions, this parameter is ignored
473+
with a warning.
368474
369475
Returns
370476
-------
371477
:class:`Window`
372-
The newly created window.
478+
The newly created window object
479+
480+
Raises
481+
------
482+
:exc:`exc.LibTmuxException`
483+
If tmux command execution fails
484+
485+
See Also
486+
--------
487+
:meth:`new_window` : Synchronous version of this method
488+
:meth:`Session.kill_window` : Kill a window
489+
:class:`Window` : Window object documentation
490+
491+
Notes
492+
-----
493+
This method is non-blocking and suitable for use in async applications.
494+
It's particularly powerful when creating multiple windows concurrently
495+
using ``asyncio.gather()``, which can significantly improve performance
496+
compared to sequential creation.
497+
498+
.. versionadded:: 0.48.0
499+
500+
Added async window creation support.
501+
502+
.. versionchanged:: 0.28.0
503+
504+
``attach`` default changed from ``True`` to ``False``.
373505
374506
Examples
375507
--------
376-
>>> window = await session.anew_window(window_name='My Window')
377-
>>> window
378-
Window(@... 2:My Window, Session($1 libtmux_...))
508+
Basic window creation::
509+
510+
window = await session.anew_window(window_name='editor')
511+
# Window(@2 2:editor, Session($1 my_session))
512+
513+
With custom working directory::
514+
515+
from pathlib import Path
516+
517+
window = await session.anew_window(
518+
window_name='project',
519+
start_directory='~/code/myproject'
520+
)
521+
# All panes in this window start in ~/code/myproject
522+
523+
With environment variables (tmux 3.0+)::
524+
525+
window = await session.anew_window(
526+
window_name='dev',
527+
environment={
528+
'NODE_ENV': 'development',
529+
'DEBUG': 'true'
530+
}
531+
)
532+
# Environment variables available in window
533+
534+
Creating multiple windows concurrently::
535+
536+
import asyncio
537+
538+
windows = await asyncio.gather(
539+
session.anew_window(window_name='editor'),
540+
session.anew_window(window_name='terminal'),
541+
session.anew_window(window_name='logs'),
542+
)
543+
# All three windows created in parallel
544+
# len(windows) == 3
545+
546+
With window shell command::
547+
548+
window = await session.anew_window(
549+
window_name='monitor',
550+
window_shell='htop'
551+
)
552+
# Window runs htop, closes when htop exits
553+
554+
With specific window index::
555+
556+
window = await session.anew_window(
557+
window_name='first',
558+
window_index='1'
559+
)
560+
# Window created at index 1
561+
562+
With direction (tmux 3.2+)::
563+
564+
window = await session.anew_window(
565+
window_name='after',
566+
direction='after',
567+
target_window='@1'
568+
)
569+
# Window created after window @1
379570
"""
380571
window_args: tuple[str, ...] = ()
381572

src/libtmux/window.py

Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -283,23 +283,97 @@ async def akill(
283283
) -> None:
284284
"""Kill :class:`Window` asynchronously.
285285
286-
``$ tmux kill-window``.
286+
This is the async version of :meth:`kill`. It uses ``await self.acmd()``
287+
for non-blocking window destruction, making it suitable for async applications.
288+
289+
Equivalent to::
290+
291+
$ tmux kill-window
292+
293+
When ``all_except=True``::
294+
295+
$ tmux kill-window -a
287296
288297
Parameters
289298
----------
290299
all_except : bool, optional
291-
If True, kill all windows except this one.
300+
If True, kill all windows in the session except this one.
301+
If False or None (default), kill only this window.
302+
303+
Useful for cleaning up all other windows while keeping one active.
304+
305+
Raises
306+
------
307+
:exc:`exc.LibTmuxException`
308+
If tmux command execution fails
309+
310+
See Also
311+
--------
312+
:meth:`kill` : Synchronous version of this method
313+
:meth:`Session.kill_window` : Kill a window by target
314+
:meth:`Session.anew_window` : Create a new window asynchronously
315+
316+
Notes
317+
-----
318+
This method is non-blocking and suitable for use in async applications.
319+
After killing a window, the window object should not be used as it no
320+
longer represents a valid tmux window.
321+
322+
When ``all_except=True``, all other windows in the session are destroyed,
323+
leaving only the current window active. This is useful for cleaning up
324+
a session to a single window.
325+
326+
.. versionadded:: 0.48.0
327+
328+
Added async window killing support.
292329
293330
Examples
294331
--------
295-
Kill a window:
332+
Kill a single window::
296333
297-
>>> window_1 = await session.anew_window()
298-
>>> window_1 in session.windows
299-
True
300-
>>> await window_1.akill()
301-
>>> window_1 not in session.windows
302-
True
334+
# Create a window
335+
window = await session.anew_window(window_name='temp')
336+
337+
# Kill it
338+
await window.akill()
339+
# window no longer exists in session
340+
341+
Kill all windows except one::
342+
343+
# Create multiple windows
344+
keep_window = await session.anew_window(window_name='main')
345+
await session.anew_window(window_name='temp1')
346+
await session.anew_window(window_name='temp2')
347+
await session.anew_window(window_name='temp3')
348+
349+
# Kill all except keep_window
350+
await keep_window.akill(all_except=True)
351+
# Only keep_window remains in session
352+
353+
Concurrent window cleanup::
354+
355+
import asyncio
356+
357+
# Create some temporary windows
358+
temp_windows = await asyncio.gather(
359+
session.anew_window(window_name='temp1'),
360+
session.anew_window(window_name='temp2'),
361+
session.anew_window(window_name='temp3'),
362+
)
363+
364+
# Kill all temporary windows concurrently
365+
await asyncio.gather(*[w.akill() for w in temp_windows])
366+
# All temp windows destroyed in parallel
367+
368+
Cleanup pattern::
369+
370+
try:
371+
# Do work with window
372+
window = await session.anew_window(window_name='work')
373+
# ... use window ...
374+
finally:
375+
# Always clean up
376+
await window.akill()
303377
"""
304378
flags: tuple[str, ...] = ()
305379

0 commit comments

Comments
 (0)