DEV Community

Cover image for How to automate the launch of your terminal processes (fzf + tmux + teamocil)
Volodymyr Potiichuk
Volodymyr Potiichuk

Posted on

How to automate the launch of your terminal processes (fzf + tmux + teamocil)

Do you know this feeling, when you get so tired after the workday, that you want nothing more than to go to sleep as soon as possible? Or you know how it feels when you do boring things from day to day and they affect you negatively because they don’t do you any good?

If yes, don’t feel lonely, I had the same problem with terminal work until recently, and I ran into it at my job.

Long story short

I’ve been working as a front-end developer for a consulting company for the past couple of years, and just like on any other regular job, I’ve spent 90% of my time working on 1–2 projects.

But, as time went on I got assigned several projects to do (don’t think that my company is the devil and try to get the maximum from my developer soul), but there was a situation where I didn’t have enough workload on any of the projects I worked on.

Problem description

The main point is that each project it’s a set of different processes (e.g. backend, frontend, database, etc) that should be started to get your project up and running. And if you have one project, running a couple of processes is not a problem, because it is done one or at most a couple of times a day.

Now, let’s imagine the situation when I have 3 projects. The required processes are listed in the image below:

As you can see, there are a bunch of processes in each project, and the ports they occupy on my machine overlap a lot (which means I couldn’t run them in parallel even if I wanted to). So every time to switch between projects and run them, I had to close the old one and retype a set of long process commands like this:

cd backend && pipenv --python 3.14.0 && pipenv run gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:4000
# ...
cd frontend && npm run dev
# ...
docker-compose up db redis
# ... and so on
Enter fullscreen mode Exit fullscreen mode

to just get my next project up and running. Of course, I was exhausted doing this by typing and searching for the commands every day for each of those projects several times per day…

Small picture: how I feel in such moments

As you understand, this tedious, useless, and often repeated process will not affect us favorably but will bring unpleasant moments in our work. The time I spent on this switching between projects could be spent sleeping, eating, or resting my eyes, which I think is much cooler. And worth saying that I am a person who believes that everything we do should bring more pleasure, and the work I spend most of my time on is certainly no exception.

At some point in time, I had an idea of how to fix this, as I realized that the list of commands is almost always the same, it runs from the same folders, and it can quietly be automated.

Solution

To solve this problem we need several tools that are good on their own, but if we combine them, we can optimize our workflows by more than 99%. Let’s talk about each of them in more detail and write some code!

Tools that we are going to use

Step 1 — Start using tmux application to make your terminal life easier

What is tmux?

In simple words, tmux is an application that can manipulate any number of terminals (processes) in a single window and provides an API for working with them. Take a look at the picture below:

The view when you are in tmux

Here you can see that I have a “test” session, with 3 windows opened and in any of them I can open any amount of processes. It makes switching between projects and processes a lot faster than replicating terminal instances just to achieve the same behavior.

Step 2 — Tool for managing tmux sessions easily

The next step will be a tool that can help us achieve fast bootstrapping of the projects (sessions), it can be either teamocil or tmuxinator, these are the most popular ones and in this tutorial, I will use teamocil. Those tools allow you to write a configuration for a specific session and run this session with many processes and windows in one click.

Example of teamocil session configuration

In the screenshot above you can see the structure of the simple configuration file, it has a *.yaml format, and some hierarchy that simply replicates the architecture of tmux.

Such config leads to the ability to use one command for bootstrapping the tmux session:

teamocil <config_name>
Enter fullscreen mode Exit fullscreen mode

and voilà, we will get up and running session with one command:

Example of bootstrapping whole session in just one click

As you can see, we have already eliminated one of the problems, we don’t need to type and remember all commands, open new terminal windows, and switch folders every time, those magic tools will do it for us.

Step 3 — Fuzzy finder

FZF (Fuzzy finder) is a command-line application that allows you to turn any list into an interactive menu with support for awesome fuzzy search, which you can read more about here.

Example of FZF work

I think that you should get familiar with this application as soon as possible because it can come in handy everywhere where you need to search for something in a list, think about GitHub branches for example.

Step 4 — Automate with a shell scripting

At this point, we already know how to open sessions in one click and do a smart (fuzzy) search, now we need to put it all together with shell (sh) scripting.

I am sure you are already familiar with this and used some commands such as “change directory” or “copy” and so on. Thanks to shell scripting it is possible to automate many processes, for example, sending messages to Slack, or pulling the database from the environment, and in our case, we can make a script that will allow us to control our sessions via simple GUI and shortcuts without typing any commands.

In my case, I use the bash shell (Bourne-Again SHell) as it is a slightly improved version of sh. But you can also use the “sh” by itself or tools that allow you to translate your code from any desired language into the shell, for example, “zx” from Google, which allows you to write your scripts in node.js and run them as shell scripts.

Coding part

To meet our expectations with the optimization we need to create an application that can do three things:

  1. Start selected session

  2. Delete selected session

  3. Navigate between running sessions

Let’s start with the first point which we can achieve with teamocil and fuzzy finder, FZF will be as a GUI and teamocil as a tool that we will call when a certain session is selected (to bootstrap our session). A simple version of the script will look like this:

# start selected session
teamocil $(ls $HOME/.teamocil/ | awk -F. '{print $1}' | fzf)
Enter fullscreen mode Exit fullscreen mode

Don’t be afraid if you don’t understand it right now, let’s see what we did there:

  1. Here we take the folder with our session configs and get a list of files from there
# Imagine we have such file structure in our $HOME/.teamocil folder:
# - first_project.yml
# - second_project.yml
# - third_project.yml
# - ...*.yml

ls $HOME/.teamocil/
Enter fullscreen mode Exit fullscreen mode
  1. We process these files via the “awk” tool to get only the session name (without a file extension) and pass them to FZF.
awk -F. '{print $1}' | fzf

# In runtime it will look like this
# first_project.yml     first_project
# second_project.yml -> second_project | fzf
# third_project.yml.    third_project
Enter fullscreen mode Exit fullscreen mode
  1. The result we get from the FZF is forwarded to teamocil, which bootstraps the actual session.

Already with this small command, we can start our sessions in an instant like that:

Starting sessions

Alright, we finished with the creation of the sessions, and now we can proceed with switching between sessions and deleting them:

# change active session
tmux switch -t $(tmux list-sessions | awk -F: '{print $1}' | fzf)

# delete session
tmux kill-session -t $(tmux list-sessions | awk -F: '{print $1}' | fzf)
Enter fullscreen mode Exit fullscreen mode

You see, it’s almost the same as the previous one, however, we are checking the list of the active sessions with the tmux command and passing it to the “switch” or “kill-session” native command of the tmux depending on the desired behavior. That’s it, demonstration of our script is there:

Demo

At this point, we have one last thing to do: unify our scripts into one whole like a multi-tool, where we can create, delete, and switch between sessions. A cool way to do this is to use the tmux “display-popup” command, which allows you to display a window on top of all the processes in tmux, and that’s where I’d like to put the script implementation.

In my tmux.conf:

bind f display-popup -w 75% -h 50% -E "~/.config/fzf_tmux_sessions/bin/fzf_tmux_sessions.sh"
Enter fullscreen mode Exit fullscreen mode

This command will open a tmux popup with a width of 75% and height of 50%, invoke the code from the specified file.

That’s it, with small improvements to our code above we will get something like this:

Image description

It turns out that in this case, you can switch between different projects in less than 5 seconds instead of 5-10 minutes. Isn’t that cool, imagine how much time you save if you switch between projects 5 times a day or just bootstrapping large projects every day? If you want to see more, you can find the full code of this script in my GitHub repo.

In conclusion, I can say that this project has taught me quite a lot of skills, and I think that if you want to optimize something in your life, do not hesitate, it is very exciting and educational.

Thank you so much for reading this article, I hope it was helpful to you, see you next time!

Top comments (0)