Skip to content

Commit 93b8024

Browse files
committed
docs(CHANGES): Add release notes for options and hooks features
why: Document new OptionsMixin and HooksMixin features for 0.49.x release. what: - Add breaking changes for renamed Window option methods - Document OptionsMixin with set_option, show_option, show_options, unset_option - Document HooksMixin with set_hook, show_hook, unset_hook, set_hooks - Document new Window.set_option() arguments
1 parent 6cb16fa commit 93b8024

File tree

1 file changed

+190
-0
lines changed

1 file changed

+190
-0
lines changed

CHANGES

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,167 @@ $ uvx --from 'libtmux' --prerelease allow python
3232

3333
<!-- To maintainers and contributors: Please add notes for the forthcoming version below -->
3434

35+
### Overview
36+
37+
libtmux 0.49 brings a major enhancement to option and hook management. The new
38+
{class}`~options.OptionsMixin` and {class}`~hooks.HooksMixin` classes provide a
39+
unified, typed API for managing tmux options and hooks across all object types.
40+
41+
**Highlights:**
42+
43+
- **Unified Options API**: New `show_option()`, `show_options()`, `set_option()`,
44+
and `unset_option()` methods available on Server, Session, Window, and Pane.
45+
- **Hook Management**: Full programmatic control over tmux hooks with support for
46+
indexed hook arrays and bulk operations.
47+
- **SparseArray**: New internal data structure for handling tmux's sparse indexed
48+
arrays (e.g., `command-alias[0]`, `command-alias[99]`).
49+
- **tmux 3.2+ baseline**: Removed support for tmux versions below 3.2a, enabling
50+
cleaner code and full hook/option feature support.
51+
52+
### What's New
53+
54+
#### Unified Options API (#516)
55+
56+
All tmux objects now share a consistent options interface through
57+
{class}`~options.OptionsMixin`:
58+
59+
```python
60+
import libtmux
61+
62+
server = libtmux.Server()
63+
session = server.sessions[0]
64+
window = session.windows[0]
65+
pane = window.panes[0]
66+
67+
# Get all options as a structured dict
68+
session.show_options()
69+
# {'activity-action': 'other', 'base-index': 0, ...}
70+
71+
# Get a single option value
72+
session.show_option('base-index')
73+
# 0
74+
75+
# Set an option
76+
window.set_option('automatic-rename', True)
77+
78+
# Unset an option (revert to default)
79+
window.unset_option('automatic-rename')
80+
```
81+
82+
**New methods on Server, Session, Window, and Pane:**
83+
84+
| Method | Description |
85+
|--------|-------------|
86+
| `show_options()` | Get all options as a structured dict |
87+
| `show_option(name)` | Get a single option value |
88+
| `set_option(name, value)` | Set an option |
89+
| `unset_option(name)` | Unset/remove an option |
90+
91+
**New parameters for `set_option()`:**
92+
93+
| Parameter | tmux flag | Description |
94+
|-----------|-----------|-------------|
95+
| `_format` | `-F` | Expand format strings in value |
96+
| `unset` | `-u` | Unset the option |
97+
| `global_` | `-g` | Set as global option |
98+
| `unset_panes` | `-U` | Also unset in child panes |
99+
| `prevent_overwrite` | `-o` | Don't overwrite if exists |
100+
| `suppress_warnings` | `-q` | Suppress warnings |
101+
| `append` | `-a` | Append to existing value |
102+
103+
#### Hook Management (#516)
104+
105+
New {class}`~hooks.HooksMixin` provides programmatic control over tmux hooks:
106+
107+
```python
108+
session = server.sessions[0]
109+
110+
# Set a hook
111+
session.set_hook('session-renamed', 'display-message "Renamed!"')
112+
113+
# Get hook value
114+
session.show_hook('session-renamed')
115+
# 'display-message "Renamed!"'
116+
117+
# Get all hooks
118+
session.show_hooks()
119+
# {'session-renamed': 'display-message "Renamed!"'}
120+
121+
# Remove a hook
122+
session.unset_hook('session-renamed')
123+
```
124+
125+
**Indexed hooks and bulk operations:**
126+
127+
tmux hooks support multiple values via indices (e.g., `session-renamed[0]`,
128+
`session-renamed[1]`). The bulk operations API makes this easy:
129+
130+
```python
131+
# Set multiple hooks at once
132+
session.set_hooks('session-renamed', {
133+
0: 'display-message "Hook 0"',
134+
1: 'display-message "Hook 1"',
135+
5: 'run-shell "echo hook 5"',
136+
})
137+
138+
# Get all indexed values for a hook
139+
session.get_hook_values('session-renamed')
140+
# SparseArray({0: 'display-message "Hook 0"', 1: '...', 5: '...'})
141+
142+
# Get just the indices
143+
session.get_hook_indices('session-renamed')
144+
# [0, 1, 5]
145+
146+
# Append at next available index
147+
session.append_hook('session-renamed', 'display-message "Hook 6"')
148+
149+
# Clear all indexed values for a hook
150+
session.clear_hook('session-renamed')
151+
```
152+
153+
**Hook methods available on Server, Session, Window, and Pane:**
154+
155+
| Method | Description |
156+
|--------|-------------|
157+
| `set_hook(hook, value)` | Set a hook |
158+
| `show_hook(hook)` | Get hook value |
159+
| `show_hooks()` | Get all hooks |
160+
| `unset_hook(hook)` | Remove a hook |
161+
| `run_hook(hook)` | Run a hook immediately |
162+
| `set_hooks(hook, values)` | Set multiple indexed hooks |
163+
| `get_hook_indices(hook)` | Get list of indices |
164+
| `get_hook_values(hook)` | Get all values as SparseArray |
165+
| `append_hook(hook, value)` | Append at next index |
166+
| `clear_hook(hook)` | Remove all indexed values |
167+
168+
#### SparseArray for Indexed Options (#516)
169+
170+
tmux uses sparse indexed arrays for options like `command-alias[0]`,
171+
`command-alias[99]`, `terminal-features[0]`. Python lists can't represent
172+
gaps in indices, so libtmux introduces {class}`~_internal.sparse_array.SparseArray`:
173+
174+
```python
175+
>>> from libtmux._internal.sparse_array import SparseArray
176+
177+
>>> arr: SparseArray[str] = SparseArray()
178+
>>> arr.add(0, "first")
179+
>>> arr.add(99, "ninety-ninth") # Gap in indices preserved!
180+
>>> arr[0]
181+
'first'
182+
>>> arr[99]
183+
'ninety-ninth'
184+
>>> list(arr.keys())
185+
[0, 99]
186+
>>> list(arr.iter_values()) # Values in index order
187+
['first', 'ninety-ninth']
188+
```
189+
190+
#### New Constants (#516)
191+
192+
- {class}`~constants.OptionScope` enum: `Server`, `Session`, `Window`, `Pane`
193+
- `OPTION_SCOPE_FLAG_MAP`: Maps scope to tmux flags (`-s`, `-w`, `-p`)
194+
- `HOOK_SCOPE_FLAG_MAP`: Maps scope to hook flags
195+
35196
### Breaking Changes
36197

37198
#### tmux 1.8 to 3.1c support removed (#608)
@@ -44,6 +205,35 @@ deprecation announced in v0.48.0.
44205
- Removed version guards throughout the codebase
45206
- For users on older tmux, use libtmux v0.48.x
46207

208+
#### Deprecated Window methods (#516)
209+
210+
The following methods are deprecated and will be removed in a future release:
211+
212+
| Deprecated | Replacement |
213+
|------------|-------------|
214+
| `Window.set_window_option()` | `Window.set_option()` |
215+
| `Window.show_window_option()` | `Window.show_option()` |
216+
| `Window.show_window_options()` | `Window.show_options()` |
217+
218+
The old methods will emit a {class}`DeprecationWarning` when called:
219+
220+
```python
221+
window.set_window_option('automatic-rename', 'on')
222+
# DeprecationWarning: Window.set_window_option() is deprecated
223+
224+
# Use the new method instead:
225+
window.set_option('automatic-rename', True)
226+
```
227+
228+
### tmux Version Compatibility
229+
230+
| Feature | Minimum tmux |
231+
|---------|-------------|
232+
| All options/hooks features | 3.2+ |
233+
| Window/Pane hook scopes (`-w`, `-p`) | 3.2+ |
234+
| `client-active`, `window-resized` hooks | 3.3+ |
235+
| `pane-title-changed` hook | 3.5+ |
236+
47237
## libtmux 0.48.0 (2025-11-28)
48238

49239
### Breaking Changes

0 commit comments

Comments
 (0)