Core LibraryunreleasedConcepts

Choose documentation 1

latest

Current version

latest
English

Unreleased libtmux_erlang has not been released. Its API may change during development. This site's structure and URLs may change too.

Object graph

This program creates two sessions, a shared two-pane window, and two extra window links. It then checks the physical object graph and session-relative membership counts. tmux_window_link acts on a session/index membership and checks its expected physical window before dispatch.

Selecting a window membership changes that session’s current window. tmux_session:select/2 switches one explicitly named attached client to a session. It never attaches a client or chooses a current client implicitly. Its tmux_session:select/3 variant updates the destination environment only when requested. Client names can be reused after disconnection; this call does not provide an atomic client-incarnation check. The native API contract documents name lookup and environment-removal semantics.

Run it on a private server after compiling:

Terminal window
$ mise exec -- escript tools/run_examples.escript graph
-module(linked_graph).
-moduledoc "Distinguish physical windows from their session memberships.".
-export([run/2]).
-spec run(binary(), binary()) -> map().
run(Socket, Executable) ->
Endpoint = #{socket_path => Socket, executable => Executable},
{ok, Server} = tmux_server:open(Endpoint),
tmux_scope:run_or_error(fun() ->
{ok, Work} = tmux_session:create(Server,
#{name => <<"work">>, launch => #{argv => [<<"/bin/cat">>]}}),
tmux_scope:run_or_error(fun() ->
{ok, Mirror} = tmux_session:create(Server,
#{name => <<"mirror">>, launch => #{argv => [<<"/bin/cat">>]}}),
tmux_scope:run_or_error(fun() ->
{ok, Shared} = tmux_window:create(Work,
#{name => <<"shared">>,
launch => #{argv => [<<"/bin/cat">>]}}),
Launch = #{launch => #{argv => [<<"/bin/cat">>]}},
{ok, _} = tmux_pane:split(Shared, Launch),
WorkId = tmux_model:get(id, Work),
WindowId = tmux_model:get(id, Shared),
{ok, Before} = tmux_server:snapshot(Server),
{ok, Source} = tmux_select:one(#{window_id => WindowId},
tmux_select:window_links(Before)),
{ok, _} = tmux_window_link:link(Source, Work, #{index => 7}),
{ok, _} = tmux_window_link:link(
Source, Mirror, #{index => 9}),
{ok, Snapshot} = tmux_server:snapshot(Server),
3 = length(tmux_snapshot:windows(Snapshot)),
4 = length(tmux_snapshot:panes(Snapshot)),
5 = length(tmux_snapshot:window_links(Snapshot)),
{ok, CapturedWork} = tmux_snapshot:get(
session, WorkId, Snapshot),
{ok, Physical} = tmux_snapshot:related(
windows, CapturedWork, Snapshot),
{ok, Memberships} = tmux_snapshot:related(
window_links, CapturedWork, Snapshot),
2 = length(Physical),
3 = length(Memberships),
Criteria = #{window_links => #{count => 3},
panes => #{every => #{current_command => <<"cat">>},
count => 2}},
{ok, Only} = tmux_select:one(
Criteria, tmux_select:windows(Snapshot)),
WindowId = tmux_model:get(id, Only),
#{physical_windows => 3, physical_panes => 4, window_links => 5,
work_windows => 2, work_memberships => 3,
shared_window_panes => 2}
end, fun() ->
{ok, _} = tmux_session:kill(Mirror),
ok
end)
end, fun() ->
{ok, _} = tmux_session:kill(Work),
ok
end)
end, fun() ->
ok = tmux_server:close(Server)
end).

There are three physical windows and four physical panes. Five window links remain because the shared window occurs at two indexes in work and once in mirror. The windows relationship yields two unique windows for work; its window_links relationship retains all three memberships. Both traversals use tmux_snapshot:related/3.

A link is identified within a capture by session, index and expected physical window. It has no stable tmux link ID. Captured index references cannot promise atomic compare-and-act after another client moves a link.

Use tmux_window_link:get/3 for a fresh membership. link/3 adds a membership; move/3 moves just the checked membership; swap/3 exchanges two memberships’ physical windows. Their input rows must share one registered owner. Actions return command results and leave captured values unchanged.

select/1 selects the checked window in its session. unlink/2 removes one membership, retaining tmux’s last-link protection by default. Explicit force => true can destroy the physical window if its final membership goes. tmux_window:kill/1 destroys that window across all links.

If a captured index disappears or names another physical window, actions return stale_link before dispatch. tmux_server:bind/2 applies this same precondition when rebinding a link to an owner. It does not adopt the new occupant of an old index. The one-shot preflight and action are separate; another client can still change that membership between them.

The relation query checks the full captured graph. Filtering a window selection does not replace its panes with only matching panes. some, every, none and count require complete membership coverage, including empty selections. The query guide explains validation and correlation.

Compare captured server incarnations

Live tmux_snapshot:metadata/1 includes an opaque server_instance value. tmux_identity:fingerprint/1 derives a versioned binary comparison key from that captured identity without I/O. The key survives reconnecting through another endpoint handle and changes when the observed process incarnation changes. The installed consumer checks its JSON round trip.

An endpoint’s generation identifies that handle’s lifetime; it changes when the handle is reopened. A persisted incarnation key serves a different purpose: comparing the server observed by those handles. It cannot make a stale row actionable, establish current liveness or authorize an action. Use tmux_server:bind/2 to obtain a fresh actionable row.

Esc

Type to search.

Reference previewOpen reference