| Crates.io | rmuxinator |
| lib.rs | rmuxinator |
| version | 4.1.0 |
| created_at | 2020-12-10 20:45:59.108548+00 |
| updated_at | 2025-07-22 14:04:40.646143+00 |
| description | tmux project configuration utility |
| homepage | |
| repository | https://github.com/ethagnawl/rmuxinator |
| max_upload_size | |
| id | 321584 |
| size | 142,935 |
This project aims to be a successor to tmuxinator, which allows users to define tmux project profiles (e.g. open two windows, split each into three panes and run a series of commands in each). It is written in Rust and will be more dependable (config is typechecked where possible) and simpler to install. It's also a great excuse for me to learn more about Rust, its ecosystem and compiling/distributing binaries for various platforms.
cargo install rmuxinatorrmuxinator start samples/Example.tomlcargo buildcargo build && ./target/debug/rmuxinator start samples/Example.toml./target/debug/rmuxinator start samples/Example.tomlcargo runcargo run start samples/Example.tomlProjects are defined using toml.
For example:
attached = true
layout = "main-horizontal"
name = "example"
pane_name_user_option = "custom_pane_title"
start_directory = "/home/peter/projects/vim"
tmux_options = "-f /tmp/tmux.work.conf -L work-socket"
[[hooks]]
command = "run-shell \"tmux display-message 'Hi from pane-focus-in hook!'\""
name = "pane-focus-in"
[[windows]]
layout = "tiled"
name = "one"
start_directory = "/home/peter/projects/sample-project"
[[windows.panes]]
commands = ["echo pane-one"]
name = "Work"
[[windows.panes]]
commands = ["echo pane-two"]
name = "Music"
start_directory = "/home/peter/projects/rmuxinator/src"
[[windows.panes]]
commands = ["echo pane-three"]
name = "RSS"
[[windows.panes]]
commands = ["echo hi one", "echo intermediate one", "echo bye one"]
[[windows]]
layout = "df47,213x57,0,0[213x23,0,0,4,213x1,0,24,5,213x31,0,26{31x31,0,26,6,181x31,32,26,7}]"
name = "two"
start_directory = "/home/peter/projects/sample-project"
[[windows.panes]]
commands = ["echo pane-one"]
[[windows.panes]]
commands = ["echo pane-two"]
start_directory = "/home/peter/projects/rmuxinator/src"
[[windows.panes]]
commands = ["echo pane-three"]
[[windows.panes]]
commands = ["echo hi one", "echo intermediate one", "echo bye one"]
Optional attributes will be noted below.
name (string)windows (array; see dedicated entry)attached (bool; defaults to true; whether or not to attach to newly created tmux session)hooks (array; see dedicated entry)layout (string; preset layouts: "even-horizontal", "even-vertical", "main-horizontal", "main-vertical", "tiled" or custom layout of the form displayed by tmux list-windows -- see samples/CustomLayout.toml)pane_name_user_option (string; must have matching entry in .tmux.conf (e.g. set -g pane-border-format "#{@custom_pane_title}")start_directory (string)terminal_multiplexer (string; defaults to tmux; executable on $PATH which is sufficiently tmux-like (e.g. tmux, tmux-rs or shell script which wraps tmux))tmux_options (string; CLI flags to pass through to tmux)command (string; must use tmux's run_shell; see tmux docs)name (string; must match existing tmux hook (e.g. after-select-pane); see tmux docs)panes (array; see dedicated entry)layout (string; preset layouts: "even-horizontal", "even-vertical", "main-horizontal", "main-vertical", "tiled" or custom layout of the form displayed by tmux list-windows -- see samples/CustomLayout.toml)name (string)start_directory (string)commands (array of strings)name (string)start_directory (string)debugPrint the tmux commands that would be used to start and configure a tmux
session using a path to a project config file:
rmuxinator debug samples/Example.toml
startStart a tmux session using a path to a project config file:
rmuxinator start samples/Example.toml
rmuxinator can also be used as a library by other programs.
There are two ways to achieve this:
This option accepts a path to an rmuxinator config file and is how the rmuxinator binary works. This is how this project's binary entrypoint works.
Example:
let config = rmuxinator::Config::new_from_config_path(&String::from("/home/pi/foo.toml")).map_err(|error| format!("Problem parsing config file: {}", error))?;
rmuxinator::run_start(config).map_err(|error| format!("Rmuxinator error: {}", error));
This option allows the caller to create an rmuxinator Config struct and then pass it to the run_start function.
The pi-wall-utils project (also maintained by ethagnawl) does this and can be used as a reference.
Example:
let rmuxinator_config = rmuxinator::Config {
attached: true,
hooks: vec![],
layout: None,
name: String::from("rmuxinator-library-example"),
windows: vec![
rmuxinator::Window {
layout: None,
name: None,
panes: vec![rmuxinator::Pane {
commands: vec![
String::from("echo 'hello!'"),
],
name: None,
start_directory: None,
}],
start_directory: None,
}
];
};
rmuxinator::run_start(rmuxinator_config).map_err(|error| format!("Rmuxinator error: {}", error))
If you provide a custom tmux config file via tmux_options, you may need to
restart your tmux server (tmux kill-server) before some/all of its changes
will take effect. For example, changes to base-index and pane-base-index
are known to require a restart in order to be detected and used as expected.
It might be possible to work around this issue but it needs more thought. The heavy handed option would be to have this library explicitly kill and restart the tmux server but that could have unintended consequences if other tmux sessions are in use.
In some situations, splitting panes can result in errors because tmux determines that there is not enough usable space in the session. To mitigate this, rmuxinator is adopting the common workaround which repeatedly sets the layout to tiled after splitting panes and then sets the computed layout only once at the end of the block of window configuration code. This will usually be transparent but if the user has not specified any layouts, they will see their panes laid out using the tiled layout. This strikes the maintainer as a perfectly reasonable "default" but I thought it was worth calling out.
tmuxinator uses a similar strategy and the tmux maintainers also suggest this approach.
This project is currently a proof of concept and I'll be duplicating tmuxinator features and adding additional improvements as I can find time. Right now, it's capable of:
tmux kill-window was failing silentlyHere are the platforms rmuxinator is known to work on: