Skip to content

Commit 7f08187

Browse files
committed
Hooks(docs): add doctests for from_stdout parsing pipeline
why: Document full pipeline from raw tmux output to typed Hooks dataclass what: - Add class-level doctests showing hook parsing and access patterns - Add from_stdout() doctests with parameter docs and examples - Demonstrate sparse index preservation and multiple hook types
1 parent 8fa77d5 commit 7f08187

File tree

1 file changed

+113
-1
lines changed

1 file changed

+113
-1
lines changed

src/libtmux/_internal/constants.py

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,71 @@ def __init__(self, **kwargs: object) -> None:
252252
class Hooks(
253253
SkipDefaultFieldsReprMixin,
254254
):
255-
"""tmux hooks data structure."""
255+
"""tmux hooks data structure.
256+
257+
Parses tmux hook output into typed :class:`SparseArray` fields, preserving
258+
array indices for hooks that can have multiple commands at different indices.
259+
260+
Examples
261+
--------
262+
Parse raw tmux hook output:
263+
264+
>>> from libtmux._internal.constants import Hooks
265+
266+
>>> raw = [
267+
... "session-renamed[0] set-option -g status-left-style bg=red",
268+
... "session-renamed[1] display-message 'session renamed'",
269+
... ]
270+
>>> hooks = Hooks.from_stdout(raw)
271+
272+
Access individual hook commands by index:
273+
274+
>>> hooks.session_renamed[0]
275+
'set-option -g status-left-style bg=red'
276+
>>> hooks.session_renamed[1]
277+
"display-message 'session renamed'"
278+
279+
Get all commands as a list (sorted by index):
280+
281+
>>> hooks.session_renamed.as_list()
282+
['set-option -g status-left-style bg=red', "display-message 'session renamed'"]
283+
284+
Sparse indices are preserved (gaps in index numbers):
285+
286+
>>> raw_sparse = [
287+
... "pane-focus-in[0] refresh-client",
288+
... "pane-focus-in[5] display-message 'focus'",
289+
... ]
290+
>>> hooks_sparse = Hooks.from_stdout(raw_sparse)
291+
>>> 0 in hooks_sparse.pane_focus_in
292+
True
293+
>>> 5 in hooks_sparse.pane_focus_in
294+
True
295+
>>> 3 in hooks_sparse.pane_focus_in
296+
False
297+
>>> sorted(hooks_sparse.pane_focus_in.keys())
298+
[0, 5]
299+
300+
Iterate over values in index order:
301+
302+
>>> for cmd in hooks_sparse.pane_focus_in.iter_values():
303+
... print(cmd)
304+
refresh-client
305+
display-message 'focus'
306+
307+
Multiple hook types in one parse:
308+
309+
>>> raw_multi = [
310+
... "after-new-window[0] select-pane -t 0",
311+
... "after-new-window[1] send-keys 'clear' Enter",
312+
... "window-renamed[0] refresh-client -S",
313+
... ]
314+
>>> hooks_multi = Hooks.from_stdout(raw_multi)
315+
>>> len(hooks_multi.after_new_window)
316+
2
317+
>>> len(hooks_multi.window_renamed)
318+
1
319+
"""
256320

257321
# --- Tmux normal hooks ---
258322
# Run when a window has activity. See monitor-activity.
@@ -453,6 +517,54 @@ class Hooks(
453517

454518
@classmethod
455519
def from_stdout(cls, value: list[str]) -> Hooks:
520+
"""Parse raw tmux hook output into a Hooks instance.
521+
522+
The parsing pipeline:
523+
524+
1. ``parse_options_to_dict()`` - Parse "key value" lines into dict
525+
2. ``explode_arrays(force_array=True)`` - Extract array indices into SparseArray
526+
3. ``explode_complex()`` - Handle complex option types
527+
4. Rename keys: ``session-renamed`` → ``session_renamed``
528+
529+
Parameters
530+
----------
531+
value : list[str]
532+
Raw tmux output lines from ``show-hooks`` command.
533+
534+
Returns
535+
-------
536+
Hooks
537+
Parsed hooks with SparseArray fields for each hook type.
538+
539+
Examples
540+
--------
541+
Basic parsing:
542+
543+
>>> from libtmux._internal.constants import Hooks
544+
545+
>>> raw = ["session-renamed[0] display-message 'renamed'"]
546+
>>> hooks = Hooks.from_stdout(raw)
547+
>>> hooks.session_renamed[0]
548+
"display-message 'renamed'"
549+
550+
The pipeline preserves sparse indices:
551+
552+
>>> raw = [
553+
... "after-select-window[0] refresh-client",
554+
... "after-select-window[10] display-message 'selected'",
555+
... ]
556+
>>> hooks = Hooks.from_stdout(raw)
557+
>>> sorted(hooks.after_select_window.keys())
558+
[0, 10]
559+
560+
Empty input returns empty SparseArrays:
561+
562+
>>> hooks_empty = Hooks.from_stdout([])
563+
>>> len(hooks_empty.session_renamed)
564+
0
565+
>>> hooks_empty.session_renamed.as_list()
566+
[]
567+
"""
456568
from libtmux.options import (
457569
explode_arrays,
458570
explode_complex,

0 commit comments

Comments
 (0)