Core LibraryalphaGuides

Choose documentation 1

latest

Current version

latest
English

Prerelease This site documents an alpha of libtmux. Its structure, URLs and APIs are subject to change.

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.

RequirementVersion or dependency
Elixir / OTPElixir 1.20.4 or later 1.20 patch, compiled for OTP 29; OTP 29.1.2 or later 29 patch
Runtime platformLinux, with a C11 compiler and headers to build the external helper
tmux3.3 minimum; tested with 3.3, 3.3a, 3.4 and 3.8
DependenciesZero third-party core runtime packages; no NIF

Installation

Add the published alpha to your Mix dependencies:

{:libtmux, "== 0.0.1-alpha.3"}

Fetch dependencies:

Terminal window
$ mix deps.get

Run the examples

The snippets below form one executable program. From this checkout, run it on a private tmux server:

Terminal window
$ python3 examples/owned_server.py \
--run "$(command -v tmux)" \
mix run examples/readme.exs

The 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

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.

Esc

Type to search.

Reference preview Open reference