tmux workspace manager, forged in Python.
Session manager for tmux. Load, freeze, and convert tmux sessions through YAML/JSON configuration files. Powered by libtmux for Python.
Explore tmux layout / workspace possibilities
session_name: sample workspacestart_directory: '~'windows:- window_name: focused window layout: main-horizontal focus: true panes: - shell_command: - cd ~ - shell_command: - cd /usr focus: true - shell_command: - cd ~ - echo "moo" - top- window_name: window 2 panes: - shell_command: - top focus: true - shell_command: - echo "hey" - shell_command: - echo "moo"- window_name: window 3 panes: - shell_command: cd / focus: true - pane - pane{ "session_name": "sample workspace", "start_directory": "~", "windows": [ { "window_name": "focused window", "layout": "main-horizontal", "focus": true, "panes": [ { "shell_command": [ "cd ~" ] }, { "shell_command": [ "cd /usr" ], "focus": true }, { "shell_command": [ "cd ~", "echo \"moo\"", "top" ] } ] }, { "window_name": "window 2", "panes": [ { "shell_command": [ "top" ], "focus": true }, { "shell_command": [ "echo \"hey\"" ] }, { "shell_command": [ "echo \"moo\"" ] } ] }, { "window_name": "window 3", "panes": [ { "shell_command": "cd /", "focus": true }, "pane", "pane" ] } ]}session_name: sample workspacestart_directory: '~'windows:- layout: main-vertical panes: - shell_command: - cmd: vim - shell_command: - cmd: echo "hey" window_name: editor- panes: - shell_command: - cmd: tail | echo 'hi' window_name: logging- window_name: test panes: - shell_command: - cmd: htop{ "session_name": "sample workspace", "start_directory": "~", "windows": [ { "layout": "main-vertical", "panes": [ { "shell_command": [ { "cmd": "vim" } ] }, { "shell_command": [ { "cmd": "echo \"hey\"" } ] } ], "window_name": "editor" }, { "panes": [ { "shell_command": [ { "cmd": "tail | echo 'hi'" } ] } ], "window_name": "logging" }, { "window_name": "test", "panes": [ { "shell_command": [ { "cmd": "htop" } ] } ] } ]}session_name: sample workspacestart_directory: '~'windows:- window_name: test layout: main-horizontal panes: - shell_command: - cmd: vim - shell_command: - cmd: echo "hey" - shell_command: - cmd: echo "moo"{ "session_name": "sample workspace", "start_directory": "~", "windows": [ { "window_name": "test", "layout": "main-horizontal", "panes": [ { "shell_command": [ { "cmd": "vim" } ] }, { "shell_command": [ { "cmd": "echo \"hey\"" } ] }, { "shell_command": [ { "cmd": "echo \"moo\"" } ] } ] } ]}shell_command_before: - 'echo "hi"'session_name: 'test'windows:- window_name: editor panes: - shell_command: - vim - :Ex - pane - cd /usr- window_name: logging panes: - shell_command: - - shell_command: - top - emacs{ "shell_command_before": [ "echo \"hi\"" ], "session_name": "test", "windows": [ { "window_name": "editor", "panes": [ { "shell_command": [ "vim", ":Ex" ] }, "pane", "cd /usr" ] }, { "window_name": "logging", "panes": [ { "shell_command": [ null ] }, { "shell_command": [ "top", "emacs" ] } ] } ]}session_name: test env varsstart_directory: "~"environment: FOO: SESSION PATH: /tmpwindows:- window_name: no_overrides panes: - pane- window_name: window_overrides environment: FOO: WINDOW panes: - pane- window_name: pane_overrides panes: - environment: FOO: PANE- window_name: both_overrides environment: FOO: WINDOW panes: - pane - environment: FOO: PANE# This test case it just needed for warnings issued in old versions of tmux.- window_name: both_overrides_on_first_pane environment: FOO: WINDOW panes: - environment: FOO: PANE{ "session_name": "test env vars", "start_directory": "~", "environment": { "FOO": "SESSION", "PATH": "/tmp" }, "windows": [ { "window_name": "no_overrides", "panes": [ "pane" ] }, { "window_name": "window_overrides", "environment": { "FOO": "WINDOW" }, "panes": [ "pane" ] }, { "window_name": "pane_overrides", "panes": [ { "environment": { "FOO": "PANE" } } ] }, { "window_name": "both_overrides", "environment": { "FOO": "WINDOW" }, "panes": [ "pane", { "environment": { "FOO": "PANE" } } ] }, { "window_name": "both_overrides_on_first_pane", "environment": { "FOO": "WINDOW" }, "panes": [ { "environment": { "FOO": "PANE" } } ] } ]}session_name: sample workspacewindows: - panes: - start_directory: /usr - start_directory: /etc{ "session_name": "sample workspace", "windows": [ { "panes": [ { "start_directory": "/usr" }, { "start_directory": "/etc" } ] } ]}session_name: Blank pane testwindows: # Emptiness will simply open a blank pane, if no shell_command_before. # All these are equivalent - window_name: Blank pane test panes: - - pane - blank - window_name: More blank panes panes: - null - shell_command: - shell_command: - # an empty string will be treated as a carriage return - window_name: Empty string (return) panes: - "" - shell_command: "" - shell_command: - "" # a pane can have other options but still be blank - window_name: Blank with options panes: - focus: true - start_directory: /tmp{ "session_name": "Blank pane test", "windows": [ { "window_name": "Blank pane test", "panes": [ null, "pane", "blank" ] }, { "window_name": "More blank panes", "panes": [ null, { "shell_command": null }, { "shell_command": [ null ] } ] }, { "window_name": "Empty string (return)", "panes": [ "", { "shell_command": "" }, { "shell_command": [ "" ] } ] }, { "window_name": "Blank with options", "panes": [ { "focus": true }, { "start_directory": "/tmp" } ] } ]}Install
Install the workspace package separately from the core library.
$ uv tool install tmuxpInstalls tmuxp in an isolated Python environment. Run tmuxp load ./workspace.yaml.
$ uvx tmuxp --helpRuns without a permanent installation. Replace --help with load ./workspace.yaml to load a workspace.
$ pipx install tmuxpInstalls the tmuxp command in an isolated Python environment.
CLI Manual
Commands, options and machine output.
Configuration
Workspace fields, normalization and execution.
Install and load
Load a workspace on a private socket, then capture it.
Example gallery
Workspace files to start from, with their prerequisites.
Runtime support
Runtime requirements and supported behavior.
Internals
The workspace library, for building sessions from code.
tmuxp loads tmux sessions from YAML or JSON using
libtmux. A file describes windows, panes and commands. tmuxp load builds the
session and can attach to it or leave it detached.
Start here¶
The CLI manual covers discovery, search, editing, conversion and import. Use examples for complete files and their prerequisites.
Install tmuxp separately from the core libtmux package. Its dependency resolver selects a compatible libtmux release. Workspace internals describe the builder and Python extension APIs.
Example workspaces
Each workspace below is a file that tmux-python/tmuxp
loads in a test or a scheduled run, as the list under it says. The drawing shows the panes of each window and the commands each pane receives.
Short-hand panes
A pane can be one command written as a string, and a command list can be one string.
session_name: sample workspacestart_directory: '~'windows:- window_name: focused window layout: main-horizontal focus: true panes: - shell_command: - cd ~ - shell_command: - cd /usr focus: true - shell_command: - cd ~ - echo "moo" - top- window_name: window 2 panes: - shell_command: - top focus: true - shell_command: - echo "hey" - shell_command: - echo "moo"- window_name: window 3 panes: - shell_command: cd / focus: true - pane - pane{ "session_name": "sample workspace", "start_directory": "~", "windows": [ { "window_name": "focused window", "layout": "main-horizontal", "focus": true, "panes": [ { "shell_command": [ "cd ~" ] }, { "shell_command": [ "cd /usr" ], "focus": true }, { "shell_command": [ "cd ~", "echo \"moo\"", "top" ] } ] }, { "window_name": "window 2", "panes": [ { "shell_command": [ "top" ], "focus": true }, { "shell_command": [ "echo \"hey\"" ] }, { "shell_command": [ "echo \"moo\"" ] } ] }, { "window_name": "window 3", "panes": [ { "shell_command": "cd /", "focus": true }, "pane", "pane" ] } ]}Converted from the YAML; the tests load the YAML.
Source: tests/fixtures/workspace/expand2-unexpanded.yaml
Loaded by:
-
test_workspace_expand2: Expands the file and compares it with the expanded fixture. Starts no tmux. (tests/workspace/test_config.py; loaded by the library in a test; the command is not run)
Two panes
A window of two panes.
session_name: sample workspacestart_directory: '~'windows:- layout: main-vertical panes: - shell_command: - cmd: vim - shell_command: - cmd: echo "hey" window_name: editor- panes: - shell_command: - cmd: tail | echo 'hi' window_name: logging- window_name: test panes: - shell_command: - cmd: htop{ "session_name": "sample workspace", "start_directory": "~", "windows": [ { "layout": "main-vertical", "panes": [ { "shell_command": [ { "cmd": "vim" } ] }, { "shell_command": [ { "cmd": "echo \"hey\"" } ] } ], "window_name": "editor" }, { "panes": [ { "shell_command": [ { "cmd": "tail | echo 'hi'" } ] } ], "window_name": "logging" }, { "window_name": "test", "panes": [ { "shell_command": [ { "cmd": "htop" } ] } ] } ]}Converted from the YAML; the tests load the YAML.
Source: tests/fixtures/workspace/builder/two_pane.yaml
Loaded by:
-
test_split_windows: Creates each window and its panes in a tmux session and checks the window count. (tests/workspace/test_builder.py; built by the library in a test; the command is not run) -
test_load_workspace: Calls load_workspace, the function the tmuxp load command is built on, detached on a real tmux server and checks the session name. The command itself does not run. (tests/cli/test_load.py; loaded by the library in a test; the command is not run)
Main-horizontal layout
The main-horizontal layout gives the first pane the top of the window and splits the rest below it.
Also shows: three panes
session_name: sample workspacestart_directory: '~'windows:- window_name: test layout: main-horizontal panes: - shell_command: - cmd: vim - shell_command: - cmd: echo "hey" - shell_command: - cmd: echo "moo"{ "session_name": "sample workspace", "start_directory": "~", "windows": [ { "window_name": "test", "layout": "main-horizontal", "panes": [ { "shell_command": [ { "cmd": "vim" } ] }, { "shell_command": [ { "cmd": "echo \"hey\"" } ] }, { "shell_command": [ { "cmd": "echo \"moo\"" } ] } ] } ]}Converted from the YAML; the tests load the YAML.
Source: tests/fixtures/workspace/builder/three_pane.yaml
Loaded by:
-
test_layout_main_horizontal: Builds the session and checks the pane count, the height of the top pane and the pane widths. (tests/workspace/test_builder.py; built by the library in a test; the command is not run)
Setup before each pane
shell_command_before runs ahead of a pane's own commands, at the session, window or pane level.
shell_command_before: - 'echo "hi"'session_name: 'test'windows:- window_name: editor panes: - shell_command: - vim - :Ex - pane - cd /usr- window_name: logging panes: - shell_command: - - shell_command: - top - emacs{ "shell_command_before": [ "echo \"hi\"" ], "session_name": "test", "windows": [ { "window_name": "editor", "panes": [ { "shell_command": [ "vim", ":Ex" ] }, "pane", "cd /usr" ] }, { "window_name": "logging", "panes": [ { "shell_command": [ null ] }, { "shell_command": [ "top", "emacs" ] } ] } ]}Converted from the YAML; the tests load the YAML.
Source: tests/fixtures/workspace/shell_command_before_session.yaml
Loaded by:
-
test_in_session_scope: Validates and expands the file and compares it with the expected fixture. Starts no tmux. (tests/workspace/test_config.py; loaded by the library in a test; the command is not run)
Environment
environment sets variables for a session, a window or a pane.
session_name: test env varsstart_directory: "~"environment: FOO: SESSION PATH: /tmpwindows:- window_name: no_overrides panes: - pane- window_name: window_overrides environment: FOO: WINDOW panes: - pane- window_name: pane_overrides panes: - environment: FOO: PANE- window_name: both_overrides environment: FOO: WINDOW panes: - pane - environment: FOO: PANE# This test case it just needed for warnings issued in old versions of tmux.- window_name: both_overrides_on_first_pane environment: FOO: WINDOW panes: - environment: FOO: PANE{ "session_name": "test env vars", "start_directory": "~", "environment": { "FOO": "SESSION", "PATH": "/tmp" }, "windows": [ { "window_name": "no_overrides", "panes": [ "pane" ] }, { "window_name": "window_overrides", "environment": { "FOO": "WINDOW" }, "panes": [ "pane" ] }, { "window_name": "pane_overrides", "panes": [ { "environment": { "FOO": "PANE" } } ] }, { "window_name": "both_overrides", "environment": { "FOO": "WINDOW" }, "panes": [ "pane", { "environment": { "FOO": "PANE" } } ] }, { "window_name": "both_overrides_on_first_pane", "environment": { "FOO": "WINDOW" }, "panes": [ { "environment": { "FOO": "PANE" } } ] } ]}Converted from the YAML; the tests load the YAML.
Source: tests/fixtures/workspace/builder/environment_vars.yaml
Loaded by:
-
test_environment_variables: Builds the session and checks the session environment and the value each pane sees. (tests/workspace/test_builder.py; built by the library in a test; the command is not run)
Start directory
start_directory chooses where a session, a window or a pane starts.
Also shows: two panes
session_name: sample workspacewindows: - panes: - start_directory: /usr - start_directory: /etc{ "session_name": "sample workspace", "windows": [ { "panes": [ { "start_directory": "/usr" }, { "start_directory": "/etc" } ] } ]}Converted from the YAML; the tests load the YAML.
Source: tests/fixtures/workspace/builder/first_pane_start_directory.yaml
Loaded by:
-
test_first_pane_start_directory: Builds the session and checks each pane's working directory. (tests/workspace/test_builder.py; built by the library in a test; the command is not run)
Blank panes
An empty entry, null, pane or blank opens a pane with no command.
session_name: Blank pane testwindows: # Emptiness will simply open a blank pane, if no shell_command_before. # All these are equivalent - window_name: Blank pane test panes: - - pane - blank - window_name: More blank panes panes: - null - shell_command: - shell_command: - # an empty string will be treated as a carriage return - window_name: Empty string (return) panes: - "" - shell_command: "" - shell_command: - "" # a pane can have other options but still be blank - window_name: Blank with options panes: - focus: true - start_directory: /tmp{ "session_name": "Blank pane test", "windows": [ { "window_name": "Blank pane test", "panes": [ null, "pane", "blank" ] }, { "window_name": "More blank panes", "panes": [ null, { "shell_command": null }, { "shell_command": [ null ] } ] }, { "window_name": "Empty string (return)", "panes": [ "", { "shell_command": "" }, { "shell_command": [ "" ] } ] }, { "window_name": "Blank with options", "panes": [ { "focus": true }, { "start_directory": "/tmp" } ] } ]}Converted from the YAML; the tests load the YAML.
Same file as tmuxp's examples/blank-panes.yaml.
Source: examples/blank-panes.yaml
Loaded by:
-
test_blank_pane_spawn: Builds the session and checks the pane count of each window. (tests/workspace/test_builder.py; built by the library in a test; the command is not run) -
test_expands_blank_panes: Expands the file and checks that each blank pane has no command. Starts no tmux. (tests/workspace/test_config.py; loaded by the library in a test; the command is not run)