Projects Archive

TMA, the tmux Automator

I’ve recently shifted my development workflow toward Neovim and tmux. This is a gradual process–I generally work at it for longer and longer each day–but I’m slowly noticing productivity gains that simply weren’t available with my previous tools. One pain point that I haven’t found a good solution for is automating tmux sessions, spinning up my editor and shells in repeatable ways.

I’ve looked at various projects, but none of them quite fit the things I want and don’t from a tmux automator:

  • I don’t want to pull in a separate interpreted language. Ideally, I want a single binary I can scp anywhere I might need it.
  • I don’t want something that does more than automate tmux sessions. Don’t spin up an editor, don’t manage a directory of project files. Just spin up and shut down tmux sessions.
  • I don’t want project files managed in a separate place. Ideally I should have a single configuration file that, say, specifies my ideal development environment for a Rust/Elixir/Node project, then simply copy that file into a new project directory.
  • I don’t want a full programming language or templating system in my configuration files. If I don’t have a configuration file for a specific project type at hand, I should be able to bash one out from memory.
  • I want to specify as little as possible. An automation solution can probably infer the root directory for a project based on from where it is launched. Likewise, most of my projects are in uniquely-named directories, so infer the session name as well.

So over the course of a few days, I whipped up this little tmux automator. Written in Rust, it’s a single binary that runs anywhere (as long as the architectures match, of course.) Configuration files are based on TOML, and are incredibly easy to create from memory once you get the hang of it. As an example, here is the configuration I use when developing tma itself:

[[window]]
name = "code"

[[window.pane]]
command = "vim"

[[window.pane]]
command = "cargo watch"

This gives me a code window with two vertically-stacked panes, one running my editor while the other recompiles the project on code change. I almost don’t need the latter pane with Neovim’s Language Server integration, but I’ll keep it for now.

Most of my projects have been somewhat large in scope. This one, I’m glad to say, seems to be just about done. I need a few extra command line flags for better tmux integration, the ability to set session names from the command line, and configuration variables for running commands before new windows/panes are open. Once those are in, I can probably focus exclusively on maintenance and move on to other things. Declaring something finished is a nice feeling. Sure, it may not work with every tmux version out there, but it works well enough for me, and I hope others find it useful as well.