<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://joelchrono.xyz/feeds/bash.xml" rel="self" type="application/atom+xml" /><link href="https://joelchrono.xyz/" rel="alternate" type="text/html" /><updated>2026-08-17T21:29:37-06:00</updated><id>https://joelchrono.xyz/feeds/bash.xml</id><title type="html">joelchrono’s blog</title><author><name>joelchrono</name><email>me@joelchrono.xyz</email></author><entry><title type="html">Rofi is my favorite app launcher</title><link href="https://joelchrono.xyz/blog/rofi-is-my-favorite-launcher/" rel="alternate" type="text/html" title="Rofi is my favorite app launcher" /><published>2023-01-16T13:15:00-06:00</published><updated>2023-01-16T13:15:00-06:00</updated><id>https://joelchrono.xyz/blog/rofi-is-my-favorite-launcher</id><content type="html" xml:base="https://joelchrono.xyz/blog/rofi-is-my-favorite-launcher/"><![CDATA[<p>Rofi describes itself as a <em>A window switcher, application launcher, ssh dialog, dmenu replacement and more</em>.</p>

<p>And that’s pretty much it. Its super fast and minimal, and works pretty much anywhere. There is even a <a href="https://hg.sr.ht/~scoopta/wofi">Wayland clone of it</a>, which I don’t use but at least its there.</p>

<p>Rofi is so good, I got really fired up when my fellow fedizen <a href="https://lazybear.social/hyde">@hyde</a> mentioned how <a href="https://lazybea.rs/posts/rofi-not-for-me/">rofi isn’t for him</a>, and he will stick to the default AwesomeWM launcher, I couldn’t help myself, and decided to write this post and answer to his complaints.</p>

<p>First of all. This is all written in a jokeful manner, no hard feelings or anything.</p>

<p><em>Seriously?</em> You use <a href="https://lazybea.rs/posts/passwords-and-websites/">pass</a> as your password manager, you use <a href="https://lazybea.rs/posts/dracula-and-mutt/">mutt for email</a>, stuff like <a href="https://lazybea.rs/posts/fzf/">fzf</a> and a bunch of other tools, you even got a weekly series of <a href="https://lazybea.rs/tags/cli/">CLI tool recommendations</a>. HOW DARE YOU disrespect rofi like THAT!?</p>

<p>Rofi can be integrated with pretty much all of the above. You can use tools such as <a href="https://github.com/carnager/rofi-pass">rofi-pass</a> to autofill your passwords everywhere (kind of better than KeepassXC Browser extensions tbh). You could create many kinds of things with neomutt, like <a href="https://beune.dev/posts/mailto-neomutt/">handling mailto: links</a></p>

<p>You can pretty much pipe whatever you want on rofi, and create general scripts for a ton of stuff. Compared to some launchers that come built-in in some desktop environments or window managers. Rofi will work on them all and can be customized quite a lot.</p>

<p>The only thing that comes close to rofi is one of its inspirations, <a href="https://tools.suckless.org/dmenu/">dmenu</a>. But given that it is even more bare bones and any additions have to be patched (rather than simply configured with rofi). I find it a little harder to sell for most.</p>

<p>I have a few posts sharing scripts, some of them <a href="/blog/rofi-automated-blog/">using rofi</a> and its simply <strong>fantastic</strong>. I’ve a couple other scripts you may be interested in checking out!</p>

<p>I actually recently changed the <a href="/blog/a-quick-tag-editor-for-my-website/">script to edit tags</a> to use just rofi. You can see some it, as well as some more of my rofi scripts <a href="https://tildegit.org/chrono/dotfiles/src/branch/main/stow_home/rofi/.config/rofi">in my dotfiles</a></p>

<p>This is day 16 of <a href="https://100daystooffload.com">#100DaysToOffload</a></p>]]></content><author><name>joelchrono</name><email>me@joelchrono.xyz</email></author><category term="bash" /><category term="coding" /><category term="linux" /><category term="foss" /><category term="ramble" /><summary type="html"><![CDATA[You probably already know by now, because I've mentioned almost as many times as to have a tag just for it. You should use Rofi!]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://joelchrono.xyz/assets/img/blogs/2023-01-16-rofi.jpg" /><media:content medium="image" url="https://joelchrono.xyz/assets/img/blogs/2023-01-16-rofi.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Cleaning my room, cleaning my phone</title><link href="https://joelchrono.xyz/blog/cleaning-my-room-cleaning-my-phone/" rel="alternate" type="text/html" title="Cleaning my room, cleaning my phone" /><published>2023-01-11T20:21:17-06:00</published><updated>2023-01-11T20:21:17-06:00</updated><id>https://joelchrono.xyz/blog/cleaning-up-day</id><content type="html" xml:base="https://joelchrono.xyz/blog/cleaning-my-room-cleaning-my-phone/"><![CDATA[<p>Since some friends will visit us soon enough, I was going to clean my bedroom, since that’s were they’ll stay for a few days. I was doing a decent job at it, if a little relaxed.</p>

<p>For some reason, my mother decided to barge into my room to clean up for me, and soon my siblings joined for the massacre. They basically started all over again, opening containers, drawers and reordering everything she saw out of place. I wanted to do it all alone while listening to some podcasts but it was just impossible.</p>

<p>I was really mad at first, but it soon turned kinda wholesome, I still have a few nostalgic things from my childhood. Some toys, my puzzle collection, an old photo album, a lot of keychains (for some reason I ignore), my small watch collection, and other miscellaneous things. In the end, I have to admit that they did a better job than I could have, and we had a good time, so it was all cool.</p>

<p>I also took some time later to do some cleanup. I backed up some pictures from my phone and compressed them. Using tools such as ImageMagick and the like.</p>

<p>This is a quick script I used, that will compress the image but will preserve its modified date to its creation date. I like this because sorting images by date is easier for me. I actually used ChatGPT for this script. 😉</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">for </span>filename <span class="k">in</span> <span class="k">*</span>.jpg<span class="p">;</span> <span class="k">do
	</span>mogrify <span class="nt">-verbose</span> <span class="nt">-resize</span> 1600 <span class="nt">-quality</span> 85 <span class="s2">"</span><span class="nv">$filename</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$filename</span><span class="s2">"</span>

  <span class="nv">date_string</span><span class="o">=</span><span class="k">${</span><span class="nv">filename</span>:4:8<span class="k">}</span>
  <span class="nv">time_string</span><span class="o">=</span><span class="k">${</span><span class="nv">filename</span>:13:4<span class="k">}</span>
  
  <span class="c"># Create the timestamp in the format YYYYMMDDHHMM</span>
  <span class="nv">timestamp</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">date_string</span><span class="k">}${</span><span class="nv">time_string</span><span class="k">}</span><span class="s2">"</span>

  <span class="c"># Use the touch command to modify the file's timestamps</span>
  <span class="nb">touch</span> <span class="nt">-m</span> <span class="nt">-t</span> <span class="s2">"</span><span class="nv">$timestamp</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$filename</span><span class="s2">"</span>
  
  <span class="nb">echo</span> <span class="s2">"modifying </span><span class="nv">$filename</span><span class="s2"> with timestamp </span><span class="nv">$timestamp</span><span class="s2">"</span>
  
<span class="k">done</span>
</code></pre></div></div>

<p>I made some new folders, reorganized some stuff and I am getting ready for switching to a new Android 13 rom. I have to do some backups, but I am almost ready! We’ll see.</p>

<p>For some reason I feel like I need to delete and uninstall every app and file I don’t need, even though I will wipe it completely anyways. I am just weird like that.</p>

<p>This is day 11 of <a href="https://100daystooffload.com">#100DaysToOffload</a></p>]]></content><author><name>joelchrono</name><email>me@joelchrono.xyz</email></author><category term="short" /><category term="bash" /><category term="personal" /><summary type="html"><![CDATA[Today was quite a tiring day, we are having friends visiting and I had to clean up my room for them to stay. Still, I also did some cleaning up of my phone's storage]]></summary></entry><entry><title type="html">A quick tag editor for my website</title><link href="https://joelchrono.xyz/blog/a-quick-tag-editor-for-my-website/" rel="alternate" type="text/html" title="A quick tag editor for my website" /><published>2023-01-05T08:08:43-06:00</published><updated>2023-01-05T08:08:43-06:00</updated><id>https://joelchrono.xyz/blog/a-quick-tag-editor-for-my-website</id><content type="html" xml:base="https://joelchrono.xyz/blog/a-quick-tag-editor-for-my-website/"><![CDATA[<p>I have a bit of a love hate relationship with bash scripting. Because you get to have access to all kinds of small tools, piping and doing unixy things, at the cost of having horrible syntax and being kinda hard to read sometimes.</p>

<p>Anyways, a couple posts ago I shared how to sort tags in different ways, the truth is I’ve been meaning to do some cleaning up, inspired by <a href="https://www.adamsdesk.com/posts/clean-tags-categories-two/">Adam’s post</a>.</p>

<p>He used the usual commands such as <code class="language-plaintext highlighter-rouge">sed</code> and <code class="language-plaintext highlighter-rouge">grep</code>, and I decided to quickly write a script to edit the desired tags for any file in a similar manner.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/usr/bin/bash</span>
<span class="c">#</span>
<span class="nv">file</span><span class="o">=</span><span class="nv">$1</span>
<span class="nv">oldtags</span><span class="o">=</span><span class="si">$(</span><span class="nb">cat</span> <span class="nv">$1</span> | <span class="nb">grep</span> <span class="s2">"tags:"</span> | <span class="nb">head</span> <span class="nt">-1</span> | <span class="nb">awk</span> <span class="s1">'{for (i=2; i&lt;NF; i++) printf $i " "; print $NF}'</span><span class="si">)</span>

<span class="nb">echo</span> <span class="nv">$oldtags</span> <span class="o">&gt;</span> /tmp/tagedit
vim /tmp/tagedit

<span class="nv">newtags</span><span class="o">=</span><span class="si">$(</span><span class="nb">cat</span> /tmp/tagedit<span class="si">)</span>

<span class="nb">rm</span> <span class="nt">-fv</span> /tmp/tagedit

<span class="nb">sed</span> <span class="nt">-i</span> <span class="s2">"s/</span><span class="nv">$oldtags</span><span class="s2">/</span><span class="nv">$newtags</span><span class="s2">/g"</span> <span class="s2">"</span><span class="nv">$file</span><span class="s2">"</span>
</code></pre></div></div>

<p>This code is rather simple, it takes the path of a file, which is given as an argument, running something like</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./edit-tags.sh filename
</code></pre></div></div>

<p>That filename is parsed, using grep, head and awk. a new temporary file containing all existing tags of that file gets opened with vim, containing the existing tags. From there I can add or remove tags as I please, and once saved, I replace the original file accordingly.</p>

<p>It is rather simple, and I think it could be done better. So please, I beg you to give me any suggestions to improve it. I tried my best to understand stuff like <code class="language-plaintext highlighter-rouge">getopts</code> and the like, to have arguments and flags but I just didn’t really get it.</p>

<p>Regardless, this is day 5 of my second attempt at <a href="https://100daystooffload.com">#100DaysToOffload</a></p>]]></content><author><name>joelchrono</name><email>me@joelchrono.xyz</email></author><category term="tutorial" /><category term="coding" /><category term="bash" /><category term="vim" /><summary type="html"><![CDATA[Yeah, I keep adding new scripts to make my blogging life easier. In this case, to help me edit tags with less hassle.]]></summary></entry><entry><title type="html">Sharing my blogs to the Fediverse automatically</title><link href="https://joelchrono.xyz/blog/sharing-my-blogs-to-the-fediverse-automatically/" rel="alternate" type="text/html" title="Sharing my blogs to the Fediverse automatically" /><published>2022-06-10T20:00:34-05:00</published><updated>2022-06-10T20:00:34-05:00</updated><id>https://joelchrono.xyz/blog/sharing-my-blogs-to-the-fediverse-automatically</id><content type="html" xml:base="https://joelchrono.xyz/blog/sharing-my-blogs-to-the-fediverse-automatically/"><![CDATA[<p>There are many problems that come when you don’t use some CMS like Wordpress or Ghost, and this is one of them. When I <a href="https://joelchrono.xyz/blog/how-to-add-mastodon-comments-to-jekyll-blog/">chose Mastodon as commenting system for my blog</a> I realized it would be quite a process to share my post and get the comment section working. I had already <a href="https://joelchrono.xyz/blog/rofi-automated-blog/">automated the blog creation process</a>, but I still had to do all this:</p>

<ul>
  <li>finish writing</li>
  <li>git add, git commit, git push</li>
  <li>write toot on mastodon sharing my blogpost</li>
  <li>copy toot link</li>
  <li>paste toot link id on original blogpost</li>
  <li>git add, git commit, git push</li>
  <li>comments section now works!</li>
</ul>

<p>However, I decided to summon the power of the command line and bash scripting once again, and I finally managed to automate pretty much all of it.</p>

<p>It depends on some basic tools such as <code class="language-plaintext highlighter-rouge">sed</code>, <code class="language-plaintext highlighter-rouge">cut</code>, <code class="language-plaintext highlighter-rouge">grep</code>, but it also requires a very simple mastodon client for the command line, <code class="language-plaintext highlighter-rouge">toot</code>, you probably have it all installed already, and toot is not hard to setup either way.</p>

<p>There really is not a lot to talk about other than this. Here is the script, its not really super clean or anything (any suggestion are absolutely welcome) but at least its serviceable.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/usr/bin/bash</span>

<span class="k">if </span>git rev-parse <span class="nt">--git-dir</span> <span class="o">&gt;</span> /dev/null 2&gt;&amp;1<span class="p">;</span> <span class="k">then</span>
    : <span class="c"># This is a valid git repository</span>

    <span class="c"># All markdown files start with YYYY-MM-DD</span>
    <span class="nv">lastpost</span><span class="o">=</span><span class="si">$(</span>/usr/bin/ls <span class="k">${</span><span class="nv">markdown_posts_folder</span><span class="k">}</span>/<span class="k">*</span>.md | <span class="nb">sort</span> <span class="nt">-r</span> | <span class="nb">head</span> <span class="nt">-n</span> 1<span class="si">)</span> 
    <span class="nv">getdesc</span><span class="o">=</span><span class="si">$(</span><span class="nb">grep</span> <span class="s2">"description:"</span> <span class="nv">$lastpost</span> | <span class="nb">cut</span> <span class="nt">-d</span> <span class="s2">" "</span> <span class="nt">-f2-</span><span class="si">)</span>
    <span class="nv">geturl</span><span class="o">=</span><span class="si">$(</span><span class="nb">grep</span> <span class="s2">"permalink:"</span> <span class="nv">$lastpost</span> | <span class="nb">cut</span> <span class="nt">-d</span> <span class="s2">" "</span> <span class="nt">-f2-</span><span class="si">)</span>
    <span class="nv">gettags</span><span class="o">=</span><span class="si">$(</span><span class="nb">grep</span> <span class="s2">"tags:"</span> <span class="nv">$lastpost</span> | <span class="nb">cut</span> <span class="nt">-d</span> <span class="s2">" "</span> <span class="nt">-f2-</span> | <span class="nb">sed</span> <span class="nt">-r</span> <span class="s1">'s/([^ ]+)/#\1/g'</span><span class="si">)</span>
    <span class="nv">post</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="nt">-e</span> <span class="s2">"</span><span class="k">${</span><span class="nv">getdesc</span><span class="k">}</span><span class="s2"> </span><span class="se">\n\n</span><span class="s2">https://joelchrono.xyz/</span><span class="k">${</span><span class="nv">geturl</span><span class="k">}</span><span class="s2"> </span><span class="se">\n\n</span><span class="k">${</span><span class="nv">gettags</span><span class="k">}</span><span class="s2"> #blogpost"</span><span class="si">)</span>
    <span class="nv">posturl</span><span class="o">=</span><span class="si">$(</span>toot post <span class="s2">"</span><span class="nv">$post</span><span class="s2">"</span> | <span class="nb">cut</span> <span class="nt">-d</span>/ <span class="nt">-f5</span><span class="si">)</span>
    <span class="nb">echo</span> <span class="nv">$posturl</span>
    <span class="nb">sed</span> <span class="nt">-i</span> <span class="s2">"s/commentsid/</span><span class="nv">$posturl</span><span class="s2">/g"</span> <span class="s2">"</span><span class="nv">$lastpost</span><span class="s2">"</span>

    git add <span class="k">*</span>
    git commit <span class="nt">-m</span> <span class="s2">"automatically added comments"</span>
    git push

    <span class="nb">exit</span>

<span class="c"># directory may not be the top level.</span>
<span class="c"># Check the output of the git rev-parse command if you care</span>
<span class="k">else</span>
    : <span class="c"># this is not a git repository</span>
    <span class="nb">echo</span> <span class="s2">"Run this inside of website folder"</span>
    <span class="nb">exit

</span><span class="k">fi</span>
</code></pre></div></div>

<p>There you go, I hope you find it useful, maybe you can improve it even further. If so, make sure to let me know, I am still learning these things.</p>]]></content><author><name>joelchrono</name><email>me@joelchrono.xyz</email></author><category term="blog" /><category term="tutorial" /><category term="coding" /><category term="bash" /><category term="linux" /><category term="git" /><category term="webdev" /><category term="blog" /><summary type="html"><![CDATA[I always share my blogposts on Mastodon when I am done writing them, but it has always been a little annoying to do so. Not anymore.]]></summary></entry><entry><title type="html">Add images to Markdown files (for Jekyll)</title><link href="https://joelchrono.xyz/blog/add-images-to-markdown-files-(for-jekyll)/" rel="alternate" type="text/html" title="Add images to Markdown files (for Jekyll)" /><published>2022-01-27T10:16:00-06:00</published><updated>2022-01-27T10:16:00-06:00</updated><id>https://joelchrono.xyz/blog/add-images-to-markdown-files-(for-jekyll)</id><content type="html" xml:base="https://joelchrono.xyz/blog/add-images-to-markdown-files-(for-jekyll)/"><![CDATA[<p>So I have already done quite a lot of posts to make the creation of new posts easier. I find Jekyll to be a pretty decent static site generator, but this little script should work with whatever you got. As long as you customize it to your file structure.</p>

<p>The script comes as a request by <a href="https://fosstodon.org/@celia">Ru</a>, or at least this is what I hope she meant when <a href="https://fosstodon.org/@celia/107694900078045072">she posted</a>:</p>

<blockquote>
  <p>Static site users who embed images frequently – what’s your workflow for it? #AskFedi</p>
</blockquote>

<p>Well, my <em>previous workflow</em> was simple enough:</p>

<ol>
  <li>Take pictures.</li>
  <li>Move to assets folder.</li>
  <li>Rename them to something like $date-$filename_without_spaces.png.</li>
  <li>Add markdown syntax and type the whole thing.</li>
  <li>Cry because you messed up the directory path.</li>
</ol>

<p>So I went ahead and decided to work on a little script I named <code class="language-plaintext highlighter-rouge">aijk</code> (Add image to Jekyll), using bash and rofi, tools that I’ve used before with decent success. I am actually really happy of how it turned out.</p>

<h1 id="the-script">The script</h1>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>

<span class="c">### AIJK (Add image to Jekyll)</span>
<span class="c">### By joelchrono12</span>

<span class="nv">pic</span><span class="o">=</span><span class="nv">$1</span>
<span class="nv">name</span><span class="o">=</span><span class="si">$(</span>rofi <span class="nt">-l</span> 0 <span class="nt">-width</span> 50 <span class="nt">-p</span> <span class="s2">"Title"</span> <span class="nt">-dmenu</span><span class="si">)</span>
<span class="nv">filen</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="nv">$name</span> | <span class="nb">tr</span> <span class="s2">" ,.!"</span> <span class="s2">"-"</span>| <span class="nb">awk</span> <span class="s1">'{print tolower($0)}'</span><span class="si">)</span>
<span class="nv">today</span><span class="o">=</span><span class="si">$(</span><span class="nb">date</span> +<span class="s2">"%Y-%m-%d"</span><span class="si">)</span>
<span class="nv">filename</span><span class="o">=(</span><span class="nv">$today</span>-<span class="nv">$filen</span><span class="o">)</span>
<span class="nv">path</span><span class="o">=</span>/path/to/website <span class="c">#without / at the end</span>
<span class="nv">imgs</span><span class="o">=</span>/from/site_root/to/assets/ <span class="c">#example = /assets/img/blogs/</span>
<span class="nv">last_post</span><span class="o">=</span><span class="si">$(</span>/usr/bin/ls /path/to/markdown/files/<span class="k">*</span>.md | <span class="nb">sort</span> <span class="nt">-r</span> | <span class="nb">head</span> <span class="nt">-n</span> 1<span class="si">)</span>

convert <span class="nv">$1</span> <span class="nt">-quality</span> 75 <span class="k">${</span><span class="nv">path</span><span class="k">}${</span><span class="nv">imgs</span><span class="k">}${</span><span class="nv">filename</span><span class="k">}</span>.png

<span class="nb">printf</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">![</span><span class="k">${</span><span class="nv">name</span><span class="k">}</span><span class="s2">](</span><span class="k">${</span><span class="nv">imgs</span><span class="k">}${</span><span class="nv">filename</span><span class="k">}</span><span class="s2">.png)"</span> <span class="o">&gt;&gt;</span> <span class="nv">$last_post</span>

</code></pre></div></div>

<h2 id="how-to-use">How to use</h2>

<p>Once added to your $PATH and making it executable, all you need is to change the required paths in the script, I think most of you will be able to figure it out on your own, but reach me out if you need help.</p>

<p>You can run it just by doing this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>aijk file.png
</code></pre></div></div>

<p>This is how it works:</p>

<ul>
  <li>Obtain picture file from argument.</li>
  <li>Add a Title to file via a rofi input.</li>
  <li>Create filename for file itself.</li>
  <li>Set paths to different required things (depends on your site).</li>
  <li>Get the latest markdown files from your site.</li>
  <li>Make changes to picture so its smaller or whatever (can be customized, requires ImageMagick).</li>
  <li>Print formatted markdown line to bottom of the latest markdown file.</li>
</ul>

<h2 id="adding-a-graphical-option-for-mouse-users">Adding a Graphical option for mouse users</h2>

<p>You can run this script with absolute ease from your terminal, if that’s what you want, but I also figured out a way to do it from a GUI if you are using Thunar as a file manager (might be possible with others, haven’t checked).</p>

<ol>
  <li>Open Thunar &gt; Edit &gt; Configure custom actions.</li>
  <li>Add a new entry for <code class="language-plaintext highlighter-rouge">aijk</code> and save it.</li>
</ol>
<figure class="img">
  <picture>
    <source srcset="/assets/img/blogs/2022-01-27-thunar-configuration.webp" type="image/webp" />
    <source srcset="/assets/img/blogs/2022-01-27-thunar-configuration.jpg" type="image/jpeg" />
    <img class="mx-auto" src="/assets/img/blogs/2022-01-27-thunar-configuration.jpg" alt="" />
  </picture>
  </figure>

<ol>
  <li>Set the appearance conditions to images only.</li>
  <li>Right click on any image to try it out!</li>
</ol>

<h1 id="final-thoughts">Final thoughts</h1>

<p>I am not completely happy with how this works. But this is usable and easy to expand, there could be a way to select the destination file instead of just getting the latest one. But I don’t normally add new images to old posts anyways, so I figured most people would be ok with how this works right now.</p>

<p>The script also assumes you want to start all your files with the date, and that your markdown files also start with the dates, since <code class="language-plaintext highlighter-rouge">sort</code>  will fail to place the line in the latest file, if such file is not the first in its output.</p>

<p>There is also no way to do this with multiple files as of now, I might be able to come up with something, I could just create another script that makes use of this one to make multiple additions at once.</p>

<p>Anyways, this is what I’ll do now to add images, I will simply right click, click again and give them a name!. Or do it properly in the terminal, whatever fits me best.</p>

<p>This has been day 95 of <a href="https://100daystooffload.com">#100DaysToOffload</a>. Make sure to check out <a href="https://rusingh.com/">Ru’s website</a>, since she single-handedly managed to inspire me to work on this quick script.</p>

<p><strong>NOTE: This is actually day 96, from here it all went wrong. If you don’t understand this note, [read here]</strong></p>]]></content><author><name>joelchrono</name><email>me@joelchrono.xyz</email></author><category term="tutorial" /><category term="coding" /><category term="bash" /><category term="linux" /><category term="webdev" /><category term="blog" /><category term="jekyll" /><summary type="html"><![CDATA[I decided to streamline the process of adding images to new posts quickly, how did I do it? Using bash scripts of course!]]></summary></entry><entry><title type="html">Blop static site generator</title><link href="https://joelchrono.xyz/blog/blop-static-site-generator/" rel="alternate" type="text/html" title="Blop static site generator" /><published>2022-01-14T20:12:58-06:00</published><updated>2022-01-14T20:12:58-06:00</updated><id>https://joelchrono.xyz/blog/blop-static-site-generator</id><content type="html" xml:base="https://joelchrono.xyz/blog/blop-static-site-generator/"><![CDATA[<p>So, I have been part of a Tilde community for a while, a public unix server known as <a href="https://tilde.cafe">tilde.cafe</a>.</p>

<p>Because of that, I got access to some nice things, like a website, a gemini capsule and an email address, which is kind of nice. I have been using that site as a place to mirror this very same website in case anything happens. Like losing my current domain or anything like that.</p>

<p><a href="https://gitlab.com/uoou/blop/">Blop</a> is a pretty nice static site generator that is basically just a bash script that uses other programs such as sed, awk and pandoc to put together a simple site generated from markdown files and simple templates.</p>

<p>However, it had a pretty serious issue, at least for me. The generated html files ended with <code class="language-plaintext highlighter-rouge">*.html</code> instead of being a clean url like here in Jekyll.</p>

<p>So I forked the project, put some work into it and I actually managed to do it!</p>

<p>I am not that great of a bash coder, and it was not really a matter of bash but of knowing where to look and using <code class="language-plaintext highlighter-rouge">/</code> to search for the right things in Vim.</p>

<p>In the end I now have clean URLs in my <a href="https://chrono.tilde.cafe">alternative site</a>, which is kind of great.</p>

<p>You can take a look at my fork, which is not really that different from the original in my <a href="https://tildegit.org/chrono/blop">tildegit</a> repository.</p>

<p>This has been day 83 of <a href="https://100daystooffload.com">#100DaysToOffload</a></p>]]></content><author><name>joelchrono</name><email>me@joelchrono.xyz</email></author><category term="bash" /><category term="coding" /><category term="blog" /><category term="short" /><category term="small-web" /><summary type="html"><![CDATA[While my main site is using Jekyll, I actually have another site that serves as a simpler mirror to this one. There I use Blop, an SSG written in Bash that I can customize to my liking]]></summary></entry><entry><title type="html">Backup your dotfiles using stow</title><link href="https://joelchrono.xyz/blog/backing-up-my-dotfiles/" rel="alternate" type="text/html" title="Backup your dotfiles using stow" /><published>2021-08-31T16:20:03-05:00</published><updated>2021-08-31T16:20:03-05:00</updated><id>https://joelchrono.xyz/blog/backing-up-my-dotfiles</id><content type="html" xml:base="https://joelchrono.xyz/blog/backing-up-my-dotfiles/"><![CDATA[<p>Managing dotfiles has always been quite annoying to me. But thankfully, I never really had a reason to do it too often. When <a href="/blog/switching-distro-ending-school/">I moved from Void Linux to EndeavourOS</a>, all I did was <code class="language-plaintext highlighter-rouge">tar</code> my whole <code class="language-plaintext highlighter-rouge">.config</code> and copied the file to an external drive.</p>

<p>That works fine,  but it’s not the best way to backup the constant changes I usually do to customize the way my programs look or act, and as a customization freak, that happens <em>quite often</em>.</p>

<p>I had seen many different ways to backup dotfiles: git bare repos, <a href="https://yadm.io">yadm</a>, symlinking scripts, and of course, GNU Stow.</p>

<p>All of these methods have their up and downs, but in the end, <code class="language-plaintext highlighter-rouge">stow</code> convinced me, and I decided to give it a try. According to their <a href="https://www.gnu.org/software/stow/">home page</a>:</p>

<blockquote>
  <p>GNU Stow is a symlink farm manager which takes distinct packages of software and/or data located in separate directories on the filesystem, and makes them appear to be installed in the same place.</p>
</blockquote>

<p>If you don’t really understand it yet, don’t worry, <em>I don’t either!</em> But in this blog, I will do my best to show you the steps to backup your current config files, I hope whoever reads this finds it useful.</p>

<h1 id="creating-a-dotfiles-repository">Creating a dotfiles repository</h1>

<p>The first step to backup your dotfiles, is to create an <strong>empty</strong> repository in some hosting service, such as <a href="https://github.com">GitHub</a>, <a href="https://codeberg.org">Codeberg</a> or <a href="https://sourcehut.org">SourceHut</a>. This is optional if you only want to see how <code class="language-plaintext highlighter-rouge">stow</code> works, but necessary to have an external backup outside your computer. Once you are done, clone the empty repo to your home directory, or in any place you want. (This tutorial will be using the home directory).</p>

<p>To clone a repo, just do:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone https://site.com/link/to/repo
</code></pre></div></div>

<p>In my case, I use <a href="https://tildegit.org">Tildegit</a>, a Gitea instance, so my command looks like this.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone https://tildegit.org/chrono/dotfiles.git
</code></pre></div></div>

<p>You can clone my dotfiles if you want to use them, <a href="https://tildegit.org/chrono/dotfiles.git">here</a> they are if you are interested.</p>

<h1 id="using-stow-to-backup-your-configuration">Using stow to backup your configuration</h1>

<p>Before actually backing something up, we need to install <code class="language-plaintext highlighter-rouge">stow</code>, depending on your distribution, you can install it with your package manager of choice. In my case, Endeavor is based on Arch, so I do:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>pacman <span class="nt">-S</span> stow
</code></pre></div></div>

<p>Lets start by backing up the configuration of a single program. While we can backup our whole <code class="language-plaintext highlighter-rouge">.config</code> folder, that’s <strong>not</strong> a good idea, since <strong>some</strong> programs store <strong>important</strong> information that <em>should</em> stay private, and I think its better to only backup what we have actually configured. For this example, I will backup my <code class="language-plaintext highlighter-rouge">picom</code> configurations.</p>

<p>The first step is to create a new directory to use as a base (if you cloned your empty repo, you’ll be using that). You also have to create a folder structure, depending on where you want the configuration to be stored, this depends on the location the program will read its configuration from. We’ll refer to this folder as <code class="language-plaintext highlighter-rouge">dotfiles</code>.</p>

<p>If you want to add a <code class="language-plaintext highlighter-rouge">README</code> file or other stuff that you is not a config files, you can create another directory inside of <code class="language-plaintext highlighter-rouge">dotfiles</code>, in my case, I have made a <code class="language-plaintext highlighter-rouge">stow_home</code> folder, which will be where we’ll run the <code class="language-plaintext highlighter-rouge">stow</code> command. <sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup></p>

<p>Lets explain how <code class="language-plaintext highlighter-rouge">stow</code> works. Picom expects its config file in <code class="language-plaintext highlighter-rouge">~/.config/picom/picom.conf</code>, so, inside of the new <code class="language-plaintext highlighter-rouge">home_stow</code> directory, we recreate that folder structure, but using the program name (<code class="language-plaintext highlighter-rouge">picom</code>) instead of the tilde (<code class="language-plaintext highlighter-rouge">~</code>), which usually refers to the home folder. <sup id="fnref:2"><a href="#fn:2" class="footnote" rel="footnote" role="doc-noteref">2</a></sup></p>

<p>Lets put all of this together in the terminal.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir </span>dotfiles <span class="o">&amp;&amp;</span> <span class="nb">cd </span>dotfiles <span class="c"># mkdir only if you didn't clone it</span>
<span class="nb">touch </span>README.md other_file.txt <span class="c"># optional</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> ~/dotfiles/stow_home/picom/.config/picom/
<span class="nb">mv</span> ~/.config/picom/ ~/dotfiles/stow_home/picom/.config/
</code></pre></div></div>

<p>Once you do that, your picom folder is no longer in the <code class="language-plaintext highlighter-rouge">.config</code> directory, but inside of <code class="language-plaintext highlighter-rouge">dotfiles/home_stow</code>, following <em>the same folder structure</em>, as if <code class="language-plaintext highlighter-rouge">home_stow</code> was the <code class="language-plaintext highlighter-rouge">/home</code> directory, followed by the user <code class="language-plaintext highlighter-rouge">picom</code> and the path to the picom configuration files. <sup id="fnref:4"><a href="#fn:4" class="footnote" rel="footnote" role="doc-noteref">3</a></sup></p>

<p>Now we repeat this process with all of the files and directories we want to back up. Once done, the behavior of the programs you use, such as <code class="language-plaintext highlighter-rouge">vim</code>, should revert to their default configurations, since the user config files are no longer there. So, <strong>now its time to fix that!</strong> Inside of <code class="language-plaintext highlighter-rouge">stow_home</code>, run the following command:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>stow <span class="nt">-vt</span> ~ <span class="k">*</span>
</code></pre></div></div>

<p>This will symlink <strong>everything</strong> inside of <code class="language-plaintext highlighter-rouge">stow_home</code> <sup id="fnref:3"><a href="#fn:3" class="footnote" rel="footnote" role="doc-noteref">4</a></sup>, targetting <code class="language-plaintext highlighter-rouge">~</code> as the starting point. The <code class="language-plaintext highlighter-rouge">-v</code> flag will let you know of everything being done, so you should see an output like this, depending on the programs you backed up:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># $ stow -vt ~ *</span>
LINK: .config/awesome <span class="o">=&gt;</span> ../dotfiles/stow_home/awesome/.config/awesome
LINK: .config/bat <span class="o">=&gt;</span> ../dotfiles/stow_home/bat/.config/bat
LINK: .config/dunst <span class="o">=&gt;</span> ../dotfiles/stow_home/dunst/.config/dunst
LINK: .config/nvim <span class="o">=&gt;</span> ../dotfiles/stow_home/nvim/.config/nvim
LINK: .config/picom <span class="o">=&gt;</span> ../dotfiles/stow_home/picom/.config/picom
LINK: .config/rofi <span class="o">=&gt;</span> ../dotfiles/stow_home/rofi/.config/rofi
LINK: .config/spectrwm <span class="o">=&gt;</span> ../dotfiles/stow_home/spectrwm/.config/spectrwm
</code></pre></div></div>

<h1 id="file-versioning-with-git">File versioning with git</h1>

<p>If you stumbled upon this guide, you probably know the necesary <code class="language-plaintext highlighter-rouge">git</code> commands to backup everything to the service you chose at the beginning of this guide.</p>

<p>Generally, everytime you do changes you only need to follow these three commands, inside of your <code class="language-plaintext highlighter-rouge">dotfiles</code> folder.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git add <span class="k">*</span>
git commit <span class="nt">-m</span> <span class="s2">"Added config files"</span>
git push
</code></pre></div></div>

<p>Remember that the last command will not work if you don’t have an external repository.</p>

<p>The manual of GNU Stow contains a lot more than what I mentioned here, like unlinking and other flags that can be used and might be useful for your use case.</p>

<h1 id="finishing-up">Finishing up</h1>

<p>Anyways, that’s all folks, this has been day 54 of <a href="https://100DaysToOffload.com">#100DaysToOffload</a>, you can check out my dotfiles if you want to see how <code class="language-plaintext highlighter-rouge">stow</code> looks once setup, besides, my <a href="/blog/spectrwm-setup">Spectrwm configuration</a> is quite sick if I do say so myself.</p>

<p>If you feel like a step is not clear enough, please let me know in the comments or via e-mail.</p>

<h2 id="secret-bonus-script">Secret bonus script!</h2>

<p>So, if you read until the end of this blog. I actually did a pretty decent bash script to automate everything here.</p>

<p>All you need to do is configure it to your liking and run it like this</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dotstow file_or_folder
</code></pre></div></div>

<p>The script is as follows, it uses basic tools like <code class="language-plaintext highlighter-rouge">cut</code> and of course, <code class="language-plaintext highlighter-rouge">stow</code></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/usr/bin/bash</span>
<span class="c"># Dotstow - Backup your chosen dotfiles in one go using stow.</span>
<span class="c"># Run it outside of the folder/file you want to back up</span>
<span class="c"># $ dotstow file-or-program</span>
<span class="c"># This program was made by joelchrono12</span>

<span class="nv">STOW_DIR</span><span class="o">=</span><span class="nv">$HOME</span>/dotfiles/stow_home
<span class="nv">DIR</span><span class="o">=</span><span class="si">$(</span><span class="nb">pwd</span> | <span class="nb">cut</span> <span class="nt">-d</span> <span class="s1">'/'</span> <span class="nt">-f4-</span><span class="si">)</span>
<span class="nv">NEW_DIR</span><span class="o">=</span><span class="nv">$STOW_DIR</span>/<span class="nv">$1</span>/<span class="nv">$DIR</span>
<span class="nb">mkdir</span> <span class="nt">-pv</span> <span class="nv">$NEW_DIR</span>
<span class="nb">mv</span> <span class="nt">-v</span> <span class="nv">$1</span> <span class="nv">$NEW_DIR</span>
<span class="nb">cd</span> <span class="nv">$STOW_DIR</span>
stow <span class="nt">-vt</span> ~ <span class="nv">$1</span>
</code></pre></div></div>

<p>The program does not check if a folder already exists or anything like that. So feel free to send any suggestions and changes to it in a comment or using <a href="https://git-send-email.io/">git send-email</a> to my email address.</p>

<hr />

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>You can just use dotfiles as is without a folder inside it, but if you want to be able to quickly deploy everything using <code class="language-plaintext highlighter-rouge">*</code>, you must make a folder where README and other files you don’t want to symlink won’t interfere . <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2">
      <p>Other files, like <code class="language-plaintext highlighter-rouge">.bashrc</code>, are not in the <code class="language-plaintext highlighter-rouge">.config</code> folder, keep in mind that the path to use depends on where the program needs it to be. In this case, it would have to be placed in <code class="language-plaintext highlighter-rouge">~/dotfiles/stow_home/bash/.bashrc</code>. <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:4">
      <p>You can also move specific files of a configuration folder. For example, <code class="language-plaintext highlighter-rouge">tut</code>, a mastodon client, saves the account data (passwords, etc) inside of another file in its configuration folder. if thats the case. You should move only the files you want, instead of the whole directory. <code class="language-plaintext highlighter-rouge">stow</code> should manage the rest. <a href="#fnref:4" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:3">
      <p>If you are unsure about the paths you created, you can run the <code class="language-plaintext highlighter-rouge">-n</code> flag to <em>simulate</em> the output and see exactly where each symlink <em>would be</em> placed. That way you dont end up symlinking in the wrong place and doing weird stuff to your filesystem. <a href="#fnref:3" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>joelchrono</name><email>me@joelchrono.xyz</email></author><category term="linux" /><category term="foss" /><category term="vim" /><category term="tutorial" /><category term="dotfiles" /><category term="coding" /><category term="bash" /><summary type="html"><![CDATA[I finally figured out a nice way to backup my config files, and I decided to upload mine once and for all.]]></summary></entry></feed>