<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>sglavoie.com – Tag: Rofi</title><link>https://www.sglavoie.com/tags/rofi/</link><description>Posts and writings by Sébastien Lavoie. Customization setups and articles on productivity for developers who like minimalism.</description><language>en</language><atom:link href="https://www.sglavoie.com/tags/rofi/feed.xml" rel="self" type="application/rss+xml"/><lastBuildDate>Sun, 19 Sep 2021 18:13:00 -0500</lastBuildDate><item><title>Managing multiple tmux sessions at once</title><link>https://www.sglavoie.com/posts/managing-multiple-tmux-sessions-at-once/</link><description>Open and close projects with tmux sessions in a breeze via two keyboard shortcuts.</description><content:encoded>&lt;hr&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Released back in 2007, &lt;a href="https://github.com/tmux/tmux/wiki"&gt;tmux&lt;/a&gt; keeps being amazing! Because I have never bothered automating anything to make its use simpler, it took some time for it to become a working environment I enjoy for everyday use. This is a thing of the past: thanks to Oleksandr Kocherhin from &lt;a href="https://monsterlessons-academy.com/"&gt;Monsterlessons Academy&lt;/a&gt;, who shared his tmux workflow in his YouTube video titled &lt;a href="https://www.youtube.com/watch?v=GuH7pw9LejY"&gt;Best Terminal Application for Web Development&lt;/a&gt;, I saw a few automation opportunities I thought were worth tackling.&lt;/p&gt;
&lt;p&gt;In this post, I&amp;rsquo;m sharing a little tip about managing tmux sessions that was inspired from the mentioned video. I am using &lt;a href="https://i3wm.org/"&gt;i3wm&lt;/a&gt; on Linux, but you can adapt this with any desktop environment as long as you can trigger the execution of programs with a keyboard shortcut in one way or another. I will be using Rofi and the &lt;code&gt;find&lt;/code&gt; command, which you can find on Unix systems. If you would rather use dmenu instead of Rofi with this script, &lt;a href="https://www.sglavoie.com/posts/using-dmenu-to-optimize-common-tasks/"&gt;this article can serve as a reference&lt;/a&gt;. Enough said, let&amp;rsquo;s get to it.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="what-is-this-all-about"&gt;What is this all about?&lt;/h2&gt;
&lt;p&gt;The idea is simple: have a few keyboard shortcuts to manage tmux sessions. That means being able to open new sessions and being able to kill them too. I kept this setup very simple on purpose but of course some improvements could be made. For instance, it could be nice to know which projects have already been opened so that the script doesn&amp;rsquo;t prompt you with a list of projects that include projects that you have already launched, but I haven&amp;rsquo;t found the need so far to deal with this potential issue as I tend to only work on a couple of projects during the course of a given day.&lt;/p&gt;
&lt;p&gt;In summary, here is what we want to achieve in this post:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Configure projects so that when we want to open them, they will be set up in the right directory with servers running, etc.;&lt;/li&gt;
&lt;li&gt;Open a tmux session with a keyboard shortcut, listing all projects that were configured in the previous step;&lt;/li&gt;
&lt;li&gt;Kill any opened tmux session with another keyboard shortcut.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&amp;rsquo;s it!&lt;/p&gt;
&lt;h2 id="1-configuring-projects-to-launch-tmux-sessions"&gt;1. Configuring projects to launch tmux sessions&lt;/h2&gt;
&lt;p&gt;Firstly, we need to create new files to open our projects in the way we want. Basically, we need to create a file, let&amp;rsquo;s call it &lt;code&gt;.tmux&lt;/code&gt;, and put it at the root of the project we&amp;rsquo;re interested in working with tmux. Then, we need to put some instructions that will be run with the shell (e.g. Bash or Zsh) so that tmux commands will be run automatically for us and let us &amp;ldquo;attach&amp;rdquo; to the session once all the necessary actions are performed. That means we need to make that file executable. In the terminal, this would be done as follows, assuming the project&amp;rsquo;s folder is the current working directory:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod +x .tmux&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;At last, we want to give some orders to tmux so that when we execute that file, it will open our project in a pre-configured state so we&amp;rsquo;re ready to go. This will need to be customized depending on your needs, but here is a simple example to illustrate what could happen. So, we could put the following inside the &lt;code&gt;.tmux&lt;/code&gt; file:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/sh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; -e
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; tmux has-session -t&lt;span class="o"&gt;=&lt;/span&gt;my-project 2&amp;gt; /dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; tmux attach -t my-project
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tmux new-session -d -s my-project -n nvim -x &lt;span class="k"&gt;$(&lt;/span&gt;tput cols&lt;span class="k"&gt;)&lt;/span&gt; -y &lt;span class="k"&gt;$(&lt;/span&gt;tput lines&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Neovim&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tmux send-keys -t my-project:nvim &lt;span class="s2"&gt;&amp;#34;n&amp;#34;&lt;/span&gt; Enter
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Servers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tmux new-window -t my-project -n servers
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tmux send-keys -t my-project:servers &lt;span class="s2"&gt;&amp;#34;cd frontend &amp;amp;&amp;amp; yarn start&amp;#34;&lt;/span&gt; Enter
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tmux split-window -t &lt;span class="m"&gt;2&lt;/span&gt; -v -p &lt;span class="m"&gt;50&lt;/span&gt; &lt;span class="c1"&gt;# split it into two halves&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tmux send-keys -t my-project:servers &lt;span class="s2"&gt;&amp;#34;cd backend &amp;amp;&amp;amp; ap &amp;amp;&amp;amp; uvicorn main:app --reload&amp;#34;&lt;/span&gt; Enter
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tmux attach -t my-project:nvim&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Here is what is happening:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If our project, named &lt;code&gt;my-project&lt;/code&gt;, has a tmux session already running, then we &amp;ldquo;attach&amp;rdquo; to it and nothing more is done.&lt;/li&gt;
&lt;li&gt;Otherwise, the session is created in &amp;ldquo;detached&amp;rdquo; mode so we can run a few commands smoothly and later attach to the created session.&lt;/li&gt;
&lt;li&gt;With the &lt;code&gt;-n&lt;/code&gt; flag, we name the window to be created (here, the first window is &lt;code&gt;nvim&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Then, we &amp;ldquo;send&amp;rdquo; keys to the session, to that newly created &lt;code&gt;nvim&lt;/code&gt; window. In this case, we send a single keystroke &lt;code&gt;n&lt;/code&gt;, which is just an alias for executing Neovim.&lt;/li&gt;
&lt;li&gt;In a new window named &lt;code&gt;servers&lt;/code&gt;, we send keys to execute the frontend server.&lt;/li&gt;
&lt;li&gt;Then, we split the second window we just created vertically and we run the commands needed to launch the backend server, again making use of Bash aliases for convenience.&lt;/li&gt;
&lt;li&gt;Finally, we attach to the session and we open the first window &lt;code&gt;nvim&lt;/code&gt;, ready to work.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And just like this, what takes quite a few steps to do manually can be automated in one go when setting up the environment at the beginning of a working bout. Now, it could be convenient to create a generic template for the above script to use when creating new projects, especially if those tend to be short-lived and share some properties (e.g. maybe they all need to launch some kind of server in the background).&lt;/p&gt;
&lt;h2 id="2-script-to-open-projects"&gt;2. Script to open projects&lt;/h2&gt;
&lt;p&gt;Firstly, we need a way to list and open all &amp;ldquo;known&amp;rdquo; projects. This is achieved in this example very simply with the &lt;code&gt;find&lt;/code&gt; command as well as with the help of &lt;code&gt;rofi&lt;/code&gt;. The script in question is as follows:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Get the path to the `.tmux` file to execute using `find` and `rofi`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;PROJECT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;find &lt;span class="nv"&gt;$HOME&lt;/span&gt;/dev -type d &lt;span class="se"&gt;\(&lt;/span&gt; -name node_modules -o -name .venv &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -o -path name &lt;span class="se"&gt;\)&lt;/span&gt; -prune -false -o -name &lt;span class="s1"&gt;&amp;#39;.tmux&amp;#39;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;|&lt;/span&gt; rofi -i -dmenu -theme purple -font &lt;span class="s1"&gt;&amp;#39;JetBrainsMono 14&amp;#39;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -width &lt;span class="m"&gt;90&lt;/span&gt; -show window&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Get the full directory path to the `.tmux` file, excluding the filename&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;PROJECT_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$PROJECT&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; xargs -I &lt;span class="o"&gt;{}&lt;/span&gt; dirname &lt;span class="s2"&gt;&amp;#34;{}&amp;#34;&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# If $PROJECT is empty (e.g. pressing Esc at the prompt), don&amp;#39;t do anything&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; ! -z &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$PROJECT&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; kitty --directory &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$PROJECT_DIR&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; -e &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$PROJECT&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;So, what this does is this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It finds all the directories where a &lt;code&gt;.tmux&lt;/code&gt; file exists, excluding non-useful folders like &lt;code&gt;node_modules&lt;/code&gt;. The &lt;code&gt;-prune&lt;/code&gt; flag is passed to avoid recursion further inside a directory once a &lt;code&gt;.tmux&lt;/code&gt; file is found. The results of &lt;code&gt;find&lt;/code&gt; are &amp;ldquo;piped&amp;rdquo; into &lt;code&gt;rofi&lt;/code&gt;, which displays the results. User selection is then stored in the &lt;code&gt;PROJECT&lt;/code&gt; variable.&lt;/li&gt;
&lt;li&gt;Once a file is selected, the full path without the filename is extracted and stored in the &lt;code&gt;PROJECT_DIR&lt;/code&gt; variable.&lt;/li&gt;
&lt;li&gt;Finally, all that is left to do is check if the user selected a project and if so, run it with the desired terminal from the correct directory. This will be different for most terminal emulators: here, an example is shown with the &lt;a href="https://sw.kovidgoyal.net/kitty/"&gt;kitty terminal&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="3-script-to-close-projects"&gt;3. Script to close projects&lt;/h2&gt;
&lt;p&gt;Here, we are concerned with the sessions that are now opened and that we might want to close. In a similar fashion as what we did to open projects, we want to kill them with a script that will run Rofi and do the job silently in the background. One such script that will get us there is shown below:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Get the name of all running sessions&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;TMUX_SESSIONS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;tmux ls &lt;span class="p"&gt;|&lt;/span&gt; cut -f1 -d &lt;span class="s2"&gt;&amp;#34;:&amp;#34;&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# No listed session, then notify about it&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; -z &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$TMUX_SESSIONS&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; notify-send &lt;span class="s2"&gt;&amp;#34;No active tmux session found&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Show all running sessions with Rofi and store the selection in a variable&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;SESSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$TMUX_SESSIONS&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; rofi -sep &lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt; -i -dmenu -theme purple -font &lt;span class="s1"&gt;&amp;#39;JetBrainsMono 14&amp;#39;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -width &lt;span class="m"&gt;90&lt;/span&gt; -show window&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Kill the selected session&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tmux kill-session -t &lt;span class="nv"&gt;$SESSION&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In this case, the usage is quite straightforward: only running sessions are shown, so it&amp;rsquo;s just a matter of choosing the one we want to kill or pressing the &lt;code&gt;Escape&lt;/code&gt; key to abort the Rofi pop-up.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="example-workflow"&gt;Example workflow&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s a matter of setting up keyboard shortcuts to run the scripts to open and kill projects. For instance, one such configuration for the &lt;code&gt;i3&lt;/code&gt; window manager would be as follows:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__bar" data-pagefind-ignore&gt;
 &lt;span class="code-block__lang"&gt;bash&lt;/span&gt;
 &lt;button class="code-block__wrap" type="button" aria-pressed="false" hidden&gt;Wrap&lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bindsym &lt;span class="nv"&gt;$mod&lt;/span&gt;+Mod1+p &lt;span class="nv"&gt;$exec&lt;/span&gt; ~/path/to/projects-start.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bindsym &lt;span class="nv"&gt;$mod&lt;/span&gt;+Mod1+k &lt;span class="nv"&gt;$exec&lt;/span&gt; ~/path/to/projects-kill.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;A simple shortcut lets us choose sessions to open.&lt;/li&gt;
&lt;li&gt;Next, if we decide to kill a session at some point, we have another shortcut to do that.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Far from being a perfect solution (although it already feels comfortable as a main driver), this workflow initiates what I think can lead to substantial optimizations when it comes to using tmux. There&amp;rsquo;s room for improvement when a user selects an already opened session: ideally, we would just switch to that session automatically. These details need to be implemented based on the window manager that&amp;rsquo;s being used, but suffice to say, it can be done! In any case, I hope this may give you a semblance of inspiration to take this idea to the next level. There are tools to help with session persistence, such as &lt;a href="https://github.com/tmux-plugins/tmux-resurrect"&gt;tmux-resurrect&lt;/a&gt;, but that&amp;rsquo;s a topic for another time.&lt;/p&gt;
&lt;h2 id="more-resources-and-references"&gt;More resources and references&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=GuH7pw9LejY"&gt;Best Terminal Application for Web Development&lt;/a&gt;, original inspiration for this workflow. — Monsterlessons Academy, YouTube.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tmux/tmux/wiki"&gt;The tmux wiki&lt;/a&gt;, GitHub.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tmux-plugins/tmux-resurrect"&gt;tmux-resurrect&lt;/a&gt;, GitHub.&lt;/li&gt;
&lt;/ul&gt;</content:encoded><dc:creator>Sébastien Lavoie</dc:creator><pubDate>Sun, 19 Sep 2021 18:13:00 -0500</pubDate><guid isPermaLink="false">https://www.sglavoie.com/posts/managing-multiple-tmux-sessions-at-once/</guid><category>workflow</category><category>bash</category><category>i3</category><category>rofi</category><category>script</category><category>tmux</category></item></channel></rss>