Workspace ManagerGuides

Choose documentation 3

latest

Current version

latest
English

Prerelease This site documents an alpha of libtmux. Its structure, URLs and APIs are subject to change.

Workspace guide

LibTmuxWorkspace 0.1.0-alpha.1 · Source

LibTmuxWorkspace reads a documented tmuxp-style YAML/JSON subset. Validation, expansion and planning are pure. Applying a plan creates tmux resources and can execute shell input. Keep those stages explicit when reviewing an untrusted configuration.

From a consumer project directory, add the core and workspace package from the same public Git tag:

Terminal window
$ julia \
--startup-file=no \
-e 'using Pkg; Pkg.activate("."); repo="https://github.com/libtmux/libtmux-julia.git"; tag="v0.1.0-alpha.1"; Pkg.add([Pkg.PackageSpec(url=repo, rev=tag), Pkg.PackageSpec(url=repo, rev=tag, subdir="packages/LibTmuxWorkspace")])'

The following executable source example needs a checkout and its own consumer environment. Clone the same tag, then enter the checkout:

Terminal window
$ git clone \
--branch v0.1.0-alpha.1 \
--depth 1 \
https://github.com/libtmux/libtmux-julia.git
Terminal window
$ cd libtmux-julia

Create a local environment for the example:

Terminal window
$ julia \
--startup-file=no \
-e 'using Pkg; Pkg.activate(".workspace-env"); repo="https://github.com/libtmux/libtmux-julia.git"; tag="v0.1.0-alpha.1"; Pkg.add([Pkg.PackageSpec(url=repo, rev=tag), Pkg.PackageSpec(url=repo, rev=tag, subdir="packages/LibTmuxWorkspace")])'

It loads two panes, checks their layout and focus, freezes the supported reconstruction subset, and closes the private daemon:

Terminal window
$ julia \
--startup-file=no \
--project=.workspace-env \
packages/LibTmuxWorkspace/examples/owned_load.jl

The code below is included from that executable program:

owned_load.jl
using LibTmux, LibTmuxWorkspace
function main()
endpoint = Ref{Server}()
frozen = with_server(; tmux=get(ENV, "LIBTMUX_TEST_TMUX", "tmux")) do server
endpoint[] = server
config = validate(
Dict(
"session_name" => "workspace-example",
"options" => Dict("default-shell" => "/bin/sh"),
"windows" => [
Dict(
"window_name" => "editor",
"window_index" => 0,
"layout" => "even-horizontal",
"focus" => true,
"panes" => [
Dict(
"shell_command" => [
Dict("cmd" => "printf ready", "enter" => false),
],
),
Dict("focus" => true),
],
),
],
),
)
prepared = plan(expand(config; base_directory=dirname(server.socket_path)))
result = apply(server, prepared; rollback=:created)
@assert result.status == :complete
observed = snapshot(server)
@assert length(panes(observed)) == 2
link = only(windowlinks(observed))
@assert link.index == 0 && link.active
editor = window(link)
editor_panes = sort(collect(panes(editor)); by=p -> p.index)
@assert [p.active for p in editor_panes] == [false, true]
@assert all(p -> p.height == editor.height, editor_panes)
@assert sum(p.width for p in editor_panes) + 1 == editor.width
@assert abs(editor_panes[1].width - editor_panes[2].width) <= 1
document = freeze(server, result.session)
@assert length(validate(document).windows[1].panes) == 2
frozen_editor = only(validate(document).windows)
@assert frozen_editor.name == "editor" && frozen_editor.focus
@assert [p.focus for p in frozen_editor.panes] == [false, true]
@assert all(
p -> p.start_directory == realpath(dirname(server.socket_path)),
frozen_editor.panes,
)
@assert frozen_editor.layout ==
only(read_formats(server, editor.ref, FormatField("window_layout"))).value
println("Loaded 1 window and 2 panes; frozen names, layout, paths and focus")
document
end
@assert !ispath(dirname(endpoint[].socket_path))
frozen
end
main()

Install the command

The launcher binds to that environment and performs no package resolution at startup:

Terminal window
$ julia \
--startup-file=no \
--project=.workspace-env \
-e 'using LibTmuxWorkspace; println(LibTmuxWorkspace.install_cli("bin"))'

Inspect the shipped configuration without contacting tmux:

Terminal window
$ bin/libtmux-workspace plan packages/LibTmuxWorkspace/examples/workspace.yaml \
--env PROJECT=example \
--output json

validate FILE checks syntax and schema. plan FILE expands only explicitly supplied environment/home values and produces inert ordered steps. load FILE and freeze SESSION require exactly one explicit --socket or --socket-name. Loading is detached by default; an existing session name fails unless reuse is explicit. Interactive --attach requires a terminal and remains outside automated attachment evidence.

Human progress goes to stderr. --output json writes one final result; --output ndjson writes ordered progress and one terminal record. Nonzero exit codes distinguish usage, backend failure, partial effects, cancellation and deadline. A requested rollback removes only provably created resources. Shell input, scripts and changes to borrowed resources cannot be rolled back.

The default POSIX shell readiness handshake uses directory notifications and an exact owned marker. It does not poll cursor position or infer that later commands finished. Custom interactive launchers require the explicit readiness opt-out and caller-provided coordination.

Freeze preserves names, layouts, pane directories and focus. It cannot reconstruct commands, history, environment or options. Reloading shared windows creates independent windows. Snapshot acquisition is not atomic.

Library reference

Browse the LibTmuxWorkspace API reference.

Esc

Type to search.

Reference preview Open reference