DEV Community

Cover image for Dynamic templates with Tmuxinator
Quentin Ménoret
Quentin Ménoret

Posted on

Dynamic templates with Tmuxinator

Meet Tmuxinator

A while ago, I was using vim + tmux just like I would an IDE. For instance, I would split the first window, with a huge left pane for my vim, and a smaller right pane for the tests.

Tmuxinator is great tool allowing you to define templates. It will take care of opening the needed windows and panes, and run the commands needed inside.


Let's say you have a template called mytmux. Then you can run tmuxinator mytmux, and the needed windows, panes and command will execute. If you run tmuxinator mytmux again, it will attach to the same tmux session.

But what if we want to use a single template on several projects?

I often use the same setups in my terminal based on the language I work with. A few years back, when learning Haskell, I was working on a lot of small exercises (for instance using exercism) which are all structured the same way. Every time I wanted to code on a project, I would use at least two commands, in two panes:

  • vim -p src/Lib.hs test/Spec.hs
  • stack test --file-watch

It is easy to setup a tmuxinator file to do this in a specific location: you need to specify the path of your project in the template. But here, we want it to be dynamic. My first attempt was to use . as the path of my template. I would just need to move to the project location, and then to run tmuxinator.

At first, it seems to be working well. But as stated earlier, if your template is called mytmux, then the session name will be mytmux. That means that you won't be able to use the template in two different projects at the same time. Calling tmuxinator mytmux would just connect you to the existing session.

So I did some research, and found out you can actually pass arguments from the command line, and use them in the tmuxinator template. You can also access environment variables and use ruby code directly inside the template. Using this, you will be able to create a dynamic template.

A dynamic template

You'll find below a (simplified) version of my stack template. It will use as root the path given on the command line, or if none is given, the current working directory from the environment variable PWD. It will also split this path to extract the project directory (the project name in my case), and use it as session name.

Thanks to this little trick, if I use twice tmuxinator on the same directory, I will just join the same session, but if directories differs, it will start a new session. The alternative to this would be to generate a random name for the session, which would allow to create different sessions even for the same project.

# Set var "WDIR" to workdir
<% if @args[0] %>
<% WDIR=@args[0] %> 
<% else %>
<% WDIR=ENV["PWD"] %>
<% end %>

name: <%= WDIR.split('/').last  %>
root: <%= @args[0] %>

  - editor:
      layout: f5f0,238x64,0,0{166x64,0,0,0,71x64,167,0,1} 
        - vim:
          - vim -p src/Lib.hs test/Spec.hs
        - tests:
          - stack test --file-watch
Enter fullscreen mode Exit fullscreen mode

Top comments (2)

vyaser profile image

Nicely done, this is exactly what I was looking for.

What language is the top part of the config file?

qmenoret profile image
Quentin Ménoret

Thanks! It's ruby