File: README.md

package info (click to toggle)
python-libtmux 0.50.0-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,684 kB
  • sloc: python: 10,663; makefile: 199; sh: 38
file content (323 lines) | stat: -rw-r--r-- 10,074 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
<div align="center">
  <h1>⚙️ libtmux</h1>
  <p><strong>Drive tmux from Python: typed, object-oriented control over servers, sessions, windows, and panes.</strong></p>
  <p>
    <a href="https://libtmux.git-pull.com/"><img src="https://raw.githubusercontent.com/tmux-python/libtmux/master/docs/_static/img/libtmux.svg" alt="libtmux logo" height="120"></a>
  </p>
  <p>
    <a href="https://pypi.org/project/libtmux/"><img src="https://img.shields.io/pypi/v/libtmux.svg" alt="PyPI version"></a>
    <a href="https://libtmux.git-pull.com/"><img src="https://github.com/tmux-python/libtmux/workflows/docs/badge.svg" alt="Docs status"></a>
    <a href="https://github.com/tmux-python/libtmux/actions"><img src="https://github.com/tmux-python/libtmux/workflows/tests/badge.svg" alt="Tests status"></a>
    <a href="https://codecov.io/gh/tmux-python/libtmux"><img src="https://codecov.io/gh/tmux-python/libtmux/branch/master/graph/badge.svg" alt="Coverage"></a>
    <a href="https://github.com/tmux-python/libtmux/blob/master/LICENSE"><img src="https://img.shields.io/github/license/tmux-python/libtmux.svg" alt="License"></a>
  </p>
</div>

## 🐍 What is libtmux?

libtmux is a typed Python API over [tmux], the terminal multiplexer. Stop shelling out and parsing `tmux ls`. Instead, interact with real Python objects: `Server`, `Session`, `Window`, and `Pane`. The same API powers [tmuxp], so it stays battle-tested in real-world workflows.

### ✨ Features

- Typed, object-oriented control of tmux state
- Query and [traverse](https://libtmux.git-pull.com/topics/traversal.html) live sessions, windows, and panes
- Raw escape hatch via `.cmd(...)` on any object
- Works with multiple tmux sockets and servers
- [Context managers](https://libtmux.git-pull.com/topics/context_managers.html) for automatic cleanup
- [pytest plugin](https://libtmux.git-pull.com/pytest-plugin/index.html) for isolated tmux fixtures
- Proven in production via tmuxp and other tooling

## Requirements & support

- tmux: >= 3.2a
- Python: >= 3.10 (CPython and PyPy)

Maintenance-only backports (no new fixes):

- Python 2.x: [`v0.8.x`](https://github.com/tmux-python/libtmux/tree/v0.8.x)
- tmux 1.8-3.1c: [`v0.48.x`](https://github.com/tmux-python/libtmux/tree/v0.48.x)

## 📦 Installation

Stable release:

```bash
pip install libtmux
```

With pipx:

```bash
pipx install libtmux
```

With uv / uvx:

```bash
uv add libtmux
uvx --from "libtmux" python
```

From the main branch (bleeding edge):

```bash
pip install 'git+https://github.com/tmux-python/libtmux.git'
```

Tip: libtmux is pre-1.0. Pin a range in projects to avoid surprises:

requirements.txt:

```ini
libtmux==0.49.*
```

pyproject.toml:

```toml
libtmux = "0.49.*"
```

## 🚀 Quickstart

### Open a tmux session

First, start a tmux session to connect to:

```console
$ tmux new-session -s foo -n bar
```

### Pilot your tmux session via Python

Use [ptpython], [ipython], etc. for a nice REPL with autocompletions:

```console
$ pip install --user ptpython
$ ptpython
```

Connect to a live tmux session:

```python
>>> import libtmux
>>> svr = libtmux.Server()
>>> svr
Server(socket_path=/tmp/tmux-.../default)
```

**Tip:** You can also use [tmuxp]'s [`tmuxp shell`] to drop straight into your
current tmux server / session / window / pane.

[ptpython]: https://github.com/prompt-toolkit/ptpython
[ipython]: https://ipython.org/
[`tmuxp shell`]: https://tmuxp.git-pull.com/cli/shell.html

### Run any tmux command

Every object has a `.cmd()` escape hatch that honors socket name and path:

```python
>>> server = Server(socket_name='libtmux_doctest')
>>> server.cmd('display-message', 'hello world')
<libtmux...>
```

Create a new session:

```python
>>> server.cmd('new-session', '-d', '-P', '-F#{session_id}').stdout[0]
'$...'
```

### List and filter sessions

[**Learn more about Filtering**](https://libtmux.git-pull.com/topics/filtering.html)

```python
>>> server.sessions
[Session($... ...), ...]
```

Filter by attribute:

```python
>>> server.sessions.filter(history_limit='2000')
[Session($... ...), ...]
```

Direct lookup:

```python
>>> server.sessions.get(session_id=session.session_id)
Session($... ...)
```

### Control sessions and windows

[**Learn more about Workspace Setup**](https://libtmux.git-pull.com/topics/workspace_setup.html)

```python
>>> session.rename_session('my-session')
Session($... my-session)
```

Create new window in the background (don't switch to it):

```python
>>> bg_window = session.new_window(attach=False, window_name="bg-work")
>>> bg_window
Window(@... ...:bg-work, Session($... ...))

>>> session.windows.filter(window_name__startswith="bg")
[Window(@... ...:bg-work, Session($... ...))]

>>> session.windows.get(window_name__startswith="bg")
Window(@... ...:bg-work, Session($... ...))

>>> bg_window.kill()
```

### Split windows and send keys

[**Learn more about Pane Interaction**](https://libtmux.git-pull.com/topics/pane_interaction.html)

```python
>>> pane = window.split(attach=False)
>>> pane
Pane(%... Window(@... ...:..., Session($... ...)))
```

Type inside the pane (send keystrokes):

```python
>>> pane.send_keys('echo hello')
>>> pane.send_keys('echo hey', enter=False)
>>> pane.enter()
Pane(%... ...)
```

### Capture pane output

```python
>>> pane.clear()
Pane(%... ...)
>>> pane.send_keys("echo 'hello world'", enter=True)
>>> pane.cmd('capture-pane', '-p').stdout  # doctest: +SKIP
["$ echo 'hello world'", 'hello world', '$']
```

### Traverse the hierarchy

[**Learn more about Traversal**](https://libtmux.git-pull.com/topics/traversal.html)

Navigate from pane up to window to session:

```python
>>> pane.window
Window(@... ...:..., Session($... ...))
>>> pane.window.session
Session($... ...)
```

## Core concepts

| libtmux object | tmux concept                | Notes                          |
|----------------|-----------------------------|--------------------------------|
| [`Server`](https://libtmux.git-pull.com/api/servers.html) | tmux server / socket | Entry point; owns sessions |
| [`Session`](https://libtmux.git-pull.com/api/sessions.html) | tmux session (`$0`, `$1`,...) | Owns windows |
| [`Window`](https://libtmux.git-pull.com/api/windows.html) | tmux window (`@1`, `@2`,...) | Owns panes |
| [`Pane`](https://libtmux.git-pull.com/api/panes.html) | tmux pane (`%1`, `%2`,...) | Where commands run |

Also available: [`Options`](https://libtmux.git-pull.com/api/options.html) and [`Hooks`](https://libtmux.git-pull.com/api/hooks.html) abstractions for tmux configuration.

Collections are live and queryable:

```python
server = libtmux.Server()
session = server.sessions.get(session_name="demo")
api_windows = session.windows.filter(window_name__startswith="api")
pane = session.active_window.active_pane
pane.send_keys("echo 'hello from libtmux'", enter=True)
```

## tmux vs libtmux vs tmuxp

| Tool    | Layer                      | Typical use case                                   |
|---------|----------------------------|----------------------------------------------------|
| tmux    | CLI / terminal multiplexer | Everyday terminal usage, manual control            |
| libtmux | Python API over tmux       | Programmatic control, automation, testing          |
| tmuxp   | App on top of libtmux      | Declarative tmux workspaces from YAML / TOML       |

## Testing & fixtures

[**Learn more about the pytest plugin**](https://libtmux.git-pull.com/pytest-plugin/index.html)

Writing a tool that interacts with tmux? Use our fixtures to keep your tests clean and isolated.

```python
def test_my_tmux_tool(session):
    # session is a real tmux session in an isolated server
    window = session.new_window(window_name="test")
    pane = window.active_pane
    pane.send_keys("echo 'hello from test'", enter=True)

    assert window.window_name == "test"
    # Fixtures handle cleanup automatically
```

- Fresh tmux server/session/window/pane fixtures per test
- Temporary HOME and tmux config fixtures keep indices stable
- `TestServer` helper spins up multiple isolated tmux servers

## When you might not need libtmux

- Layouts are static and live entirely in tmux config files
- You do not need to introspect or control running tmux from other tools
- Python is unavailable where tmux is running

## Project links

**Topics:**
[Traversal](https://libtmux.git-pull.com/topics/traversal.html) ·
[Filtering](https://libtmux.git-pull.com/topics/filtering.html) ·
[Pane Interaction](https://libtmux.git-pull.com/topics/pane_interaction.html) ·
[Workspace Setup](https://libtmux.git-pull.com/topics/workspace_setup.html) ·
[Automation Patterns](https://libtmux.git-pull.com/topics/automation_patterns.html) ·
[Context Managers](https://libtmux.git-pull.com/topics/context_managers.html) ·
[Options & Hooks](https://libtmux.git-pull.com/topics/options_and_hooks.html)

**Reference:**
[Docs][docs] ·
[API][api] ·
[pytest plugin](https://libtmux.git-pull.com/pytest-plugin/index.html) ·
[Architecture][architecture] ·
[Changelog][history] ·
[Migration][migration]

**Project:**
[Issues][issues] ·
[Coverage][coverage] ·
[Releases][releases] ·
[License][license] ·
[Support][support]

**[The Tao of tmux][tao]** — deep-dive book on tmux fundamentals

## Contributing & support

Contributions are welcome. Please open an issue or PR if you find a bug or want to improve the API or docs. If libtmux helps you ship, consider sponsoring development via [support].

[docs]: https://libtmux.git-pull.com
[api]: https://libtmux.git-pull.com/api.html
[architecture]: https://libtmux.git-pull.com/about.html
[history]: https://libtmux.git-pull.com/history.html
[migration]: https://libtmux.git-pull.com/migration.html
[issues]: https://github.com/tmux-python/libtmux/issues
[coverage]: https://codecov.io/gh/tmux-python/libtmux
[releases]: https://pypi.org/project/libtmux/
[license]: https://github.com/tmux-python/libtmux/blob/master/LICENSE
[support]: https://tony.sh/support.html
[tao]: https://leanpub.com/the-tao-of-tmux
[tmuxp]: https://tmuxp.git-pull.com
[tmux]: https://github.com/tmux/tmux