Captured queries
snapshot acquires finite observations. panes(snap) contains
unique physical panes; paneoccurrences(snap) follows each session/window
link and may contain the same pane more than once. Filtering preserves the
source’s order and multiplicity.
PaneWhere, WindowWhere, SessionWhere,
WindowLinkWhere and ClientWhere are callable criteria.
Use them with Base filter, count, any, all, findall and
Iterators.filter. Ordinary closures and downstream callable values work
where Base accepts them. findall returns collection positions; those are
one-based Julia indices, independent of tmux’s configured indices.
filter preserves a Selection. collect and row projections give
ordinary Julia collections. A selection pins its snapshot; keeping one pane
can therefore retain the whole captured graph. Refreshing acquires a new
snapshot and never changes existing selections.
The complete shared-window example is included directly from its tested source:
using LibTmuximport LibTmux.Filters as F
function main() snap = with_server(; tmux=get(ENV, "LIBTMUX_TEST_TMUX", "tmux")) do server dev = new_session(server; name="dev", command=["/bin/cat"]) initial = snapshot(server) api = only(windows(initial)).ref rename_window(server, api, "api") split_window(server, only(panes(initial)).ref; command=["/bin/cat"]) new_window(server, dev; name="build", command=["/bin/cat"])
ops = new_session(server; name="ops", command=["/bin/cat"]) captured = snapshot(server) placeholder = only(windows(onlymatch(SessionWhere(name="ops"), sessions(captured)))).ref source = onlymatch( WindowLinkWhere(window=WindowWhere(name="api")), windowlinks(captured), ) link_window(server, WindowLinkRef(source), ops; index=4) kill_window(server, placeholder) snapshot(server) end
@assert length(sessions(snap)) == 2 @assert length(windows(snap)) == 2 @assert length(windowlinks(snap)) == 3 @assert length(panes(snap)) == 3 @assert length(paneoccurrences(snap)) == 5
# Captured relations remain usable after the owned daemon has stopped. has_api = SessionWhere(windows=F.AnyRelated(WindowWhere(name="api"))) @assert count(has_api, sessions(snap)) == 2 selected = filter(PaneWhere(active=true, window=WindowWhere(name="api")), panes(snap)) @assert length(selected) == 1 @assert only(selected).ref == only(Iterators.filter(p -> p.active && p.window.name == "api", panes(snap))).ref println("2 sessions, 2 windows, 3 links, 3 panes, 5 occurrences") snapend
main()Fields in one criterion are conjoined. Nested relations preserve correlation:
conditions within one AnyRelated(WindowWhere(...)) concern the same window.
Two separate AnyRelated clauses can match different windows. On a captured
empty relation, any/all/none evaluates to false/true/true. Uncaptured membership
raises SnapshotCoverageError, including in short-circuited branches.
only keeps Base’s zero/multiple-result errors. onlymatch adds
distinct NoMatchError and MultipleMatchesError diagnostics.
Portable criteria use encode_where and decode_where.
Closures are local code and cannot be encoded. TypeScript and Rust adapters
are separately named and reject semantics outside their verified intersection.
JSON and Tables are optional extensions, not mandatory core dependencies.
Criterion construction and wire conversion are pure and can be checked without a tmux executable:
julia> using LibTmux
julia> criterion = PaneWhere(active=true);
julia> criterion isa Functiontrue
julia> encode_where(decode_where(encode_where(criterion))) == encode_where(criterion)true