How to script a Tmux session

This week, Alyve published a nice blog posts about Tmuxinator (french). Halfway in this posts you can read :

Alors on va me dire “Oui mais tu peux configurer un script sh pour quand tu lances tmux toussa toussa”. Oui, j’ai pas ton temps, frère. Je suis là pour être productive et botter des culs avec mes nouvelles Doc Martens.

Which I took as a challenge : Yes, we can easily automate things in Tmux natively !

We will try to reproduce the same behavior as this blogpost :

  • 1 tmux session
  • the first workspace with a text editor
  • A second workspace split in two
  • The first part will run hugo
  • The second will launch one git command and wait

Scripting it one step at a time 🔗

All we need to do is writing every tmux command needed to do this in a script and it should work.

So let's write /usr/local/bin/blog, and don't forget to make it executable with chmod +x /usr/local/bin/blog. Let's go !

#! /bin/sh
session="blog"
window="$session:0"

Every script starts with a … shebang and some variables to ease our life. All you need to know is that Tmux creates sessions where will resides windows which can contain multiples panes. Panes ar virtual terminal with a shell.

If you want to do something to a specific pane you'll need to give its name which looks like this : session:window.pane . And remember, we counts from 0.

Then the first (and hardest part of the script) is to make sure that if the tmux session already exists to not build it but attach to it.

if [ $(tmux attach -t "$session" )]; then
  exit 0
fi

If our session exists we go inside it and we stop the script (if we don't, it will recreate it each time…).

cd /home/lord/www
tmux new-session -d -s "$session"

We first go in the right folder and create a brand new tmux session with the right name. Make sure to create it but don't attach to it (-d) and to give it a name (-s blog)

tmux split-window -t "$window"
tmux split-window -t "$window"
tmux select-layout -t "$window" main-vertical

We then split the workspace in three panes and apply the main-vertical layout which is one big terminal on the left and a stack of secondary terminals on the right.

tmux send-keys -t "$window.0" "kak" C-m

Now, we start [Kakoune (my favourite text editor)(https://kakoune.org) in the left pane (0). C-m means Ctrl-m (it also works in a regular shell) but you could also use Enter.

tmux send-keys -t "$window.1" "hugo server --navigateToChanged --disableFastRender" C-m

We then launch hugo server in the top right pane.

tmux send-keys -t blog "git status" C-m

And finally we launch git status in the bottom right pane, ready to work.

tmux attach -t "$session"

This is the end of the script. You attach to your newly built session.

We built our T800.

Here is the complete script
#! /bin/sh
session="blog"
window="$session:0"

if [ $(tmux attach -t "$session") ]; then
  exit 0
fi

cd /home/lord/www
tmux new-session -d -s "$session"

tmux split-window -t "$window"
tmux split-window -t "$window"
tmux select-layout -t "$window" main-vertical

tmux send-keys -t "$window.0" "kak" C-m
tmux send-keys -t "$window.1" "hugo server --navigateToChanged --disableFastRender" C-m
tmux send-keys -t "$window.2" "git status" C-m

tmux attach -t "$session"

It probably takes a bit more time to setup than Tmuxinator but you won't need to install anything. Thanks for the little challeng and go see Alyve's blog (fr).