1106 symbols, extracted from source. Every type name in a signature links to its own entry; every cross-reference in a doc comment resolves against the same table.
Server 4 types
A tmux server found listening on a socket.
The bounded result of scanning for tmux servers.
The identity of one running tmux daemon at one endpoint.
A tmux server, addressed by its endpoint.
Session 2 types
A tmux session id such as $1.
A tmux session, as it was when the listing was read.
Window 6 types
Where a new window goes relative to one that is already there.
A tmux window id such as @1.
The session-local identity of one link to a window.
One tmux window, independent of every session that links it.
One session-local link to a window.
One window and one session-local appearance, read from the same tmux reply.
Pane 4 types
Where a split puts the pane it creates.
How big a split makes the pane it creates.
A tmux pane id such as %1.
A tmux pane, as it was when the listing was read.
Client 1 type
A client attached to a tmux server.
Hooks 2 types
Which of tmux's hook tables a hook lives in.
One tmux hook: a command tmux runs when something happens.
Options 2 types
The exact tmux table that owns an option.
One tmux option.
Buffers 1 type
One of the server's paste buffers.
Layout and geometry 1 type
Which way a resize moves the boundary a pane shares with its neighbour.
Environment 2 types
Which environment a variable lives in.
One variable in a tmux environment.
Versions 1 type
A tmux release, ordered the way tmux numbers them.
Commands 3 types
Several tmux commands sent in one invocation.
One tmux command, as argv.
A command to put in a pane, and whether to run it.
Control mode 4 types, 1 function or constant
One command's reply, framed between tmux's %begin and its terminator.
Something tmux said without being asked.
A live control-mode connection.
One observer's control notifications with finite pending storage.
- SubscriptionChangeStream : typealias SubscriptionChangeStream
-
A lazy view of subscription changes from one bounded notification observer.
Formats 1 type
A format tmux reports changes to, rather than being asked for.
Queries 6 types, 3 functions and constants
A value a filter can compare against.
A model that can be filtered declaratively.
How a filter compares one field.
Builds a filter from a field__operator=value lookup written as text.
The filtering vocabulary, as a document.
A quantified filter over a relation, as one value.
- exactlyOne(_:) ( expression : FilterExpr<Element> ) Self.Element
-
The one element the filter matches.
Distinguishes "nothing matched" from "several matched", because a caller that meant to address one object needs to know which mistake it made.
- Raises
- filter(_:) ( expression : FilterExpr<Element> ) [Self.Element]
-
Every element the filter matches, in order.
Returns a plain array: ordered, replayable, and free of any live connection to tmux.
- Raises
- oneOrNil(_:) ( expression : FilterExpr<Element> ) Self.Element?
-
The one element the filter matches, or
nilif none did.Only ambiguity is an error here; absence is an ordinary answer.
- Raises
Queries — Operators 2 types
A typed operator. The Value it is built for is the projected type of the key path it is paired with, so pairing a text operator with an integer field is a compile error rather than a runtime surprise.
How many related objects have to match.
Queries — Expressions 1 type
A filter over one model, held as data.
Snapshots 4 types
Where a previous read of a pane stopped.
What a pane has said since a cursor was taken.
A bounded read of a pane.
Every object read from one daemon incarnation.
Errors 12 types, 1 function or constant
Why a filter could not be built.
Why a decoded filter cannot be evaluated safely.
Why selecting one result from a filter failed.
Why a filter keyword could not be turned into a comparison.
Why a filtered listing failed.
Why a RegexPattern could not be compiled.
Why a compiled RegexPattern could not finish matching.
Everything a tmux operation can fail with.
A tmux reply that did not match its projection.
Why a lookup that expected exactly one match did not get one.
Why waiting for pane output failed before it produced an outcome.
Why a workspace could not be built, including what happened while undoing.
-
Narrowing a scope's thrown type back to
TmuxError.Every call in this library throws
TmuxErrorand says so, which lets a program writethrows(TmuxError)from top to bottom. The scoped forms —Server/using(_:_:),Server/connected(attachingTo:_:)andServer/withControlMode(attachingTo:_:)— are the exception: they take a closure, and a closure's thrown type cannot be carried out of one.That is a property of the language rather than a choice made here. Swift 6.2 does not infer a closure literal's thrown type from its body, so a
throws(TmuxError)overload of those scopes is unreachable without spelling the closure's own signature at every call site — and even with the type inferred, a scope that can fail on its own behalf has no way to rethrow that failure as the body's error, because there is no union of the two.So the narrowing happens at the boundary instead of inside the scope:
One wrapper per scope, rather than an annotation per closure.
- Important: This is for work that only fails with
TmuxError. Anything elsebodythrows is flattened intoTmuxError/invocationFailed(reason:)with its description as the reason, which keeps the signature honest but loses the original type. A body that throws errors of its own should stay untyped and be caught as itself. - Parameter body: the work to run, typically a scoped call.
- Returns: whatever
bodyreturned. - Throws:
TmuxError, either as thrown or as a flattened foreign error.
Examples
func names(_ server: Server) async throws(TmuxError) -> [String] {try await withTmuxError {try await server.using(.connected(to: "main")) { server intry await server.sessions().map(\.name)}}}- Raises
- Important: This is for work that only fails with
Constants and enums 1 type
How work reaches tmux.
Testing utilities 2 types, 8 functions and constants
Thrown when a name-addressed case runs without a directory to put it in.
The reaper was asked to remove a path outside this port's owned roots.
- namedSocketRoot : let namedSocketRoot: URL?
-
The directory a socket *name* resolves inside, when the run provides one.
tmux looks a name up in
TMUX_TMPDIR, whose default is shared with every other tmux on the machine — the other libtmux ports' included. A suite that addressed servers by name without moving that directory would put its sockets exactly where anything sweeping by prefix can reach them, which is what this whole root exists to prevent.So the directory is taken from the environment rather than set into it. The obvious alternative —
setenvfrom the fixture — writes toenvironwhile other cases are concurrently reading it to build a tmux environment, and that is a data race whether or not it has bitten yet. Cases that address a socket by path do not care either way,-Sbeing absolute.CONTRIBUTING.mdand CI name the directory;namedSocketsAvailableis what the suite checks so a run without one skips those cases rather than scattering sockets.
- namedSocketsAvailable : var namedSocketsAvailable: Bool
-
Whether this run can address servers by socket name inside the suite's root.
- reaperCommand(root:) ( root : URL ) TmuxCommand
-
A reaper that outlives this process, so a killed run leaves no server behind.
Arm it in the same invocation that creates the server's first session, and give it the directory holding the socket. Public because the benchmark provisions its own servers — with a counting shim standing in for tmux — and a second copy of this reasoning is a second copy to get wrong.
deferandkill-serverboth run *in the process that started the server*, which makes them useless in the one case that actually leaks: the run is killed outright by a harness timeout or an impatient operator, and every tmux server it started survives with no owner and no way to reach it. Cleanup that depends on the cleaner surviving is not deterministic.So the reaper lives inside the tmux server instead, as a background job. It watches the owning process and, once that is gone, removes the directory and kills the server. Three details carry the design:
- The directory goes first.
killends the server, and tmux kills its jobs when it exits, so anything sequenced after it would not run. - The server is addressed by pid, not by socket, because the socket is inside the directory just removed.
-
#{pid}is left for tmux to expand rather than asked for first, which is what lets arming ride in the same invocation that creates the session. Sent separately, a run killed in the gap between the two leaves a server no reaper ever covered — measurably, under load, about one server in six. - The interval is whole seconds. Fractions are a GNU and BSD extension that POSIX does not require, and a
sleepthat rejects its argument turns this into a busy loop per server rather than a slower one. Reaping a second later costs nothing here.
- Raises
- The directory goes first.
-
The lane binary when a matrix runner selected one, otherwise whatever
tmuxresolves to. Resolved to a path because the transport never searchesPATH.
-
Waits until a pane's shell has drawn its first prompt.
Keys sent before that are echoed with no prompt in front of them, which leaves the prompt to land on the row the command's own output wants. A case looking for a row equal to what it printed is then waiting for something that cannot arrive, and reports it as a timeout naming nothing. One capture settles it for every case that follows.
What the prompt *says* is not portable —
shis dash on Linux and bash on macOS, which printssh-3.2$— so readiness is that the pane has drawn anything at all. Until the shell starts it has drawn nothing.This reads the pane directly rather than through the wait machinery: a fixture that bootstrapped itself with the code under test would make every unrelated case depend on it.
-
-
Polls
conditionuntil it holds, and reports whether it did.Bounded in wall-clock rather than in attempts. What makes one of these polls slow is the tmux call inside it, so a count of attempts says nothing about how long the loop can run: on a contended machine a generous-looking budget outlives the case's time limit, and the failure reads as a timeout instead of naming the thing that never became true.
- Raises
Discussed in Waiting and retrying
-
Runs
bodyagainst a private tmux server addressed by socket *name*, and always kills it.The same guarantees as
withTmuxServer(_:)— its own server, killed on the way out and reaped if this process is killed outright — for the half ofEndpointthat a path-addressed fixture never exercises.- Raises
-
Runs
bodyagainst a private tmux server and always kills it — including when this process is killed outright.Each case gets its own socket, so cases never see each other's sessions and teardown never touches a server it did not start. The server is bootstrapped with one session named
bootstrap: a tmux server exits as soon as its last session goes away, so without one there is nothing to hold it open. Scope assertions to the objects the case created rather than to the server being otherwise empty.- Raises
Discussed in Use the Swift workspace builder
Other 8 types
Finding the tmux servers already running on this machine.
Where a tmux server listens.
A regular-expression feature this package deliberately does not execute.
A compiled regular expression with bounded memory and matching work.
What tmux said.
Where the tmux this process is running inside can be found.
What a wait on a pane's output ended on.
One report that a subscribed format's value changed.