# fastmux


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

fastmux is a pythonic binding to [tmux](https://github.com/tmux/tmux).
[`tmux()`](./core.html#tmux) shows every session, window, and pane as a
tree, and `tmux(target)` returns a live
[`Session`](./core.html#session), [`Window`](./core.html#window), or
[`Pane`](./core.html#pane) handle, using standard tmux target syntax
such as `mysess:1.2`, `%5`, or `@3`. A [`Pane`](./core.html#pane)’s repr
is its current screen, its transcript can be indexed and sliced like a
list of lines, any scope can be searched rg-style, and panes are driven
with [`send`](./bg.html#send), [`send_keys`](./bg.html#send_keys), and
friends. `fastmux.bg` adds named, managed background sessions on top:
create-or-reuse a session by name and drive it by sid, so an agent and a
user can share the same terminal.

## Install

``` sh
pip install fastmux
```

You will also need [`tmux`](./core.html#tmux) itself installed and on
your `PATH`.

## Getting started

``` python
import sys
from fastmux import *
```

Start a throwaway session running anything you like. It’s created
detached, so your terminal is untouched:

``` python
s = new_session([sys.executable,'-u','-c','import time\n'
                                          'for i in range(30): print(f"line {i}")\n'
                                          'time.sleep(600)'],
                width=60, height=8)
p = s.pane
p.poll(wait_ms=2000)  # wait for output to arrive
p
```

<div class="prose" markdown="1">

``` python
line 23
line 24
line 25
line 26
line 27
line 28
line 29
```

</div>

A [`Pane`](./core.html#pane)’s repr is its live screen. The whole
transcript (scrollback included) works like a list of lines:

``` python
len(p), p[0], p[-1], p[5:7].lines
```

    (30, 'line 0', 'line 29', ('line 5', 'line 6'))

Split panes with the directional verbs `rsplit`, `bsplit`, `lsplit`, and
`asplit` (no tmux `-h`/`-v` confusion), again without stealing focus:

``` python
p.bsplit(size=3, cmd="top")
s.windows
```

    1: nbs* (2 panes) @0
      1.1: [60x4] %0 python (active)
      1.2: [60x3] %1 tmux

Panes can also be driven directly: `p.send('ls\n')` pastes text and
polls for the response, `p.send_keys('C-c')` sends tmux key names, and
`p.wait()` returns an exit status. See the [full
docs](https://AnswerDotAI.github.io/fastmux/core.html) for the complete
API.

Search any scope (one pane, a window, a session, or every terminal you
have) and get rg-style hits whose `target` can be pasted straight back
into [`tmux()`](./core.html#tmux):

``` python
hits = s.search('line 2')
hits
```

    0:1.1:2: line 2
    0:1.1:20: line 20
    0:1.1:21: line 21
    0:1.1:22: line 22
    0:1.1:23: line 23
    0:1.1:24: line 24
    0:1.1:25: line 25
    0:1.1:26: line 26
    0:1.1:27: line 27
    0:1.1:28: line 28
    0:1.1:29: line 29

``` python
tmux(hits[0].target)[-3:]
```

<div class="prose" markdown="1">

``` python
line 27
line 28
line 29
── 0:1.1 %0 · lines 27-30 of 30
```

</div>

And [`tmux()`](./core.html#tmux) alone shows everything as a tree of
sessions, windows, and panes:

``` python
tmux()
```

    0: 1 windows
      1: nbs* (2 panes) @0
        1.1: [60x4] %0 python (active)
        1.2: [60x3] %1 top

``` python
s.kill()
```

## Background sessions

A handle like `p` only helps while you can hold it. A background session
outlives that: it is created in one tool call, driven from another, and
shared with a user who attaches by name. `fastmux.bg` addresses sessions
by *sid* — a session name, a `%pane_id`, a handle, or `None` for the
current pane — and [`start_session`](./bg.html#start_session)
creates-or-reuses, so the same line works in every call:

``` python
from fastmux.bg import *
```

``` python
sid = 'fastmux-demo-bg'
start_session(sid, width=60, height=8)
send(sid, 'echo $((6*7)) apples\n', wait_ms=2000)
```

The user can watch or type alongside with
`tmux attach -t fastmux-demo-bg`, and polling is seen-state based:
output that arrived while nobody was watching satisfies the next
`poll(sid)` immediately, rather than making it wait for yet another
change. [`managed_sessions()`](./bg.html#managed_sessions) lists every
session [`start_session`](./bg.html#start_session) created, and
`close(sid)` kills one:

``` python
managed_sessions()
```

``` python
close(sid)
```
