Observing output
Use observe_output for raw future terminal bytes. A screen capture
is a separate observation: capture_baseline returns captured bytes
and an explicit :reset boundary. Its before/after cursors do not establish
an atomic relationship between the screen and the stream.
This program checks the exact bytes of terminal echo. Echo does not prove that a command started, finished or succeeded.
using LibTmux
environment = Dict( "PATH" => get(ENV, "PATH", "/usr/bin:/bin"), "TERM" => "xterm-256color", "SHELL" => "/bin/sh",)
with_server(; tmux=get(ENV, "LIBTMUX_TEST_TMUX", "tmux"), env=environment) do server created = new_session(server; name="stream", command=["/bin/cat"]) pane = only(panes(snapshot(server))).ref open_control(server, created) do connection observe_output(connection, pane) do stream baseline = capture_baseline(stream) @assert baseline.continuity === :reset message = "observed terminal echo: λ" send_keys(server, pane, message; literal=true) bytes = UInt8[] started = time_ns() while length(bytes) < ncodeunits(message) remaining = 0.9 - (time_ns() - started) / 1e9 remaining > 0 || error("terminal echo deadline expired") append!(bytes, take!(stream; timeout=remaining).bytes) end @assert bytes == codeunits(message) @assert observation_cursor(stream).pane == pane.id println(decode_text(bytes)) end endendEach stream has one consumer and independent item/byte limits. A slow
consumer loses its own stream with ObservationLost; it cannot block
the shared control reader. take! accepts timeout and cancel. Always use
the callback form or close explicitly, including after an iteration error.
An unreachable stream is eventually retired, but GC does not provide a cleanup
deadline.
observation_cursor identifies the last consumed event. Replay with
after=cursor is limited to the same connection and retained history:
256 records or 4 MiB, shared across event types. Foreign, expired or
topology-invalidated cursors require a new stream and baseline. Retaining a
cursor does not retain history. Closing the connection invalidates replay.
notifications observes tmux notifications. subscribe_format
observes sampled field changes and preserves window-link context. tmux’s
roughly one-second subscription cadence cannot establish prompt readiness
or output quiescence. Pane movement or removal requires a new subscription.
Use format_value to decode a format update’s escaped bytes locally;
literal tabs, newlines and backslashes are preserved.