Core LibraryunreleasedGuides

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.

Isolate and rejoin a running pane

Move a job into its own window, then join it back without respawning it. This complete program checks the process ID, changed parent window, removal of the temporary window and immutability of the earlier capture. The runner owns the server and verifies cleanup:

Terminal window
$ mise exec -- escript tools/run_examples.escript panes
-module(pane_demo).
-moduledoc "Isolate a running pane, then join it back without respawning.".
-export([run/2]).
-spec run(binary(), binary()) -> map().
run(Socket, Executable) ->
{ok, Server} = tmux_server:open(
#{socket_path => Socket, executable => Executable}),
tmux_scope:run_or_error(fun() ->
{ok, Session} = tmux_session:create(Server,
#{name => <<"pane-workflow">>, window_name => <<"editor">>,
launch => #{argv => [<<"/bin/cat">>]}}),
tmux_scope:run_or_error(fun() ->
{ok, Initial} = tmux_server:snapshot(Server),
{ok, Link} = tmux_select:one(
#{session_id => tmux_model:get(id, Session)},
tmux_select:window_links(Initial)),
{ok, Window} = tmux_snapshot:related(window, Link, Initial),
{ok, [Anchor]} = tmux_snapshot:related(panes, Window, Initial),
WindowId = tmux_model:get(id, Window),
{ok, Pane} = tmux_pane:split(Anchor,
#{launch => #{argv => [<<"/bin/cat">>]}}),
Id = tmux_model:get(id, Pane),
Pid = tmux_model:get(pid, Pane),
{ok, Before} = tmux_server:snapshot(Server),
{ok, _} = tmux_pane:break(Pane, Link, Session,
#{index => 9, name => <<"isolated #{pane_id}">>}),
{ok, Isolated} = tmux_pane:get(Server, Id),
Pid = tmux_model:get(pid, Isolated),
Temporary = tmux_model:get(window_id, Isolated),
true = Temporary =/= WindowId,
{ok, OldPane} = tmux_snapshot:get(pane, Id, Before),
WindowId = tmux_model:get(window_id, OldPane),
{ok, _} = tmux_pane:join(Pane, Anchor,
#{direction => horizontal, size => {percent, 40}}),
{ok, Joined} = tmux_pane:get(Server, Id),
WindowId = tmux_model:get(window_id, Joined),
Pid = tmux_model:get(pid, Joined),
{error, #{code := target_gone}} =
tmux_window:get(Server, Temporary),
{ok, Final} = tmux_server:snapshot(Server),
2 = length(tmux_snapshot:panes(Final)),
#{same_process => true, snapshot_unchanged => true,
temporary_window_removed => true, panes_after_join => 2}
end, fun() ->
{ok, _} = tmux_session:kill(Session),
ok
end)
end, fun() ->
ok = tmux_server:close(Server)
end).
{
"same_process": true,
"snapshot_unchanged": true,
"temporary_window_removed": true,
"panes_after_join": 2
}

The archive check repeats this reader program outside the source checkout. Its separate native consumer also exercises same-window move and pane swap.

Supply a membership when breaking a pane

A physical window can be linked several times, even within one session. A pane therefore has no single source membership. tmux_pane:break/4 takes the pane, an explicit source window link, the destination session and placement options. index is required. detach defaults to true; false selects the destination membership. name is a literal UTF-8 argument, without format expansion.

Source windowWhat tmux changes
Several panesCreates a physical window and moves the pane into it; the original links remain
Only one paneMoves the selected membership of the existing physical window; other links remain

Pane IDs and running processes survive both cases. Moving the final membership out of a session can destroy that source session. Session groups retain tmux’s native synchronization behavior. An occupied destination index is refused.

The API checks the link’s expected window and the pane’s observed parent. It then sends a session/index selector qualified by the stable pane ID. An absent pane cannot become whichever pane later occupies its old positional index. The preflight and action remain separate commands: concurrent changes after the check, including an index moving away and back, can remain undetected. There is no atomic compare-and-act guarantee.

Literal means unexpanded, not stored verbatim. tmux’s own name cleaning still applies. For example, 3.3/3.4 stores an added backslash before dollar-variable prefixes; later releases changed that behavior. The library returns the stored name instead of guessing which escapes a caller intended. See the object graph guide for physical windows and memberships.

Move and swap by physical pane ID

tmux_pane:join/3 and tmux_pane:move/3 use the source and destination pane IDs. Their native commands share placement behavior and permit rearrangement within one window. Geometry uses t:tmux_pane:join_options/0: vertical by default, optional direction, cells/percent size, before and full_size. Both reject identical source/destination IDs.

tmux_pane:swap/3 exchanges layout positions within or across windows. Its detach defaults to true; zoom maps to tmux’s -Z retention flag. Swapping a pane with itself exchanges nothing, but native zoom handling still runs: the default can unzoom even that same-pane call. Across windows, active positions can receive different pane IDs even in detached mode.

Moving the last pane out destroys its physical window and every link to it, and can remove sessions. Shared windows affect all memberships. Existing processes keep their process environment and working directory; inherited window options can change when the pane changes parent. With detach false, join/move selection uses tmux’s resolved destination-session context. Supply window-link actions separately when a particular session membership must be selected.

Keep captures and action results separate

These calls return the completed command result for both new-window and existing-window cases. They never refresh input records or captures. Use tmux_pane:get/2, tmux_window_link:get/3 or tmux_server:snapshot/1 to observe the resulting graph. Source/destination rows must use the same registered owner; rebind explicitly when working through another endpoint owner.

A disappeared pane or session remains an operational error. A replaced source link returns stale_link; a different observed pane parent returns pane_link_mismatch. Even an eventual native layout error can unzoom windows. These operations are not transactions and are never automatically retried. The support page separates implemented APIs from remaining control, consumer and delivery qualification.

Esc

Type to search.

Reference previewOpen reference