@@ -34,6 +34,149 @@ $ uvx --from 'libtmux' --prerelease allow python
3434
3535_ Future release notes will be placed here_
3636
37+ ### Overview
38+
39+ libtmux 0.50 brings a major enhancement to option and hook management. The new
40+ {class}` ~options.OptionsMixin ` and {class}` ~hooks.HooksMixin ` classes provide a
41+ unified, typed API for managing tmux options and hooks across all object types.
42+
43+ ** Highlights:**
44+
45+ - ** Unified Options API** : New ` show_option() ` , ` show_options() ` , ` set_option() ` ,
46+ and ` unset_option() ` methods available on Server, Session, Window, and Pane.
47+ - ** Hook Management** : Full programmatic control over tmux hooks with support for
48+ indexed hook arrays and bulk operations.
49+ - ** SparseArray** : New internal data structure for handling tmux's sparse indexed
50+ arrays (e.g., ` command-alias[0] ` , ` command-alias[99] ` ).
51+ - ** tmux 3.2+ baseline** : Removed support for tmux versions below 3.2a, enabling
52+ cleaner code and full hook/option feature support.
53+
54+ ### What's New
55+
56+ #### Unified Options API (#516 )
57+
58+ All tmux objects now share a consistent options interface through
59+ {class}` ~options.OptionsMixin ` :
60+
61+ ``` python
62+ import libtmux
63+
64+ server = libtmux.Server()
65+ session = server.sessions[0 ]
66+ window = session.windows[0 ]
67+ pane = window.panes[0 ]
68+
69+ # Get all options as a structured dict
70+ session.show_options()
71+ # {'activity-action': 'other', 'base-index': 0, ...}
72+
73+ # Get a single option value
74+ session.show_option(' base-index' )
75+ # 0
76+
77+ # Set an option
78+ window.set_option(' automatic-rename' , True )
79+
80+ # Unset an option (revert to default)
81+ window.unset_option(' automatic-rename' )
82+ ```
83+
84+ ** New methods on Server, Session, Window, and Pane:**
85+
86+ | Method | Description |
87+ | --------| -------------|
88+ | ` show_options() ` | Get all options as a structured dict |
89+ | ` show_option(name) ` | Get a single option value |
90+ | ` set_option(name, value) ` | Set an option |
91+ | ` unset_option(name) ` | Unset/remove an option |
92+
93+ ** New parameters for ` set_option() ` :**
94+
95+ | Parameter | tmux flag | Description |
96+ | -----------| -----------| -------------|
97+ | ` _format ` | ` -F ` | Expand format strings in value |
98+ | ` unset ` | ` -u ` | Unset the option |
99+ | ` global_ ` | ` -g ` | Set as global option |
100+ | ` unset_panes ` | ` -U ` | Also unset in child panes |
101+ | ` prevent_overwrite ` | ` -o ` | Don't overwrite if exists |
102+ | ` suppress_warnings ` | ` -q ` | Suppress warnings |
103+ | ` append ` | ` -a ` | Append to existing value |
104+
105+ #### Hook Management (#516 )
106+
107+ New {class}` ~hooks.HooksMixin ` provides programmatic control over tmux hooks:
108+
109+ ``` python
110+ session = server.sessions[0 ]
111+
112+ # Set a hook
113+ session.set_hook(' session-renamed' , ' display-message "Renamed!"' )
114+
115+ # Get hook value
116+ session.show_hook(' session-renamed' )
117+ # 'display-message "Renamed!"'
118+
119+ # Get all hooks
120+ session.show_hooks()
121+ # {'session-renamed': 'display-message "Renamed!"'}
122+
123+ # Remove a hook
124+ session.unset_hook(' session-renamed' )
125+ ```
126+
127+ ** Indexed hooks and bulk operations:**
128+
129+ tmux hooks support multiple values via indices (e.g., ` session-renamed[0] ` ,
130+ ` session-renamed[1] ` ). The bulk operations API makes this easy:
131+
132+ ``` python
133+ # Set multiple hooks at once
134+ session.set_hooks(' session-renamed' , {
135+ 0 : ' display-message "Hook 0"' ,
136+ 1 : ' display-message "Hook 1"' ,
137+ 5 : ' run-shell "echo hook 5"' ,
138+ })
139+ ```
140+
141+ ** Hook methods available on Server, Session, Window, and Pane:**
142+
143+ | Method | Description |
144+ | --------| -------------|
145+ | ` set_hook(hook, value) ` | Set a hook |
146+ | ` show_hook(hook) ` | Get hook value (returns SparseArray for indexed hooks) |
147+ | ` show_hooks() ` | Get all hooks |
148+ | ` unset_hook(hook) ` | Remove a hook |
149+ | ` run_hook(hook) ` | Run a hook immediately |
150+ | ` set_hooks(hook, values) ` | Set multiple indexed hooks at once |
151+
152+ #### SparseArray for Indexed Options (#516 )
153+
154+ tmux uses sparse indexed arrays for options like ` command-alias[0] ` ,
155+ ` command-alias[99] ` , ` terminal-features[0] ` . Python lists can't represent
156+ gaps in indices, so libtmux introduces {class}` ~_internal.sparse_array.SparseArray ` :
157+
158+ ``` python
159+ >> > from libtmux._internal.sparse_array import SparseArray
160+
161+ >> > arr: SparseArray[str ] = SparseArray()
162+ >> > arr.add(0 , " first" )
163+ >> > arr.add(99 , " ninety-ninth" ) # Gap in indices preserved!
164+ >> > arr[0 ]
165+ ' first'
166+ >> > arr[99 ]
167+ ' ninety-ninth'
168+ >> > list (arr.keys())
169+ [0 , 99 ]
170+ >> > list (arr.iter_values()) # Values in index order
171+ [' first' , ' ninety-ninth' ]
172+ ```
173+
174+ #### New Constants (#516 )
175+
176+ - {class}` ~constants.OptionScope ` enum: ` Server ` , ` Session ` , ` Window ` , ` Pane `
177+ - ` OPTION_SCOPE_FLAG_MAP ` : Maps scope to tmux flags (` -s ` , ` -w ` , ` -p ` )
178+ - ` HOOK_SCOPE_FLAG_MAP ` : Maps scope to hook flags
179+
37180## libtmux 0.49.0 (2025-11-29)
38181
39182### Breaking Changes
@@ -48,6 +191,35 @@ deprecation announced in v0.48.0.
48191- Removed version guards throughout the codebase
49192- For users on older tmux, use libtmux v0.48.x
50193
194+ #### Deprecated Window methods (#516 )
195+
196+ The following methods are deprecated and will be removed in a future release:
197+
198+ | Deprecated | Replacement |
199+ | ------------| -------------|
200+ | ` Window.set_window_option() ` | ` Window.set_option() ` |
201+ | ` Window.show_window_option() ` | ` Window.show_option() ` |
202+ | ` Window.show_window_options() ` | ` Window.show_options() ` |
203+
204+ The old methods will emit a {class}` DeprecationWarning ` when called:
205+
206+ ``` python
207+ window.set_window_option(' automatic-rename' , ' on' )
208+ # DeprecationWarning: Window.set_window_option() is deprecated
209+
210+ # Use the new method instead:
211+ window.set_option(' automatic-rename' , True )
212+ ```
213+
214+ ### tmux Version Compatibility
215+
216+ | Feature | Minimum tmux |
217+ | ---------| -------------|
218+ | All options/hooks features | 3.2+ |
219+ | Window/Pane hook scopes (` -w ` , ` -p ` ) | 3.2+ |
220+ | ` client-active ` , ` window-resized ` hooks | 3.3+ |
221+ | ` pane-title-changed ` hook | 3.5+ |
222+
51223## libtmux 0.48.0 (2025-11-28)
52224
53225### Breaking Changes
0 commit comments