<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>tmux on Arthur Jordão</title><link>/tags/tmux/</link><description>Recent content in tmux on Arthur Jordão</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Tue, 12 Sep 2023 01:00:00 +0000</lastBuildDate><atom:link href="/tags/tmux/index.xml" rel="self" type="application/rss+xml"/><item><title>Tmux + Tmuxinator + FZF workflow</title><link>/posts/tmux-tmuxinator-fzf-workflow/</link><pubDate>Tue, 12 Sep 2023 01:00:00 +0000</pubDate><guid>/posts/tmux-tmuxinator-fzf-workflow/</guid><description>An adventure for the perfect tmux workflow.</description><content:encoded><![CDATA[<p>I adopted tmux to my workflow recently and one of the things that I wanted on my workflow was the ability to create tmux sessions for projects that I was working on using a specific layout. Most often I found myself using the following layout:</p>
<ul>
<li>Window 1 (editor)
<ul>
<li>nvim .</li>
</ul>
</li>
<li>Window 2 (workspace vertical)
<ul>
<li>Server</li>
<li>Random commands workspace.</li>
</ul>
</li>
</ul>
<p>Creating this tmux session was kind of boring. My flow was something like:</p>
<ul>
<li><code>cd</code> to the project.</li>
<li>Start <code>nvim</code> on the first window.</li>
<li>Create a new panel</li>
<li>Split the window into two panels.</li>
</ul>
<p>I thought well, I can optimize that!</p>
<p>First I tried <a href="https://github.com/tmuxinator/tmuxinator#erb">tmuxinator</a>, which is an awesome tool that you can describe a tmux session using yaml. You just need to save a yaml file under <code>.config/tmuxinator/sample.yml</code>, and the configuration looks something like that:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># ~/.config/tmuxinator/sample.yml</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">sample</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">root</span><span class="p">:</span><span class="w"> </span><span class="l">~/dev/personal/sample</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">windows</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">editor</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">layout</span><span class="p">:</span><span class="w"> </span><span class="l">main-vertical</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">panes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="l">vim</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">server</span><span class="p">:</span><span class="w"> </span><span class="l">bundle exec rails s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">logs</span><span class="p">:</span><span class="w"> </span><span class="l">tail -f log/development.log</span><span class="w">
</span></span></span></code></pre></div><p>I started to use it, and I could just execute <code>tmuxinator start sample</code> and everything was setup as I wanted, but one thing that bored me was creating one tmuxinator config per project, and also having to type all the tmuxinator command, needing to remember the name of the project that I wanted to work on <del>my memory sucks!</del>.</p>
<p>So, I got inspiration from <a href="https://github.com/ThePrimeagen/.dotfiles/blob/master/bin/.local/scripts/tmux-sessionizer">tmux sessionizer</a> and gave a try to a way to integrate my tmux workflow with <code>fzf</code>. So I created a base <code>tmuxinator</code> configuration, which is the following:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># ~/.tmuxinator/project.yml</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">project</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">root</span><span class="p">:</span><span class="w"> </span><span class="l">&lt;%= @settings[&#34;workspace&#34;] %&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">windows</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">editor</span><span class="p">:</span><span class="w"> </span><span class="l">nvim .</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">server</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">layout</span><span class="p">:</span><span class="w"> </span><span class="l">main-vertical</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">panes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>-<span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>-<span class="w">
</span></span></span></code></pre></div><p>In this configuration, I just have my default config for every project which is one window with the editor and another with server/workspace panels. This config works for me in 90% of the projects.</p>
<p>Note that on the root I added an <a href="https://github.com/tmuxinator/tmuxinator#erb">erb</a> syntax for passing the project directory.</p>
<p>Using this configuration, I created a new <code>bash</code> command using <code>fzf</code>, that finds all the folders located under <code>~/dev/noredink</code> (my work dev directory), and <code>~/dev/personal</code> (my personal dev directory). After that, I piped it to <code>fzf</code> so I could select the project that I wanted to work on.</p>
<p>If in the folder there is a <code>.tmuxinator.yml</code> I use the local config for the project, if not I use the default config and then I create a new tmux session using tmuxinator.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># ~/.local/bin</span>
</span></span><span class="line"><span class="cl"><span class="c1">#!/usr/bin/env bash</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[[</span> <span class="nv">$#</span> -eq <span class="m">1</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="nv">selected</span><span class="o">=</span><span class="nv">$1</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">    <span class="nv">selected</span><span class="o">=</span><span class="k">$(</span>find ~/dev/noredink ~/dev/personal -mindepth <span class="m">1</span> -maxdepth <span class="m">1</span> -type d <span class="p">|</span> fzf<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[[</span> -z <span class="nv">$selected</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="nb">exit</span> <span class="m">0</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">selected_name</span><span class="o">=</span><span class="k">$(</span>basename <span class="s2">&#34;</span><span class="nv">$selected</span><span class="s2">&#34;</span> <span class="p">|</span> tr . _<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">tmux_config_file</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$selected</span><span class="s2">/.tmuxinator.yml&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[[</span> -f <span class="s2">&#34;</span><span class="nv">$tmux_config_file</span><span class="s2">&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="nb">cd</span> <span class="nv">$selected</span>
</span></span><span class="line"><span class="cl">  tmuxinator <span class="nb">local</span>
</span></span><span class="line"><span class="cl">  <span class="nb">cd</span> -
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">  tmuxinator start project -n <span class="nv">$selected_name</span> <span class="nv">workspace</span><span class="o">=</span><span class="nv">$selected</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span></code></pre></div><p>This is flexible enough to have custom configurations when needed or just use the default one!</p>
<p>I also added <code>.tmuxinator.yml</code> to my <code>~/.gitignore</code>, so it doesn&rsquo;t pollute my git projects with tmux configuration files.</p>
<pre tabindex="0"><code># ~/.gitignore
...
.tmuxinator.yml
</code></pre><p>Finally, I added a keybinding to start the <code>tmux-sessionizer</code> on my tmux config:</p>
<pre tabindex="0"><code># .config/tmux/tmux.conf
...
# Start tmux session on project
bind-key -r f run-shell &#34;tmux neww ~/.local/bin/tmux-sessionizer&#34;
</code></pre><p>Result:</p>
<p><img loading="lazy" src="/posts/tmux-tmuxinator-fzf-workflow/output.webp" type="" alt="A video showing  the command being executed, creating a new tmux session"  /></p>
]]></content:encoded></item></channel></rss>