Getting started
Hex.pm · API reference · HexDocs · Documentation
Read tmux sessions, windows and panes from Elixir. Filter a snapshot, rename a window, split a pane, send input, or capture its screen. Queries use the captured snapshot; actions contact tmux explicitly.
Capture and query · Rename a window · Split and send input · Guides
Status and requirements¶
Alpha: the API may change between releases.
| Requirement | Version or dependency |
|---|---|
| Elixir / OTP¶ | Elixir 1.20.4 or later 1.20 patch, compiled for OTP 29; OTP 29.1.2 or later 29 patch |
| Runtime platform¶ | Linux, with a C11 compiler and headers to build the external helper |
| tmux¶ | 3.3 minimum; tested with 3.3, 3.3a, 3.4 and 3.8 |
| Dependencies¶ | Zero third-party core runtime packages; no NIF |
Installation¶
Add the published alpha to your Mix dependencies:
{:libtmux, "== 0.0.1-alpha.3"}Fetch dependencies:
$ mix deps.getRun the examples¶
The snippets below form one executable program. From this checkout, run it on a private tmux server:
$ python3 examples/owned_server.py \ --run "$(command -v tmux)" \ mix run examples/readme.exsThe runner creates a private server and cleans it up afterward. It supplies the executable, socket and session ID used below, leaving your existing tmux sessions alone. The runner needs Python 3.9+.
Already have a server? Use the capture-only program, which takes its socket explicitly and leaves the server running.
Capture and query¶
Server.snapshot!/2 captures an immutable graph.
Selection.where/2 accepts predicate data; ordinary Enum functions
work on the selection. These queries make no further tmux calls.
alias LibTmux.{Selection, Server, Snapshot}
[executable, socket, session_id] = System.argv()
server = Server.new( executable: executable, socket: socket, env: Map.drop(System.get_env(), ["TMUX", "TMUX_PANE"]) )
snapshot = Server.snapshot!(server)
active_ids = snapshot |> Snapshot.panes() |> Selection.where(active: true) |> Enum.map(& &1.id)The fixture starts with one pane, so active_ids is ["%0"]. To use an
Elixir function as the predicate, choose Selection.filter/2.
Capture again explicitly when you need fresh observations.
Rename a window¶
Continue with the same snapshot and server.
Selection.one!/2 requires exactly one match, and
Session.active_window/2 reads the captured relationship.
Ref.from_observation/1 carries the observed identity into an action.
alias LibTmux.{Ref, Selection, Session, Snapshot, Window}
session = snapshot |> Snapshot.sessions() |> Selection.one!(id: session_id)window = Session.active_window(snapshot, session){:ok, session_ref} = Ref.from_observation(session){:ok, window_ref} = Ref.from_observation(window)
Window.rename!(server, window_ref, "editor", session: session_ref)Window.rename!/4 returns :ok when tmux acknowledges completion.
The session option chooses this window’s session membership. The original
snapshot still contains the name captured before the action.
Split a pane and send input¶
Continue with that window and session.
Control.with_connection/2
owns connection startup and cleanup around the callback. Its returned value
is available after connection retirement.
alias LibTmux.{Control, Pane, Ref, Selection, Snapshot}
pane = snapshot |> Snapshot.panes() |> Selection.one!(window_id: window.id, active: true){:ok, pane_ref} = Ref.from_observation(pane)
{:ok, created_id} = Control.with_connection( [server: server, session: {:existing, session.id}, lane: :host_qualified], fn control -> %{id: id, ref: created} = Pane.split!(control, pane_ref, axis: :horizontal, command: {:argv, ["/bin/cat"]})
Pane.send_text!(control, created, "hello") Pane.send_keys!(control, created, ["Enter"]) id end )Pane.split!/3 returns the new pane’s ID and bound reference on this
connection. Pane.send_text!/4 sends literal text;
Pane.send_keys!/4 sends named keys. {:argv, ["/bin/cat"]} requests
a program directly; {:shell, "command"} requests shell interpretation.
Acknowledgement does not mean the program has finished processing its input.
The private runner qualifies this example’s lane: :host_qualified declaration.
That option does not configure or qualify an arbitrary server. Read the
managed-control guide before using another host.
For one-shot screen reads, use Pane.capture!/3.
The complete program prints the active pane %0, the new pane %1, and the
window name editor. These examples run in CI. Each snippet shows its aliases;
they shorten module names and are not inferred.
Errors and recovery¶
The domain actions shown above raise when they cannot complete. If a command times out, it may still have taken effect. The recovery guide shows how to inspect the result before deciding what to do next.
Concepts and reference¶
- Filtering: predicates, relationships and finding one match.
- One-shot actions: rename, split, input and screen capture.
- Managed control: reuse a connection for multiple commands.
- Mental model: snapshots, references and command results.
- API reference: functions and types.
Contributing¶
See Contributing for development setup and checks, and Writing for documentation conventions.
Related projects: libtmux for Python, libtmux ports, and tmux. Artwork. Licensed under the MIT License.