TMUX Semi-automation
I have been using TMUX for a while now, and it has made my time in the terminal more effective and fluid.
Since I spend most of my time developing a React Native app at work, my TMUX configuration always looks the same, and I use the panels for the same purposes. My sessions look like this:
------------------------------| 1 | |--------------| 3 || 2 | |------------------------------
Panel 1 remains static running the app's metro-bundler.
Panel 2 is used to run npx react-native run-{platform} and for git commands.
Panel 3 has the emulator running.
I would start tmux and manually build the panels and start the same tasks in each panel, it became repetitive to do it daily.
Investigating a bit I found out that I can achieve the panel layout and the tasks of each one with a simple command at the moment of starting the TMUX session. So those are my two goals, to achieve the layout structure and to start the tasks in each panel.
Panels in process...
To achieve the layout manually I always follow the next steps:
$ tmux # Start TMUX sessionC-b % # Split the screen in 2 verticallyC-b q 1 # Go back to the first halfC-b " # Split the first panel in 2 horizontally
To achieve the layout from the moment the TMUX session starts the syntax is different since at that moment you don't have access to the keyboard shortcuts like C-b and M-x, but we have tmux commands, we initially need two (split-window and select-pane). As an initial test we will have:
$ tmux new-session \; \split-window -h# Result------------------------------| | || 1 | 2 || | |------------------------------
The -h argument indicates that the window will be split into two panels horizontally, the next step is to split Panel 1 into two panels vertically, so complementing the command is:
$ tmux new-session \; \split-window -h \; \split-window -v \;# Result------------------------------| | 2 || 1 |---------------|| | 3 |------------------------------
The result is not exactly the same as what I look for, but taking into account how TMUX works, once you split the screen, TMUX automatically chooses the active panel:
- when you split the screen horizontally, the right panel is active.
- when you split the screen vertically, the bottom panel is active.
In this case, since that the screen initially has two panels (1 and 2) separated horizontally, the next split-window command will split the active panel 2. The solution to this is to select the panel 1 before splitting it using the command select-pane:
$ tmux new-session \; \split-window -h \; \select-pane -t 0 \; \split-window -v \;# Result------------------------------| 1 | |--------------| 3 || 2 | |------------------------------
🎉🎉🎉 Done!, the layout is as I want it...
Starting tasks in each panel
Now that the layout is ready, the next step is to start the tasks in each panel.
- Panel 1: Start the metro-bundler
- Panel 2: Run
npx react-native run-{platform} - Panel 3: Start the emulator
To achieve this, we can use the send-keys followed by C-m which is a parameter that executes the command. Each time we create a panel, we will start its task.
$ tmux new-session \; \send-keys 'yarn && yarn start' C-m \; \split-window -h \; \send-keys 'androidemu @Pixel3a' C-m \; \select-pane -t 1 \; \split-window -v \; \send-keys 'npx react-native run-android' C-m \;
🎉🎉🎉 Done! adding the send-keys at the moment when each panel is created initiates the task for each onemptied. Now every time I want to start TMUX to work on my React Native project, I can simply run the command and have the layout and tasks set up automatically.
Improvements
There are some improvements that I can make to this command, first is that I have to change the directory to the root of the project before copying and pasting the TMUX command, that can be improved!. The new-session command has the -c flag that allows you to specify the directory in which the TMUX session starts, applying this we have:
$ tmux new-session -c /path/to/react-native-project \; \send-keys 'yarn && yarn start' C-m \; \split-window -h \; \send-keys 'androidemu @Pixel3a' C-m \; \select-pane -t 1 \; \split-window -v \; \send-keys 'npx react-native run-android' C-m \;
Using the -c flag saves the step of having to be in the root of the project before copying and pasting the TMUX command. From any directory in which the terminal is, the TMUX session will start in the desired project.
The last improvement is to give a name to the session, the -n flag of new-session does just that:
$ tmux new-session -n tmux-rules -c /path/to/react-native-project \; \send-keys 'yarn && yarn start' C-m \; \split-window -h \; \send-keys 'androidemu @Pixel3a' C-m \; \select-pane -t 1 \; \split-window -v \; \send-keys 'npx react-native run-android' C-m \;
MISSION ACCOMPLISHED
This gist has the final command with the improvements mentioned above. Now I can start my TMUX session with a single command and have everything set up for me to start working on my React Native project.