Skip to content

Commit e86b07d

Browse files
committed
docs(CHANGES): Add release notes for options and hooks features
why: Document new OptionsMixin and HooksMixin features for 0.50.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 8e6169a commit e86b07d

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
@@ -34,6 +34,167 @@ $ 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+
# Get all indexed values for a hook
141+
session.get_hook_values('session-renamed')
142+
# SparseArray({0: 'display-message "Hook 0"', 1: '...', 5: '...'})
143+
144+
# Get just the indices
145+
session.get_hook_indices('session-renamed')
146+
# [0, 1, 5]
147+
148+
# Append at next available index
149+
session.append_hook('session-renamed', 'display-message "Hook 6"')
150+
151+
# Clear all indexed values for a hook
152+
session.clear_hook('session-renamed')
153+
```
154+
155+
**Hook methods available on Server, Session, Window, and Pane:**
156+
157+
| Method | Description |
158+
|--------|-------------|
159+
| `set_hook(hook, value)` | Set a hook |
160+
| `show_hook(hook)` | Get hook value |
161+
| `show_hooks()` | Get all hooks |
162+
| `unset_hook(hook)` | Remove a hook |
163+
| `run_hook(hook)` | Run a hook immediately |
164+
| `set_hooks(hook, values)` | Set multiple indexed hooks |
165+
| `get_hook_indices(hook)` | Get list of indices |
166+
| `get_hook_values(hook)` | Get all values as SparseArray |
167+
| `append_hook(hook, value)` | Append at next index |
168+
| `clear_hook(hook)` | Remove all indexed values |
169+
170+
#### SparseArray for Indexed Options (#516)
171+
172+
tmux uses sparse indexed arrays for options like `command-alias[0]`,
173+
`command-alias[99]`, `terminal-features[0]`. Python lists can't represent
174+
gaps in indices, so libtmux introduces {class}`~_internal.sparse_array.SparseArray`:
175+
176+
```python
177+
>>> from libtmux._internal.sparse_array import SparseArray
178+
179+
>>> arr: SparseArray[str] = SparseArray()
180+
>>> arr.add(0, "first")
181+
>>> arr.add(99, "ninety-ninth") # Gap in indices preserved!
182+
>>> arr[0]
183+
'first'
184+
>>> arr[99]
185+
'ninety-ninth'
186+
>>> list(arr.keys())
187+
[0, 99]
188+
>>> list(arr.iter_values()) # Values in index order
189+
['first', 'ninety-ninth']
190+
```
191+
192+
#### New Constants (#516)
193+
194+
- {class}`~constants.OptionScope` enum: `Server`, `Session`, `Window`, `Pane`
195+
- `OPTION_SCOPE_FLAG_MAP`: Maps scope to tmux flags (`-s`, `-w`, `-p`)
196+
- `HOOK_SCOPE_FLAG_MAP`: Maps scope to hook flags
197+
37198
## libtmux 0.49.0 (2025-11-29)
38199

39200
### Breaking Changes
@@ -48,6 +209,35 @@ deprecation announced in v0.48.0.
48209
- Removed version guards throughout the codebase
49210
- For users on older tmux, use libtmux v0.48.x
50211

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

53243
### Breaking Changes

0 commit comments

Comments
 (0)